diff options
Diffstat (limited to 'nixpkgs/pkgs/build-support/rust')
9 files changed, 121 insertions, 58 deletions
diff --git a/nixpkgs/pkgs/build-support/rust/build-rust-crate/default.nix b/nixpkgs/pkgs/build-support/rust/build-rust-crate/default.nix index f6079b7316d6..4e3e2045e8ec 100644 --- a/nixpkgs/pkgs/build-support/rust/build-rust-crate/default.nix +++ b/nixpkgs/pkgs/build-support/rust/build-rust-crate/default.nix @@ -353,6 +353,10 @@ crate_: lib.makeOverridable extraRustcOpts buildTests codegenUnits; }; dontStrip = !release; + + # We need to preserve metadata in .rlib, which might get stripped on macOS. See https://github.com/NixOS/nixpkgs/issues/218712 + stripExclude = [ "*.rlib" ]; + installPhase = installCrate crateName metadata buildTests; # depending on the test setting we are either producing something with bins diff --git a/nixpkgs/pkgs/build-support/rust/build-rust-package/default.nix b/nixpkgs/pkgs/build-support/rust/build-rust-package/default.nix index 9eab4733db64..ea15421b29fa 100644 --- a/nixpkgs/pkgs/build-support/rust/build-rust-package/default.nix +++ b/nixpkgs/pkgs/build-support/rust/build-rust-package/default.nix @@ -64,7 +64,6 @@ let assert cargoVendorDir == null && cargoLock == null -> !(args ? cargoSha256 && args.cargoSha256 != null) && !(args ? cargoHash && args.cargoHash != null) -> throw "cargoSha256, cargoHash, cargoVendorDir, or cargoLock must be set"; - assert buildType == "release" || buildType == "debug"; let @@ -85,14 +84,9 @@ let targetIsJSON = lib.hasSuffix ".json" target; useSysroot = targetIsJSON && !__internal_dontAddSysroot; - # see https://github.com/rust-lang/cargo/blob/964a16a28e234a3d397b2a7031d4ab4a428b1391/src/cargo/core/compiler/compile_kind.rs#L151-L168 - # the "${}" is needed to transform the path into a /nix/store path before baseNameOf - shortTarget = if targetIsJSON then - (lib.removeSuffix ".json" (builtins.baseNameOf "${target}")) - else target; - sysroot = callPackage ./sysroot { } { - inherit target shortTarget; + inherit target; + shortTarget = rust.lib.toRustTargetSpecShort stdenv.hostPlatform; RUSTFLAGS = args.RUSTFLAGS or ""; originalCargoToml = src + /Cargo.toml; # profile info is later extracted }; diff --git a/nixpkgs/pkgs/build-support/rust/hooks/cargo-build-hook.sh b/nixpkgs/pkgs/build-support/rust/hooks/cargo-build-hook.sh index af94e02e38ae..ed982c7ff30a 100644 --- a/nixpkgs/pkgs/build-support/rust/hooks/cargo-build-hook.sh +++ b/nixpkgs/pkgs/build-support/rust/hooks/cargo-build-hook.sh @@ -17,7 +17,7 @@ cargoBuildHook() { fi if [ "${cargoBuildType}" != "debug" ]; then - cargoBuildProfileFlag="--${cargoBuildType}" + cargoBuildProfileFlag="--profile ${cargoBuildType}" fi if [ -n "${cargoBuildNoDefaultFeatures-}" ]; then @@ -30,13 +30,8 @@ cargoBuildHook() { ( set -x - env \ - "CC_@rustBuildPlatform@=@ccForBuild@" \ - "CXX_@rustBuildPlatform@=@cxxForBuild@" \ - "CC_@rustTargetPlatform@=@ccForHost@" \ - "CXX_@rustTargetPlatform@=@cxxForHost@" \ - cargo build -j $NIX_BUILD_CORES \ - --target @rustTargetPlatformSpec@ \ + @setEnv@ cargo build -j $NIX_BUILD_CORES \ + --target @rustHostPlatformSpec@ \ --frozen \ ${cargoBuildProfileFlag} \ ${cargoBuildNoDefaultFeaturesFlag} \ diff --git a/nixpkgs/pkgs/build-support/rust/hooks/cargo-check-hook.sh b/nixpkgs/pkgs/build-support/rust/hooks/cargo-check-hook.sh index 57fc2779cfe9..971a140ec178 100644 --- a/nixpkgs/pkgs/build-support/rust/hooks/cargo-check-hook.sh +++ b/nixpkgs/pkgs/build-support/rust/hooks/cargo-check-hook.sh @@ -17,7 +17,7 @@ cargoCheckHook() { fi if [ "${cargoCheckType}" != "debug" ]; then - cargoCheckProfileFlag="--${cargoCheckType}" + cargoCheckProfileFlag="--profile ${cargoCheckType}" fi if [ -n "${cargoCheckNoDefaultFeatures-}" ]; then @@ -29,7 +29,7 @@ cargoCheckHook() { fi argstr="${cargoCheckProfileFlag} ${cargoCheckNoDefaultFeaturesFlag} ${cargoCheckFeaturesFlag} - --target @rustTargetPlatformSpec@ --frozen ${cargoTestFlags}" + --target @rustHostPlatformSpec@ --frozen ${cargoTestFlags}" ( set -x diff --git a/nixpkgs/pkgs/build-support/rust/hooks/cargo-install-hook.sh b/nixpkgs/pkgs/build-support/rust/hooks/cargo-install-hook.sh index 69ce72669366..24a6e6fa9eb3 100644 --- a/nixpkgs/pkgs/build-support/rust/hooks/cargo-install-hook.sh +++ b/nixpkgs/pkgs/build-support/rust/hooks/cargo-install-hook.sh @@ -1,7 +1,7 @@ cargoInstallPostBuildHook() { echo "Executing cargoInstallPostBuildHook" - releaseDir=target/@shortTarget@/$cargoBuildType + releaseDir=target/@targetSubdirectory@/$cargoBuildType tmpDir="${releaseDir}-tmp"; mkdir -p $tmpDir @@ -21,7 +21,7 @@ cargoInstallHook() { # rename the output dir to a architecture independent one - releaseDir=target/@shortTarget@/$cargoBuildType + releaseDir=target/@targetSubdirectory@/$cargoBuildType tmpDir="${releaseDir}-tmp"; mapfile -t targets < <(find "$NIX_BUILD_TOP" -type d | grep "${tmpDir}$") diff --git a/nixpkgs/pkgs/build-support/rust/hooks/cargo-nextest-hook.sh b/nixpkgs/pkgs/build-support/rust/hooks/cargo-nextest-hook.sh index de85683ead2a..29ba18a6a1e3 100644 --- a/nixpkgs/pkgs/build-support/rust/hooks/cargo-nextest-hook.sh +++ b/nixpkgs/pkgs/build-support/rust/hooks/cargo-nextest-hook.sh @@ -17,7 +17,7 @@ cargoNextestHook() { fi if [ "${cargoCheckType}" != "debug" ]; then - cargoCheckProfileFlag="--${cargoCheckType}" + cargoCheckProfileFlag="--cargo-profile ${cargoCheckType}" fi if [ -n "${cargoCheckNoDefaultFeatures-}" ]; then @@ -29,7 +29,7 @@ cargoNextestHook() { fi argstr="${cargoCheckProfileFlag} ${cargoCheckNoDefaultFeaturesFlag} ${cargoCheckFeaturesFlag} - --target @rustTargetPlatformSpec@ --frozen ${cargoTestFlags}" + --target @rustHostPlatformSpec@ --frozen ${cargoTestFlags}" ( set -x diff --git a/nixpkgs/pkgs/build-support/rust/hooks/default.nix b/nixpkgs/pkgs/build-support/rust/hooks/default.nix index 2eb388fe07ba..205d085d3507 100644 --- a/nixpkgs/pkgs/build-support/rust/hooks/default.nix +++ b/nixpkgs/pkgs/build-support/rust/hooks/default.nix @@ -9,32 +9,20 @@ , rust , rustc , stdenv -, target ? rust.toRustTargetSpec stdenv.hostPlatform -}: -let - targetIsJSON = lib.hasSuffix ".json" target; +# This confusingly-named parameter indicates the *subdirectory of +# `target/` from which to copy the build artifacts. It is derived +# from a stdenv platform (or a JSON file). +, target ? rust.lib.toRustTargetSpecShort stdenv.hostPlatform +}: - # see https://github.com/rust-lang/cargo/blob/964a16a28e234a3d397b2a7031d4ab4a428b1391/src/cargo/core/compiler/compile_kind.rs#L151-L168 - # the "${}" is needed to transform the path into a /nix/store path before baseNameOf - shortTarget = if targetIsJSON then - (lib.removeSuffix ".json" (builtins.baseNameOf "${target}")) - else target; - ccForBuild = "${buildPackages.stdenv.cc}/bin/${buildPackages.stdenv.cc.targetPrefix}cc"; - cxxForBuild = "${buildPackages.stdenv.cc}/bin/${buildPackages.stdenv.cc.targetPrefix}c++"; - ccForHost = "${stdenv.cc}/bin/${stdenv.cc.targetPrefix}cc"; - cxxForHost = "${stdenv.cc}/bin/${stdenv.cc.targetPrefix}c++"; - rustBuildPlatform = rust.toRustTarget stdenv.buildPlatform; - rustTargetPlatform = rust.toRustTarget stdenv.hostPlatform; - rustTargetPlatformSpec = rust.toRustTargetSpec stdenv.hostPlatform; -in { +{ cargoBuildHook = callPackage ({ }: makeSetupHook { name = "cargo-build-hook.sh"; propagatedBuildInputs = [ cargo ]; substitutions = { - inherit ccForBuild ccForHost cxxForBuild cxxForHost - rustBuildPlatform rustTargetPlatform rustTargetPlatformSpec; + inherit (rust.envVars) rustHostPlatformSpec setEnv; }; } ./cargo-build-hook.sh) {}; @@ -43,7 +31,7 @@ in { name = "cargo-check-hook.sh"; propagatedBuildInputs = [ cargo ]; substitutions = { - inherit rustTargetPlatformSpec; + inherit (rust.envVars) rustHostPlatformSpec; }; } ./cargo-check-hook.sh) {}; @@ -52,7 +40,7 @@ in { name = "cargo-install-hook.sh"; propagatedBuildInputs = [ ]; substitutions = { - inherit shortTarget; + targetSubdirectory = target; }; } ./cargo-install-hook.sh) {}; @@ -61,7 +49,7 @@ in { name = "cargo-nextest-hook.sh"; propagatedBuildInputs = [ cargo cargo-nextest ]; substitutions = { - inherit rustTargetPlatformSpec; + inherit (rust.envVars) rustHostPlatformSpec; }; } ./cargo-nextest-hook.sh) {}; @@ -78,23 +66,26 @@ in { cargoConfig = '' [target."${rust.toRustTarget stdenv.buildPlatform}"] - "linker" = "${ccForBuild}" + "linker" = "${rust.envVars.ccForBuild}" ${lib.optionalString (stdenv.buildPlatform.config != stdenv.hostPlatform.config) '' - [target."${shortTarget}"] - "linker" = "${ccForHost}" + [target."${rust.toRustTarget stdenv.hostPlatform}"] + "linker" = "${rust.envVars.ccForHost}" ''} "rustflags" = [ "-C", "target-feature=${if stdenv.hostPlatform.isStatic then "+" else "-"}crt-static" ] ''; }; } ./cargo-setup-hook.sh) {}; - maturinBuildHook = callPackage ({ }: + maturinBuildHook = callPackage ({ pkgsHostTarget }: makeSetupHook { name = "maturin-build-hook.sh"; - propagatedBuildInputs = [ cargo maturin rustc ]; + propagatedBuildInputs = [ + pkgsHostTarget.maturin + pkgsHostTarget.cargo + pkgsHostTarget.rustc + ]; substitutions = { - inherit ccForBuild ccForHost cxxForBuild cxxForHost - rustBuildPlatform rustTargetPlatform rustTargetPlatformSpec; + inherit (rust.envVars) rustTargetPlatformSpec setEnv; }; } ./maturin-build-hook.sh) {}; diff --git a/nixpkgs/pkgs/build-support/rust/hooks/maturin-build-hook.sh b/nixpkgs/pkgs/build-support/rust/hooks/maturin-build-hook.sh index 62d5619660c6..d5ff069290ba 100644 --- a/nixpkgs/pkgs/build-support/rust/hooks/maturin-build-hook.sh +++ b/nixpkgs/pkgs/build-support/rust/hooks/maturin-build-hook.sh @@ -9,12 +9,7 @@ maturinBuildHook() { ( set -x - env \ - "CC_@rustBuildPlatform@=@ccForBuild@" \ - "CXX_@rustBuildPlatform@=@cxxForBuild@" \ - "CC_@rustTargetPlatform@=@ccForHost@" \ - "CXX_@rustTargetPlatform@=@cxxForHost@" \ - maturin build \ + @setEnv@ maturin build \ --jobs=$NIX_BUILD_CORES \ --frozen \ --target @rustTargetPlatformSpec@ \ diff --git a/nixpkgs/pkgs/build-support/rust/lib/default.nix b/nixpkgs/pkgs/build-support/rust/lib/default.nix index aa5ba14c1397..ceca7323176c 100644 --- a/nixpkgs/pkgs/build-support/rust/lib/default.nix +++ b/nixpkgs/pkgs/build-support/rust/lib/default.nix @@ -1,4 +1,8 @@ -{ lib }: +{ lib +, stdenv +, buildPackages +, targetPackages +}: rec { # https://doc.rust-lang.org/reference/conditional-compilation.html#target_arch @@ -59,8 +63,88 @@ rec { then builtins.toFile (toRustTarget platform + ".json") (builtins.toJSON platform.rustc.platform) else toRustTarget platform; + # Returns the name of the rust target if it is standard, or the + # basename of the file containing the custom target spec, without + # the .json extension. + # + # This is the name used by Cargo for target subdirectories. + toRustTargetSpecShort = platform: + lib.removeSuffix ".json" + (baseNameOf "${toRustTargetSpec platform}"); + + # When used as part of an environment variable name, triples are + # uppercased and have all hyphens replaced by underscores: + # + # https://github.com/rust-lang/cargo/pull/9169 + # https://github.com/rust-lang/cargo/issues/8285#issuecomment-634202431 + # + toRustTargetForUseInEnvVars = platform: + lib.strings.replaceStrings ["-"] ["_"] + (lib.strings.toUpper + (toRustTargetSpecShort platform)); + # Returns true if the target is no_std # https://github.com/rust-lang/rust/blob/2e44c17c12cec45b6a682b1e53a04ac5b5fcc9d2/src/bootstrap/config.rs#L415-L421 IsNoStdTarget = platform: let rustTarget = toRustTarget platform; in builtins.any (t: lib.hasInfix t rustTarget) ["-none" "nvptx" "switch" "-uefi"]; + + # These environment variables must be set when using `cargo-c` and + # several other tools which do not deal well with cross + # compilation. The symptom of the problem they fix is errors due + # to buildPlatform CFLAGS being passed to the + # hostPlatform-targeted compiler -- for example, `-m64` being + # passed on a build=x86_64/host=aarch64 compilation. + envVars = let + ccForBuild = "${buildPackages.stdenv.cc}/bin/${buildPackages.stdenv.cc.targetPrefix}cc"; + cxxForBuild = "${buildPackages.stdenv.cc}/bin/${buildPackages.stdenv.cc.targetPrefix}c++"; + ccForHost = "${stdenv.cc}/bin/${stdenv.cc.targetPrefix}cc"; + cxxForHost = "${stdenv.cc}/bin/${stdenv.cc.targetPrefix}c++"; + + # Unfortunately we must use the dangerous `targetPackages` here + # because hooks are artificially phase-shifted one slot earlier + # (they go in nativeBuildInputs, so the hostPlatform looks like + # a targetPlatform to them). + ccForTarget = "${targetPackages.stdenv.cc}/bin/${targetPackages.stdenv.cc.targetPrefix}cc"; + cxxForTarget = "${targetPackages.stdenv.cc}/bin/${targetPackages.stdenv.cc.targetPrefix}c++"; + + rustBuildPlatform = toRustTarget stdenv.buildPlatform; + rustBuildPlatformSpec = toRustTargetSpec stdenv.buildPlatform; + rustHostPlatform = toRustTarget stdenv.hostPlatform; + rustHostPlatformSpec = toRustTargetSpec stdenv.hostPlatform; + rustTargetPlatform = toRustTarget stdenv.targetPlatform; + rustTargetPlatformSpec = toRustTargetSpec stdenv.targetPlatform; + in { + inherit + ccForBuild cxxForBuild rustBuildPlatform rustBuildPlatformSpec + ccForHost cxxForHost rustHostPlatform rustHostPlatformSpec + ccForTarget cxxForTarget rustTargetPlatform rustTargetPlatformSpec; + + # Prefix this onto a command invocation in order to set the + # variables needed by cargo. + # + setEnv = '' + env \ + '' + # Due to a bug in how splicing and targetPackages works, in + # situations where targetPackages is irrelevant + # targetPackages.stdenv.cc is often simply wrong. We must omit + # the following lines when rustTargetPlatform collides with + # rustHostPlatform. + + lib.optionalString (rustTargetPlatform != rustHostPlatform) '' + "CC_${toRustTargetForUseInEnvVars stdenv.targetPlatform}=${ccForTarget}" \ + "CXX_${toRustTargetForUseInEnvVars stdenv.targetPlatform}=${cxxForTarget}" \ + "CARGO_TARGET_${toRustTargetForUseInEnvVars stdenv.targetPlatform}_LINKER=${ccForTarget}" \ + '' + '' + "CC_${toRustTargetForUseInEnvVars stdenv.hostPlatform}=${ccForHost}" \ + "CXX_${toRustTargetForUseInEnvVars stdenv.hostPlatform}=${cxxForHost}" \ + "CARGO_TARGET_${toRustTargetForUseInEnvVars stdenv.hostPlatform}_LINKER=${ccForHost}" \ + '' + '' + "CC_${toRustTargetForUseInEnvVars stdenv.buildPlatform}=${ccForBuild}" \ + "CXX_${toRustTargetForUseInEnvVars stdenv.buildPlatform}=${cxxForBuild}" \ + "CARGO_TARGET_${toRustTargetForUseInEnvVars stdenv.buildPlatform}_LINKER=${ccForBuild}" \ + "CARGO_BUILD_TARGET=${rustBuildPlatform}" \ + "HOST_CC=${buildPackages.stdenv.cc}/bin/cc" \ + "HOST_CXX=${buildPackages.stdenv.cc}/bin/c++" \ + ''; + }; } |