内核模块编译和KBUILD_NOPEDANTIC

我注意到最近的内核(从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. 

从这里 :

在less数情况下,外部模块通过修改CFLAGS来修改gcc选项。 这从来没有logging,是一个不好的做法。

来自LKML的其他email

为什么这个主意不好? 什么是理性?

首先,可能值得一提的是, EXTRA_CFLAGS前一阵子已被弃用,并被ccflags-y所取代。 你可以在Documentation/kbuild/makefiles.txt 3.7节中阅读ccflags-y的意图。

基本上,这个变量允许你把设置追加到C编译标志集合中,只在文件所在的范围内。 你不应该改变全局标志,因为这可能会超出你自己的makefile的全局影响,这被认为是不好的做法。 您提到的检查确实确实,全局标志没有被包含的makefile改变。

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

根据scripts/Makefile.libEXTRA_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 $@ $< 

请注意,这些都是递归扩展的变量,使用=和not := ,这意味着当您在自己的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 

这个答案中引用的文件全部是今天检索的。

现在……不是这方面的专家,在把这个整个故事写下来之后,进一步看看这个造型文件,有一件事情我也不明白。 在我看来, CFLAGS不是在构建系统中使用的(不是隐含的,也不是明确的),但是KBUILD_CFLAGS是。 所以我想知道这个检查CFLAGS变化是否应该实际上检查KBUILD_CFLAGS变化。

Linux makefiles以适合内核的方式构建CFLAGS
重写CFLAGS意味着你添加一些标志,并可能删除一些标志。 一些删除的标志对于正确的编译可能是重要的。