From 4d5eb32921af67d58a367e960478808612085950 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Thalheim?= Date: Thu, 26 Mar 2026 18:15:01 +0000 Subject: [PATCH] build-rust-crate: use synthetic .PHONY targets in generated Makefile MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Makefile generated for parallel binary builds used the binary names directly as make targets. This caused make to silently skip a build whenever a file or directory with the same name existed in the crate source root — e.g. a crate with a `cli` binary and a `cli/` directory would "succeed" without producing the binary. Using the binary name as a target also risked collision with the `all` meta-target and with make metacharacters (`$`, `:`, `#`) in user-supplied crateName or bin.path values. Switch to synthetic numeric targets (b0, b1, …) declared .PHONY, and escape `$` in the recipe arguments. --- .../rust/build-rust-crate/build-crate.nix | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/pkgs/build-support/rust/build-rust-crate/build-crate.nix b/pkgs/build-support/rust/build-rust-crate/build-crate.nix index 7006fd3b4c49..0322201cd666 100644 --- a/pkgs/build-support/rust/build-rust-crate/build-crate.nix +++ b/pkgs/build-support/rust/build-rust-crate/build-crate.nix @@ -238,12 +238,21 @@ in export -f build_bin build_bin_test echo_build_heading noisily echo_colored echo_error # Generate a Makefile and pipe it to make, which handles parallel execution # and the jobserver protocol natively so rustc invocations share a token pool. + # Targets use synthetic names (b0, b1, …) and are declared .PHONY so that a + # file/dir in the source tree matching a binary name cannot cause make to + # skip the build, and so that binary names never collide with make syntax + # or the `all` target. { - printf 'SHELL = %s\nall:' "$BASH" - for _n in "''${!BINS[@]}"; do printf ' %s' "$_n"; done - printf '\n' + printf 'SHELL = %s\n' "$BASH" + _i=0 for _n in "''${!BINS[@]}"; do - printf '%s:\n\t${build_bin} "%s" "%s"\n' "$_n" "$_n" "''${BINS[$_n]}" + # Escape `$` for make; other metachars are confined to the quoted + # recipe string where only `$` is special to make. + _en=''${_n//\$/\$\$} + _ep=''${BINS[$_n]//\$/\$\$} + printf '.PHONY: b%d\nall: b%d\nb%d:\n\t${build_bin} "%s" "%s"\n' \ + "$_i" "$_i" "$_i" "$_en" "$_ep" + _i=$((_i + 1)) done } | make --no-print-directory -j"''${NIX_BUILD_CORES:-1}" -f - fi