diff options
author | Adam Joseph <adam@westernsemico.com> | 2023-08-06 15:06:54 -0700 |
---|---|---|
committer | Alyssa Ross <hi@alyssa.is> | 2023-09-26 06:30:44 +0000 |
commit | c1df604e9fbae74f7aa7530ec13e14a85758be61 (patch) | |
tree | cdd153e6887c1ebcc03ea50689ae2e82514ba606 /pkgs | |
parent | aa53f325374cde77bcad69696616d0e9a7b923e5 (diff) |
rust: add rust.envVars
Diffstat (limited to 'pkgs')
-rw-r--r-- | pkgs/build-support/rust/lib/default.nix | 77 | ||||
-rw-r--r-- | pkgs/development/compilers/rust/1_72.nix | 1 | ||||
-rw-r--r-- | pkgs/development/compilers/rust/default.nix | 5 |
3 files changed, 80 insertions, 3 deletions
diff --git a/pkgs/build-support/rust/lib/default.nix b/pkgs/build-support/rust/lib/default.nix index aa5ba14c1397b..8ca3758e51477 100644 --- a/pkgs/build-support/rust/lib/default.nix +++ b/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,79 @@ rec { then builtins.toFile (toRustTarget platform + ".json") (builtins.toJSON platform.rustc.platform) else toRustTarget 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 + (toRustTarget 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++" \ + ''; + }; } diff --git a/pkgs/development/compilers/rust/1_72.nix b/pkgs/development/compilers/rust/1_72.nix index 60eef6d44ec87..f540c229c6ff6 100644 --- a/pkgs/development/compilers/rust/1_72.nix +++ b/pkgs/development/compilers/rust/1_72.nix @@ -11,6 +11,7 @@ { stdenv, lib , buildPackages +, targetPackages , newScope, callPackage , CoreFoundation, Security, SystemConfiguration , pkgsBuildTarget, pkgsBuildBuild, pkgsBuildHost diff --git a/pkgs/development/compilers/rust/default.nix b/pkgs/development/compilers/rust/default.nix index 90e921651f140..0a0af7832366b 100644 --- a/pkgs/development/compilers/rust/default.nix +++ b/pkgs/development/compilers/rust/default.nix @@ -13,6 +13,7 @@ }: { stdenv, lib , buildPackages +, targetPackages , newScope, callPackage , CoreFoundation, Security, SystemConfiguration , pkgsBuildBuild @@ -21,7 +22,7 @@ let # Use `import` to make sure no packages sneak in here. - lib' = import ../../../build-support/rust/lib { inherit lib; }; + lib' = import ../../../build-support/rust/lib { inherit lib stdenv buildPackages targetPackages; }; # Allow faster cross compiler generation by reusing Build artifacts fastCross = (stdenv.buildPlatform == stdenv.hostPlatform) && (stdenv.hostPlatform != stdenv.targetPlatform); in @@ -29,7 +30,7 @@ in lib = lib'; # Backwards compat before `lib` was factored out. - inherit (lib') toTargetArch toTargetOs toRustTarget toRustTargetSpec IsNoStdTarget; + inherit (lib') toTargetArch toTargetOs toRustTarget toRustTargetSpec IsNoStdTarget toRustTargetForUseInEnvVars envVars; # This just contains tools for now. But it would conceivably contain # libraries too, say if we picked some default/recommended versions to build |