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:
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.
Additional email
from LKML.
Why is it bad idea? What is rational?
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.
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.
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:
EXTRA_CFLAGS
can still be used, according to scripts/Makefile.lib
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
):
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:
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.
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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With