2010-05-02 14 views
79

Tôi hiểu rằng CFLAGS (hoặc CXXFLAGS cho C++) là dành cho trình biên dịch, trong khi CPPFLAGS được sử dụng bởi bộ tiền xử lý.CFLAGS vs CPPFLAGS

Nhưng tôi vẫn không hiểu sự khác biệt.

Tôi cần chỉ định đường dẫn bao gồm cho tệp tiêu đề được bao gồm với #include - vì #include là chỉ thị tiền xử lý, là bộ tiền xử lý (CPPFLAGS) điều duy nhất tôi quan tâm?

Trong trường hợp nào tôi cần phải cung cấp cho trình biên dịch một đường dẫn bổ sung?

Nói chung, nếu bộ tiền xử lý tìm và bao gồm các tệp tiêu đề cần thiết, tại sao nó cần được thông báo về các thư mục bổ sung? Sử dụng CFLAGS là gì?

(Trong trường hợp của tôi, tôi thực sự thấy rằng CẢ những cho phép tôi để biên dịch chương trình của tôi, mà thêm vào sự nhầm lẫn ... Tôi có thể sử dụng CFLAGS HOẶC CPPFLAGS để hoàn thành mục tiêu của tôi (trong autoconf Điều gì cho?)

+1

thể trùng lặp của http://stackoverflow.com/questions/495598/difference-between-cppflags-and-cxxflags-in-gnu -make –

Trả lời

120

Các tiềm ẩn làm cho quy tắc cho soạn thảo một chương trình C là

%.o:%.c 
    $(CC) $(CPPFLAGS) $(CFLAGS) -c -o [email protected] $< 

nơi cú pháp $() mở rộng các biến. Vì cả hai CPPFLAGSCFLAGS được sử dụng trong trình biên dịch cuộc gọi, mà bạn sử dụng để xác định đường dẫn bao gồm là một vấn đề về sở thích cá nhân. Ví dụ nếu foo.c là một tập tin trong thư mục hiện

make foo.o CPPFLAGS="-I/usr/include" 
make foo.o CFLAGS="-I/usr/include" 

cả hai sẽ gọi trình biên dịch của bạn trong một cách chính xác theo cùng một cách, cụ thể là

gcc -I/usr/include -c -o foo.o foo.c 

Sự khác biệt giữa hai đi vào chơi khi bạn có nhiều ngôn ngữ cần có cùng một đường dẫn bao gồm, ví dụ: nếu bạn có bar.cpp thì hãy thử

make bar.o CPPFLAGS="-I/usr/include" 
make bar.o CFLAGS="-I/usr/include" 

thì tổng hợp sẽ là

g++ -I/usr/include -c -o bar.o bar.cpp 
g++ -c -o bar.o bar.cpp 

vì quy tắc ngầm C++ cũng sử dụng biến số CPPFLAGS.

Sự khác biệt này cung cấp cho bạn hướng dẫn tốt để sử dụng - nếu bạn muốn cờ được sử dụng cho tất cả ngôn ngữ đặt trong CPPFLAGS, nếu nó là ngôn ngữ cụ thể, hãy đặt nó trong CFLAGS, CXXFLAGS v.v. loại bao gồm tuân thủ tiêu chuẩn hoặc cờ cảnh báo - bạn sẽ không muốn vượt qua -std=c99 vào trình biên dịch C++ của mình!

Sau đó, bạn có thể kết thúc với một cái gì đó như thế này trong makefile của bạn

CPPFLAGS=-I/usr/include 
CFLAGS=-std=c99 
CXXFLAGS=-Weffc++ 
+0

Lưu ý rằng bạn không thể chạy 'cpp' độc lập bằng' CPPFLAGS' và mong đợi bất kỳ kết quả hợp lý nào vì '-std = c99' ảnh hưởng đến các ký hiệu được xác định (đặc biệt thay cho các macro thử nghiệm tính năng). Thay vào đó, bạn cần '$ (CC) $ (CPPFLAGS) $ (CFLAGS) -E'. – Jed

2

Bạn đang theo dõi implicit make rules.

+0

Trong khi liên kết này có thể trả lời câu hỏi, tốt hơn nên bao gồm các phần thiết yếu của câu trả lời ở đây và cung cấp liên kết để tham khảo. Câu trả lời chỉ liên kết có thể trở thành không hợp lệ nếu trang được liên kết thay đổi. - [Từ đánh giá] (/ review/low-quality-posts/18639008) – Ctznkane525

9

Macro CPPFLAGS là một cái để sử dụng để chỉ định các thư mục #include.

Cả hai CPPFLAGSCFLAGS đều hoạt động trong trường hợp của bạn vì quy tắc make (1) kết hợp cả tiền xử lý và biên dịch thành một lệnh (vì vậy cả hai macro được sử dụng trong lệnh).

Bạn không cần chỉ định . làm thư mục bao gồm nếu bạn sử dụng biểu mẫu #include "...". Bạn cũng không cần phải chỉ định trình biên dịch tiêu chuẩn bao gồm thư mục. Bạn cần phải chỉ định tất cả các thư mục bao gồm khác.

+0

Điều này có ý nghĩa hơn, nhưng tôi vẫn không thấy những gì CFLAGS làm, sau đó. Nếu, như bạn có vẻ ngụ ý, việc biên dịch trong các dự án phức tạp hơn được thực hiện trong một bước riêng biệt từ tiền xử lý, sẽ tiền xử lý thành công nhưng biên dịch thất bại nếu CFLAGS không thêm cùng đường dẫn CPPFLAGS được thêm vào cho bộ tiền xử lý? Tôi đoán tôi không hiểu trình biên dịch làm gì với các đường dẫn bao gồm nếu trình tiền xử lý đã xử lý #include chỉ thị? – EBM

+3

@EB Nếu bạn đang biên dịch các tệp đã được xử lý trước thì bao gồm các đường dẫn không cần thiết - các tiêu đề bắt buộc đã được thêm vào nguồn tiền xử lý (Hãy xem đầu ra khi bạn chạy 'gcc -E' trên một tệp - không có # bao gồm). Hầu hết các trình biên dịch hiện đại kết hợp các bước xử lý trước và biên dịch, vì vậy bạn không phải lo lắng về điều này. –

Các vấn đề liên quan