diff --git a/pkgs/build-support/rust/hooks/default.nix b/pkgs/build-support/rust/hooks/default.nix index 168224e39b35..2eb388fe07ba 100644 --- a/pkgs/build-support/rust/hooks/default.nix +++ b/pkgs/build-support/rust/hooks/default.nix @@ -76,37 +76,14 @@ in { # inputs do not cause us to find the wrong `diff`. diff = "${lib.getBin buildPackages.diffutils}/bin/diff"; - # We want to specify the correct crt-static flag for both - # the build and host platforms. This is important when the wanted - # value for crt-static does not match the defaults in the rustc target, - # like for pkgsMusl or pkgsCross.musl64; Upstream rustc still assumes - # that musl = static[1]. - # - # By default, Cargo doesn't apply RUSTFLAGS when building build.rs - # if --target is passed, so the only good way to set crt-static for - # build.rs files is to use the unstable -Zhost-config Cargo feature. - # This allows us to specify flags that should be passed to rustc - # when building for the build platform. We also need to use - # -Ztarget-applies-to-host, because using -Zhost-config requires it. - # - # When doing this, we also have to specify the linker, or cargo - # won't pass a -C linker= argument to rustc. This will make rustc - # try to use its default value of "cc", which won't be available - # when cross-compiling. - # - # [1]: https://github.com/rust-lang/compiler-team/issues/422 cargoConfig = '' - [host] + [target."${rust.toRustTarget stdenv.buildPlatform}"] "linker" = "${ccForBuild}" - "rustflags" = [ "-C", "target-feature=${if stdenv.buildPlatform.isStatic then "+" else "-"}crt-static" ] - - [target."${shortTarget}"] - "linker" = "${ccForHost}" + ${lib.optionalString (stdenv.buildPlatform.config != stdenv.hostPlatform.config) '' + [target."${shortTarget}"] + "linker" = "${ccForHost}" + ''} "rustflags" = [ "-C", "target-feature=${if stdenv.hostPlatform.isStatic then "+" else "-"}crt-static" ] - - [unstable] - host-config = true - target-applies-to-host = true ''; }; } ./cargo-setup-hook.sh) {}; diff --git a/pkgs/development/compilers/rust/cargo.nix b/pkgs/development/compilers/rust/cargo.nix index 481b4195891c..eb3dc238a9ab 100644 --- a/pkgs/development/compilers/rust/cargo.nix +++ b/pkgs/development/compilers/rust/cargo.nix @@ -1,4 +1,4 @@ -{ lib, stdenv, pkgsHostHost +{ lib, stdenv, pkgsBuildHost, pkgsHostHost , file, curl, pkg-config, python3, openssl, cmake, zlib , installShellFiles, makeWrapper, rustPlatform, rustc , CoreFoundation, Security @@ -20,6 +20,42 @@ rustPlatform.buildRustPackage { inherit (rustc) tests; }; + # Upstream rustc still assumes that musl = static[1]. The fix for + # this is to disable crt-static by default for non-static musl + # targets. + # + # For every package apart from Cargo, we can fix this by just + # patching rustc to not have crt-static by default. But Cargo is + # built with the upstream bootstrap binary for rustc, which we can't + # easily patch. This means we need to find another way to make sure + # crt-static is not used during the build of pkgsMusl.cargo. + # + # By default, Cargo doesn't apply RUSTFLAGS when building build.rs + # if --target is passed, so the only good way to set -crt-static for + # build.rs files used in the Cargo build is to use the unstable + # -Zhost-config Cargo feature. This allows us to specify flags that + # should be passed to rustc when building for the build platform. + # We also need to use -Ztarget-applies-to-host, because using + # -Zhost-config requires it. + # + # When doing this, we also have to specify the linker, or cargo + # won't pass a -C linker= argument to rustc. This will make rustc + # try to use its default value of "cc", which won't be available + # when cross-compiling. + # + # [1]: https://github.com/rust-lang/compiler-team/issues/422 + postPatch = lib.optionalString (with stdenv.buildPlatform; isMusl && !isStatic) '' + mkdir -p .cargo + cat <> .cargo/config + [host] + rustflags = "-C target-feature=-crt-static" + linker = "${pkgsBuildHost.stdenv.cc}/bin/${pkgsBuildHost.stdenv.cc.targetPrefix}cc" + [unstable] + host-config = true + target-applies-to-host = true + EOF + ''; + # changes hash of vendor directory otherwise dontUpdateAutotoolsGnuConfigScripts = true; diff --git a/pkgs/development/compilers/rust/rustc.nix b/pkgs/development/compilers/rust/rustc.nix index 7cb6f22c949b..f9068a7999a2 100644 --- a/pkgs/development/compilers/rust/rustc.nix +++ b/pkgs/development/compilers/rust/rustc.nix @@ -147,6 +147,18 @@ in stdenv.mkDerivation rec { # Useful debugging parameter # export VERBOSE=1 + '' + lib.optionalString (stdenv.targetPlatform.isMusl && !stdenv.targetPlatform.isStatic) '' + # Upstream rustc still assumes that musl = static[1]. The fix for + # this is to disable crt-static by default for non-static musl + # targets. + # + # Even though Cargo will build build.rs files for the build platform, + # cross-compiling _from_ musl appears to work fine, so we only need + # to do this when rustc's target platform is dynamically linked musl. + # + # [1]: https://github.com/rust-lang/compiler-team/issues/422 + substituteInPlace compiler/rustc_target/src/spec/linux_musl_base.rs \ + --replace "base.crt_static_default = true" "base.crt_static_default = false" '' + lib.optionalString (stdenv.isDarwin && stdenv.isx86_64) '' # See https://github.com/jemalloc/jemalloc/issues/1997 # Using a value of 48 should work on both emulated and native x86_64-darwin.