内核模块编译和KBUILD_NOPEDANTIC

14

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

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

这里获取:

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

LKML的附加电子邮件。

为什么这是一个不好的想法?有何理据?

2个回答

10

首先值得一提的是,EXTRA_CFLAGS 已经被弃用了,现在由 ccflags-y 替代。您可以阅读 Documentation/kbuild/makefiles.txt 第3.7节中关于 ccflags-y 的说明。

基本上,这个变量允许您在分配它的文件的范围内附加设置到 C 编译标志集中。您不应该更改全局标志,因为那可能会对您自己的 makefile 以外的范围产生全局影响,这被认为是不好的做法。您提到的检查确保了全局标志没有被包含的 makefile 更改。

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

根据 scripts/Makefile.lib,仍然可以使用 EXTRA_CFLAGS

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 $@ $<

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

最后提到一下标题中提到但实际问题中未提及的KBUILD_NOPEDANTIC。通过给KBUILD_NOPEDANTIC分配任何值,可以禁用对CFLAGS值的更改测试 -- 请参见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,发现有一件事我也不理解。在构建系统中,似乎没有隐式或显式地使用,但使用了。因此,我想知道这个检查的更改是否应该实际上是检查的更改。

1

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


如果我理解正确,CFLAGS是整个内核编译时使用的标志,因此不应更改。这意味着内核KBuild系统将使用CFLAGS+ EXTRA_CFLAGS编译我的外部模块。正确吗? - dimba

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接