| # SPDX-License-Identifier: GPL-2.0 |
| # =========================================================================== |
| # Module versions |
| # =========================================================================== |
| # |
| # Stage one of module building created the following: |
| # a) The individual .o files used for the module |
| # b) A <module>.o file which is the .o files above linked together |
| # c) A <module>.mod file, listing the name of the preliminary <module>.o file, |
| # plus all .o files |
| # d) modules.order, which lists all the modules |
| |
| # Stage 2 is handled by this file and does the following |
| # 1) Find all modules listed in modules.order |
| # 2) modpost is then used to |
| # 3) create one <module>.mod.c file per module |
| # 4) create one Module.symvers file with CRC for all exported symbols |
| |
| # Step 3 is used to place certain information in the module's ELF |
| # section, including information such as: |
| # Version magic (see include/linux/vermagic.h for full details) |
| # - Kernel release |
| # - SMP is CONFIG_SMP |
| # - PREEMPT is CONFIG_PREEMPT[_RT] |
| # - GCC Version |
| # Module info |
| # - Module version (MODULE_VERSION) |
| # - Module alias'es (MODULE_ALIAS) |
| # - Module license (MODULE_LICENSE) |
| # - See include/linux/module.h for more details |
| |
| # Step 4 is solely used to allow module versioning in external modules, |
| # where the CRC of each module is retrieved from the Module.symvers file. |
| |
| PHONY := __modpost |
| __modpost: |
| |
| include include/config/auto.conf |
| include $(srctree)/scripts/Kbuild.include |
| |
| mixed-build-prefix = $(if $(KBUILD_MIXED_TREE),$(KBUILD_MIXED_TREE)/) |
| |
| modpost-args = \ |
| $(if $(CONFIG_MODVERSIONS),-m) \ |
| $(if $(CONFIG_MODULE_SRCVERSION_ALL),-a) \ |
| $(if $(CONFIG_SECTION_MISMATCH_WARN_ONLY),,-E) \ |
| $(if $(KBUILD_NSDEPS),-d $(MODULES_NSDEPS)) \ |
| $(if $(CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS)$(KBUILD_NSDEPS),-N) \ |
| -o $@ |
| |
| # 'make -i -k' ignores compile errors, and builds as many modules as possible. |
| ifneq ($(findstring i,$(filter-out --%,$(MAKEFLAGS))),) |
| modpost-args += -n |
| endif |
| |
| ifeq ($(CONFIG_MODULE_SCMVERSION),y) |
| ifeq ($(KBUILD_EXTMOD),) |
| module_srcpath := $(srctree) |
| else |
| # Get the external module's source path. KBUILD_EXTMOD could either be an |
| # absolute path or relative path from $(srctree). This makes sure that we |
| # aren't using a relative path from a separate working directory (O= or |
| # KBUILD_OUTPUT) since that may not be the actual module's SCM project path. So |
| # check the path relative to $(srctree) first. |
| ifneq ($(realpath $(srctree)/$(KBUILD_EXTMOD) 2>/dev/null),) |
| module_srcpath := $(srctree)/$(KBUILD_EXTMOD) |
| else |
| module_srcpath := $(KBUILD_EXTMOD) |
| endif |
| endif |
| |
| # Get the SCM version of the module. Sed verifies setlocalversion returns |
| # a proper revision based on the SCM type, e.g. git, mercurial, or svn. |
| # Note: relative M= paths are not supported when building the kernel out of the |
| # srctree since setlocalversion won't be able to find the module srctree. |
| module_scmversion := $(shell $(srctree)/scripts/setlocalversion $(module_srcpath) | \ |
| sed -n 's/.*-\(\(g\|hg\)[a-fA-F0-9]\+\(-dirty\)\?\|svn[0-9]\+\).*/\1/p') |
| ifneq ($(module_scmversion),) |
| modpost-args += -v $(module_scmversion) |
| endif |
| endif |
| |
| ifeq ($(KBUILD_EXTMOD),) |
| |
| # Generate the list of in-tree objects in vmlinux |
| # --------------------------------------------------------------------------- |
| |
| # This is used to retrieve symbol versions generated by genksyms. |
| ifdef CONFIG_MODVERSIONS |
| ifndef KBUILD_MIXED_TREE |
| vmlinux.symvers Module.symvers: .vmlinux.objs |
| endif |
| endif |
| |
| # Ignore libgcc.a |
| # Some architectures do '$(CC) --print-libgcc-file-name' to borrow libgcc.a |
| # from the toolchain, but there is no EXPORT_SYMBOL in it. |
| |
| quiet_cmd_vmlinux_objs = GEN $@ |
| cmd_vmlinux_objs = \ |
| for f in $(real-prereqs); do \ |
| case $${f} in \ |
| *libgcc.a) ;; \ |
| *) $(AR) t $${f} ;; \ |
| esac \ |
| done > $@ |
| |
| quiet_cmd_vmlinux_symvers = GEN $@ |
| cmd_vmlinux_symvers = grep "\<vmlinux\s\+EXPORT" $< > $@ |
| |
| quiet_cmd_cat_symvers = GEN $@ |
| cmd_cat_symvers = cat $(real-prereqs) > $@ |
| |
| ifndef KBUILD_MIXED_TREE |
| targets += .vmlinux.objs |
| .vmlinux.objs: vmlinux.a $(KBUILD_VMLINUX_LIBS) FORCE |
| $(call if_changed,vmlinux_objs) |
| endif |
| |
| vmlinux.o-if-present := $(wildcard vmlinux.o) |
| output-symdump := vmlinux.symvers |
| |
| ifdef KBUILD_MODULES |
| output-symdump := $(if $(vmlinux.o-if-present), Module.symvers, modules-only.symvers) |
| missing-input := $(filter-out $(vmlinux.o-if-present),vmlinux.o) |
| |
| targets += vmlinux.symvers |
| vmlinux.symvers: Module.symvers FORCE |
| $(call if_changed,vmlinux_symvers) |
| |
| __modpost: $(if $(vmlinux.o-if-present),vmlinux.symvers,) |
| endif |
| |
| # Overwrite values for mixed building (overwritting makes merges easier) |
| ifdef KBUILD_MIXED_TREE |
| targets += Module.symvers |
| Module.symvers: $(mixed-build-prefix)vmlinux.symvers modules-only.symvers FORCE |
| $(call if_changed,cat_symvers) |
| |
| __modpost: Module.symvers |
| |
| vmlinux.o-if-present := |
| vmlinux.symvers-if-present := $(wildcard $(mixed-build-prefix)vmlinux.symvers) |
| modpost-args += $(addprefix -i ,$(vmlinux.symvers-if-present)) |
| output-symdump := modules-only.symvers |
| missing-input := $(filter-out $(vmlinux.symvers-if-present),$(mixed-build-prefix)vmlinux.symvers) |
| endif |
| |
| else |
| |
| # set src + obj - they may be used in the modules's Makefile |
| obj := $(KBUILD_EXTMOD) |
| src := $(obj) |
| |
| # Include the module's Makefile to find KBUILD_EXTRA_SYMBOLS |
| include $(or $(wildcard $(src)/Kbuild), $(src)/Makefile) |
| |
| module.symvers-if-present := $(wildcard Module.symvers) |
| output-symdump := $(KBUILD_EXTMOD)/Module.symvers |
| missing-input := $(filter-out $(module.symvers-if-present), Module.symvers) |
| |
| modpost-args += -e $(addprefix -i ,$(module.symvers-if-present) $(KBUILD_EXTRA_SYMBOLS)) |
| |
| endif # ($(KBUILD_EXTMOD),) |
| |
| ifneq ($(KBUILD_MODPOST_WARN)$(missing-input),) |
| modpost-args += -w |
| endif |
| |
| modorder-if-needed := $(if $(KBUILD_MODULES), $(MODORDER)) |
| |
| MODPOST = scripts/mod/modpost |
| |
| # Read out modules.order to pass in modpost. |
| # Otherwise, allmodconfig would fail with "Argument list too long". |
| quiet_cmd_modpost = MODPOST $@ |
| cmd_modpost = \ |
| $(if $(missing-input), \ |
| echo >&2 "WARNING: $(missing-input) is missing."; \ |
| echo >&2 " Modules may not have dependencies or modversions."; \ |
| echo >&2 " You may get many unresolved symbol warnings.";) \ |
| sed 's/ko$$/o/' $(or $(modorder-if-needed), /dev/null) | $(MODPOST) $(modpost-args) -T - $(vmlinux.o-if-present) |
| |
| targets += $(output-symdump) |
| $(output-symdump): $(modorder-if-needed) $(vmlinux.o-if-present) $(module.symvers-if-present) $(MODPOST) FORCE |
| $(call if_changed,modpost) |
| |
| __modpost: $(output-symdump) |
| PHONY += FORCE |
| FORCE: |
| |
| existing-targets := $(wildcard $(sort $(targets))) |
| |
| -include $(foreach f,$(existing-targets),$(dir $(f)).$(notdir $(f)).cmd) |
| |
| .PHONY: $(PHONY) |