@@ -76,8 +76,20 @@ extern struct module __this_module;
___cond_export_sym(sym, sec, conf)
#define ___cond_export_sym(sym, sec, enabled) \
__cond_export_sym_##enabled(sym, sec)
-#define __cond_export_sym_1(sym, sec) ___EXPORT_SYMBOL(sym, sec)
-#define __cond_export_sym_0(sym, sec) /* nothing */
+#define __cond_export_sym_1(sym, sec) \
+ __KSYM_DEP(sym) ___EXPORT_SYMBOL(sym, sec)
+#define __cond_export_sym_0(sym, sec) \
+ __KSYM_DEP(sym) /* nothing */
+
+/*
+ * For fine grained build dependencies, we want to tell the build system
+ * about each possible exported symbol even if they're not actually exported.
+ * This is accomplished with a preprocessor warning that gets captured by
+ * the make rule (see ksym_dep_filter in scripts/Kbuild.include).
+ */
+#define __KSYM_DEP(sym) __pragma_string( KBUILD_AUTOKSYM_DEP: sym )
+#define __pragma_string(x) __emit_pragma( GCC warning #x )
+#define __emit_pragma(x) _Pragma(#x)
#else
#define __EXPORT_SYMBOL ___EXPORT_SYMBOL
@@ -258,12 +258,40 @@ 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 advertised as warning pragmas
+# by the preprocessor and write them to $(1). We must consider continuation
+# lines as well: they start with a blank, or the preceeding line ends with
+# a ':'. Anything else is passed through as is.
+# See also __KSYM_DEP() in include/linux/export.h.
+ksym_dep_filter = sed -n \
+ -e '1 {x; $$!d}' \
+ -e '/^ / {H; $$!d}' \
+ -e 'x; /:$$/ {x; H; $$!d; s/^/ /; x}' \
+ -e ':filter; /^.*KBUILD_AUTOKSYM_DEP: /! {p; b next}' \
+ -e 's//KSYM_/; s/\n.*//; w $(1)' \
+ -e ':next; $$!d' \
+ -e '1 q; s/^/ /; x; /^ /! b filter'
+
+cmd_and_fixdep = \
+ $(echo-cmd) \
+ $(cmd_$(1)) 2>&1 | $(call ksym_dep_filter,$(dot-target).ksym.tmp) >&2;\
+ scripts/basic/fixdep -e $(depfile) $@ '$(make-cmd)' \
+ < $(dot-target).ksym.tmp > $(dot-target).tmp; \
+ rm -f $(dot-target).ksym.tmp $(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).
@@ -354,6 +354,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")) {