diff --git a/pkgs/build-support/rust/hooks/default.nix b/pkgs/build-support/rust/hooks/default.nix index 2eb388fe07ba8..0ca151dfc14dc 100644 --- a/pkgs/build-support/rust/hooks/default.nix +++ b/pkgs/build-support/rust/hooks/default.nix @@ -27,6 +27,18 @@ let rustBuildPlatform = rust.toRustTarget stdenv.buildPlatform; rustTargetPlatform = rust.toRustTarget stdenv.hostPlatform; rustTargetPlatformSpec = rust.toRustTargetSpec stdenv.hostPlatform; + + rustFlagsFor = plat: [ + # https://doc.rust-lang.org/rustc/codegen-options/index.html#target-feature + "-C" "target-feature=${if plat.isStatic then "+" else "-"}crt-static" + ] ++ lib.optionals (plat ? gcc.arch) [ + # https://doc.rust-lang.org/rustc/codegen-options/index.html#target-cpu + #"-C" "target-cpu=${plat.gcc.arch}" + ] ++ lib.optionals (plat ? gcc.tune) [ + # https://doc.rust-lang.org/rustc/codegen-options/index.html#tune-cpu + #"-Z" "tune-cpu=${plat.gcc.tune}" # nightly builds only; uncomment when stabilized + ] ++ (plat.rustc.flags or []); + in { cargoBuildHook = callPackage ({ }: makeSetupHook { @@ -76,14 +88,37 @@ 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 = '' - [target."${rust.toRustTarget stdenv.buildPlatform}"] + [host] "linker" = "${ccForBuild}" - ${lib.optionalString (stdenv.buildPlatform.config != stdenv.hostPlatform.config) '' - [target."${shortTarget}"] - "linker" = "${ccForHost}" - ''} - "rustflags" = [ "-C", "target-feature=${if stdenv.hostPlatform.isStatic then "+" else "-"}crt-static" ] + "rustflags" = [ ${lib.concatMapStringsSep ", " (f: "\"${builtins.toString f}\"") (rustFlagsFor stdenv.buildPlatform)} ] + + [target."${shortTarget}"] + "linker" = "${ccForHost}" + "rustflags" = [ ${lib.concatMapStringsSep ", " (f: "\"${builtins.toString f}\"") (rustFlagsFor stdenv.hostPlatform)} ] + + [unstable] + host-config = true + target-applies-to-host = true ''; }; } ./cargo-setup-hook.sh) {};