public inbox for rust-for-linux@vger.kernel.org
 help / color / mirror / Atom feed
From: Mohamad Alsadhan <mo@sdhn.cc>
To: nathan@kernel.org, nsc@kernel.org, ojeda@kernel.org
Cc: gary@garyguo.net, miguel.ojeda.sandonis@gmail.com,
	linux-kbuild@vger.kernel.org, rust-for-linux@vger.kernel.org,
	Mohamad Alsadhan <mo@sdhn.cc>,
	Yoann Congal <yoann.congal@smile.fr>
Subject: [PATCH v3] kbuild: host: use single executable for rustc -C linker
Date: Thu, 12 Mar 2026 03:28:52 +0300	[thread overview]
Message-ID: <20260312002852.11292-1-mo@sdhn.cc> (raw)
In-Reply-To: <20260227132713.23106-1-mo@sdhn.cc/>

rustc's -C linker= option expects a single executable path. When
HOSTCC contains a wrapper (e.g. "ccache gcc"), passing
`-Clinker=$(HOSTCC)` results in the shell splitting the value into
multiple words, and rustc interprets the additional word as an
input filename:

  error: multiple input filenames provided ...

Generate a small wrapper script and pass it to -Clinker e.g.
```
\#!/bin/sh
exec sh -c 'exec "$0" "$@"' ccache gcc "$@"
```

This fix should be general enough to address most if not all cases
(incl. wrappers or subcommands) and avoids surprises of simpler fixes
like just defaulting to gcc.

This avoids passing the user command as an environment variable as
that would be more challenging to trace and debug shell expansions.

Link: https://github.com/Rust-for-Linux/linux/issues/1224
Suggested-by: Yoann Congal <yoann.congal@smile.fr>
Signed-off-by: Mohamad Alsadhan <mo@sdhn.cc>
---
v2 -> v3:
  - Scrap previous hacky approaches (e.g. using lastword) and go with
    a proper fix which turned out not that complex to implement.
    Apologies Gary, I should have listened to you earlier :/

v1 -> v2:
  - Rename HOSTRUSTC_LINKER to HOSTRUSTC_LD for consistency
  - Introduce explicit HOSTRUSTC_LD override
  - Warn when falling back due to multi-argument HOSTCC
  - Error out if a user-specified HOSTRUSTC_LD is not an executable

v1: https://lore.kernel.org/all/20260225102819.16553-1-mo@sdhn.cc/
v2: https://lore.kernel.org/all/20260227132713.23106-1-mo@sdhn.cc/
---
 scripts/Makefile.host | 21 +++++++++++++++++++--
 1 file changed, 19 insertions(+), 2 deletions(-)

diff --git a/scripts/Makefile.host b/scripts/Makefile.host
index c1dedf646..f976a07b7 100644
--- a/scripts/Makefile.host
+++ b/scripts/Makefile.host
@@ -87,11 +87,28 @@ hostcxx_flags  = -Wp,-MMD,$(depfile) \
                  $(KBUILD_HOSTCXXFLAGS) $(HOST_EXTRACXXFLAGS) \
                  $(HOSTCXXFLAGS_$(target-stem).o)
 
+# rustc's `-Clinker=` expects a single executable path, not a command line.
+# `HOSTCC` may be a multi-word command when wrapped (e.g. "ccache gcc"), which
+# would otherwise be split by the shell and mis-parsed by rustc.
+# To work around this, we generate a wrapper script that forwards arguments to
+# `HOSTRUSTC_LD` so that such commands can be used safely.
+#
+# Set `HOSTRUSTC_LD` for a different rustc linker command than `HOSTCC` 
+HOSTRUSTC_LD ?= $(HOSTCC)
+quiet_cmd_rustc-wrapper = HOSTGEN $@
+      cmd_rustc-wrapper = \
+	echo '\#!/bin/sh' > $@; \
+	echo 'exec sh -c '\''exec "$$0" "$$@"'\'' $(HOSTRUSTC_LD) "$$@"' >> $@; \
+	chmod +x $@
+
+$(obj)/rustc-wrapper: FORCE
+	$(call if_changed,rustc-wrapper)
+
 # `--out-dir` is required to avoid temporaries being created by `rustc` in the
 # current working directory, which may be not accessible in the out-of-tree
 # modules case.
 hostrust_flags = --out-dir $(dir $@) --emit=dep-info=$(depfile) \
-		 -Clinker-flavor=gcc -Clinker=$(HOSTCC) \
+		 -Clinker-flavor=gcc -Clinker=$(obj)/rustc-wrapper \
 		 -Clink-args='$(call escsq,$(KBUILD_HOSTLDFLAGS))' \
                  $(KBUILD_HOSTRUSTFLAGS) $(HOST_EXTRARUSTFLAGS) \
                  $(HOSTRUSTFLAGS_$(target-stem))
@@ -153,7 +170,7 @@ $(host-cxxobjs): $(obj)/%.o: $(obj)/%.cc FORCE
 quiet_cmd_host-rust	= HOSTRUSTC $@
       cmd_host-rust	= \
 	$(HOSTRUSTC) $(hostrust_flags) --emit=link=$@ $<
-$(host-rust): $(obj)/%: $(src)/%.rs FORCE
+$(host-rust): $(obj)/%: $(src)/%.rs $(obj)/rustc-wrapper FORCE
 	+$(call if_changed_dep,host-rust)
 
 targets += $(host-csingle) $(host-cmulti) $(host-cobjs) \
-- 
2.52.0


       reply	other threads:[~2026-03-12  0:29 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20260227132713.23106-1-mo@sdhn.cc/>
2026-03-12  0:28 ` Mohamad Alsadhan [this message]
2026-03-12 13:50   ` [PATCH v3] kbuild: host: use single executable for rustc -C linker Nicolas Schier
2026-03-17 11:10     ` Mohamad Alsadhan
2026-03-20  6:50       ` Nicolas Schier
2026-03-17 11:20   ` [PATCH v4] " Mohamad Alsadhan
2026-03-20  6:51     ` Nicolas Schier
2026-03-21 14:57       ` Mohamad Alsadhan
2026-03-21 15:00     ` [PATCH v5] " Mohamad Alsadhan
2026-03-25  8:45       ` Nicolas Schier
2026-03-29  2:12         ` Mohamad Alsadhan
2026-03-29 19:46           ` Nicolas Schier
2026-03-25 14:25       ` Yoann Congal

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260312002852.11292-1-mo@sdhn.cc \
    --to=mo@sdhn.cc \
    --cc=gary@garyguo.net \
    --cc=linux-kbuild@vger.kernel.org \
    --cc=miguel.ojeda.sandonis@gmail.com \
    --cc=nathan@kernel.org \
    --cc=nsc@kernel.org \
    --cc=ojeda@kernel.org \
    --cc=rust-for-linux@vger.kernel.org \
    --cc=yoann.congal@smile.fr \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox