I've noticed that recent kernels (starting from 2.16.24?) don't like if CFLAGS
is changed in external module Kbuild file. If CFLAGS
is changed you'll be issued the following error by Linux kernel Kbuild system:
我注意到最近的内核(从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.
From here:
从这里开始:
External modules have in a few cases modifed gcc option by modifying CFLAGS. This has never been documented and was a bad practice.
在一些情况下,外部模块通过修改CFLAGS来修改gcc选项。这从未被记录在案,而且是一个糟糕的做法。
Additional email
from LKML.
从LKML额外的电子邮件。
Why is it bad idea? What is rational?
为什么这是个坏主意?理性是什么?
2 个解决方案
#1
9
First of all, it might be worth mentioning that EXTRA_CFLAGS
has been deprecated a while ago and is replaced by ccflags-y
. You can read about the intention of ccflags-y
in Documentation/kbuild/makefiles.txt
, section 3.7.
首先,值得一提的是,EXTRA_CFLAGS已经被废弃了,并且被ccflags-y所取代。您可以在文档/kbuild/makefile中阅读关于ccflag -y的意图。txt,3.7节。
Basically, this variable allows you to append settings to the set of C compilation flags, within the scope of the file where it is assigned only. You are not supposed to change the global flags, because that might have a global impact beyond your own makefile, which is considered bad practice. The check that you mention verifies that indeed, the global flags did not get changed by included makefiles.
基本上,这个变量允许您在只分配C编译标志的文件范围内,将设置附加到C编译标志集。您不应该更改全局标志,因为这可能会影响到您自己的makefile之外的全局影响,这被认为是糟糕的实践。您提到的检查确实验证了这一点,包含的makefile并没有更改全局标记。
It is interesting to check out how ccflags-y
, formerly known as EXTRA_CFLAGS
, ends up being used in the build process. Tracing some relevant points (but not all, because that is left as an exercise to the reader ;-) ) shows the following:
查看ccflag -y(以前称为EXTRA_CFLAGS)是如何在构建过程中使用的,这很有趣。追踪一些相关的点(但不是全部,因为这是留给读者的练习;-))
EXTRA_CFLAGS
can still be used, according to scripts/Makefile.lib
根据脚本/Makefile.lib, EXTRA_CFLAGS仍然可以使用
1 # Backward compatibility
2 asflags-y += $(EXTRA_AFLAGS)
3 ccflags-y += $(EXTRA_CFLAGS)
The same file shows how ccflags-y
ends up in the C compilation flags (and also shows you that you have another variable at your disposal, called CFLAGS_<filename>.o
):
相同的文件显示了ccflags-y最终如何出现在C编译标志中(还显示您有另一个变量可以使用,名为CFLAGS_
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)
Then in scripts/Makefile.build
, the compilation rule is defined:
然后在脚本/ Makefile。编译规则定义为:
234 cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $<
Note that these are all recursively expanded variables, using =
and not :=
, which means that your own value of ccflags-y
gets inserted into the C flags when you define it in your own makefile.
注意,这些都是递归展开的变量,使用=而不是:=,这意味着当您在自己的makefile中定义它时,您自己的ccflags-y值将被插入到C标志中。
Finally about KBUILD_NOPEDANTIC
, which you mention in the title but not in the actual question. This test for changed value of CFLAGS
can be disabled by giving KBUILD_NOPEDANTIC
any value -- see scripts/Makefile.build
最后是KBUILD_NOPEDANTIC,你在标题中提到过,但在实际问题中没有提到。可以通过提供KBUILD_NOPEDANTIC任何值(参见脚本/Makefile.build)来禁用CFLAGS的更改值
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
The files referenced in this answer were all retrieved today.
这个答案中引用的文件今天都被检索到了。
Now... not being an expert in this area and looking further into the makefiles after writing this whole story down, there is a thing that I do not understand either. It seems to me that CFLAGS
is not used in the build system (not implicitly, nor explicitly), but KBUILD_CFLAGS
is. So I wonder whether this check for changes in CFLAGS
should actually be a check for changes in KBUILD_CFLAGS
instead.
现在…我并不是这个领域的专家,在写完这个故事之后,我进一步研究了makefile,有一件事我也不明白。在我看来,在构建系统中不使用CFLAGS(不是隐式的,也不是显式的),但是KBUILD_CFLAGS是。因此,我想知道CFLAGS中的更改是否应该作为KBUILD_CFLAGS中的更改的检查。
#2
1
Linux makefiles build CFLAGS
in a way which is appropriate for the kernel.
Overriding CFLAGS
mean you add some flags and may remove some flags. Some of the removed flags may be important for correct compilation.
Linux makefile以适合内核的方式构建CFLAGS。重写CFLAGS意味着您添加了一些标记,并可能删除一些标记。一些被删除的标志对于正确编译可能很重要。
#1
9
First of all, it might be worth mentioning that EXTRA_CFLAGS
has been deprecated a while ago and is replaced by ccflags-y
. You can read about the intention of ccflags-y
in Documentation/kbuild/makefiles.txt
, section 3.7.
首先,值得一提的是,EXTRA_CFLAGS已经被废弃了,并且被ccflags-y所取代。您可以在文档/kbuild/makefile中阅读关于ccflag -y的意图。txt,3.7节。
Basically, this variable allows you to append settings to the set of C compilation flags, within the scope of the file where it is assigned only. You are not supposed to change the global flags, because that might have a global impact beyond your own makefile, which is considered bad practice. The check that you mention verifies that indeed, the global flags did not get changed by included makefiles.
基本上,这个变量允许您在只分配C编译标志的文件范围内,将设置附加到C编译标志集。您不应该更改全局标志,因为这可能会影响到您自己的makefile之外的全局影响,这被认为是糟糕的实践。您提到的检查确实验证了这一点,包含的makefile并没有更改全局标记。
It is interesting to check out how ccflags-y
, formerly known as EXTRA_CFLAGS
, ends up being used in the build process. Tracing some relevant points (but not all, because that is left as an exercise to the reader ;-) ) shows the following:
查看ccflag -y(以前称为EXTRA_CFLAGS)是如何在构建过程中使用的,这很有趣。追踪一些相关的点(但不是全部,因为这是留给读者的练习;-))
EXTRA_CFLAGS
can still be used, according to scripts/Makefile.lib
根据脚本/Makefile.lib, EXTRA_CFLAGS仍然可以使用
1 # Backward compatibility
2 asflags-y += $(EXTRA_AFLAGS)
3 ccflags-y += $(EXTRA_CFLAGS)
The same file shows how ccflags-y
ends up in the C compilation flags (and also shows you that you have another variable at your disposal, called CFLAGS_<filename>.o
):
相同的文件显示了ccflags-y最终如何出现在C编译标志中(还显示您有另一个变量可以使用,名为CFLAGS_
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)
Then in scripts/Makefile.build
, the compilation rule is defined:
然后在脚本/ Makefile。编译规则定义为:
234 cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $<
Note that these are all recursively expanded variables, using =
and not :=
, which means that your own value of ccflags-y
gets inserted into the C flags when you define it in your own makefile.
注意,这些都是递归展开的变量,使用=而不是:=,这意味着当您在自己的makefile中定义它时,您自己的ccflags-y值将被插入到C标志中。
Finally about KBUILD_NOPEDANTIC
, which you mention in the title but not in the actual question. This test for changed value of CFLAGS
can be disabled by giving KBUILD_NOPEDANTIC
any value -- see scripts/Makefile.build
最后是KBUILD_NOPEDANTIC,你在标题中提到过,但在实际问题中没有提到。可以通过提供KBUILD_NOPEDANTIC任何值(参见脚本/Makefile.build)来禁用CFLAGS的更改值
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
The files referenced in this answer were all retrieved today.
这个答案中引用的文件今天都被检索到了。
Now... not being an expert in this area and looking further into the makefiles after writing this whole story down, there is a thing that I do not understand either. It seems to me that CFLAGS
is not used in the build system (not implicitly, nor explicitly), but KBUILD_CFLAGS
is. So I wonder whether this check for changes in CFLAGS
should actually be a check for changes in KBUILD_CFLAGS
instead.
现在…我并不是这个领域的专家,在写完这个故事之后,我进一步研究了makefile,有一件事我也不明白。在我看来,在构建系统中不使用CFLAGS(不是隐式的,也不是显式的),但是KBUILD_CFLAGS是。因此,我想知道CFLAGS中的更改是否应该作为KBUILD_CFLAGS中的更改的检查。
#2
1
Linux makefiles build CFLAGS
in a way which is appropriate for the kernel.
Overriding CFLAGS
mean you add some flags and may remove some flags. Some of the removed flags may be important for correct compilation.
Linux makefile以适合内核的方式构建CFLAGS。重写CFLAGS意味着您添加了一些标记,并可能删除一些标记。一些被删除的标志对于正确编译可能很重要。