From e4aca45950050fc584e036bb1b266ce1264a6daf Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Wed, 17 Feb 2016 15:50:06 -0500 Subject: kbuild: de-duplicate fixdep usage The generation and postprocessing of automatic dependency rules is duplicated in rule_cc_o_c, rule_as_o_S and if_changed_dep. Since this is not a trivial one-liner action, it is now abstracted under cmd_and_fixdep to simplify things and make future changes in this area easier. In the rule_cc_o_c and rule_as_o_S cases that means the order of some commands has been altered, namely fixdep and related file manipulations are executed earlier, but they didn't depend on those commands that now execute later. Signed-off-by: Nicolas Pitre --- scripts/Kbuild.include | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'scripts/Kbuild.include') diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include index b2ab2a92a375..80ca538bfba9 100644 --- a/scripts/Kbuild.include +++ b/scripts/Kbuild.include @@ -256,10 +256,13 @@ if_changed = $(if $(strip $(any-prereq) $(arg-check)), \ # Execute the command and also postprocess generated .d dependencies file. if_changed_dep = $(if $(strip $(any-prereq) $(arg-check) ), \ @set -e; \ + $(cmd_and_fixdep), @:) + +cmd_and_fixdep = \ $(echo-cmd) $(cmd_$(1)); \ scripts/basic/fixdep $(depfile) $@ '$(make-cmd)' > $(dot-target).tmp;\ rm -f $(depfile); \ - mv -f $(dot-target).tmp $(dot-target).cmd, @:) + mv -f $(dot-target).tmp $(dot-target).cmd; # Usage: $(call if_changed_rule,foo) # Will check if $(cmd_foo) or any of the prerequisites changed, -- cgit From c1a95fda2a40ae8c7aad3fa44fa7718a3710eb2d Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Fri, 22 Jan 2016 13:41:57 -0500 Subject: kbuild: add fine grained build dependencies for exported symbols Like with kconfig options, we now have the ability to compile in and out individual EXPORT_SYMBOL() declarations based on the content of include/generated/autoksyms.h. However we don't want the entire world to be rebuilt whenever that file is touched. Let's apply the same build dependency trick used for CONFIG_* symbols where the time stamp of empty files whose paths matching those symbols is used to trigger fine grained rebuilds. In our case the key is the symbol name passed to EXPORT_SYMBOL(). However, unlike config options, we cannot just use fixdep to parse the source code for EXPORT_SYMBOL(ksym) because several variants exist and parsing them all in a separate tool, and keeping it in synch, is not trivially maintainable. Furthermore, there are variants such as EXPORT_SYMBOL_GPL(pci_user_read_config_##size); that are instanciated via a macro for which we can't easily determine the actual exported symbol name(s) short of actually running the preprocessor on them. Storing the symbol name string in a special ELF section doesn't work for targets that output assembly or preprocessed source. So the best way is really to leverage the preprocessor by having it output actual symbol names anchored by a special sequence that can be easily filtered out. Then the list of symbols is simply fed to fixdep to be merged with the other dependencies. That implies the preprocessor is executed twice for each source file. A previous attempt relied on a warning pragma for each EXPORT_SYMBOL() instance that was filtered apart from stderr by the build system with a sed script during the actual compilation pass. Unfortunately the preprocessor/compiler diagnostic output isn't stable between versions and this solution, although more efficient, was deemed too fragile. Because of the lowercasing performed by fixdep, there might be name collisions triggering spurious rebuilds for similar symbols. But this shouldn't be a big issue in practice. (This is the case for CONFIG_* symbols and I didn't want to be different here, whatever the original reason for doing so.) To avoid needless build overhead, the exported symbol name gathering is performed only when CONFIG_TRIM_UNUSED_KSYMS is selected. Signed-off-by: Nicolas Pitre Acked-by: Rusty Russell --- include/linux/export.h | 13 ++++++++++++- scripts/Kbuild.include | 27 +++++++++++++++++++++++++++ scripts/basic/fixdep.c | 1 + 3 files changed, 40 insertions(+), 1 deletion(-) (limited to 'scripts/Kbuild.include') diff --git a/include/linux/export.h b/include/linux/export.h index 77afdb2a2506..2f9ccbe6a639 100644 --- a/include/linux/export.h +++ b/include/linux/export.h @@ -65,7 +65,18 @@ extern struct module __this_module; __attribute__((section("___ksymtab" sec "+" #sym), unused)) \ = { (unsigned long)&sym, __kstrtab_##sym } -#ifdef CONFIG_TRIM_UNUSED_KSYMS +#if defined(__KSYM_DEPS__) + +/* + * For fine grained build dependencies, we want to tell the build system + * about each possible exported symbol even if they're not actually exported. + * We use a string pattern that is unlikely to be valid code that the build + * system filters out from the preprocessor output (see ksym_dep_filter + * in scripts/Kbuild.include). + */ +#define __EXPORT_SYMBOL(sym, sec) === __KSYM_##sym === + +#elif defined(CONFIG_TRIM_UNUSED_KSYMS) #include #include diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include index 80ca538bfba9..a09927e02713 100644 --- a/scripts/Kbuild.include +++ b/scripts/Kbuild.include @@ -258,12 +258,39 @@ if_changed_dep = $(if $(strip $(any-prereq) $(arg-check) ), \ @set -e; \ $(cmd_and_fixdep), @:) +ifndef CONFIG_TRIM_UNUSED_KSYMS + cmd_and_fixdep = \ $(echo-cmd) $(cmd_$(1)); \ scripts/basic/fixdep $(depfile) $@ '$(make-cmd)' > $(dot-target).tmp;\ rm -f $(depfile); \ mv -f $(dot-target).tmp $(dot-target).cmd; +else + +# Filter out exported kernel symbol names from the preprocessor output. +# See also __KSYM_DEPS__ in include/linux/export.h. +# We disable the depfile generation here, so as not to overwrite the existing +# depfile while fixdep is parsing it. +flags_nodeps = $(filter-out -Wp$(comma)-M%, $($(1))) +ksym_dep_filter = \ + case "$(1)" in \ + cc_*_c) $(CPP) $(call flags_nodeps,c_flags) -D__KSYM_DEPS__ $< ;; \ + as_*_S) $(CPP) $(call flags_nodeps,a_flags) -D__KSYM_DEPS__ $< ;; \ + boot*|build*|*cpp_lds_S|dtc|host*|vdso*) : ;; \ + *) echo "Don't know how to preprocess $(1)" >&2; false ;; \ + esac | sed -rn 's/^.*=== __KSYM_(.*) ===.*$$/KSYM_\1/p' + +cmd_and_fixdep = \ + $(echo-cmd) $(cmd_$(1)); \ + $(ksym_dep_filter) | \ + scripts/basic/fixdep -e $(depfile) $@ '$(make-cmd)' \ + > $(dot-target).tmp; \ + rm -f $(depfile); \ + mv -f $(dot-target).tmp $(dot-target).cmd; + +endif + # Usage: $(call if_changed_rule,foo) # Will check if $(cmd_foo) or any of the prerequisites changed, # and if so will execute $(rule_foo). diff --git a/scripts/basic/fixdep.c b/scripts/basic/fixdep.c index 7e90a1f7de0f..746ec1ece614 100644 --- a/scripts/basic/fixdep.c +++ b/scripts/basic/fixdep.c @@ -358,6 +358,7 @@ static void parse_dep_file(void *map, size_t len) /* Ignore certain dependencies */ if (strrcmp(s, "include/generated/autoconf.h") && + strrcmp(s, "include/generated/autoksyms.h") && strrcmp(s, "arch/um/include/uml-config.h") && strrcmp(s, "include/linux/kconfig.h") && strrcmp(s, ".ver")) { -- cgit From 366f4856f0ef1f3dbdb85b0cc57bef2a77c08b86 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Tue, 26 Apr 2016 11:21:34 -0400 Subject: kbuild: adjust ksym_dep_filter for some cmd_* renames The following renames occurred recently: cmd_cc_i_c --> cmd_cpp_i_c cmd_as_s_S --> cmd_cpp_s_S The respective cc_*_c and as_*_S patterns no longer match the above therefore additional patterns are needed. Signed-off-by: Nicolas Pitre Signed-off-by: Michal Marek --- scripts/Kbuild.include | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'scripts/Kbuild.include') diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include index a09927e02713..36e9475395aa 100644 --- a/scripts/Kbuild.include +++ b/scripts/Kbuild.include @@ -275,10 +275,12 @@ else flags_nodeps = $(filter-out -Wp$(comma)-M%, $($(1))) ksym_dep_filter = \ case "$(1)" in \ - cc_*_c) $(CPP) $(call flags_nodeps,c_flags) -D__KSYM_DEPS__ $< ;; \ - as_*_S) $(CPP) $(call flags_nodeps,a_flags) -D__KSYM_DEPS__ $< ;; \ - boot*|build*|*cpp_lds_S|dtc|host*|vdso*) : ;; \ - *) echo "Don't know how to preprocess $(1)" >&2; false ;; \ + cc_*_c|cpp_i_c) \ + $(CPP) $(call flags_nodeps,c_flags) -D__KSYM_DEPS__ $< ;; \ + as_*_S|cpp_s_S) \ + $(CPP) $(call flags_nodeps,a_flags) -D__KSYM_DEPS__ $< ;; \ + boot*|build*|*cpp_lds_S|dtc|host*|vdso*) : ;; \ + *) echo "Don't know how to preprocess $(1)" >&2; false ;; \ esac | sed -rn 's/^.*=== __KSYM_(.*) ===.*$$/KSYM_\1/p' cmd_and_fixdep = \ -- cgit From f110e0fec89935879a76aebe1726dce3fcb6ab13 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Thu, 28 Apr 2016 17:29:42 -0400 Subject: kbuild: fix ksym_dep_filter when multiple EXPORT_SYMBOL() on the same line In kernel/cgroup.c there is: #define SUBSYS(_x) \ DEFINE_STATIC_KEY_TRUE(_x ## _cgrp_subsys_enabled_key); \ DEFINE_STATIC_KEY_TRUE(_x ## _cgrp_subsys_on_dfl_key); \ EXPORT_SYMBOL_GPL(_x ## _cgrp_subsys_enabled_key); \ EXPORT_SYMBOL_GPL(_x ## _cgrp_subsys_on_dfl_key); The expansion of this macro causes multiple EXPORT_SYMBOL_GPL() instances to appear on the same preprocessor line output, confusing the sed script expecting only one of them per line. Unfortunately this can't be fixed nicely in the sed script as sed's regexp can't do non greedy matching. Fix this by turning any semicolon into a line break before filtering. Reported-by: Arnd Bergmann Signed-off-by: Nicolas Pitre Signed-off-by: Michal Marek --- scripts/Kbuild.include | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts/Kbuild.include') diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include index 36e9475395aa..1f0d41cc73d1 100644 --- a/scripts/Kbuild.include +++ b/scripts/Kbuild.include @@ -281,7 +281,7 @@ ksym_dep_filter = \ $(CPP) $(call flags_nodeps,a_flags) -D__KSYM_DEPS__ $< ;; \ boot*|build*|*cpp_lds_S|dtc|host*|vdso*) : ;; \ *) echo "Don't know how to preprocess $(1)" >&2; false ;; \ - esac | sed -rn 's/^.*=== __KSYM_(.*) ===.*$$/KSYM_\1/p' + esac | tr ";" "\n" | sed -rn 's/^.*=== __KSYM_(.*) ===.*$$/KSYM_\1/p' cmd_and_fixdep = \ $(echo-cmd) $(cmd_$(1)); \ -- cgit From 9c8fa9bc08f60ac657751daba9fccf828a36cfed Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 7 May 2016 15:48:26 +0900 Subject: kbuild: fix if_change and friends to consider argument order Currently, arg-check is implemented as follows: arg-check = $(strip $(filter-out $(cmd_$(1)), $(cmd_$@)) \ $(filter-out $(cmd_$@), $(cmd_$(1))) ) This does not care about the order of arguments that appear in $(cmd_$(1)) and $(cmd_$@). So, if_changed and friends never rebuild the target if only the argument order is changed. This is a problem when the link order is changed. Apparently, obj-y += foo.o obj-y += bar.o and obj-y += bar.o obj-y += foo.o should be distinguished because the link order determines the probe order of drivers. So, built-in.o should be rebuilt when the order of objects is changed. This commit fixes arg-check to compare the old/current commands including the argument order. Of course, this change has a side effect; Kbuild will react to the change of compile option order. For example, "-DFOO -DBAR" and "-DBAR -DFOO" should give no difference to the build result, but false positive should be better than false negative. I am moving space_escape to the top of Kbuild.include just for a matter of preference. In practical terms, space_escape can be defined after arg-check because arg-check uses "=" flavor, not ":=". Having said that, collecting convenient variables in one place makes sense from the point of readability. Chaining "%%%SPACE%%%" to "_-_SPACE_-_" is also a matter of taste at this point. Actually, it can be arbitrary as long as it is an unlikely used string. The only problem I see in "%%%SPACE%%%" is that "%" is a special character in "$(patsubst ...)" context. This commit just uses "$(subst ...)" for arg-check, but I am fixing it now in case we might want to use it in $(patsubst ...) context in the future. Signed-off-by: Masahiro Yamada Signed-off-by: Michal Marek --- scripts/Kbuild.include | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'scripts/Kbuild.include') diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include index 1f0d41cc73d1..0f82314621f2 100644 --- a/scripts/Kbuild.include +++ b/scripts/Kbuild.include @@ -7,6 +7,7 @@ quote := " squote := ' empty := space := $(empty) $(empty) +space_escape := _-_SPACE_-_ ### # Name of target with a '.' as filename prefix. foo/bar.o => foo/.bar.o @@ -226,10 +227,10 @@ objectify = $(foreach o,$(1),$(if $(filter /%,$(o)),$(o),$(obj)/$(o))) # See Documentation/kbuild/makefiles.txt for more info ifneq ($(KBUILD_NOCMDDEP),1) -# Check if both arguments has same arguments. Result is empty string if equal. -# User may override this check using make KBUILD_NOCMDDEP=1 -arg-check = $(strip $(filter-out $(cmd_$(1)), $(cmd_$@)) \ - $(filter-out $(cmd_$@), $(cmd_$(1))) ) +# Check if both arguments are the same including their order. Result is empty +# string if equal. User may override this check using make KBUILD_NOCMDDEP=1 +arg-check = $(filter-out $(subst $(space),$(space_escape),$(strip $(cmd_$@))), \ + $(subst $(space),$(space_escape),$(strip $(cmd_$1)))) else arg-check = $(if $(strip $(cmd_$@)),,1) endif @@ -373,8 +374,6 @@ endif # ############################################################################### # -space_escape := %%%SPACE%%% -# define config_filename ifneq ($$(CONFIG_$(1)),"") $(1)_FILENAME := $$(subst \\,\,$$(subst \$$(quote),$$(quote),$$(subst $$(space_escape),\$$(space),$$(patsubst "%",%,$$(subst $$(space),$$(space_escape),$$(CONFIG_$(1))))))) -- cgit