CFLAGS与CPPFLAGS

EBM*_*EBM 92 autoconf makefile autotools cflags

我知道CFLAGS(或CXXFLAGS for C++)是针对编译器的,而CPPFLAGS是由预处理器使用的.

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

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

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

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

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

Sco*_*les 145

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

%.o:%.c
    $(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $<
Run Code Online (Sandbox Code Playgroud)

其中$()语法扩展变量.由于在编译器调用中使用了两者CPPFLAGS并且CFLAGS用于定义包含路径,这是个人品味的问题.例如,if foo.c是当前目录中的文件

make foo.o CPPFLAGS="-I/usr/include"
make foo.o CFLAGS="-I/usr/include"
Run Code Online (Sandbox Code Playgroud)

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

gcc -I/usr/include -c -o foo.o foo.c
Run Code Online (Sandbox Code Playgroud)

当你有多种语言需要相同的包含路径时,两者之间的区别就会发挥作用,例如,如果你有bar.cpp尝试的话

make bar.o CPPFLAGS="-I/usr/include"
make bar.o CFLAGS="-I/usr/include"
Run Code Online (Sandbox Code Playgroud)

然后汇编将是

g++ -I/usr/include -c -o bar.o bar.cpp
g++ -c -o bar.o bar.cpp
Run Code Online (Sandbox Code Playgroud)

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

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

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

CPPFLAGS=-I/usr/include
CFLAGS=-std=c99
CXXFLAGS=-Weffc++
Run Code Online (Sandbox Code Playgroud)


Ste*_*son 10

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

无论CPPFLAGSCFLAGS工作,你的情况是因为make(1)规则结合了预处理和一个命令(这样既宏在命令中使用)编制.

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

  • @EB如果您正在编译预处理文件,那么包含路径是不必要的 - 所需的标题已经添加到预处理源中(在文件上运行`gcc -E`时查看输出 - 没有#includes ).大多数现代编译器结合了预处理和编译步骤,因此您不必担心这一点. (4认同)