CFLAGS,CCFLAGS,CXXFLAGS-这些变量究竟控制什么?


76

我正在使用GNU make编译我的C ++代码,并且我想了解如何使我的编译可定制。

我看在不同的地方在于CFLAGSCCFLAGS并且CXXFLAGS被用于此目的。那么我应该如何使用它们呢?如果我对编译器有其他命令行参数,我应该将它们附加到CFLAGS或前面?有没有惯例?

为什么三个不同的变量?我想C编译器应该获取CFLAGSCCFLAGS,而C ++编译器应该获取CFLAGSCXXFLAGS-我做对了吗?

人类使用者是否应该设置所有这些变量?做任何自动工具(automakeautoconf等)设置它们?我应该使用的linux系统没有定义任何这些变量-这是典型的吗?

目前,我的Makefile看起来像这样,我感觉有点脏:

我很确定这里没有错误;Makefile效果很好。但是有什么违背约定的东西吗(例如CCFLAGSINT-我应该改写CCFLAGS吗?还是CXXFLAGSFUD!)

很抱歉有这么多问题;您显然不会全部回答,但我希望答案会帮助我理解这些设置背后的一般想法。


根据这些答案,可以公平地说这些环境变量不会更改gcc或未由或clang编译器本身使用吗?
iono

Answers:


84

如您所见,这些是Makefile {宏或变量},而不是编译器选项。它们实现了一组约定。(宏是它们的旧名称,至今仍被某些人使用。GNUmake doc将它们称为变量。)

名称很重要的唯一原因是默认的make规则(通过可见)make -p,其中使用了其中一些规则。

如果编写所有自己的规则,则可以选择所有自己的宏名称。

在香草牛肝菌中,没有CCFLAGS这样的东西。还有CFLAGSCPPFLAGSCXXFLAGSCFLAGS适用于C编译器,CXXFLAGS适用于C ++和CPPFLAGS适用于两者。

为什么CPPFLAGS两者都有?按照惯例,它是预处理器标志()的宿主-D-U并且c和c ++都使用它们。现在,每个人都希望为c和c ++使用相同的定义环境的假设可能值得怀疑,但是这很传统。


PS如James Moore所述,某些项目使用CPPFLAGS标记C ++编译器,而不标记C预处理器。Android NDK就是一个很好的例子。


7
我对您的错误表示不满,但您已经足够正确了,以至于我不应该给出一个完全独立的答案。$(CPPFLAGS)是预处理器的标志。它们在$(CC)和的调用中使用的事实$(CXX)是偶然的。而且,它们是Makefile变量,而不是宏。
杰克·凯利

3
@Jack:GNU Make称它们为变量;其他几个来源,包括《单一Unix规范》对make的描述,也称它们为宏。一样。
约翰·马歇尔

2
1982年我遇到@Jack时,他们就将它们称为宏。
bmargulies 2011年

4
我已经完全上学了。多谢你们。
杰克·凯利

2
@杰克,不,不,不。我不是要教育你,只是为了解释我的观点是从何而来的。实际上,请注意编辑…
bmargulies

13

根据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


nc会自动以配方形式
'$(CC)$(CPPFLAGS)$(CFLAGS)-c'编译C程序no 。


从n.cc,n.cpp或nC会自动以配方形式
'$(CXX)$(CPPFLAGS)$(CXXFLAGS)-c'编译C ++程序。
我们建议您对C ++源文件使用后缀“ .cc”,而不是“ .C”。

src:https//www.gnu.org/software/make/manual/make.html#Catalogue-of-Rules


3

最小的例子

并以Mizux所说的最小为例:

main_c.c

main_cpp.cpp

然后,没有任何Makefile

运行:

因此,我们了解到:

  • make有隐含的规则,使main_cmain_cppmain_c.cmain_cpp.cpp
  • CFLAGS和CPPFLAGS用作以下隐式规则的一部分 .c编译
  • CXXFLAGS和CPPFLAGS用作以下隐式规则的一部分 .cpp编译
  • 不使用CCFLAGS

这些变量仅在make的隐式规则中自动使用:如果编译使用了我们自己的显式规则,则我们将必须显式使用这些变量,如下所示:

达到与隐式规则相似的效果。

我们还可以根据需要命名这些变量:但是由于Make已经在隐式规则中神奇地对待了它们,因此它们成为了不错的名称选择。

在Ubuntu 16.04和GNU Make 4.1中进行了测试。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.