Hi Suraj,
On 2026-09-29T11:02:52, Suraj Kakade <[email protected]> wrote:
> scripts: pass dtc cpp flags via a GCC response file
>
> 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 so the shell command stays short.
>
> This change requires GNU Make >= 4.0, since $(file ...) is not
> supported by Make 3.x.
>
> Fixes: d31ff219a833 ("Makefile.lib: find capsule ESL dtsi file with
> CONFIG_OF_UPSTREAM")
> Fixes: 1e7883f6325a ("dtbo: Fix dtbo generation rules")
These two commits only touched the lines being changed (one added
-I$(obj), the other replaced '-' with $<), and neither made the
command line long. The length comes from upstream_dtsi_include, added
by 3a4e5944c96 ("Makefile: Allow upstream DT subtree to provide DT
includes"), combined with a long $(srctree). Please can you either
point the Fixes tag at that commit or drop these two tags?
> Signed-off-by: Suraj Kakade <[email protected]>
> Reviewed-by: Tom Rini <[email protected]>
>
> scripts/Makefile.lib | 7 +++++--
> 1 file changed, 5 insertions(+), 2 deletions(-)
> diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
> @@ -448,7 +448,8 @@ cmd_dtc = mkdir -p $(dir ${dtc-tmp}) ; \
> - $(HOSTCC) -E $(dtc_cpp_flags) -I$(obj) -x assembler-with-cpp -o
> $(dtc-tmp) $(pre-tmp) ; \
> + $(file >$(dtc-flags-tmp),$(dtc_cpp_flags) -I$(obj)) \
> + $(HOSTCC) -E @$(dtc-flags-tmp) -x assembler-with-cpp -o $(dtc-tmp)
> $(pre-tmp) ; \
This breaks the command-line check in if_changed_dep. Both cmd-check
and make-cmd work on the expanded cmd_dtb, and $(file ...) expands to
an empty string. The cmd_ line saved in the .cmd file therefore holds
only '@.../.foo.dtb.dtc.flags.tmp' and none of the flags. If
dtc_cpp_flags changes (a new -I path after a dts/upstream sync, a
change to UBOOTINCLUDE, or a new -D), the compared string stays the
same. The .dtb is then not rebuilt and stale output is left behind.
The same applies to cmd_dtco.
Also, cmd-check expands cmd_dtb on every make run, so the flags file
is rewritten for every dtb even on a no-op build.
Also, $(file >...) runs when make expands the recipe. That is before
the shell runs the 'mkdir -p $(dir ${dtc-tmp})' at the start of the
same command, so if the directory does not exist yet, make stops with
'open: No such file or directory'. Makefile.build normally creates
obj-dirs for $(targets), so this may not happen in practice. But the
mkdir is there for a reason, and I am not sure every dtb/dtbo rule
goes through that path. Please can you check with a clean O= build,
including the dtbo case?
To keep the rebuild check, one option is to leave $(dtc_cpp_flags) in
the compared string without passing it to the shell, e.g. by
overriding cmd-check for these targets or using a filechk-style rule
for the flags file. Another option is to shorten the command line
itself. You could use relative paths for the upstream include
directories, or fix upstream_dtsi_include: its $(if (CONFIG_ARM64),
...) is missing a '$', so the condition is always true and the arm64
include directories are added for every arch. What do you think?
> diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
> @@ -486,7 +488,8 @@ quiet_cmd_dtco = DTCO $@
> - $(CPP) $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \
> + $(file >$(dtc-flags-tmp),$(dtc_cpp_flags)) \
> + $(CPP) @$(dtc-flags-tmp) -x assembler-with-cpp -o $(dtc-tmp) $< ; \
Two other places still pass $(dtc_cpp_flags) inline: cmd_dtc_diff
(used with DEVICE_TREE_DEBUG) and dts/upstream/Makefile. cmd_dtc_diff
is appended to cmd_dtc, so with DEVICE_TREE_DEBUG set the command is
still too long. Please can you handle those too, or say in the commit
message why they are left alone?
Regards,
Simon