典型的makefile经常使用内置变量CFLAGS
,CXXFLAGS
,CPPFLAGS
等 1 来设置传递给C,C ++的标志或其他编译器/工具。原则上,由于各种内置规则都使用这些标志,因此有时甚至可以避免完全编写编译配方。
通常,makefile可能会将东西添加到需要编译的代码的FLAGS
变量中,例如include目录,指示使用哪种语言标准的参数等。 。这些变量还可能包含“可选”或“默认”参数,例如优化级别,警告级别和可能有效更改或删除的其他设置。
由于CFLAGS
和字段是“众所周知的”变量,因此它们显然也是最终用户的配置点。例如,如果默认情况下一个项目在编译时没有调试信息,则期望CFLAGS=-g
命令行上的make
导致-g
被添加到$(CC)编译器命令行中,并且因此导致产生调试信息。同样,对于最终用户可能希望控制的其他选项,例如优化级别,gcc上的-march
设置,等等。
但是,这两种用法似乎与我不兼容。如果用户覆盖$(CFLAGS)
,则他们将删除如上所述的所有内部“必需”标志,并且该项目可能无法编译或编译不正确。
是否有处理此问题的最佳实践?对于像$(CC)
这样的“单值”变量,实际上不会出现相同的问题,因为它们通常只有一个值:在本示例中,使用的是C编译器。如果用户覆盖它,则使用其值。诸如$(CFLAGS)
之类的东西原则上是一个值列表,其中一些值是内部值,不应覆盖,而其他值则用户可能希望覆盖。
从直觉上讲,一种解决方案似乎是将$(CFLAGS)
和朋友保留为空且未在您的Makefile中使用它们,而更喜欢说CFLAGS_INTERNAL
作为Makefile中的参数,然后将两者都放在命令行中。但是,我很好奇,是否有最佳实践,或者是否缺少明显的东西。
1 对于此问题的其余部分,我通常会简单地参考$(CFLAGS)
,前提是这只是整个编译器标记变量家族的方便代表,例如$(CPPFLAGS)
,$(CXXFLAGS)
等。
答案 0 :(得分:1)
我面临着同样的问题。目前,我的解决方案是提供“ {@ 1}},OPTIMS
,WARNINGS
之类的“非标准”标志,这些标志将在内部附加到“标准” MODENV
上。
如果用户在命令行中定义CXXFLAGS
,则假定他要覆盖它,如果这就是他想要的,那他应该得到:覆盖。具有讽刺意味的是,这意味着我不在Makefile中使用CXXFLAGS
。
我不希望高级用户放弃他们的头发,因为我坚持将自己的东西添加/添加到他们的标志上,所以我认为最终的情况是这样的:
答案 1 :(得分:0)
您可能正在寻找override指令:
$ cat Makefile
override CFLAGS += -foobar
all:
$(info CFLAGS = $(CFLAGS))
$ make
CFLAGS = -foobar
make: 'all' is up to date.
$ make CFLAGS=-g
CFLAGS = -g -foobar
make: 'all' is up to date.
请注意,您也可以使用:
$ make CFLAGS+=-g
在命令行上,但其行为类似于:
$ make CFLAGS=-g
答案 2 :(得分:0)
我更喜欢的方法是为这些公共变量提供合理的默认值,但让用户提供自己的值-覆盖默认值。
include $(wildcard makefile.in Makefile.in)
BUILD ?= build
CFLAGS ?= -O2 -fPIC -pedantic -Wall -Wextra -Wconversion
这可以通过环境变量,命令行参数(例如make CFLAGS=-g
或永久存在于makefile.in
中)完成。
我知道这并不能完全解决您在问题中描述的问题,但是我发现用例中用户希望使用非默认标志编译项目应该可以
如果某人想要使用一些特殊标志进行构建并且无法执行这些步骤,那么无论如何都会有一些更严重的问题。
当构建变得更加复杂并且默认值在较大的Makefile中设置并取决于其他条件时,这种方法将无法很好地扩展。
答案 3 :(得分:0)
在使用debuginfo软件包构建RPM时,偶然发现了相同的问题。
生成debuginfo的要求是在-g
中传递CFLAGS
,同时保留软件CFLAGS
中包含的Makefile
。
因此,如果您想向CFLAGS
添加一些额外的位,而又不覆盖Makefile
中存在的位,则可以简单地将CFLAGS
用作环境变量。但是只要有问题的Makefile
使用CFLAGS += ...
表示法即可。
例如,假设您拥有Makefile
拥有以下软件:
CFLAGS += $(ARCH) -O3 -std=gnu11 -Wall ...
要使用所有这些标志和 -g
构建它,您将执行以下操作:
CFLAGS='-g' make
请注意,将其作为make
的参数传递是无效的,例如:make CFLAGS='-g'
是错误的,因为它将覆盖内部CFLAGS
。
有关pass -g
for building debuginfo packages properly
这里是make: appending to variables上的参考。