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