内核模块编译和KBUILD_NOPEDANTIC

dim*_*mba 13 linux makefile linux-device-driver linux-kernel

我注意到最近的内核(从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.
Run Code Online (Sandbox Code Playgroud)

这里:

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

另外email来自LKML.

为什么不好主意?什么是理性的?

Rei*_*eek 9

首先,值得一提的EXTRA_CFLAGS是,前一段时间已被弃用,并被替换为ccflags-y.你可以阅读有关的意向ccflags-yDocumentation/kbuild/makefiles.txt,第3.7节.

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

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

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

1 # Backward compatibility
2 asflags-y  += $(EXTRA_AFLAGS)
3 ccflags-y  += $(EXTRA_CFLAGS)
Run Code Online (Sandbox Code Playgroud)

同一个文件显示了如何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)
Run Code Online (Sandbox Code Playgroud)

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

234 cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $<
Run Code Online (Sandbox Code Playgroud)

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

最后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
Run Code Online (Sandbox Code Playgroud)

今天回答了这个答案中引用的文件.

现在......在写完整个故事之后,不是这方面的专家并进一步研究makefile,有一件事我也不明白.在我看来,CFLAGS它没有在构建系统中使用(不是隐式地,也不是明确地),而是KBUILD_CFLAGS.所以我想知道这次检查是否CFLAGS真的应该检查是否有变化KBUILD_CFLAGS.


ugo*_*ren 1

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