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 d5b7166207fa..0322201cd666 100644 --- a/pkgs/build-support/rust/build-rust-crate/build-crate.nix +++ b/pkgs/build-support/rust/build-rust-crate/build-crate.nix @@ -162,6 +162,8 @@ in fi ''} + declare -A BINS + ${lib.optionalString (lib.length crateBin > 0) ( lib.concatMapStringsSep "\n" ( bin: @@ -188,7 +190,7 @@ in BIN_PATH='${bin.path}' '' } - ${build_bin} "$BIN_NAME" "$BIN_PATH" + BINS["$BIN_NAME"]="$BIN_PATH" '' else '' @@ -222,13 +224,39 @@ in ${lib.optionalString (lib.length crateBin == 0 && !hasCrateBin) '' if [[ -e src/main.rs ]]; then mkdir -p target/bin - ${build_bin} ${crateName} src/main.rs + BINS["${crateName}"]="src/main.rs" fi for i in src/bin/*.rs; do #*/ mkdir -p target/bin - ${build_bin} "$(basename $i .rs)" "$i" + BINS["$(basename $i .rs)"]="$i" done ''} + + if [[ ''${#BINS[@]} -gt 0 ]]; then + export BIN_RUSTC_OPTS LINK EXTRA_LINK_ARGS EXTRA_LINK_ARGS_BINS EXTRA_LIB \ + BUILD_OUT_DIR EXTRA_BUILD EXTRA_FEATURES EXTRA_RUSTC_FLAGS CAP_LINTS + 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\n' "$BASH" + _i=0 + for _n in "''${!BINS[@]}"; do + # 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 + # Remove object files to avoid "wrong ELF type" find target -type f -name "*.o" -print0 | xargs -0 rm -f runHook postBuild diff --git a/pkgs/build-support/rust/build-rust-crate/lib.sh b/pkgs/build-support/rust/build-rust-crate/lib.sh index 4d736302a0c9..28da36666dad 100644 --- a/pkgs/build-support/rust/build-rust-crate/lib.sh +++ b/pkgs/build-support/rust/build-rust-crate/lib.sh @@ -58,7 +58,7 @@ build_bin() { $EXTRA_BUILD \ $EXTRA_FEATURES \ $EXTRA_RUSTC_FLAGS \ - --color ${colors} \ + --color ${colors} || return 1 if [ "$crate_name_" != "$crate_name" ]; then if [ -f "$out_dir/$crate_name_.wasm" ]; then