ana*_*lyg 64 gcc makefile naming-conventions
我正在使用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 $@
Run Code Online (Sandbox Code Playgroud)
我很确定这里没有错误; Makefile工作得很好.但是有没有违反惯例的事情(比如CCFLAGSINT- 我应该改写CCFLAGS吗?或者CXXFLAGS?FUD!)
抱歉这么多问题; 你显然不会全部回答,但我希望这些答案能帮助我理解这些设置背后的一般理念.
bma*_*ies 76
正如您所注意到的,这些是Makefile {宏或变量},而不是编译器选项.它们实现了一组约定.(宏是他们的旧名称,仍然被一些人使用.GNU make doc称他们为变量.)
名称重要的唯一原因是默认的make规则,可见make -p,使用其中的一些.
如果您编写所有自己的规则,则可以选择所有自己的宏名称.
在香草gnu make中,没有CCFLAGS这样的东西.还有CFLAGS,CPPFLAGS和CXXFLAGS.CFLAGS用于C编译器,CXXFLAGS用于C++,以及CPPFLAGS用于两者.
为什么CPPFLAGS两者兼而有之?通常,它是预处理程序标志(-D,-U)的主页,c和c ++都使用它们.现在,假设每个人都想要相同的c和c ++定义环境,这可能是值得怀疑的,但却是传统的.
PS正如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
使用
"$(CC)$(CPPFLAGS)$(CFLAGS)-c" 形式的配方从nc自动编译C程序.编译C++程序
no是从n.cc,n.cpp或nC自动生成的,其配方形式为
'$(CXX)$(CPPFLAGS)$(CXXFLAGS)-c'.
我们建议您对C++源文件使用后缀".cc"而不是".C".
src:https://www.gnu.org/software/make/manual/make.html#Catalogue-of-Rules
最小的例子
只是为了让Mizux 所说的作为一个最小的例子:
main_c.c
#include <stdio.h>
int main(void) {
puts("hello");
}
Run Code Online (Sandbox Code Playgroud)
main_cpp.cpp
#include <iostream>
int main(void) {
std::cout << "hello" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
然后,没有任何Makefile:
make CFLAGS='-g -O3' \
CXXFLAGS='-ggdb3 -O0' \
CPPFLAGS='-DX=1 -DY=2' \
CCFLAGS='--asdf' \
main_c \
main_cpp
Run Code Online (Sandbox Code Playgroud)
运行:
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
Run Code Online (Sandbox Code Playgroud)
所以我们明白:
make有隐含的规则,使main_c和main_cpp从main_c.c与main_cpp.cpp
CFLAGS 和 CPPFLAGS 被用作.c编译隐式规则的一部分
CXXFLAGS 和 CPPFLAGS 被用作.cpp编译隐式规则的一部分
不使用 CCFLAGS。
顺便说一句,例如,SCons 构建系统使用 CCFLAGS 作为 C 和 C++ 通用的标志,这是我有时在自定义生成规则上遵循的约定。
这些变量仅在 make 的隐式规则中自动使用:如果编译使用了我们自己的显式规则,那么我们将不得不显式使用这些变量,如下所示:
main_c: main_c.c
$(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $<
main_cpp: main_c.c
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -o $@ $<
Run Code Online (Sandbox Code Playgroud)
实现与隐式规则类似的效果。
我们也可以随意命名这些变量:但是由于 Make 已经在隐式规则中神奇地对待它们,因此它们是很好的名称选择。
在 Ubuntu 16.04、GNU Make 4.1 中测试。
| 归档时间: |
|
| 查看次数: |
95288 次 |
| 最近记录: |