Loading pkgs/build-support/rust/build-rust-crate/build-crate.nix +68 −2 Original line number Diff line number Diff line Loading @@ -70,6 +70,25 @@ let binRustcOpts = lib.concatStringsSep " " baseRustcOpts; build_bin = if buildTests then "build_bin_test" else "build_bin"; # Shell snippet that builds a binary target to target/cargo-bin-exe/ # so integration tests can exec it via CARGO_BIN_EXE_<name>. buildBinForTests = bin: '' mkdir -p target/cargo-bin-exe BIN_NAME='${bin.name or crateName}' ${ if !bin ? path then '' BIN_PATH="" search_for_bin_path "$BIN_NAME" '' else '' BIN_PATH='${bin.path}' '' } build_bin "$BIN_NAME" "$BIN_PATH" target/cargo-bin-exe ''; in '' runHook preBuild Loading @@ -88,13 +107,60 @@ in if [[ -e "$LIB_PATH" ]]; then build_lib "$LIB_PATH" ${lib.optionalString buildTests ''build_lib_test "$LIB_PATH"''} elif [[ -e src/lib.rs ]]; then build_lib src/lib.rs ${lib.optionalString buildTests "build_lib_test src/lib.rs"} fi ${ # When building tests, first build the real (non-test) binaries so # integration tests can exec them via CARGO_BIN_EXE_<name>. They go # to target/cargo-bin-exe/ to avoid colliding with the --test # harnesses written to target/bin/. After building, populate the # CARGO_BIN_EXE_ENV array so subsequent rustc invocations see the # env vars (via `env` prefix in lib.sh, which unlike bash `export` # accepts hyphenated names). lib.optionalString buildTests ( lib.concatMapStringsSep "\n" ( bin: let haveRequiredFeature = if bin ? requiredFeatures then lib.intersectLists bin.requiredFeatures crateFeatures == bin.requiredFeatures else true; in lib.optionalString haveRequiredFeature (buildBinForTests bin) ) crateBin + lib.optionalString (lib.length crateBin == 0 && !hasCrateBin) '' if [[ -e src/main.rs ]]; then mkdir -p target/cargo-bin-exe build_bin ${crateName} src/main.rs target/cargo-bin-exe fi for i in src/bin/*.rs; do [ -e "$i" ] || continue mkdir -p target/cargo-bin-exe build_bin "$(basename $i .rs)" "$i" target/cargo-bin-exe done '' + '' if [ -d target/cargo-bin-exe ]; then for b in target/cargo-bin-exe/*; do [ -x "$b" ] || continue name=$(basename "$b") CARGO_BIN_EXE_ENV+=("CARGO_BIN_EXE_$name=$out/bin/$name") done fi '' ) } ${lib.optionalString buildTests '' if [[ -e "$LIB_PATH" ]]; then build_lib_test "$LIB_PATH" elif [[ -e src/lib.rs ]]; then build_lib_test src/lib.rs fi ''} ${lib.optionalString (lib.length crateBin > 0) ( lib.concatMapStringsSep "\n" ( Loading pkgs/build-support/rust/build-rust-crate/install-crate.nix +6 −0 Original line number Diff line number Diff line Loading @@ -48,6 +48,12 @@ else -executable \ -print0 | xargs --no-run-if-empty --null install --target $out/tests; fi # Real (non-test) binaries that integration tests may exec via # CARGO_BIN_EXE_<name>. if [ -d target/cargo-bin-exe ]; then mkdir -p $out/bin cp -rP target/cargo-bin-exe/* $out/bin fi runHook postInstall '' pkgs/build-support/rust/build-rust-crate/lib.sh +8 −7 Original line number Diff line number Diff line Loading @@ -10,7 +10,7 @@ build_lib() { lib_src=$1 echo_build_heading $lib_src ${libName} noisily rustc \ noisily env "${CARGO_BIN_EXE_ENV[@]}" rustc \ --crate-name $CRATE_NAME \ $lib_src \ --out-dir target/lib \ Loading @@ -36,17 +36,18 @@ build_bin() { local crate_name=$1 local crate_name_=$(echo $crate_name | tr '-' '_') local main_file="" local out_dir="${3:-target/bin}" if [[ ! -z $2 ]]; then main_file=$2 fi echo_build_heading $@ noisily rustc \ echo_build_heading $crate_name $main_file noisily env "${CARGO_BIN_EXE_ENV[@]}" rustc \ --crate-name $crate_name_ \ $main_file \ --crate-type bin \ $BIN_RUSTC_OPTS \ --out-dir target/bin \ --out-dir "$out_dir" \ -L dependency=target/deps \ $LINK \ $EXTRA_LINK_ARGS \ Loading @@ -60,10 +61,10 @@ build_bin() { --color ${colors} \ if [ "$crate_name_" != "$crate_name" ]; then if [ -f "target/bin/$crate_name_.wasm" ]; then mv target/bin/$crate_name_.wasm target/bin/$crate_name.wasm if [ -f "$out_dir/$crate_name_.wasm" ]; then mv "$out_dir/$crate_name_.wasm" "$out_dir/$crate_name.wasm" else mv target/bin/$crate_name_ target/bin/$crate_name mv "$out_dir/$crate_name_" "$out_dir/$crate_name" fi fi } Loading pkgs/build-support/rust/build-rust-crate/test/default.nix +68 −0 Original line number Diff line number Diff line Loading @@ -458,6 +458,74 @@ rec { "test flat_test ... ok" ]; }; rustBinTestsCargoBinExe = { # Integration tests locate the crate's own binary via # `env!("CARGO_BIN_EXE_<name>")`, which cargo sets automatically. crateName = "my-crate"; src = symlinkJoin { name = "rust-bin-tests-cargo-bin-exe"; paths = [ (mkFile "src/main.rs" '' fn main() { println!("hello from my-crate"); } '') (mkFile "tests/run_bin.rs" '' #[test] fn runs_binary() { let bin = env!("CARGO_BIN_EXE_my-crate"); let out = std::process::Command::new(bin) .output() .expect("spawn"); assert!(out.status.success()); assert_eq!( String::from_utf8_lossy(&out.stdout).trim(), "hello from my-crate" ); } '') ]; }; buildTests = true; expectedTestOutputs = [ "test runs_binary ... ok" ]; }; rustBinTestsCargoBinExeAutoDetect = { # Verify CARGO_BIN_EXE_<name> is also set for auto-detected # src/bin/*.rs binaries, not just src/main.rs or explicit # crateBin entries. crateName = "multi-bin"; src = symlinkJoin { name = "rust-bin-tests-cargo-bin-exe-auto"; paths = [ (mkFile "src/lib.rs" "") (mkFile "src/bin/tool-a.rs" '' fn main() { println!("tool-a ran"); } '') (mkFile "src/bin/tool-b.rs" '' fn main() { println!("tool-b ran"); } '') (mkFile "tests/run_tools.rs" '' #[test] fn runs_both() { for (bin, want) in [ (env!("CARGO_BIN_EXE_tool-a"), "tool-a ran"), (env!("CARGO_BIN_EXE_tool-b"), "tool-b ran"), ] { let out = std::process::Command::new(bin) .output() .expect("spawn"); assert!(out.status.success()); assert_eq!(String::from_utf8_lossy(&out.stdout).trim(), want); } } '') ]; }; buildTests = true; expectedTestOutputs = [ "test runs_both ... ok" ]; }; linkAgainstRlibCrate = { crateName = "foo"; src = mkFile "src/main.rs" '' Loading Loading
pkgs/build-support/rust/build-rust-crate/build-crate.nix +68 −2 Original line number Diff line number Diff line Loading @@ -70,6 +70,25 @@ let binRustcOpts = lib.concatStringsSep " " baseRustcOpts; build_bin = if buildTests then "build_bin_test" else "build_bin"; # Shell snippet that builds a binary target to target/cargo-bin-exe/ # so integration tests can exec it via CARGO_BIN_EXE_<name>. buildBinForTests = bin: '' mkdir -p target/cargo-bin-exe BIN_NAME='${bin.name or crateName}' ${ if !bin ? path then '' BIN_PATH="" search_for_bin_path "$BIN_NAME" '' else '' BIN_PATH='${bin.path}' '' } build_bin "$BIN_NAME" "$BIN_PATH" target/cargo-bin-exe ''; in '' runHook preBuild Loading @@ -88,13 +107,60 @@ in if [[ -e "$LIB_PATH" ]]; then build_lib "$LIB_PATH" ${lib.optionalString buildTests ''build_lib_test "$LIB_PATH"''} elif [[ -e src/lib.rs ]]; then build_lib src/lib.rs ${lib.optionalString buildTests "build_lib_test src/lib.rs"} fi ${ # When building tests, first build the real (non-test) binaries so # integration tests can exec them via CARGO_BIN_EXE_<name>. They go # to target/cargo-bin-exe/ to avoid colliding with the --test # harnesses written to target/bin/. After building, populate the # CARGO_BIN_EXE_ENV array so subsequent rustc invocations see the # env vars (via `env` prefix in lib.sh, which unlike bash `export` # accepts hyphenated names). lib.optionalString buildTests ( lib.concatMapStringsSep "\n" ( bin: let haveRequiredFeature = if bin ? requiredFeatures then lib.intersectLists bin.requiredFeatures crateFeatures == bin.requiredFeatures else true; in lib.optionalString haveRequiredFeature (buildBinForTests bin) ) crateBin + lib.optionalString (lib.length crateBin == 0 && !hasCrateBin) '' if [[ -e src/main.rs ]]; then mkdir -p target/cargo-bin-exe build_bin ${crateName} src/main.rs target/cargo-bin-exe fi for i in src/bin/*.rs; do [ -e "$i" ] || continue mkdir -p target/cargo-bin-exe build_bin "$(basename $i .rs)" "$i" target/cargo-bin-exe done '' + '' if [ -d target/cargo-bin-exe ]; then for b in target/cargo-bin-exe/*; do [ -x "$b" ] || continue name=$(basename "$b") CARGO_BIN_EXE_ENV+=("CARGO_BIN_EXE_$name=$out/bin/$name") done fi '' ) } ${lib.optionalString buildTests '' if [[ -e "$LIB_PATH" ]]; then build_lib_test "$LIB_PATH" elif [[ -e src/lib.rs ]]; then build_lib_test src/lib.rs fi ''} ${lib.optionalString (lib.length crateBin > 0) ( lib.concatMapStringsSep "\n" ( Loading
pkgs/build-support/rust/build-rust-crate/install-crate.nix +6 −0 Original line number Diff line number Diff line Loading @@ -48,6 +48,12 @@ else -executable \ -print0 | xargs --no-run-if-empty --null install --target $out/tests; fi # Real (non-test) binaries that integration tests may exec via # CARGO_BIN_EXE_<name>. if [ -d target/cargo-bin-exe ]; then mkdir -p $out/bin cp -rP target/cargo-bin-exe/* $out/bin fi runHook postInstall ''
pkgs/build-support/rust/build-rust-crate/lib.sh +8 −7 Original line number Diff line number Diff line Loading @@ -10,7 +10,7 @@ build_lib() { lib_src=$1 echo_build_heading $lib_src ${libName} noisily rustc \ noisily env "${CARGO_BIN_EXE_ENV[@]}" rustc \ --crate-name $CRATE_NAME \ $lib_src \ --out-dir target/lib \ Loading @@ -36,17 +36,18 @@ build_bin() { local crate_name=$1 local crate_name_=$(echo $crate_name | tr '-' '_') local main_file="" local out_dir="${3:-target/bin}" if [[ ! -z $2 ]]; then main_file=$2 fi echo_build_heading $@ noisily rustc \ echo_build_heading $crate_name $main_file noisily env "${CARGO_BIN_EXE_ENV[@]}" rustc \ --crate-name $crate_name_ \ $main_file \ --crate-type bin \ $BIN_RUSTC_OPTS \ --out-dir target/bin \ --out-dir "$out_dir" \ -L dependency=target/deps \ $LINK \ $EXTRA_LINK_ARGS \ Loading @@ -60,10 +61,10 @@ build_bin() { --color ${colors} \ if [ "$crate_name_" != "$crate_name" ]; then if [ -f "target/bin/$crate_name_.wasm" ]; then mv target/bin/$crate_name_.wasm target/bin/$crate_name.wasm if [ -f "$out_dir/$crate_name_.wasm" ]; then mv "$out_dir/$crate_name_.wasm" "$out_dir/$crate_name.wasm" else mv target/bin/$crate_name_ target/bin/$crate_name mv "$out_dir/$crate_name_" "$out_dir/$crate_name" fi fi } Loading
pkgs/build-support/rust/build-rust-crate/test/default.nix +68 −0 Original line number Diff line number Diff line Loading @@ -458,6 +458,74 @@ rec { "test flat_test ... ok" ]; }; rustBinTestsCargoBinExe = { # Integration tests locate the crate's own binary via # `env!("CARGO_BIN_EXE_<name>")`, which cargo sets automatically. crateName = "my-crate"; src = symlinkJoin { name = "rust-bin-tests-cargo-bin-exe"; paths = [ (mkFile "src/main.rs" '' fn main() { println!("hello from my-crate"); } '') (mkFile "tests/run_bin.rs" '' #[test] fn runs_binary() { let bin = env!("CARGO_BIN_EXE_my-crate"); let out = std::process::Command::new(bin) .output() .expect("spawn"); assert!(out.status.success()); assert_eq!( String::from_utf8_lossy(&out.stdout).trim(), "hello from my-crate" ); } '') ]; }; buildTests = true; expectedTestOutputs = [ "test runs_binary ... ok" ]; }; rustBinTestsCargoBinExeAutoDetect = { # Verify CARGO_BIN_EXE_<name> is also set for auto-detected # src/bin/*.rs binaries, not just src/main.rs or explicit # crateBin entries. crateName = "multi-bin"; src = symlinkJoin { name = "rust-bin-tests-cargo-bin-exe-auto"; paths = [ (mkFile "src/lib.rs" "") (mkFile "src/bin/tool-a.rs" '' fn main() { println!("tool-a ran"); } '') (mkFile "src/bin/tool-b.rs" '' fn main() { println!("tool-b ran"); } '') (mkFile "tests/run_tools.rs" '' #[test] fn runs_both() { for (bin, want) in [ (env!("CARGO_BIN_EXE_tool-a"), "tool-a ran"), (env!("CARGO_BIN_EXE_tool-b"), "tool-b ran"), ] { let out = std::process::Command::new(bin) .output() .expect("spawn"); assert!(out.status.success()); assert_eq!(String::from_utf8_lossy(&out.stdout).trim(), want); } } '') ]; }; buildTests = true; expectedTestOutputs = [ "test runs_both ... ok" ]; }; linkAgainstRlibCrate = { crateName = "foo"; src = mkFile "src/main.rs" '' Loading