Gcc CFLAGS、CCFLAGS、CXXFLAGS—这些变量究竟控制什么? 我使用GNUmake编译我的C++代码,我想知道如何使我的编译可定制。
我在不同的地方看到,Gcc CFLAGS、CCFLAGS、CXXFLAGS—这些变量究竟控制什么? 我使用GNUmake编译我的C++代码,我想知道如何使我的编译可定制。,gcc,naming-conventions,makefile,Gcc,Naming Conventions,Makefile,我在不同的地方看到,CFLAGS、CCFLAGS和cxflags用于此目的。那么我应该如何使用它们呢?如果我对编译器有额外的命令行参数,我应该将它们附加到CFLAGS还是在它们前面加上前缀?有共同的做法吗 为什么这三个变量不同?我认为C编译器应该得到 cFLAGs >代码> CCFLAGS < /C>,而C++编译器应该得到 cFLAGs和 CXXFLACK< -我做对了吗? 人类用户应该设置这些变量吗?是否有任何自动工具(automake、autoconf等)对其进行了设置?我应该使用的li
CFLAGS
、CCFLAGS
和cxflags
用于此目的。那么我应该如何使用它们呢?如果我对编译器有额外的命令行参数,我应该将它们附加到CFLAGS
还是在它们前面加上前缀?有共同的做法吗
为什么这三个变量不同?我认为C编译器应该得到<代码> cFLAGs<代码> >代码> CCFLAGS < /C>,而C++编译器应该得到<代码> cFLAGs<代码>和<代码> CXXFLACK< <代码> -我做对了吗?
人类用户应该设置这些变量吗?是否有任何自动工具(automake
、autoconf
等)对其进行了设置?我应该使用的linux系统没有定义这些变量中的任何一个——这是典型的吗
目前我的Makefile看起来像这样,我觉得有点脏:
ifdef code_coverage
GCOV_FLAG := -fprofile-arcs -ftest-coverage
else
GCOV_FLAG :=
endif
WFLAGS := -Wall
INC_FLAGS := -Istuff -Imore_stuff -Ietc
CCFLAGSINT := -O3 $(WFLAGS) $(INC_FLAGS) $(CCFLAGS)
... (somewhere in the makefile, the command-line for compilation looks like this)
$(CC) $(CCFLAGSINT) -c $< -o $@
... (somewhere in the makefile, the command-line for linking looks like this)
$(CC) $(GCOV_FLAG) $(CCFLAGSINT) $(OBJLIST) $(LDFLAGS) -o $@
ifdef代码覆盖率
GCOV_标志:=-fprofile arcs-ftest覆盖率
其他的
GCOV_标志:=
恩迪夫
WFLAGS:=-Wall
INC_标志:=-Istuff-Imore_-Ietc
CCFLAGSINT:=-O3$(WFLAGS)$(INC_标志)$(CCFLAGS)
... (在makefile的某个地方,编译的命令行如下所示)
$(CC)$(CCFLAGSINT)-c$<-o$@
... (在makefile的某个地方,用于链接的命令行如下所示)
$(CC)$(GCOV_标志)$(CCFLAGSINT)$(OBJLIST)$(LDFLAGS)-o$@
我很确定这里没有虫子;Makefile工作得非常好。但是是否有任何违反约定的内容(比如CCFLAGSINT
-我应该只覆盖CCFLAGS
?还是cxflags
?FUD!)
对不起,有这么多问题;您显然不会全部回答,但我希望这些回答能帮助我理解这些设置背后的总体思路。正如您所注意到的,这些是Makefile{macros或variables},而不是编译器选项。它们执行一系列约定。(宏是它们的旧名称,仍然被一些人使用。GNU make doc将它们称为变量。) 名称起作用的唯一原因是默认的make规则,可以通过
make-p
看到,它使用了其中的一些规则
如果您编写所有自己的规则,您就可以选择所有自己的宏名称
在香草gnu制造中,没有CCFLAGS这样的东西。有CFLAGS
、CPPFLAGS
和cxflags
CPPFLAGS
在两者中都有?传统上,它是预处理器标志的所在地(<代码> -d<代码> >代码> -u/COD>),C和C++都使用它们。现在,假设每个人都希望C和C++的定义环境相同,这可能是有问题的,但是传统的。
S.正如所指出的,一些项目使用CppFLAGS标志到C++编译器,而不是使用C预处理器的标志。Android NDK就是一个巨大的例子。
根据GNU make手册: CFLAGS:给C编译器的额外标志。CXXFLAGS:给C++编译器的额外标志。 CPPFLAGS:给C预处理器和使用它的程序(C和Fortran编译器)的额外标志 src:
注:PP代表预处理器(而非加号),即 CPP:用于运行C预处理器的程序,将结果输出到标准输出;默认值“$(CC)-E” 这些变量由
make
编译C程序n、 o由n.c自动制成,配方为
“$(CC)$(CPPFLAGS)$(CFLAGS)-c” <编译C++程序> n、 o由n.cc、n.cpp或n.C自动制成,配方为
“$(CXX)$(CPPFLAGS)$(CXXFLAGS)-c”。
我们鼓励您使用后缀“.cc”来代替C++源文件,而不是'.c'。
src:最小示例 作为一个简单的例子: 主电路
#include <stdio.h>
int main(void) {
puts("hello");
}
运行:
因此,我们理解:
具有从make
和main\u c.c
生成main\u cpp
的隐式规则main\u cpp
- CFLAGS和CPPFLAGS被用作
编译的隐式规则的一部分.c
- CXXFLAGS和CPPFLAGS被用作
编译的隐式规则的一部分.cpp
- 不使用CCFLAGS
main_c: main_c.c
$(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $<
main_cpp: main_c.c
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -o $@ $<
main_c:main_c.c
$(CC)$(CFLAGS)$(CPPFLAGS)-o$@$<
main_cpp:main_c.c
$(CXX)$(CXXFLAGS)$(CPPFLAGS)-o$@$<
达到与隐式规则类似的效果
我们也可以随意命名这些变量:但是由于Make已经在隐式规则中神奇地处理了它们,所以这些变量可以很好地选择名称
GNU Make 4.1在Ubuntu 16.04中进行了测试。我否决了你的观点,认为你有点错,但你已经接近正确,不值得我单独回答
$(cppfagas)
是预处理器的标志。在调用$(CC)
和$(CXX)
时使用它们是偶然的。而且,它们是Makefile变量,而不是宏。@Jack:GNU Make调用它们变量;其他几个来源,包括单一Unix规范对make的描述,都称它们为宏。同样的事情。@Jack在1982年,当我遇到make时,他们叫他们macros.aa,我已经完全被带到学校去了。谢谢你们。@Jack,不,不,不。我不是想教育你们,只是想解释我的特殊观点是从哪里来的。事实上,请注意编辑……根据这些答案,可以公平地说这些环境变量没有改变/没有使用吗
make CFLAGS='-g -O3' \
CXXFLAGS='-ggdb3 -O0' \
CPPFLAGS='-DX=1 -DY=2' \
CCFLAGS='--asdf' \
main_c \
main_cpp
cc -g -O3 -DX=1 -DY=2 main_c.c -o main_c
g++ -ggdb3 -O0 -DX=1 -DY=2 main_cpp.cpp -o main_cpp
main_c: main_c.c
$(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $<
main_cpp: main_c.c
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -o $@ $<