137 lines
5 KiB
Nix
137 lines
5 KiB
Nix
{
|
|
lib,
|
|
stdenv,
|
|
pkgsBuildHost,
|
|
pkgsBuildTarget,
|
|
pkgsTargetTarget,
|
|
}:
|
|
|
|
rec {
|
|
# 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
|
|
|
|
# As a workaround for https://github.com/rust-lang/rust/issues/89626 use lld on pkgsStatic aarch64
|
|
shouldUseLLD = platform: platform.isAarch64 && platform.isStatic && !stdenv.isDarwin;
|
|
|
|
ccForBuild = "${pkgsBuildHost.stdenv.cc}/bin/${pkgsBuildHost.stdenv.cc.targetPrefix}cc";
|
|
cxxForBuild = "${pkgsBuildHost.stdenv.cc}/bin/${pkgsBuildHost.stdenv.cc.targetPrefix}c++";
|
|
linkerForBuild = ccForBuild;
|
|
|
|
ccForHost = "${stdenv.cc}/bin/${stdenv.cc.targetPrefix}cc";
|
|
cxxForHost = "${stdenv.cc}/bin/${stdenv.cc.targetPrefix}c++";
|
|
linkerForHost =
|
|
if shouldUseLLD stdenv.targetPlatform && !stdenv.cc.bintools.isLLVM then
|
|
"${pkgsBuildHost.llvmPackages.bintools}/bin/${stdenv.cc.targetPrefix}ld.lld"
|
|
else
|
|
ccForHost;
|
|
|
|
# Unfortunately we must use the dangerous `pkgsTargetTarget` here
|
|
# because hooks are artificially phase-shifted one slot earlier
|
|
# (they go in nativeBuildInputs, so the hostPlatform looks like
|
|
# a targetPlatform to them).
|
|
ccForTarget = "${pkgsTargetTarget.stdenv.cc}/bin/${pkgsTargetTarget.stdenv.cc.targetPrefix}cc";
|
|
cxxForTarget = "${pkgsTargetTarget.stdenv.cc}/bin/${pkgsTargetTarget.stdenv.cc.targetPrefix}c++";
|
|
linkerForTarget =
|
|
if
|
|
shouldUseLLD pkgsTargetTarget.stdenv.targetPlatform && !pkgsTargetTarget.stdenv.cc.bintools.isLLVM # whether stdenv's linker is lld already
|
|
then
|
|
"${pkgsBuildTarget.llvmPackages.bintools}/bin/${pkgsTargetTarget.stdenv.cc.targetPrefix}ld.lld"
|
|
else
|
|
ccForTarget;
|
|
|
|
rustBuildPlatform = stdenv.buildPlatform.rust.rustcTarget;
|
|
rustBuildPlatformSpec = stdenv.buildPlatform.rust.rustcTargetSpec;
|
|
rustHostPlatform = stdenv.hostPlatform.rust.rustcTarget;
|
|
rustHostPlatformSpec = stdenv.hostPlatform.rust.rustcTargetSpec;
|
|
rustTargetPlatform = stdenv.targetPlatform.rust.rustcTarget;
|
|
rustTargetPlatformSpec = stdenv.targetPlatform.rust.rustcTargetSpec;
|
|
in
|
|
{
|
|
inherit
|
|
ccForBuild
|
|
cxxForBuild
|
|
linkerForBuild
|
|
rustBuildPlatform
|
|
rustBuildPlatformSpec
|
|
ccForHost
|
|
cxxForHost
|
|
linkerForHost
|
|
rustHostPlatform
|
|
rustHostPlatformSpec
|
|
ccForTarget
|
|
cxxForTarget
|
|
linkerForTarget
|
|
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 pkgsTargetTarget works, in
|
|
# situations where pkgsTargetTarget is irrelevant
|
|
# pkgsTargetTarget.stdenv.cc is often simply wrong. We must omit
|
|
# the following lines when rustTargetPlatform collides with
|
|
# rustHostPlatform.
|
|
+ lib.optionalString (rustTargetPlatform != rustHostPlatform) ''
|
|
"CC_${stdenv.targetPlatform.rust.cargoEnvVarTarget}=${ccForTarget}" \
|
|
"CXX_${stdenv.targetPlatform.rust.cargoEnvVarTarget}=${cxxForTarget}" \
|
|
"CARGO_TARGET_${stdenv.targetPlatform.rust.cargoEnvVarTarget}_LINKER=${linkerForTarget}" \
|
|
''
|
|
+ ''
|
|
"CC_${stdenv.hostPlatform.rust.cargoEnvVarTarget}=${ccForHost}" \
|
|
"CXX_${stdenv.hostPlatform.rust.cargoEnvVarTarget}=${cxxForHost}" \
|
|
"CARGO_TARGET_${stdenv.hostPlatform.rust.cargoEnvVarTarget}_LINKER=${linkerForHost}" \
|
|
''
|
|
+ ''
|
|
"CC_${stdenv.buildPlatform.rust.cargoEnvVarTarget}=${ccForBuild}" \
|
|
"CXX_${stdenv.buildPlatform.rust.cargoEnvVarTarget}=${cxxForBuild}" \
|
|
"CARGO_TARGET_${stdenv.buildPlatform.rust.cargoEnvVarTarget}_LINKER=${linkerForBuild}" \
|
|
"CARGO_BUILD_TARGET=${rustBuildPlatform}" \
|
|
"HOST_CC=${pkgsBuildHost.stdenv.cc}/bin/cc" \
|
|
"HOST_CXX=${pkgsBuildHost.stdenv.cc}/bin/c++" \
|
|
'';
|
|
};
|
|
}
|
|
//
|
|
lib.mapAttrs
|
|
(
|
|
old: new: platform:
|
|
# TODO: enable warning after 23.05 is EOL.
|
|
# lib.warn "`rust.${old} platform` is deprecated. Use `platform.rust.${new}` instead."
|
|
lib.getAttrFromPath new platform.rust
|
|
)
|
|
{
|
|
toTargetArch = [
|
|
"platform"
|
|
"arch"
|
|
];
|
|
toTargetOs = [
|
|
"platform"
|
|
"os"
|
|
];
|
|
toTargetFamily = [
|
|
"platform"
|
|
"target-family"
|
|
];
|
|
toTargetVendor = [
|
|
"platform"
|
|
"vendor"
|
|
];
|
|
toRustTarget = [ "rustcTarget" ];
|
|
toRustTargetSpec = [ "rustcTargetSpec" ];
|
|
toRustTargetSpecShort = [ "cargoShortTarget" ];
|
|
toRustTargetForUseInEnvVars = [ "cargoEnvVarTarget" ];
|
|
IsNoStdTarget = [ "isNoStdTarget" ];
|
|
}
|