Commit bc081dd6e9f6 ("kbuild: generate modules.builtin") added infrastructure to generate modules.builtin, the list of all builtin modules. Basically, it works like this: - Kconfig generates include/config/tristate.conf, the list of tristate CONFIG options with a value in a capital letter. - scripts/Makefile.modbuiltin makes Kbuild descend into directories to collect the information of builtin modules. I am not a big fan of it because Kbuild ends up with traversing the source tree twice. I am not sure how perfectly it should work, but this approach cannot avoid false positives; even if the relevant CONFIG option is tristate, some Makefiles forces obj-m to obj-y. Some examples are: arch/powerpc/platforms/powermac/Makefile: obj-$(CONFIG_NVRAM:m=y) += nvram.o net/ipv6/Makefile: obj-$(subst m,y,$(CONFIG_IPV6)) += inet6_hashtables.o net/netlabel/Makefile: obj-$(subst m,y,$(CONFIG_IPV6)) += netlabel_calipso.o Nobody has complained about (or noticed) it, so it is probably fine to have false positives in modules.builtin. This commit simplifies the implementation. Let's exploit the fact that every module has MODULE_LICENSE(). (modpost shows a warning if MODULE_LICENSE is missing. If so, 0-day bot would already have blocked such a module.) I added MODULE_FILE to <linux/module.h>. When the code is being compiled as builtin, it will be filled with the file path of the module, and collected into modules.builtin.info. Then, scripts/link-vmlinux.sh extracts the list of builtin modules out of it. This new approach fixes the false-positives above, but adds another type of false-positives; non-modular code may have MODULE_LICENSE() by mistake. This is not a big deal, it is just the code is always orphan. We can clean it up if we like. You can see cleanup examples by: $ git log --grep='make.* explicitly non-modular' To sum up, this commits deletes lots of code, but still produces almost equivalent results. Please note it does not increase the vmlinux size at all. As you can see in include/asm-generic/vmlinux.lds.h, the .modinfo section is discarded in the link stage.
Showing the changes to scripts (4 of 7 files). Show all
Unified · Split
| @@ -163,12 +163,6 @@ ld-ifversion = $(shell [ $(ld-version) $(1) $(2) ] && echo $(3) || echo $(4)) · 162 unmodified lines | ||
| 163 | 163 | # $(Q)$(MAKE) $(build)=dir |
| 164 | 164 | build := -f $(srctree)/scripts/Makefile.build obj |
| 165 | 165 | |
| 166 | −### | |
| 167 | −# Shorthand for $(Q)$(MAKE) -f scripts/Makefile.modbuiltin obj= | |
| 168 | −# Usage: | |
| 169 | −# $(Q)$(MAKE) $(modbuiltin)=dir | |
| 170 | −modbuiltin := -f $(srctree)/scripts/Makefile.modbuiltin obj | |
| 171 | − | |
| 172 | 166 | ### |
| 173 | 167 | # Shorthand for $(Q)$(MAKE) -f scripts/Makefile.dtbinst obj= |
| 174 | 168 | # Usage: |
| @@ -1,57 +0,0 @@ | ||
| 1 | −# SPDX-License-Identifier: GPL-2.0 | |
| 2 | −# ========================================================================== | |
| 3 | −# Generating modules.builtin | |
| 4 | −# ========================================================================== | |
| 5 | − | |
| 6 | −src := $(obj) | |
| 7 | − | |
| 8 | −PHONY := __modbuiltin | |
| 9 | −__modbuiltin: | |
| 10 | − | |
| 11 | −include include/config/auto.conf | |
| 12 | −# tristate.conf sets tristate variables to uppercase 'Y' or 'M' | |
| 13 | −# That way, we get the list of built-in modules in obj-Y | |
| 14 | −include include/config/tristate.conf | |
| 15 | − | |
| 16 | −include scripts/Kbuild.include | |
| 17 | − | |
| 18 | −ifdef building_out_of_srctree | |
| 19 | −# Create output directory if not already present | |
| 20 | −_dummy := $(shell [ -d $(obj) ] || mkdir -p $(obj)) | |
| 21 | −endif | |
| 22 | − | |
| 23 | −# The filename Kbuild has precedence over Makefile | |
| 24 | −kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src)) | |
| 25 | −kbuild-file := $(if $(wildcard $(kbuild-dir)/Kbuild),$(kbuild-dir)/Kbuild,$(kbuild-dir)/Makefile) | |
| 26 | −include $(kbuild-file) | |
| 27 | − | |
| 28 | −include scripts/Makefile.lib | |
| 29 | −__subdir-Y := $(patsubst %/,%,$(filter %/, $(obj-Y))) | |
| 30 | −subdir-Y += $(__subdir-Y) | |
| 31 | −subdir-ym := $(sort $(subdir-y) $(subdir-Y) $(subdir-m)) | |
| 32 | −subdir-ym := $(addprefix $(obj)/,$(subdir-ym)) | |
| 33 | −obj-Y := $(addprefix $(obj)/,$(obj-Y)) | |
| 34 | − | |
| 35 | −modbuiltin-subdirs := $(patsubst %,%/modules.builtin, $(subdir-ym)) | |
| 36 | −modbuiltin-mods := $(filter %.ko, $(obj-Y:.o=.ko)) | |
| 37 | −modbuiltin-target := $(obj)/modules.builtin | |
| 38 | − | |
| 39 | −__modbuiltin: $(modbuiltin-target) $(subdir-ym) | |
| 40 | − @: | |
| 41 | − | |
| 42 | −$(modbuiltin-target): $(subdir-ym) FORCE | |
| 43 | − $(Q)(for m in $(modbuiltin-mods); do echo $$m; done; \ | |
| 44 | − cat /dev/null $(modbuiltin-subdirs)) > $@ | |
| 45 | − | |
| 46 | −PHONY += FORCE | |
| 47 | − | |
| 48 | −FORCE: | |
| 49 | − | |
| 50 | −# Descending | |
| 51 | −# --------------------------------------------------------------------------- | |
| 52 | − | |
| 53 | −PHONY += $(subdir-ym) | |
| 54 | −$(subdir-ym): | |
| 55 | − $(Q)$(MAKE) $(modbuiltin)=$@ | |
| 56 | − | |
| 57 | −.PHONY: $(PHONY) | |
| @@ -710,25 +710,6 @@ static struct conf_printer header_printer_cb = · 709 unmodified lines | ||
| 710 | 710 | .print_comment = header_print_comment, |
| 711 | 711 | }; |
| 712 | 712 | |
| 713 | −/* | |
| 714 | − * Tristate printer | |
| 715 | − * | |
| 716 | − * This printer is used when generating the `include/config/tristate.conf' file. | |
| 717 | − */ | |
| 718 | −static void | |
| 719 | −tristate_print_symbol(FILE *fp, struct symbol *sym, const char *value, void *arg) | |
| 720 | −{ | |
| 721 | − | |
| 722 | − if (sym->type == S_TRISTATE && *value != 'n') | |
| 723 | − fprintf(fp, "%s%s=%c\n", CONFIG_, sym->name, (char)toupper(*value)); | |
| 724 | −} | |
| 725 | − | |
| 726 | −static struct conf_printer tristate_printer_cb = | |
| 727 | −{ | |
| 728 | − .print_symbol = tristate_print_symbol, | |
| 729 | − .print_comment = kconfig_print_comment, | |
| 730 | −}; | |
| 731 | − | |
| 732 | 713 | static void conf_write_symbol(FILE *fp, struct symbol *sym, |
| 733 | 714 | struct conf_printer *printer, void *printer_arg) |
| 734 | 715 | { |
| @@ -1062,7 +1043,7 @@ int conf_write_autoconf(int overwrite) · 327 unmodified lines | ||
| 1062 | 1043 | struct symbol *sym; |
| 1063 | 1044 | const char *name; |
| 1064 | 1045 | const char *autoconf_name = conf_get_autoconfig_name(); |
| 1065 | − FILE *out, *tristate, *out_h; | |
| 1046 | + FILE *out, *out_h; | |
| 1066 | 1047 | int i; |
| 1067 | 1048 | |
| 1068 | 1049 | if (!overwrite && is_present(autoconf_name)) |
| @@ -1077,23 +1058,13 @@ int conf_write_autoconf(int overwrite) · 8 unmodified lines | ||
| 1077 | 1058 | if (!out) |
| 1078 | 1059 | return 1; |
| 1079 | 1060 | |
| 1080 | − tristate = fopen(".tmpconfig_tristate", "w"); | |
| 1081 | − if (!tristate) { | |
| 1082 | − fclose(out); | |
| 1083 | − return 1; | |
| 1084 | − } | |
| 1085 | − | |
| 1086 | 1061 | out_h = fopen(".tmpconfig.h", "w"); |
| 1087 | 1062 | if (!out_h) { |
| 1088 | 1063 | fclose(out); |
| 1089 | − fclose(tristate); | |
| 1090 | 1064 | return 1; |
| 1091 | 1065 | } |
| 1092 | 1066 | |
| 1093 | 1067 | conf_write_heading(out, &kconfig_printer_cb, NULL); |
| 1094 | − | |
| 1095 | − conf_write_heading(tristate, &tristate_printer_cb, NULL); | |
| 1096 | − | |
| 1097 | 1068 | conf_write_heading(out_h, &header_printer_cb, NULL); |
| 1098 | 1069 | |
| 1099 | 1070 | for_all_symbols(i, sym) { |
| @@ -1101,15 +1072,11 @@ int conf_write_autoconf(int overwrite) · 1 unmodified line | ||
| 1101 | 1072 | if (!(sym->flags & SYMBOL_WRITE) || !sym->name) |
| 1102 | 1073 | continue; |
| 1103 | 1074 | |
| 1104 | − /* write symbol to auto.conf, tristate and header files */ | |
| 1075 | + /* write symbols to auto.conf and autoconf.h */ | |
| 1105 | 1076 | conf_write_symbol(out, sym, &kconfig_printer_cb, (void *)1); |
| 1106 | − | |
| 1107 | − conf_write_symbol(tristate, sym, &tristate_printer_cb, (void *)1); | |
| 1108 | − | |
| 1109 | 1077 | conf_write_symbol(out_h, sym, &header_printer_cb, NULL); |
| 1110 | 1078 | } |
| 1111 | 1079 | fclose(out); |
| 1112 | − fclose(tristate); | |
| 1113 | 1080 | fclose(out_h); |
| 1114 | 1081 | |
| 1115 | 1082 | name = getenv("KCONFIG_AUTOHEADER"); |
| @@ -1120,14 +1087,6 @@ int conf_write_autoconf(int overwrite) · 4 unmodified lines | ||
| 1120 | 1087 | if (rename(".tmpconfig.h", name)) |
| 1121 | 1088 | return 1; |
| 1122 | 1089 | |
| 1123 | − name = getenv("KCONFIG_TRISTATE"); | |
| 1124 | − if (!name) | |
| 1125 | − name = "include/config/tristate.conf"; | |
| 1126 | − if (make_parent_dir(name)) | |
| 1127 | − return 1; | |
| 1128 | − if (rename(".tmpconfig_tristate", name)) | |
| 1129 | − return 1; | |
| 1130 | − | |
| 1131 | 1090 | if (make_parent_dir(autoconf_name)) |
| 1132 | 1091 | return 1; |
| 1133 | 1092 | /* |
| @@ -250,6 +250,10 @@ ${MAKE} -f "${srctree}/scripts/Makefile.modpost" MODPOST_VMLINUX=1 · 249 unmodified lines | ||
| 250 | 250 | |
| 251 | 251 | info MODINFO modules.builtin.modinfo |
| 252 | 252 | ${OBJCOPY} -j .modinfo -O binary vmlinux.o modules.builtin.modinfo |
| 253 | +info GEN modules.builtin | |
| 254 | +# The second line aids cases where multiple modules share the same object. | |
| 255 | +tr '\0' '\n' < modules.builtin.modinfo | sed -n 's/^[[:alnum:]:_]*\.file=//p' | | |
| 256 | + tr ' ' '\n' | uniq | sed -e 's:^:kernel/:' -e 's/$/.ko/' > modules.builtin | |
| 253 | 257 | |
| 254 | 258 | btf_vmlinux_bin_o="" |
| 255 | 259 | if [ -n "${CONFIG_DEBUG_INFO_BTF}" ]; then |