cmd_dtc inlines dtc_cpp_flags (including every upstream dtsi -I
path) in the HOSTCC command. With a long $(srctree) that command is
too large for /bin/sh -c and Make fails with "Argument list too
long" while building a .dtb.
Write the flags to a per-target .dtc.flags.tmp file and pass @file to
HOSTCC/CPP for dtb and dtbo generation and the DEVICE_TREE_DEBUG diff,
so the shell command stays short. The flags are still compared and
saved with the command, so a change to them rebuilds the output, and
the file is only written when a rebuild is needed.
dts/upstream/Makefile uses short relative include paths and is left
unchanged.
GNU Make 4.0 is now the enforced minimum, so using $(file ...) is safe.
Fixes: 3a4e5944c96c ("Makefile: Allow upstream DT subtree to provide DT
includes")
Signed-off-by: Suraj Kakade <[email protected]>
---
scripts/Kbuild.include | 17 ++++++++++++++---
scripts/Makefile.lib | 15 ++++++++++++---
2 files changed, 26 insertions(+), 6 deletions(-)
diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include
index ece44b73506..f07918b1819 100644
--- a/scripts/Kbuild.include
+++ b/scripts/Kbuild.include
@@ -114,8 +114,11 @@ cmd = @set -e; $(echo-cmd) $($(quiet)redirect) $(cmd_$(1))
ifneq ($(KBUILD_NOCMDDEP),1)
# Check if both commands are the same including their order. Result is empty
# string if equal. User may override this check using make KBUILD_NOCMDDEP=1
-cmd-check = $(filter-out $(subst $(space),$(space_escape),$(strip $(cmd_$@))),
\
- $(subst $(space),$(space_escape),$(strip $(cmd_$1))))
+#
+# cmd_extra_<rule> is optional text compared and saved with the command, but
+# not passed to the shell. cmdflags_<target> is that text from the last build.
+cmd-check = $(filter-out $(subst $(space),$(space_escape),$(strip $(cmd_$@)
$(cmdflags_$@))), \
+ $(subst $(space),$(space_escape),$(strip $(cmd_$1)
$(cmd_extra_$1))))
else
cmd-check = $(if $(strip $(cmd_$@)),,1)
endif
@@ -128,6 +131,10 @@ endif
# (needed for the shell)
make-cmd = $(call escsq,$(subst $(pound),$$(pound),$(subst
$$,$$$$,$(cmd_$(1)))))
+# Record cmd_extra_<rule> for the next cmd-check without putting it on a
+# shell command line.
+cmd_savecmdflags = $(if $(cmd_extra_$(1)),$(file
>$(dot-target).cmdflags,cmdflags_$@ := $(subst $(pound),$$(pound),$(subst
$$,$$$$,$(cmd_extra_$(1))))))
+
# Find any prerequisites that are newer than target or that do not exist.
# (This is not true for now; $? should contain any non-existent prerequisites,
# but it does not work as expected when .SECONDARY is present. This seems a bug
@@ -145,15 +152,19 @@ if-changed-cond =
$(newer-prereqs)$(cmd-check)$(check-FORCE)
if_changed = $(if $(if-changed-cond),$(cmd_and_savecmd),@:)
cmd_and_savecmd = \
+ $(cmd_prepare_$(1))$(cmd_savecmdflags) \
$(cmd); \
- printf '%s\n' 'cmd_$@ := $(make-cmd)' > $(dot-target).cmd
+ printf '%s\n' 'cmd_$@ := $(make-cmd)' > $(dot-target).cmd; \
+ $(if $(cmd_extra_$(1)),cat $(dot-target).cmdflags >> $(dot-target).cmd
&& rm -f $(dot-target).cmdflags;)
# Execute the command and also postprocess generated .d dependencies file.
if_changed_dep = $(if $(if-changed-cond),$(cmd_and_fixdep),@:)
cmd_and_fixdep = \
+ $(cmd_prepare_$(1))$(cmd_savecmdflags) \
$(cmd); \
scripts/basic/fixdep $(depfile) $@ '$(make-cmd)' > $(dot-target).cmd;\
+ $(if $(cmd_extra_$(1)),cat $(dot-target).cmdflags >> $(dot-target).cmd
&& rm -f $(dot-target).cmdflags;) \
rm -f $(depfile)
# Usage: $(call if_changed_rule,foo)
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 122c8e78204..0c0abbd19de 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -424,7 +424,7 @@ endif
# minimize the diff between upstream DTs and U-Boot DTs.
ifdef DEVICE_TREE_DEBUG
cmd_dtc_diff = \
- $(HOSTCC) -E $(dtc_cpp_flags) -I$(obj) -x assembler-with-cpp -o
$(dtn-tmp) $< ; \
+ $(HOSTCC) -E @$(dtc-flags-tmp) -x assembler-with-cpp -o $(dtn-tmp) $< ;
\
$(DTC) -s -O dts -o [email protected] -b 0 \
-i $(dir $<) $(DTC_FLAGS) $(dtn-tmp) || \
(echo "Check $(shell pwd)/$< for errors" && false); \
@@ -448,7 +448,7 @@ cmd_dtc = mkdir -p $(dir ${dtc-tmp}) ; \
(cat $< > $(pre-tmp)); \
$(foreach f,$(subst $(quote),,$(dtsi_include_list)
$(CONFIG_DEVICE_TREE_INCLUDES)), \
echo '$(pound)include "$(f)"' >> $(pre-tmp);) \
- $(HOSTCC) -E $(dtc_cpp_flags) -I$(obj) -x assembler-with-cpp -o
$(dtc-tmp) $(pre-tmp) ; \
+ $(HOSTCC) -E @$(dtc-flags-tmp) -x assembler-with-cpp -o $(dtc-tmp)
$(pre-tmp) ; \
$(DTC) -O dtb -o $@ -b 0 \
-i $(dir $<) -i $(u_boot_dtsi_loc) $(DTC_FLAGS) \
-d $(depfile).dtc.tmp $(dtc-tmp) || \
@@ -477,6 +477,15 @@ $(obj)/%.dtb: $(src)/%.dts $(DTC)
$(dtsi_include_list_deps) $(DT_TMP_SCHEMA) FOR
pre-tmp = $(subst $(comma),_,$(dot-target).pre.tmp)
dtc-tmp = $(subst $(comma),_,$(dot-target).dts.tmp)
+dtc-flags-tmp = $(subst $(comma),_,$(dot-target).dtc.flags.tmp)
+
+# if_changed_dep compares cmd_extra_* but does not pass it to the shell.
+# The response file is written only after that check decides to rebuild.
+cmd_extra_dtb = $(dtc_cpp_flags) -I$(obj)
+cmd_prepare_dtb = $(file >$(dtc-flags-tmp),$(cmd_extra_dtb))
+
+cmd_extra_dtco = $(dtc_cpp_flags)
+cmd_prepare_dtco = $(file >$(dtc-flags-tmp),$(cmd_extra_dtco))
# DTCO
# ---------------------------------------------------------------------------
@@ -486,7 +495,7 @@ quiet_cmd_dtco = DTCO $@
# No generation of assembly file either
# Modified for U-Boot
cmd_dtco = mkdir -p $(dir ${dtc-tmp}) ; \
- $(CPP) $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \
+ $(CPP) @$(dtc-flags-tmp) -x assembler-with-cpp -o $(dtc-tmp) $< ; \
$(DTC) -@ -O dtb -o $@ -b 0 \
-i $(dir $<) $(DTC_FLAGS) \
-d $(depfile).dtc.tmp $(dtc-tmp) ; \
--
2.43.7