kbuild: support building external modules in a separate build directory

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>
This commit is contained in:
Masahiro Yamada 2024-11-10 10:34:35 +09:00
parent bad6beb2c0
commit 11b3d5175e
5 changed files with 35 additions and 11 deletions

View 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

View 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
-------

View File

@ -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.

View 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
#####

View 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))