2009-07-27 59 views
49

Tôi có chương trình dựa trên Visual Studio C++ sử dụng các tiêu đề được biên dịch trước (stdafx.h). Bây giờ chúng tôi đang chuyển ứng dụng sang Linux bằng cách sử dụng gcc 4.x.Xử lý stdafx.h trong mã đa nền

Câu hỏi là cách xử lý tiêu đề được biên dịch trước trong cả hai môi trường. Tôi đã googled nhưng không thể đi đến kết luận.

Rõ ràng là tôi muốn rời khỏi stdafx.h trong Visual Studio vì cơ sở mã là các tiêu đề khá lớn và được biên dịch trước giúp tăng thời gian biên dịch.

Nhưng câu hỏi là phải làm gì trong Linux. Đây là những gì tôi tìm thấy:

  1. Để nguyên stdafx.h. gcc biên dịch mã nhanh hơn đáng kể so với VC++ (hoặc nó chỉ là máy Linux của tôi mạnh hơn ... :)), vì vậy tôi có thể hài lòng với tùy chọn này.
  2. Sử dụng cách tiếp cận từ here - làm stdafx.h cái nhìn tương tự (thiết USE_PRECOMPILED_HEADER chỉ VS):

    #ifdef USE_PRECOMPILED_HEADER 
    ... my stuff 
    #endif 
    
  3. Sử dụng cách tiếp cận từ here - biên dịch VC++ với /FI để ngầm bao gồm stdafx.h trong mỗi tập tin cpp. Vì vậy trong VS mã của bạn có thể được chuyển dễ dàng để được biên dịch mà không có tiêu đề được biên dịch trước và không có mã nào sẽ phải được thay đổi.
    Cá nhân tôi không thích phụ thuộc và sự lộn xộn stdafx.h đang đẩy một cơ sở mã lớn hướng tới. Do đó, tùy chọn này hấp dẫn với tôi - trên Linux, bạn không có stdafx.h, trong khi vẫn có thể bật tiêu đề được biên dịch trước trên VS chỉ /FI.

  4. Trên Linux biên dịch stdafx.h chỉ như là một tiêu đề biên dịch sẵn (bắt chước Visual Studio)

Ý kiến ​​của bạn? Có cách tiếp cận nào khác để xử lý vấn đề này không?

Trả lời

41

Bạn nên sử dụng các tiêu đề được biên dịch sẵn để biên soạn nhanh nhất.

Bạn cũng có thể sử dụng các tiêu đề được biên dịch sẵn trong gcc. See here.

Tiêu đề được biên dịch sẵn biên dịch sẽ có phần mở rộng được nối thêm là .gch thay vì .pch.

Vì vậy, ví dụ nếu bạn precompile stdafx.h bạn sẽ có một tiêu đề biên dịch sẵn mà sẽ được tự động tìm kiếm gọi là stdafx.h.gch bất cứ lúc nào bạn bao gồm stdafx.h

Ví dụ:

stdafx.h:

#include <string> 
#include <stdio.h> 

a.cpp:

#include "stdafx.h" 
int main(int argc, char**argv) 
{ 
    std::string s = "Hi"; 
    return 0; 
} 

Sau đó biên dịch như:

> g++ -c stdafx.h -o stdafx.h.gch
> g++ a.cpp
> ./a.out

biên soạn của bạn sẽ làm việc ngay cả khi bạn loại bỏ stdafx.h sau bước 1.

+0

xóa stdafx.h khỏi đâu? – dimba

+3

Tôi có nghĩa là chỉ sau khi bạn chạy g ++ -c stdafx.h -o stdafx.h.gch, bạn có thể loại bỏ stdafx.h và biên dịch của bạn sẽ vẫn hoạt động (g ++ a.cpp). Bạn sẽ không thực sự làm điều này, nhưng tôi đã đề cập nó như là bằng chứng cho thấy nó đang sử dụng tiêu đề biên dịch sẵn. –

+0

@Brian Có lẽ tôi sai nhưng có vẻ như tùy chọn 4 Tôi đã liệt kê :) Tôi đã cố xoá stdafx.h khỏi a.cpp và nó không được biên dịch - tiêu đề biên dịch trước sẽ chỉ được tìm kiếm nếu tệp tiêu đề tương ứng được bao gồm. Tôi xác nhận nó với strace :)). – dimba

3

Tôi đã sử dụng option 3 lần cuối cùng tôi cần phải làm điều tương tự. Dự án của tôi là khá nhỏ nhưng điều này đã làm việc tuyệt vời.

0

Tôi đã thực hiện cả hai tùy chọn 2 (#ifdef) và tùy chọn 4 (PCH cho gcc) cho mã nền tảng chéo mà không có vấn đề gì.

Tôi tìm gcc biên dịch nhanh hơn nhiều so với VS nên các tiêu đề được biên dịch trước thường không quan trọng, trừ khi bạn đang tham khảo một số tệp tiêu đề lớn.

2

Tôi muốn chọn tùy chọn 4 hoặc tùy chọn 2. Tôi đã thử nghiệm với các tiêu đề được biên dịch sẵn trên cả hai phiên bản VS khác nhau và GCC trên Linux (bài đăng trên blog về số này herehere). Theo kinh nghiệm của tôi, VS nhạy cảm hơn nhiều với độ dài của đường dẫn bao gồm, số lượng thư mục trong đường dẫn bao gồm và số lượng tệp bao gồm hơn G ++. Khi tôi đo thời gian xây dựng đúng sắp xếp các tiêu đề biên dịch sẵn sẽ làm cho một sự khác biệt lớn cho thời gian biên dịch theo VS trong khi G + + là khá nhiều unimpressed bởi điều này. Trên thực tế, dựa trên những gì tôi đã làm lần cuối cùng tôi làm việc trên một dự án mà điều này là cần thiết để kiềm chế thời gian biên dịch là biên dịch tương đương với stdafx.h trong Windows, nơi nó có ý nghĩa và chỉ đơn giản là sử dụng nó dưới dạng tệp thông thường trong Linux.

1

Rất đơn giản, thực sự:

dự án-> Project Settings (Alt + F7)

Project-Settings-Dialog:
C++ -> Thể loại: precompiled Headers -> precompiled Headers nút radio - > tắt

1

Vì mặc định là stdafx.h là tất cả nội dung cụ thể cho Windows, tôi đã đặt trống stdafx.h trên nền tảng khác của mình. Bằng cách đó, mã nguồn của bạn vẫn giống hệt nhau, trong khi vô hiệu hóa hiệu quả stdafx trên Linux mà không phải xóa tất cả các dòng #include "stdafx.h" khỏi mã của bạn.

2

Giải pháp rất đơn giản. Thêm mục nhập tệp giả cho "stdafx.h" trong môi trường Linux.

1

Tôi sẽ chỉ sử dụng tùy chọn 1 trong một nhóm lớn các nhà phát triển. Tùy chọn 2, 3 và 4 thường sẽ ngừng hoạt động của các thành viên khác trong nhóm của bạn, vì vậy bạn có thể tiết kiệm một vài phút mỗi ngày trong thời gian biên dịch.

Đây là lý do:

Giả sử rằng một nửa nhà phát triển của bạn sử dụng VS và một nửa sử dụng gcc. Hiện tại, một số nhà phát triển VS sẽ quên đưa tiêu đề vào tệp .cpp. Anh ta sẽ không nhận thấy, bởi vì stdafx.h ngầm bao hàm nó.Vì vậy, ông đẩy những thay đổi của mình trong việc kiểm soát phiên bản, và sau đó một vài thành viên khác của nhóm gcc sẽ nhận được lỗi trình biên dịch. Vì vậy, cứ mỗi 5 phút mỗi ngày bạn thu được bằng cách sử dụng các tiêu đề được biên dịch trước, 5 người khác sẽ lãng phí bằng cách sửa các tiêu đề bị thiếu của bạn.

Nếu bạn không chia sẻ cùng một mã trên tất cả các trình biên dịch của mình, bạn sẽ gặp phải các vấn đề như vậy mỗi ngày. Nếu bạn buộc các nhà phát triển VS của bạn kiểm tra việc biên dịch trên gcc trước khi đẩy các thay đổi, thì bạn sẽ vứt bỏ tất cả các lợi ích về năng suất của bạn từ việc sử dụng các tiêu đề được biên dịch trước.

Tùy chọn 4 có vẻ hấp dẫn, nhưng nếu bạn muốn sử dụng trình biên dịch khác tại một thời điểm nào đó thì sao? Tùy chọn 4 chỉ hoạt động nếu bạn chỉ sử dụng VS và gcc.

Lưu ý rằng tùy chọn 1 có thể làm cho quá trình biên dịch gcc bị mất vài giây. Mặc dù nó có thể không đáng chú ý.

1

Nếu bạn đang sử dụng CMake trong dự án của mình, thì có các mô-đun tự động hóa cho bạn, rất thuận tiện, ví dụ: xem cmake-precompiled-headerhere. Để sử dụng nó chỉ bao gồm các mô-đun và gọi:

include(cmake-precompiled-header/PrecompiledHeader.cmake) 
add_precompiled_header(${target} ${header} FORCEINCLUDE SOURCE_CXX ${source}) 

Một module gọi Cotire tạo ra các tập tin tiêu đề để được biên dịch sẵn (không cần phải viết bằng tay StdAfx.h) và tăng tốc độ xây dựng theo những cách khác - xem here .