14

我注意到最近的内核(从 2.16.24 开始?)不喜欢CFLAGS外部模块 Kbuild 文件中是否更改。如果CFLAGS更改,Linux 内核 Kbuild 系统将发出以下错误:

scripts/Makefile.build:46: *** CFLAGS was changed in "/some/path". Fix it to use EXTRA_CFLAGS.  Stop.

这里

外部模块在少数情况下通过修改 CFLAGS 来修改 gcc 选项。这从未被记录在案,是一种不好的做法。

email来自 LKML 的附加信息。

为什么这是个坏主意?什么是理性?

4

2 回答 2

10

首先,值得一提的是,它EXTRA_CFLAGS已在不久前被弃用并被ccflags-y. 您可以阅读第 3.7 节ccflags-y中的意图。Documentation/kbuild/makefiles.txt

基本上,此变量允许您在仅分配它的文件范围内将设置附加到 C 编译标志集。您不应该更改全局标志,因为这可能会产生超出您自己的 makefile 的全局影响,这被认为是不好的做法。您提到的检查验证确实,包含的生成文件没有更改全局标志。

查看ccflags-y以前称为 的EXTRA_CFLAGS最终在构建过程中如何使用是很有趣的。跟踪一些相关点(但不是全部,因为这是留给读者的练习;-))显示以下内容:

EXTRA_CFLAGS照样可以用scripts/Makefile.lib

1 # Backward compatibility
2 asflags-y  += $(EXTRA_AFLAGS)
3 ccflags-y  += $(EXTRA_CFLAGS)

同一个文件显示了如何ccflags-y在 C 编译标志中结束(并且还显示您可以使用另一个变量,称为CFLAGS_<filename>.o):

104 orig_c_flags   = $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(KBUILD_SUBDIR_CCFLAGS) \
105                  $(ccflags-y) $(CFLAGS_$(basetarget).o)
106 _c_flags       = $(filter-out $(CFLAGS_REMOVE_$(basetarget).o), $(orig_c_flags))
...
133 __c_flags       = $(_c_flags)
...
147 c_flags        = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE)     \
148                  $(__c_flags) $(modkern_cflags)                           \
149                  -D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags)

然后在 中scripts/Makefile.build,定义编译规则:

234 cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $<

请注意,这些都是递归扩展的变量, using=和 not :=,这意味着ccflags-y当您在自己的 makefile 中定义它时,您自己的值被插入到 C 标志中。

最后 about KBUILD_NOPEDANTIC,您在标题中提到但在实际问题中没有提到。CFLAGS可以通过给出KBUILD_NOPEDANTIC任何值来禁用对更改值的测试- 请参阅scripts/Makefile.build

47 ifeq ($(KBUILD_NOPEDANTIC),)
48         ifneq ("$(save-cflags)","$(CFLAGS)")
49                 $(error CFLAGS was changed in "$(kbuild-file)". Fix it to use ccflags-y)
50         endif
51 endif

这个答案中引用的文件今天都被检索到了。

现在......不是这方面的专家,并且在写下整个故事之后进一步研究了makefile,还有一件事我也不明白。在我看来,CFLAGS构建系统中没有使用(不是隐式的,也不是显式的),而是KBUILD_CFLAGS。所以我想知道这种对变化CFLAGS的检查是否实际上应该是对变化的检查KBUILD_CFLAGS

于 2012-06-28T03:45:58.950 回答
1

Linux makefileCFLAGS以适合内核的方式构建。
覆盖CFLAGS意味着您添加一些标志并可能删除一些标志。一些已删除的标志对于正确编译可能很重要。

于 2012-06-18T12:55:36.117 回答