[PATCH v4 1/2] kbuild: Convert %.dtb(o) targets to single target rules
From: Rob Herring (Arm)
Date: Fri Oct 16 2026 - 15:54:37 EST
Single .dtb and .dtbo targets can be built using the existing kbuild
single target infrastructure. The only difference is the custom rules
work on a relative path under the arch dts directory, so we have to
fixup the path for the single targets.
With this both relative and full paths work:
make arch/arm64/boot/dts/arm/juno.dtb
make arm/juno.dtb
Complicating matters is building DTBs works without $ARCH compiler as
only the host preprocessor is used. This is useful for building all the
DTBs in the tree without installing a bunch of cross-compilers. The
single target rule needs to depend on 'dtbs_prepare' rather the
'prepare' to maintain support for that.
Reviewed-by: Nicolas Schier <nsc@xxxxxxxxxx>
Tested-by: Nicolas Schier <nsc@xxxxxxxxxx>
Signed-off-by: Rob Herring (Arm) <robh@xxxxxxxxxx>
---
v3:
- New patch
---
Makefile | 26 +++++++++++++++++---------
1 file changed, 17 insertions(+), 9 deletions(-)
diff --git a/Makefile b/Makefile
index 4ad67b737af7..c307ee9293bc 100644
--- a/Makefile
+++ b/Makefile
@@ -301,7 +301,7 @@ no-dot-config-targets := $(clean-targets) \
run-command
no-sync-config-targets := $(no-dot-config-targets) %install modules_sign kernelrelease \
image_name
-single-targets := %.a %.i %.ko %.lds %.ll %.lst %.mod %.o %.rsi %.s %/
+single-targets := %.a %.i %.ko %.lds %.ll %.lst %.mod %.o %.rsi %.s %.dtb %.dtbo %/
config-build :=
mixed-build :=
@@ -1663,12 +1663,6 @@ dtbindingtree := Documentation/devicetree/bindings
ifneq ($(dtstree),)
-%.dtb: dtbs_prepare
- $(Q)$(MAKE) $(build)=$(dtstree) $(dtstree)/$@
-
-%.dtbo: dtbs_prepare
- $(Q)$(MAKE) $(build)=$(dtstree) $(dtstree)/$@
-
PHONY += dtbs dtbs_prepare dtbs_install dtbs_check
dtbs: dtbs_prepare
$(Q)$(MAKE) $(build)=$(dtstree) need-dtbslist=1
@@ -1683,7 +1677,7 @@ export CHECK_DTBS=y
endif
ifneq ($(CHECK_DTBS),)
-dtbs_prepare: dt_binding_schemas
+scripts_dtc: dt_binding_schemas
endif
dtbs_check: dtbs
@@ -2190,6 +2184,8 @@ modpost: $(if $(single-build),, $(if $(KBUILD_BUILTIN), vmlinux.o)) \
#
# make foo/bar/baz/
+single-build-prep := prepare
+
ifdef single-build
# .ko is special because modpost is needed
@@ -2212,8 +2208,20 @@ ifneq ($(KBUILD_MODPOST_NOFINAL),1)
endif
$(Q)rm -f modules.order
+# For compatibility with existing %.dtb targets without full path
+single-dtb := $(filter-out $(dtstree)/%, $(filter %.dtb %.dtbo, $(single-no-ko)))
+single-no-ko := $(filter-out $(single-dtb), $(single-no-ko)) $(addprefix $(dtstree)/, $(single-dtb))
+
single-goals := $(addprefix $(build-dir)/, $(single-no-ko))
+# DT-only targets need host tools, but no architecture-specific preparation.
+ifneq ($(dtstree),)
+single-dt-patterns := $(addprefix $(dtstree)/,%.dtb %.dtbo)
+ifeq ($(filter-out $(single-dt-patterns),$(single-no-ko)),)
+single-build-prep := dtbs_prepare
+endif
+endif
+
KBUILD_MODULES := y
endif
@@ -2225,7 +2233,7 @@ prepare: outputmakefile
# make menuconfig etc.
# Error messages still appears in the original language
PHONY += $(build-dir)
-$(build-dir): prepare
+$(build-dir): $(single-build-prep)
$(Q)$(MAKE) $(build)=$@ need-builtin=1 need-modorder=1 $(single-goals)
clean-dirs := $(addprefix _clean_, $(clean-dirs))
--
2.53.0