rust: fix overriding rust flags on musl
If RUSTFLAGS is set in the environment, Cargo will ignore rustflags
settings in its TOML configuration. So setting RUSTFLAGS=-g (like
separateDebugInfo does) to generate debug info breaks
dynamically-linked Rust packages on musl. This breakage is visible
for any packages that call into C dynamic libraries. If the binary is
linked directly to a C dynamic library, it will fail to build, and if
it depends on a Rust library which links a C dynamic library, it will
segfault at runtime when it tries to call a function from the C
library. I noticed this because pkgsMusl.crosvm is broken for this
reason, since it sets separateDebugInfo = true.
It shouldn't be possible to end up with broken binaries just by using
RUSTFLAGS to do something innocuous like enable debug info, so I think
that, even though we liked the approach of modiyfing .cargo/config
better at the time, it's become clear that it's too brittle, and we
should bite the bullet and patch the compiler instead when targetting
musl. It does not appear to be necessary to modify the compiler at
all when cross-compiling /from/ dynamically-linked Musl to another
target, so I'm only checking whether the target system is
dynamically-linked Musl when deciding whether to make the modification
to the compiler.
This reverts commit c2eaaae50d66a933e38256bdf5a3ae43430592a3
("cargoSetupHook: pass host config flags"), and implements the
compiler patching approach instead.
2023-03-16 00:09:35 +00:00
|
|
|
{ lib, stdenv, pkgsBuildHost, pkgsHostHost
|
2021-09-10 10:26:04 +01:00
|
|
|
, file, curl, pkg-config, python3, openssl, cmake, zlib
|
lib.systems: elaborate Rust metadata
We need this stuff to be available in lib so make-derivation.nix can
access it to construct the Meson cross file.
This has a couple of other advantages:
- It makes Rust less special. Now figuring out what Rust calls a
platform is the same as figuring out what Linux or QEMU call it.
- We can unify the schema used to define Rust targets, and the schema
used to access those values later. Just like you can set "config"
or "system" in a platform definition, and then access those same
keys on the elaborated platform, you can now set "rustcTarget" in
your crossSystem, and then access "stdenv.hostPlatform.rustcTarget"
in your code.
"rustcTarget", "rustcTargetSpec", "cargoShortTarget", and
"cargoEnvVarTarget" have the "rustc" and "cargo" prefixes because
these are not exposed to code by the compiler, and are not
standardized. The arch/os/etc. variables are all named to match the
forms in the Rust target spec JSON.
The new rust.target-family only takes a list, since we don't need to
worry about backwards compatibility when that name is used.
The old APIs are all still functional with no warning for now, so that
it's possible for external code to use a single API on both 23.05 and
23.11. We can introduce the warnings once 23.05 is EOL, and make them
hard errors when 23.11 is EOL.
2023-05-09 14:38:32 +01:00
|
|
|
, installShellFiles, makeWrapper, rustPlatform, rustc
|
2022-12-15 23:38:33 +00:00
|
|
|
, CoreFoundation, Security
|
2023-04-22 20:52:06 +01:00
|
|
|
, auditable ? !cargo-auditable.meta.broken
|
2023-03-27 01:34:07 +01:00
|
|
|
, cargo-auditable
|
2023-04-22 20:53:23 +01:00
|
|
|
, pkgsBuildBuild
|
2018-11-21 01:47:45 +00:00
|
|
|
}:
|
2017-11-05 10:13:49 +00:00
|
|
|
|
2023-04-22 20:53:23 +01:00
|
|
|
rustPlatform.buildRustPackage.override {
|
2023-03-27 01:34:07 +01:00
|
|
|
cargo-auditable = cargo-auditable.bootstrap;
|
2023-04-22 20:53:23 +01:00
|
|
|
} ({
|
2022-03-01 10:52:52 +00:00
|
|
|
pname = "cargo";
|
rustc: add a compiler wrapper
We keep running into situations where we can't get the right
combination of rustc flags through build systems into rustc.
RUSTFLAGS is the only variable supported across build systems, but if
RUSTFLAGS is set, Cargo will ignore all other ways of specifying rustc
flags, including the target-specific ones, which we need to make
dynamic musl builds work. (This is why pkgsCross.musl64.crosvm is
currently broken — it works if you unset separateDebugInfo, which
causes RUSTFLAGS not to be set.)
So, we need to do the same thing we do for C and C++ compilers, and
add a compiler wrapper so we can inject the flags we need, regardless
of the build system.
Currently the wrapper only supports a single mechanism for injecting
flags — the NIX_RUSTFLAGS environment variable. As time goes on,
we'll probably want to add additional features, like target-specific
environment variables.
2023-10-18 12:02:45 +01:00
|
|
|
inherit (rustc.unwrapped) version src;
|
2016-06-07 19:42:51 +01:00
|
|
|
|
2018-02-20 09:59:26 +00:00
|
|
|
# the rust source tarball already has all the dependencies vendored, no need to fetch them again
|
2019-01-19 14:47:18 +00:00
|
|
|
cargoVendorDir = "vendor";
|
2020-05-13 00:28:24 +01:00
|
|
|
buildAndTestSubdir = "src/tools/cargo";
|
2016-06-07 19:42:51 +01:00
|
|
|
|
2022-12-05 01:52:06 +00:00
|
|
|
inherit auditable;
|
|
|
|
|
2022-08-23 02:10:09 +01:00
|
|
|
passthru = {
|
|
|
|
rustc = rustc;
|
2023-12-28 20:30:19 +00:00
|
|
|
inherit (rustc.unwrapped) tests;
|
2022-08-23 02:10:09 +01:00
|
|
|
};
|
2016-06-07 19:42:51 +01:00
|
|
|
|
2018-08-14 08:40:47 +01:00
|
|
|
# changes hash of vendor directory otherwise
|
|
|
|
dontUpdateAutotoolsGnuConfigScripts = true;
|
2018-02-22 11:46:30 +00:00
|
|
|
|
2021-09-10 10:26:04 +01:00
|
|
|
nativeBuildInputs = [
|
|
|
|
pkg-config cmake installShellFiles makeWrapper
|
|
|
|
(lib.getDev pkgsHostHost.curl)
|
2023-01-11 20:06:22 +00:00
|
|
|
zlib
|
2021-09-10 10:26:04 +01:00
|
|
|
];
|
2023-01-31 14:28:06 +00:00
|
|
|
buildInputs = [ file curl python3 openssl zlib ]
|
2022-12-15 23:38:33 +00:00
|
|
|
++ lib.optionals stdenv.isDarwin [ CoreFoundation Security ];
|
2016-08-08 14:55:26 +01:00
|
|
|
|
2020-02-12 16:00:19 +00:00
|
|
|
# cargo uses git-rs which is made for a version of libgit2 from recent master that
|
|
|
|
# is not compatible with the current version in nixpkgs.
|
|
|
|
#LIBGIT2_SYS_USE_PKG_CONFIG = 1;
|
2016-06-07 19:42:51 +01:00
|
|
|
|
2018-09-11 22:20:20 +01:00
|
|
|
# fixes: the cargo feature `edition` requires a nightly version of Cargo, but this is the `stable` channel
|
2019-03-12 01:19:48 +00:00
|
|
|
RUSTC_BOOTSTRAP = 1;
|
2018-09-11 22:20:20 +01:00
|
|
|
|
2016-06-07 19:42:51 +01:00
|
|
|
postInstall = ''
|
2023-01-31 14:28:06 +00:00
|
|
|
wrapProgram "$out/bin/cargo" --suffix PATH : "${rustc}/bin"
|
2020-02-11 17:52:11 +00:00
|
|
|
|
|
|
|
installManPage src/tools/cargo/src/etc/man/*
|
2020-06-26 23:56:11 +01:00
|
|
|
|
|
|
|
installShellCompletion --bash --name cargo \
|
|
|
|
src/tools/cargo/src/etc/cargo.bashcomp.sh
|
|
|
|
|
|
|
|
installShellCompletion --zsh src/tools/cargo/src/etc/_cargo
|
2016-06-07 19:42:51 +01:00
|
|
|
'';
|
|
|
|
|
|
|
|
checkPhase = ''
|
|
|
|
# Disable cross compilation tests
|
|
|
|
export CFG_DISABLE_CROSS_TESTS=1
|
|
|
|
cargo test
|
|
|
|
'';
|
|
|
|
|
2016-12-29 07:56:19 +00:00
|
|
|
# Disable check phase as there are failures (4 tests fail)
|
2016-06-07 19:42:51 +01:00
|
|
|
doCheck = false;
|
|
|
|
|
2024-01-08 01:43:33 +00:00
|
|
|
doInstallCheck = !stdenv.hostPlatform.isStatic && stdenv.hostPlatform.isElf;
|
2021-09-10 10:26:04 +01:00
|
|
|
installCheckPhase = ''
|
|
|
|
runHook preInstallCheck
|
|
|
|
readelf -a $out/bin/.cargo-wrapped | grep -F 'Shared library: [libcurl.so'
|
|
|
|
runHook postInstallCheck
|
|
|
|
'';
|
|
|
|
|
2021-01-22 11:25:31 +00:00
|
|
|
meta = with lib; {
|
2020-04-01 02:11:51 +01:00
|
|
|
homepage = "https://crates.io";
|
2016-06-07 19:42:51 +01:00
|
|
|
description = "Downloads your Rust project's dependencies and builds your project";
|
2024-03-19 02:14:51 +00:00
|
|
|
mainProgram = "cargo";
|
2023-04-03 01:24:55 +01:00
|
|
|
maintainers = teams.rust.members;
|
2016-06-07 19:42:51 +01:00
|
|
|
license = [ licenses.mit licenses.asl20 ];
|
2018-02-03 11:51:03 +00:00
|
|
|
platforms = platforms.unix;
|
2023-05-22 17:16:46 +01:00
|
|
|
# https://github.com/alexcrichton/nghttp2-rs/issues/2
|
|
|
|
broken = stdenv.hostPlatform.isx86 && stdenv.buildPlatform != stdenv.hostPlatform;
|
2016-06-07 19:42:51 +01:00
|
|
|
};
|
|
|
|
}
|
lib.systems: elaborate Rust metadata
We need this stuff to be available in lib so make-derivation.nix can
access it to construct the Meson cross file.
This has a couple of other advantages:
- It makes Rust less special. Now figuring out what Rust calls a
platform is the same as figuring out what Linux or QEMU call it.
- We can unify the schema used to define Rust targets, and the schema
used to access those values later. Just like you can set "config"
or "system" in a platform definition, and then access those same
keys on the elaborated platform, you can now set "rustcTarget" in
your crossSystem, and then access "stdenv.hostPlatform.rustcTarget"
in your code.
"rustcTarget", "rustcTargetSpec", "cargoShortTarget", and
"cargoEnvVarTarget" have the "rustc" and "cargo" prefixes because
these are not exposed to code by the compiler, and are not
standardized. The arch/os/etc. variables are all named to match the
forms in the Rust target spec JSON.
The new rust.target-family only takes a list, since we don't need to
worry about backwards compatibility when that name is used.
The old APIs are all still functional with no warning for now, so that
it's possible for external code to use a single API on both 23.05 and
23.11. We can introduce the warnings once 23.05 is EOL, and make them
hard errors when 23.11 is EOL.
2023-05-09 14:38:32 +01:00
|
|
|
// lib.optionalAttrs (stdenv.buildPlatform.rust.rustcTarget != stdenv.hostPlatform.rust.rustcTarget) {
|
2023-04-22 20:53:23 +01:00
|
|
|
HOST_PKG_CONFIG_PATH="${pkgsBuildBuild.pkg-config}/bin/pkg-config";
|
|
|
|
})
|