1{ lib
2, stdenv
3, buildPackages
4, targetPackages
5}:
6
7rec {
8 # These environment variables must be set when using `cargo-c` and
9 # several other tools which do not deal well with cross
10 # compilation. The symptom of the problem they fix is errors due
11 # to buildPlatform CFLAGS being passed to the
12 # hostPlatform-targeted compiler -- for example, `-m64` being
13 # passed on a build=x86_64/host=aarch64 compilation.
14 envVars = let
15 ccForBuild = "${buildPackages.stdenv.cc}/bin/${buildPackages.stdenv.cc.targetPrefix}cc";
16 cxxForBuild = "${buildPackages.stdenv.cc}/bin/${buildPackages.stdenv.cc.targetPrefix}c++";
17 ccForHost = "${stdenv.cc}/bin/${stdenv.cc.targetPrefix}cc";
18 cxxForHost = "${stdenv.cc}/bin/${stdenv.cc.targetPrefix}c++";
19
20 # Unfortunately we must use the dangerous `targetPackages` here
21 # because hooks are artificially phase-shifted one slot earlier
22 # (they go in nativeBuildInputs, so the hostPlatform looks like
23 # a targetPlatform to them).
24 ccForTarget = "${targetPackages.stdenv.cc}/bin/${targetPackages.stdenv.cc.targetPrefix}cc";
25 cxxForTarget = "${targetPackages.stdenv.cc}/bin/${targetPackages.stdenv.cc.targetPrefix}c++";
26
27 rustBuildPlatform = stdenv.buildPlatform.rust.rustcTarget;
28 rustBuildPlatformSpec = stdenv.buildPlatform.rust.rustcTargetSpec;
29 rustHostPlatform = stdenv.hostPlatform.rust.rustcTarget;
30 rustHostPlatformSpec = stdenv.hostPlatform.rust.rustcTargetSpec;
31 rustTargetPlatform = stdenv.targetPlatform.rust.rustcTarget;
32 rustTargetPlatformSpec = stdenv.targetPlatform.rust.rustcTargetSpec;
33 in {
34 inherit
35 ccForBuild cxxForBuild rustBuildPlatform rustBuildPlatformSpec
36 ccForHost cxxForHost rustHostPlatform rustHostPlatformSpec
37 ccForTarget cxxForTarget rustTargetPlatform rustTargetPlatformSpec;
38
39 # Prefix this onto a command invocation in order to set the
40 # variables needed by cargo.
41 #
42 setEnv = ''
43 env \
44 ''
45 # Due to a bug in how splicing and targetPackages works, in
46 # situations where targetPackages is irrelevant
47 # targetPackages.stdenv.cc is often simply wrong. We must omit
48 # the following lines when rustTargetPlatform collides with
49 # rustHostPlatform.
50 + lib.optionalString (rustTargetPlatform != rustHostPlatform) ''
51 "CC_${stdenv.targetPlatform.rust.cargoEnvVarTarget}=${ccForTarget}" \
52 "CXX_${stdenv.targetPlatform.rust.cargoEnvVarTarget}=${cxxForTarget}" \
53 "CARGO_TARGET_${stdenv.targetPlatform.rust.cargoEnvVarTarget}_LINKER=${ccForTarget}" \
54 '' + ''
55 "CC_${stdenv.hostPlatform.rust.cargoEnvVarTarget}=${ccForHost}" \
56 "CXX_${stdenv.hostPlatform.rust.cargoEnvVarTarget}=${cxxForHost}" \
57 "CARGO_TARGET_${stdenv.hostPlatform.rust.cargoEnvVarTarget}_LINKER=${ccForHost}" \
58 '' + ''
59 "CC_${stdenv.buildPlatform.rust.cargoEnvVarTarget}=${ccForBuild}" \
60 "CXX_${stdenv.buildPlatform.rust.cargoEnvVarTarget}=${cxxForBuild}" \
61 "CARGO_TARGET_${stdenv.buildPlatform.rust.cargoEnvVarTarget}_LINKER=${ccForBuild}" \
62 "CARGO_BUILD_TARGET=${rustBuildPlatform}" \
63 "HOST_CC=${buildPackages.stdenv.cc}/bin/cc" \
64 "HOST_CXX=${buildPackages.stdenv.cc}/bin/c++" \
65 '';
66 };
67} // lib.mapAttrs (old: new: platform:
68 # TODO: enable warning after 23.05 is EOL.
69 # lib.warn "`rust.${old} platform` is deprecated. Use `platform.rust.${new}` instead."
70 lib.getAttrFromPath new platform.rust)
71{
72 toTargetArch = [ "platform" "arch" ];
73 toTargetOs = [ "platform" "os" ];
74 toTargetFamily = [ "platform" "target-family" ];
75 toTargetVendor = [ "platform" "vendor" ];
76 toRustTarget = [ "rustcTarget" ];
77 toRustTargetSpec = [ "rustcTargetSpec" ];
78 toRustTargetSpecShort = [ "cargoShortTarget" ];
79 toRustTargetForUseInEnvVars = [ "cargoEnvVarTarget" ];
80 IsNoStdTarget = [ "isNoStdTarget" ];
81}