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

Reply via email to