CFLAGS与CPPFLAGS

时间:2010-05-02 21:02:10

标签: makefile autotools autoconf cflags

据我所知,CFLAGS(或CXXFLAGS for C ++)适用于编译器,而CPPFLAGS则由预处理器使用。

但我仍然不明白其中的区别。

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

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

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

(在我的情况下,我实际上发现 BOTH 这些允许我编译我的程序,这增加了混乱...我可以使用CFLAGS OR CPPFLAGS来实现我的目标(至少在autoconf环境中)。给出了什么?)

4 个答案:

答案 0 :(得分:141)

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

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

$()语法扩展变量。由于在编译器调用中使用CPPFLAGSCFLAGS,因此用于定义包含路径的是个人品味问题。例如,如果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 :(得分:10)

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

CPPFLAGSCFLAGS都适用于您的情况,因为make(1)规则在一个命令中结合了预处理和编译(因此在命令中使用了两个宏)。 / p>

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

答案 2 :(得分:4)

你在implicit make rules之后。

答案 3 :(得分:0)

要添加到提到隐式规则的人中,最好使用以下命令查看make隐式定义的内容以及为您的环境定义的内容:

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将以列表中的第一个出现。