我正在使用GNU make来编译我的C ++代码,我想了解如何使我的编译可以自定义。
我在不同的地方读到CFLAGS
,CCFLAGS
和CXXFLAGS
用于此目的。那我该怎么用呢?如果我有额外的命令行参数编译器,我应该将它们附加到CFLAGS
或前置它们吗?有共同的做法吗?
为什么三个不同的变量?我想C编译器应该得到CFLAGS
和CCFLAGS
,而C ++编译器应该得到CFLAGS
和CXXFLAGS
- 我做得对吗?
人类用户是否应该设置这些变量?是否有任何自动工具(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 $@
我很确定这里没有错误; Makefile工作得很好。但是有什么违反惯例(如CCFLAGSINT
- 我应该只改写CCFLAGS
吗?或者CXXFLAGS
?FUD!)
抱歉这么多问题;你显然不会全部回答,但我希望这些答案能帮助我理解这些设置背后的一般理念。
正如您所注意到的,这些是Makefile {宏或变量},而不是编译器选项。它们实现了一组约定。 (宏是他们的旧名称,仍然被一些人使用.GNU make doc称他们为变量。)
名称重要的唯一原因是默认的制造规则,通过make -p
可见,它们使用其中一些。
如果您编写所有自己的规则,则可以选择所有自己的宏名称。
在香草gnu make中,没有CCFLAGS这样的东西。有CFLAGS
,CPPFLAGS
和CXXFLAGS
。用于C编译器的CFLAGS
,用于C ++的CXXFLAGS
和用于两者的CPPFLAGS
。
为什么两个都是CPPFLAGS
?传统上,它是预处理器标志(-D
,-U
)的主页,c和c ++都使用它们。现在,假设每个人都想要相同的c和c ++定义环境,这可能是值得怀疑的,但却是传统的。
附:正如James Moore所指出的,一些项目使用CPPFLAGS作为C ++编译器的标志,而不是C预处理器的标志。 Android NDK,这是一个很好的例子。
根据GNU make
手册:
CFLAGS:提供给C编译器的额外标志。 CXXFLAGS:提供给C ++编译器的额外标志。 CPPFLAGS:为C预处理器和使用它的程序提供额外标志(C和Fortran编译器)。
src:https://www.gnu.org/software/make/manual/make.html#index-CFLAGS 注意:PP代表PreProcessor(而不是Plus Plus),即
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'。 我们建议您对C ++源文件使用后缀“.cc”而不是“.C”。
src:https://www.gnu.org/software/make/manual/make.html#Catalogue-of-Rules
而只是为了使Mizux said作为一个最小的例子:
main_c.c
#include <stdio.h>
int main(void) {
puts("hello");
}
main_cpp.cpp
#include <iostream>
int main(void) {
std::cout << "hello" << std::endl;
}
然后,没有任何Makefile
:
make CFLAGS='-g -O3' CXXFLAGS='-ggdb3 -O0' CPPFLAGS='-DX=1 -DY=2' 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
所以我们理解:
make
和main_c
的qazxsw poi和qazxsw poi的隐含规则main_cpp
编译的隐式规则的一部分main_c.c
编译的隐式规则的一部分这些变量仅自动用于make的隐式规则:如果编译使用了我们自己的显式规则,那么我们必须明确地使用这些变量,如:
main_cpp.cpp
实现类似于隐式规则的影响。
我们也可以根据需要命名这些变量:但是由于Make已经在隐式规则中对它们进行了神奇的处理,因此可以选择好的名称。
在Ubuntu 16.04中测试,GNU Make 4.1。