export KBUILD_CHECKSRC KBUILD_EXTMOD
+extmod-prefix = $(if $(KBUILD_EXTMOD),$(KBUILD_EXTMOD)/)
+
ifeq ($(abs_srctree),$(abs_objtree))
# building in the source tree
srctree := .
%asm-generic kernelversion %src-pkg
no-sync-config-targets := $(no-dot-config-targets) install %install \
kernelrelease
+single-targets := %.a %.i %.ko %.lds %.ll %.lst %.mod %.o %.s %.symtypes %/
config-build :=
mixed-build :=
need-config := 1
may-sync-config := 1
+single-build :=
ifneq ($(filter $(no-dot-config-targets), $(MAKECMDGOALS)),)
ifeq ($(filter-out $(no-dot-config-targets), $(MAKECMDGOALS)),)
endif
endif
+# We cannot build single targets and the others at the same time
+ifneq ($(filter $(single-targets), $(MAKECMDGOALS)),)
+ single-build := 1
+ ifneq ($(filter-out $(single-targets), $(MAKECMDGOALS)),)
+ mixed-build := 1
+ endif
+endif
+
# For "make -j clean all", "make -j mrproper defconfig all", etc.
ifneq ($(filter $(clean-targets),$(MAKECMDGOALS)),)
ifneq ($(filter-out $(clean-targets),$(MAKECMDGOALS)),)
PHONY += prepare0
-export MODORDER := $(if $(KBUILD_EXTMOD),$(KBUILD_EXTMOD)/)modules.order
+export MODORDER := $(extmod-prefix)modules.order
ifeq ($(KBUILD_EXTMOD),)
core-y += kernel/ certs/ mm/ fs/ ipc/ security/ crypto/ block/
PHONY += descend $(build-dirs)
descend: $(build-dirs)
$(build-dirs): prepare
- $(Q)$(MAKE) $(build)=$@ need-builtin=1 need-modorder=1
+ $(Q)$(MAKE) $(build)=$@ single-build=$(single-build) need-builtin=1 need-modorder=1
clean-dirs := $(addprefix _clean_, $(clean-dirs))
PHONY += $(clean-dirs) clean
# Single targets
# ---------------------------------------------------------------------------
-# Single targets are compatible with:
-# - build with mixed source and output
-# - build with separate output dir 'make O=...'
-# - external modules
+# To build individual files in subdirectories, you can do like this:
+#
+# make foo/bar/baz.s
#
-# target-dir => where to store outputfile
-# build-dir => directory in kernel source tree to use
-
-build-target = $(if $(KBUILD_EXTMOD), $(KBUILD_EXTMOD)/)$@
-build-dir = $(patsubst %/,%,$(dir $(build-target)))
-
-%.i: prepare FORCE
- $(Q)$(MAKE) $(build)=$(build-dir) $(build-target)
-%.ll: prepare FORCE
- $(Q)$(MAKE) $(build)=$(build-dir) $(build-target)
-%.lst: prepare FORCE
- $(Q)$(MAKE) $(build)=$(build-dir) $(build-target)
-%.o: prepare FORCE
- $(Q)$(MAKE) $(build)=$(build-dir) $(build-target)
-%.s: prepare FORCE
- $(Q)$(MAKE) $(build)=$(build-dir) $(build-target)
-%.symtypes: prepare FORCE
- $(Q)$(MAKE) $(build)=$(build-dir) $(build-target)
+# The supported suffixes for single-target are listed in 'single-targets'
+#
+# To build only under specific subdirectories, you can do like this:
+#
+# make foo/bar/baz/
+
+ifdef single-build
+
+single-all := $(filter $(single-targets), $(MAKECMDGOALS))
+
+# .ko is special because modpost is needed
+single-ko := $(sort $(filter %.ko, $(single-all)))
+single-no-ko := $(sort $(patsubst %.ko,%.mod, $(single-all)))
+
+$(single-ko): single_modpost
+ @:
+$(single-no-ko): descend
+ @:
+
ifeq ($(KBUILD_EXTMOD),)
-# For the single build of an in-tree module, use a temporary file to avoid
+# For the single build of in-tree modules, use a temporary file to avoid
# the situation of modules_install installing an invalid modules.order.
-%.ko: MODORDER := .modules.tmp
+MODORDER := .modules.tmp
endif
-%.ko: prepare FORCE
- $(Q)$(MAKE) $(build)=$(build-dir) $(build-target:.ko=.mod)
- $(Q)echo $(build-target) > $(MODORDER)
+
+PHONY += single_modpost
+single_modpost: $(single-no-ko)
+ $(Q){ $(foreach m, $(single-ko), echo $(extmod-prefix)$m;) } > $(MODORDER)
$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost
-%/: prepare FORCE
- $(Q)$(MAKE) KBUILD_MODULES=1 $(build)=$(build-dir) need-modorder=1
+
+KBUILD_MODULES := 1
+
+export KBUILD_SINGLE_TARGETS := $(addprefix $(extmod-prefix), $(single-no-ko))
+
+single-build = $(if $(filter-out $@/, $(single-no-ko)),1)
+
+endif
# FIXME Should go into a make.lib or something
# ===========================================================================
$(warning kbuild: Makefile.build is included improperly)
endif
-ifeq ($(MAKECMDGOALS)$(need-modorder),)
+ifeq ($(need-modorder),)
ifneq ($(obj-m),)
$(warning $(patsubst %.o,'%.ko',$(obj-m)) will not be built even though obj-m is specified.)
$(warning You cannot use subdir-y/m to visit a module Makefile. Use obj-y/m instead.)
mod-targets := $(patsubst %.o, %.mod, $(obj-m))
-__build: $(if $(KBUILD_BUILTIN),$(builtin-target) $(lib-target) $(extra-y)) \
- $(if $(KBUILD_MODULES),$(obj-m) $(mod-targets) $(modorder-target)) \
- $(subdir-ym) $(always)
- @:
-
# Linus' kernel sanity checking tool
ifeq ($(KBUILD_CHECKSRC),1)
quiet_cmd_checksrc = CHECK $<
$(call intermediate_targets, .lex.o, .lex.c) \
$(call intermediate_targets, .tab.o, .tab.c .tab.h)
+# Build
+# ---------------------------------------------------------------------------
+
+ifdef single-build
+
+curdir-single := $(sort $(foreach x, $(KBUILD_SINGLE_TARGETS), \
+ $(if $(filter $(x) $(basename $(x)).o, $(targets)), $(x))))
+
+# Handle single targets without any rule: show "Nothing to be done for ..." or
+# "No rule to make target ..." depending on whether the target exists.
+unknown-single := $(filter-out $(addsuffix /%, $(subdir-ym)), \
+ $(filter $(obj)/%, \
+ $(filter-out $(curdir-single), \
+ $(KBUILD_SINGLE_TARGETS))))
+
+__build: $(curdir-single) $(subdir-ym)
+ifneq ($(unknown-single),)
+ $(Q)$(MAKE) -f /dev/null $(unknown-single)
+endif
+ @:
+
+ifeq ($(curdir-single),)
+# Nothing to do in this directory. Do not include any .*.cmd file for speed-up
+targets :=
+else
+targets += $(curdir-single)
+endif
+
+else
+
+__build: $(if $(KBUILD_BUILTIN),$(builtin-target) $(lib-target) $(extra-y)) \
+ $(if $(KBUILD_MODULES),$(obj-m) $(mod-targets) $(modorder-target)) \
+ $(subdir-ym) $(always)
+ @:
+
+endif
+
# Descending
# ---------------------------------------------------------------------------
PHONY += $(subdir-ym)
$(subdir-ym):
$(Q)$(MAKE) $(build)=$@ \
+ $(if $(filter $@/, $(KBUILD_SINGLE_TARGETS)),single-build=) \
need-builtin=$(if $(filter $@/built-in.a, $(subdir-obj-y)),1) \
need-modorder=$(if $(need-modorder),$(if $(filter $@/modules.order, $(modorder)),1))