makefile – 允许用户覆盖CFLAGS,CXXFLAGS和朋友

典型的makefile通常使用内置变量CFLAGS,CXXFLAGS,CPPFLAGS等来设置传递给C,C或其他编译器/工具的标志.原则上,这有时甚至可以避免完全编写编译配方,因为各种内置规则使用这些标志.

通常,makefile可能会向代码编译所需的FLAGS变量添加内容,例如include目录,指示要使用的语言标准的参数等等.变量还可能包含“可选”或“默认”参数,例如优化级别,警告级别和可能有效更改或删除的其他设置.

由于CFLAGS和字段是“众所周知的”变量,它们显然也是最终用户的配置点.例如,如果项目默认情况下编译时没有调试信息,则make命令行中的CFLAGS = -g应该将-g添加到$(CC)编译器命令行,从而导致生成调试信息.类似地,对于最终用户可能想要控制的其他选项,例如优化级别,gcc上的-march设置等.

但是,这两种用法似乎与我不相容.如果用户覆盖$(CFLAGS),他们将删除任何内部“必需”标志,如上所述,并且项目可能无法编译或可能编译错误.

处理此问题是否有最佳做法? “单值”变量(如$(CC))并不会出现同样的问题,因为它们通常只有一个值:在此示例中,使用的是C编译器.如果用户覆盖它,则使用它们的值.像$(CFLAGS)这样的东西原则上是一个值列表,其中一些是内部的,不应该被覆盖,另一些是用户可能想要覆盖的值.

直观地说,一个解决方案似乎是让你的makefile中的$(CFLAGS)和朋友空闲和未使用,更喜欢将CFLAGS_INTERNAL用于in-makefile参数,然后将两者放在命令行中.然而,我很好奇,如果有最好的练习,或者我错过了一些明显的东西.

1对于这个问题的其余部分,我通常会简单地参考$(CFLAGS),理解这只是一个众所周知的编译器标志变量系列的简单代表,例如$(CPPFLAGS),$(CXXFLAGS)等等.上.

最佳答案 我面临着同样的问题.目前我的解决方案是提供“非标准”标志,例如OPTIMS,WARNINGS,MODENV,它们将在内部附加到“标准”CXXFLAGS.

如果用户从命令行定义CXXFLAGS,则假定他想要覆盖它,如果这是他想要的,那就是他应该得到的:覆盖.具有讽刺意味的是,这意味着我没有在Makefile中使用覆盖CXXFLAGS = …

我不希望高级用户拉出他们的头发,因为我坚持将我的东西附加/添加到他们的旗帜,所以在我看来最终的情况是这样的:

> GOOD:要求高级用户传递复杂的自定义标志
> BAD:要求高级用户修补Makefile

点赞