是否应在Makefile中覆盖CXXFLAGS,CPPFLAGS和LDFLAGS?

时间:2018-08-11 22:43:07

标签: makefile gnu-make

情况

我正在使用手写的GNUmakefile,其中CXXFLAGS赋值后附加了CPPFLAGSLDFLAGS+=,如下所示:

CXXFLAGS    += -std=c++11 $(MODENV) $(WARNINGS) $(OPTIMS)
CPPFLAGS    += $(DMACROS) $(INCDIRS)
LDFLAGS     += $(MODENV) $(LIBDIRS) $(EXTRA_LIBS)

问题

当用户在命令行上定义自己的标志时,将忽略Makefile中的追加。这使变量与用户设置的变量完全相同。 (就我而言,构建将失败。)该问题的通用解决方案是override the variables,如下所示:

override CXXFLAGS   += -std=c++11 $(MODENV) $(WARNINGS) $(OPTIMS)
override CPPFLAGS   += $(DMACROS) $(INCDIRS)
override LDFLAGS    += $(MODENV) $(LIBDIRS) $(EXTRA_LIBS)

这样,必要的内容将被附加到用户变量中。

问题

  1. 重载变量是否被认为是不好的做法?
  2. 是否在Makefile中设置上述标志被认为是不正确的做法?
  3. 如果对以上两个问题的回答均为“是”,那么如果不在-std=c++11中,我应该放在哪里CXXFLAGS

3 个答案:

答案 0 :(得分:1)

如果用户覆盖变量,则假定用户知道他们在做什么。他们正在使用的系统可能有非常不同的要求,并且需要覆盖变量。不要把困难变成不可能。

答案 1 :(得分:1)

由于使用make进行构建管理的用例是如此多样,因此根本没有客观地将其判定为“不良实践”的理由。如果您要为多种平台以及未知的受众和时间框架编写OSS,则应使用POLA/POLS。就是说,一个惊讶地发现比她在命令行上给出的更多标志的用户是一个不切实际的极端情况,因此-override占有一席之地。最后,您添加的值对于构建绝对必要,不是吗?

PS:POLA当然应该应用于所有工程活动-只是“惊喜”的定义会随着所讨论的任务而变化。

答案 2 :(得分:0)

我不会对好的/不好的做法发表评论,因为这取决于用例(此makefile的用户是谁?他们都与您一起工作,所以您可以告诉他们这是什么意思您可以只在makefile注释中或项目README中记录您的约定吗?)

但是...

  

如果不在-std=c++11中,我应该把CXXFLAGS放在哪里?

如果您有一些非常重要且不能被用户覆盖的标志,则可以找到另一种方法将其放入编译命令中。

例如:

CXX := g++ -std=c++11

或者:

foo.o: foo.cc
        $(CXX) $(CPPFLAGS) $(CXXFLAGS) -std=c++11 -o $@ $^

最好使用变量,以便仍可以由用户设置变量(例如,改用-std=c++14),而不是由CXXFLAGS设置:

STD := -std=c++11
foo.o: foo.cc
        $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(STD) -o $@ $^

(或只是将-std选项放在CXXFLAGS之前,以便std中的另一个CXXFLAGS选项优先)。