When CONFIG_MULTI_DTB_FIT is enabled, fit-dtb.blob is produced by
mkimage with one "-b <dtb>" argument for every entry in
CONFIG_OF_LIST. The make rule, however, only listed dts/dt.dtb
(i.e. the CONFIG_DEFAULT_DEVICE_TREE blob) as a prerequisite:
fit-dtb.blob: dts/dt.dtb FORCE
$(call if_changed,mkimage)
Because FORCE is PHONY, if_changed ignores it and rebuilds only when
any-prereq or arg-check is non-empty. Editing a non-default dts in
OF_LIST rebuilds its .dtb (tracked correctly via fixdep), but that
.dtb was not a prerequisite of fit-dtb.blob, so $? stayed empty; the
mkimage command line was unchanged too, so arg-check was empty as
well. if_changed therefore skipped mkimage and fit-dtb.blob kept the
stale dtbs. u-boot.bin, which appends fit-dtb.blob, then shipped the
old device tree and the dts change did not take effect.
A previous attempt to fix this added every OF_LIST .dtb *output* as a
prerequisite. That is wrong on two counts:
* Clean build regression: the OF_LIST .dtb files are produced only
by the recursive dts/dt.dtb -> arch-dtbs sub-make descent and have
no rule at the top make level, so listing them as prerequisites
makes them rule-less/intermediate. After a from-scratch rebuild
(e.g. `rm -rf out/.../build/uboot`) it fails:
make[1]: *** No rule to make target 'arch/arm/dts/<of>.dtb',
needed by 'fit-dtb.blob'. Stop.
* Incremental two-build race still present: the .dtb outputs are
written by a child sub-make, whose mtime updates GNU make does not
re-stat in the top-level process (GNU make bug #58734). if_changed
evaluates $? (prerequisites newer than the target) using that cached
mtime; when the stale fit-dtb.blob mtime is newer than the stale
.dtb mtime (the normal post-build state, since mkimage runs after
dtc), $? is empty at evaluation time and mkimage is skipped, so the
edit still needs two `make` invocations to take effect under
parallel make (the `bdm uboot` flow runs `make -j33`).
Depend on the OF_LIST *source* .dts files instead of the compiled .dtb
outputs. The .dts sources are found via VPATH (srctree) and never need
a recipe at this level, so they do not break a clean build. Their mtime
is set by the user's edit rather than by a child sub-make, so it is
always fresh in the top-level process and any-prereq fires mkimage in a
single parallel make, sidestepping the cached-mtime race entirely.
This fixes both the clean-build regression and the incremental
two-build race without serialising the target.
Fixes: 6f59fb07f497 ("Makefile: Build additional binaries for dtb FIT blobs
appended to U-boot")
Signed-off-by: lianghong617 <[email protected]>
---
Changes in v2:
- Depend on the OF_LIST *.dts sources instead of the compiled *.dtb
outputs. The previous version added every OF_LIST *.dtb as a
prerequisite, which broke clean builds ("No rule to make target
'arch/arm/dts/<of>.dtb'") because those .dtb files are produced by
the recursive dts/dt.dtb -> arch-dtbs sub-make descent and have no
rule at the top make level.
- The source-dep approach also closes an incremental two-build race
left by the .dtb-output approach: child sub-make mtime updates are
not re-stated by the top-level process (GNU make bug #58734), so
$? stayed empty and a single parallel `make -j` invocation still
needed to be run twice. .dts mtimes are set by the user's edit and
are always fresh, so any-prereq fires in one pass.
- Add the Fixes: tag.
---
Makefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Makefile b/Makefile
index 7d83ce16721..a9aa51b2108 100644
--- a/Makefile
+++ b/Makefile
@@ -1212,7 +1212,7 @@ fit-dtb.blob.gz: fit-dtb.blob
fit-dtb.blob.lzo: fit-dtb.blob
@lzop -f9 $< > $@
-fit-dtb.blob: dts/dt.dtb FORCE
+fit-dtb.blob: dts/dt.dtb $(patsubst %,arch/$(ARCH)/dts/%.dts,$(subst
",,$(CONFIG_OF_LIST))) FORCE
$(call if_changed,mkimage)
ifneq ($(SOURCE_DATE_EPOCH),)
touch -d @$(SOURCE_DATE_EPOCH) fit-dtb.blob
--
2.34.1