]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
kbuild: support building external modules in a separate build directory
authorMasahiro Yamada <masahiroy@kernel.org>
Sun, 10 Nov 2024 01:34:35 +0000 (10:34 +0900)
committerMasahiro Yamada <masahiroy@kernel.org>
Wed, 27 Nov 2024 23:11:55 +0000 (08:11 +0900)
There has been a long-standing request to support building external
modules in a separate build directory.

This commit introduces a new environment variable, KBUILD_EXTMOD_OUTPUT,
and its shorthand Make variable, MO.

A simple usage:

 $ make -C <kernel-dir> M=<module-src-dir> MO=<module-build-dir>

Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
Reviewed-by: Nicolas Schier <nicolas@fjasle.eu>
Documentation/kbuild/kbuild.rst
Documentation/kbuild/modules.rst
Makefile
scripts/Makefile.host
scripts/Makefile.lib

index 1796b3eba37bd1985ae93da71368629f30465f6f..17c9f920f03da6b341525895533ffb4c100c4837 100644 (file)
@@ -137,12 +137,18 @@ Specify the output directory when building the kernel.
 This variable can also be used to point to the kernel output directory when
 building external modules against a pre-built kernel in a separate build
 directory. Please note that this does NOT specify the output directory for the
-external modules themselves.
+external modules themselves. (Use KBUILD_EXTMOD_OUTPUT for that purpose.)
 
 The output directory can also be specified using "O=...".
 
 Setting "O=..." takes precedence over KBUILD_OUTPUT.
 
+KBUILD_EXTMOD_OUTPUT
+--------------------
+Specify the output directory for external modules.
+
+Setting "MO=..." takes precedence over KBUILD_EXTMOD_OUTPUT.
+
 KBUILD_EXTRA_WARN
 -----------------
 Specify the extra build checks. The same value can be assigned by passing
index cd5a54d91e6d29b5eb62b6d5192650aad08ba8d8..a01f3754c7fce6cc4c36163b6f6ad4c7e913a340 100644 (file)
@@ -66,7 +66,10 @@ Options
        of the kernel output directory if the kernel was built in a separate
        build directory.)
 
-       make -C $KDIR M=$PWD
+       You can optionally pass MO= option if you want to build the modules in
+       a separate directory.
+
+       make -C $KDIR M=$PWD [MO=$BUILD_DIR]
 
        -C $KDIR
                The directory that contains the kernel and relevant build
@@ -80,6 +83,9 @@ Options
                directory where the external module (kbuild file) is
                located.
 
+       MO=$BUILD_DIR
+               Specifies a separate output directory for the external module.
+
 Targets
 -------
 
index b82c84903c8854590bddb4ed1bf1e4329d58b5fe..5aba1ac89375d10c3d5d87733824b05e75964322 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -134,6 +134,10 @@ ifeq ("$(origin M)", "command line")
   KBUILD_EXTMOD := $(M)
 endif
 
+ifeq ("$(origin MO)", "command line")
+  KBUILD_EXTMOD_OUTPUT := $(MO)
+endif
+
 $(if $(word 2, $(KBUILD_EXTMOD)), \
        $(error building multiple external modules is not supported))
 
@@ -187,7 +191,7 @@ ifdef KBUILD_EXTMOD
     else
         objtree := $(CURDIR)
     endif
-    output := $(KBUILD_EXTMOD)
+    output := $(or $(KBUILD_EXTMOD_OUTPUT),$(KBUILD_EXTMOD))
     # KBUILD_EXTMOD might be a relative path. Remember its absolute path before
     # Make changes the working directory.
     srcroot := $(realpath $(KBUILD_EXTMOD))
@@ -645,6 +649,7 @@ quiet_cmd_makefile = GEN     Makefile
        } > Makefile
 
 outputmakefile:
+ifeq ($(KBUILD_EXTMOD),)
        @if [ -f $(srctree)/.config -o \
                 -d $(srctree)/include/config -o \
                 -d $(srctree)/arch/$(SRCARCH)/include/generated ]; then \
@@ -654,7 +659,16 @@ outputmakefile:
                echo >&2 "***"; \
                false; \
        fi
-       $(Q)ln -fsn $(srctree) source
+else
+       @if [ -f $(srcroot)/modules.order ]; then \
+               echo >&2 "***"; \
+               echo >&2 "*** The external module source tree is not clean."; \
+               echo >&2 "*** Please run 'make -C $(abs_srctree) M=$(realpath $(srcroot)) clean'"; \
+               echo >&2 "***"; \
+               false; \
+       fi
+endif
+       $(Q)ln -fsn $(srcroot) source
        $(call cmd,makefile)
        $(Q)test -e .gitignore || \
        { echo "# this is build directory, ignore it"; echo "*"; } > .gitignore
@@ -1940,6 +1954,8 @@ KBUILD_MODULES := 1
 
 endif
 
+prepare: outputmakefile
+
 # Preset locale variables to speed up the build process. Limit locale
 # tweaks to this spot to avoid wrong language settings when running
 # make menuconfig etc.
index e01c13a588ddd9257902b6d8e772574394189c1f..c1dedf646a39f708030d37b5d50170d241c9484c 100644 (file)
@@ -96,12 +96,10 @@ hostrust_flags = --out-dir $(dir $@) --emit=dep-info=$(depfile) \
                  $(KBUILD_HOSTRUSTFLAGS) $(HOST_EXTRARUSTFLAGS) \
                  $(HOSTRUSTFLAGS_$(target-stem))
 
-# $(objtree)/$(obj) for including generated headers from checkin source files
-ifeq ($(KBUILD_EXTMOD),)
+# $(obj) for including generated headers from checkin source files
 ifdef building_out_of_srctree
-hostc_flags   += -I $(objtree)/$(obj)
-hostcxx_flags += -I $(objtree)/$(obj)
-endif
+hostc_flags   += -I $(obj)
+hostcxx_flags += -I $(obj)
 endif
 
 #####
index e7859ad90224a4b2420ec1ad86c2d4e62219a2ef..5660dfc9ed36c21ccf1aa659dd9805ad32cad39c 100644 (file)
@@ -213,13 +213,11 @@ endif
 
 # $(src) for including checkin headers from generated source files
 # $(obj) for including generated headers from checkin source files
-ifeq ($(KBUILD_EXTMOD),)
 ifdef building_out_of_srctree
 _c_flags   += $(addprefix -I, $(src) $(obj))
 _a_flags   += $(addprefix -I, $(src) $(obj))
 _cpp_flags += $(addprefix -I, $(src) $(obj))
 endif
-endif
 
 # If $(is-kernel-object) is 'y', this object will be linked to vmlinux or modules
 is-kernel-object = $(or $(part-of-builtin),$(part-of-module))