CFLAGS和CPPFLAGS


103

我了解CFLAGS(或C ++的CXXFLAGS)用于编译器,而CPPFLAGS由预处理器使用。

但是我仍然不明白区别。

我需要为#include包含的头文件指定一个include路径-因为#include是预处理器指令,所以预处理器(CPPFLAGS)是我唯一关心的吗?

在什么情况下需要给编译器额外的包含路径?

通常,如果预处理程序找到并包含所需的头文件,为什么还需要告知它额外的包含目录?CFLAGS到底有什么用?

(在我的情况,我居然发现BOTH的这些让我编译我的程序,这增加了混乱......我可以使用CFLAGS OR CPPFLAGS实现我的目标(至少在autoconf的情况下)。是什么给了?)


Answers:


153

编译C程序的隐式make规则是

%.o:%.c
    $(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $<

其中$()语法扩展变量。在编译器调用中同时使用CPPFLAGS和时CFLAGS,您用来定义包含路径的过程是个人喜好问题。例如,如果foo.c是当前目录中的文件

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

都将以完全相同的方式调用编译器,即

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

当您使用多种语言需要相同的包含路径时(例如,如果您bar.cpp尝试使用

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

那么汇编将是

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

因为C ++隐式规则也使用该CPPFLAGS变量。

这种差异为您提供了一个很好的使用指南-如果您希望将标记用于所有使用的语言CPPFLAGS,如果希望将特定语言使用的标记CFLAGSCXXFLAGS等等。后一种类型的示例包括标准符合性或警告标记-您不想传递-std=c99给C ++编译器!

然后,您可能会在makefile中得到类似这样的结果

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

1
请注意,您不能独立运行并cpp使用CPPFLAGS任何期望的合理结果,因为这-std=c99会影响定义的符号(尤其是代替功能测试宏)。相反,您需要$(CC) $(CPPFLAGS) $(CFLAGS) -E
2013年

10

CPPFLAGS宏是用于指定的宏#include目录。

无论CPPFLAGSCFLAGS你的情况,因为工作make(1)规则结合了预处理,并在一个命令编译(所以这两个宏在命令中使用)。

.如果使用form,则无需指定为包含目录#include "..."。您也不需要指定标准的编译器包含目录。您确实需要指定所有其他包含目录。


这更有意义,但是我仍然看不到CFLAGS做什么。如您似乎暗示的那样,如果更复杂的项目中的编译是在与预处理不同的步骤中完成的,那么如果CFLAGS不添加与CPPFLAGS为预处理器添加的路径相同的路径,预处理是否可以成功但编译失败?我想我不明白如果预处理器已经处理了#include指令,编译器将如何处理包含路径?
EBM

4
@EB如果要编译预处理文件,则不需要包含路径-所需的标头已添加到预处理源中(gcc -E在文件上运行时查看输出-没有#includes)。大多数现代编译器将预处理和编译步骤结合在一起,因此您不必为此担心。
斯科特·威尔士,2010年


0

要补充那些提到隐式规则的人,最好使用以下命令查看make隐式定义的内容以及对您的env的定义:

make -p

例如:

%.o: %.c
    $(COMPILE.c) $(OUTPUT_OPTION) $<

扩大

COMPILE.c = $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c

这也将打印 # environment数据。在这里,您会发现GCC的包含路径以及其他有用信息。

C_INCLUDE_PATH=/usr/include

在制造中,当涉及搜索时,路径很多,光线是一个……或类似的东西。

  1. C_INCLUDE_PATH 在系统范围内,将其设置在您的shell的 *.rc
  2. $(CPPFLAGS) 用于预处理器包含路径。
  3. 如果您需要为make添加常规搜索路径,请使用:
VPATH = my_dir_to_search

...甚至更具体

vpath %.c src
vpath %.h include

make将VPATH用作一般搜索路径,因此请谨慎使用。如果文件存在于VPATH中列出的多个位置中,则make将以列表中的第一个出现。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.