Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 48 additions & 13 deletions pkgs/build-support/rust/default.nix
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{ stdenv, cacert, git, cargo, rustc, cargo-vendor, fetchcargo, python3 }:
{ stdenv, cacert, git, cargo, rustc, cargo-vendor, fetchcargo, python3, buildPackages }:

{ name, cargoSha256 ? "unset"
, src ? null
Expand All @@ -8,6 +8,7 @@
, sourceRoot ? null
, logLevel ? ""
, buildInputs ? []
, nativeBuildInputs ? []
, cargoUpdateHook ? ""
, cargoDepsHook ? ""
, cargoBuildFlags ? []
Expand Down Expand Up @@ -36,21 +37,22 @@ let
cargoDepsCopy="$sourceRoot/${cargoVendorDir}"
'';

ccForBuild="${buildPackages.stdenv.cc}/bin/${buildPackages.stdenv.cc.targetPrefix}cc";

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The build cc is almost never prefixed. I suppose there could be some weird case where it needs to be though.

cxxForBuild="${buildPackages.stdenv.cc}/bin/${buildPackages.stdenv.cc.targetPrefix}cxx";
ccForHost="${stdenv.cc}/bin/${stdenv.cc.targetPrefix}cc";
cxxForHost="${stdenv.cc}/bin/${stdenv.cc.targetPrefix}cxx";
releaseDir = "target/${stdenv.hostPlatform.config}/release";

in stdenv.mkDerivation (args // {
inherit cargoDeps;

patchRegistryDeps = ./patch-registry-deps;

buildInputs = [ cacert git cargo rustc ] ++ buildInputs;
nativeBuildInputs = [ cargo rustc git cacert ] ++ nativeBuildInputs;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note these would be buildPackges.cargo buildPackages.rustc, etc, due to splicing black magic.

inherit buildInputs;

patches = cargoPatches ++ patches;

configurePhase = args.configurePhase or ''
runHook preConfigure
# noop
runHook postConfigure
'';

postUnpack = ''
eval "$cargoDepsHook"

Expand All @@ -62,17 +64,40 @@ in stdenv.mkDerivation (args // {
config=${./fetchcargo-default-config.toml};
fi;
substitute $config .cargo/config \
--subst-var-by vendor "$(pwd)/$cargoDepsCopy"
--subst-var-by vendor "$(pwd)/$cargoDepsCopy"

unset cargoDepsCopy

export RUST_LOG=${logLevel}
'' + (args.postUnpack or "");

configurePhase = args.configurePhase or ''
runHook preConfigure
mkdir .cargo
cat > .cargo/config <<'EOF'
[target."${stdenv.buildPlatform.config}"]
"linker" = "${ccForBuild}"
${stdenv.lib.optionalString (stdenv.buildPlatform.config != stdenv.hostPlatform.config) ''
[target."${stdenv.hostPlatform.config}"]
"linker" = "${ccForHost}"
''}
EOF
cat .cargo/config
runHook postConfigure
'';

buildPhase = with builtins; args.buildPhase or ''
runHook preBuild
echo "Running cargo build --release ${concatStringsSep " " cargoBuildFlags}"
cargo build --release --frozen ${concatStringsSep " " cargoBuildFlags}
echo "Running cargo build --target ${stdenv.hostPlatform.config} --release ${concatStringsSep " " cargoBuildFlags}"
env \
"CC_${stdenv.buildPlatform.config}"="${ccForBuild}" \
"CXX_${stdenv.buildPlatform.config}"="${cxxForBuild}" \
"CC_${stdenv.hostPlatform.config}"="${ccForHost}" \
"CXX_${stdenv.hostPlatform.config}"="${cxxForHost}" \
cargo build \
--release \
--target ${stdenv.hostPlatform.config} \
--frozen ${concatStringsSep " " cargoBuildFlags}
runHook postBuild
'';

Expand All @@ -85,11 +110,21 @@ in stdenv.mkDerivation (args // {

doCheck = args.doCheck or true;

inherit releaseDir;

installPhase = args.installPhase or ''
runHook preInstall
mkdir -p $out/bin $out/lib
find target/release -maxdepth 1 -type f -executable ! \( -regex ".*\.\(so.[0-9.]+\|so\|a\|dylib\)" \) -print0 | xargs -r -0 cp -t $out/bin
find target/release -maxdepth 1 -regex ".*\.\(so.[0-9.]+\|so\|a\|dylib\)" -print0 | xargs -r -0 cp -t $out/lib

find $releaseDir \
-maxdepth 1 \
-type f \
-executable ! \( -regex ".*\.\(so.[0-9.]+\|so\|a\|dylib\)" \) \
-print0 | xargs -r -0 cp -t $out/bin
find $releaseDir \
-maxdepth 1 \
-regex ".*\.\(so.[0-9.]+\|so\|a\|dylib\)" \
-print0 | xargs -r -0 cp -t $out/lib
rmdir --ignore-fail-on-non-empty $out/lib $out/bin
runHook postInstall
'';
Expand Down
18 changes: 0 additions & 18 deletions pkgs/build-support/rust/make-rust-platform.nix

This file was deleted.

12 changes: 5 additions & 7 deletions pkgs/development/compilers/rust/cargo.nix
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
{ stdenv, file, curl, pkgconfig, python, openssl, cmake, zlib
, makeWrapper, libiconv, cacert, rustPlatform, rustc, libgit2
, CoreFoundation, Security
, version
, patches ? []
, src }:
}:

rustPlatform.buildRustPackage rec {
name = "cargo-${version}";
inherit version src patches;
name = "cargo-${rustc.version}";
inherit (rustc) version src;

# the rust source tarball already has all the dependencies vendored, no need to fetch them again
cargoVendorDir = "src/vendor";
Expand All @@ -19,8 +17,8 @@ rustPlatform.buildRustPackage rec {
# changes hash of vendor directory otherwise
dontUpdateAutotoolsGnuConfigScripts = true;

nativeBuildInputs = [ pkgconfig ];
buildInputs = [ cacert file curl python openssl cmake zlib makeWrapper libgit2 ]
nativeBuildInputs = [ pkgconfig cmake makeWrapper ];
buildInputs = [ cacert file curl python openssl zlib libgit2 ]
++ stdenv.lib.optionals stdenv.isDarwin [ CoreFoundation Security libiconv ];

LIBGIT2_SYS_USE_PKG_CONFIG=1;
Expand Down
103 changes: 59 additions & 44 deletions pkgs/development/compilers/rust/default.nix
Original file line number Diff line number Diff line change
@@ -1,52 +1,67 @@
{ stdenv, callPackage, recurseIntoAttrs, makeRustPlatform, llvm, fetchurl
{ stdenv, lib, overrideCC
, buildPackages
, newScope, callPackage
, CoreFoundation, Security
, targets ? []
, targetToolchains ? []
, targetPatches ? []
}:
, gcc6
}: rec {
makeRustPlatform = { rustc, cargo, ... }: {
rust = {
inherit rustc cargo;
};

let
rustPlatform = recurseIntoAttrs (makeRustPlatform (callPackage ./bootstrap.nix {}));
version = "1.31.0";
cargoVersion = "1.31.0";
src = fetchurl {
url = "https://static.rust-lang.org/dist/rustc-${version}-src.tar.gz";
sha256 = "01pg2619bwjnhjbphryrbkwaz0lw8cfffm4xlz35znzipb04vmcs";
};
in rec {
rustc = callPackage ./rustc.nix {
inherit stdenv llvm targets targetPatches targetToolchains rustPlatform version src;

patches = [
./patches/net-tcp-disable-tests.patch

# Re-evaluate if this we need to disable this one
#./patches/stdsimd-disable-doctest.patch

# Fails on hydra - not locally; the exact reason is unknown.
# Comments in the test suggest that some non-reproducible environment
# variables such $RANDOM can make it fail.
./patches/disable-test-inherit-env.patch
];

withBundledLLVM = false;

configureFlags = [ "--release-channel=stable" ];
buildRustPackage = callPackage ../../../build-support/rust {
inherit rustc cargo;

# 1. Upstream is not running tests on aarch64:
# see https://github.com/rust-lang/rust/issues/49807#issuecomment-380860567
# So we do the same.
# 2. Tests run out of memory for i686
#doCheck = !stdenv.isAarch64 && !stdenv.isi686;
fetchcargo = buildPackages.callPackage ../../../build-support/rust/fetchcargo.nix {
inherit cargo;
};
};

# Disabled for now; see https://github.com/NixOS/nixpkgs/pull/42348#issuecomment-402115598.
doCheck = false;
rustcSrc = callPackage ./rust-src.nix {
inherit rustc;
};
};

cargo = callPackage ./cargo.nix rec {
version = cargoVersion;
inherit src stdenv CoreFoundation Security;
inherit rustc; # the rustc that will be wrapped by cargo
inherit rustPlatform; # used to build cargo
# This just contains tools for now. But it would conceivably contain
# libraries too, say if we picked some default/recommended versions from
# `cratesIO` to build by Hydra and/or try to prefer/bias in Cargo.lock for
# all vendored Carnix-generated nix.
#
# In the end game, rustc, the rust standard library (`core`, `std`, etc.),
# and cargo would themselves be built with `buildRustCreate` like
# everything else. Tools and `build.rs` and procedural macro dependencies
# would be taken from `buildRustPackages` (and `bootstrapRustPackages` for
# anything provided prebuilt or their build-time dependencies to break
# cycles / purify builds). In this way, nixpkgs would be in control of all
# bootstrapping.
packages = {
prebuilt = callPackage ./bootstrap.nix {};
stable = lib.makeScope newScope (self: let
# Like `buildRustPackages`, but may also contain prebuilt binaries to
# break cycle. Just like `bootstrapTools` for nixpkgs as a whole,
# nothing in the final package set should refer to this.
bootstrapRustPackages = self.buildRustPackages.overrideScope' (_: _:
lib.optionalAttrs (stdenv.buildPlatform == stdenv.hostPlatform)
buildPackages.rust.packages.prebuilt);
bootRustPlatform = makeRustPlatform bootstrapRustPackages;
in {
# Packages suitable for build-time, e.g. `build.rs`-type stuff.
buildRustPackages = buildPackages.rust.packages.stable;
# Analogous to stdenv
rustPlatform = makeRustPlatform self.buildRustPackages;
rustc = self.callPackage ./rustc.nix ({
# Use boot package set to break cycle
rustPlatform = bootRustPlatform;
} // stdenv.lib.optionalAttrs (stdenv.cc.isGNU && stdenv.hostPlatform.isi686) {
stdenv = overrideCC stdenv gcc6; # with gcc-7: undefined reference to `__divmoddi4'
});
cargo = self.callPackage ./cargo.nix ({
# Use boot package set to break cycle
rustPlatform = bootRustPlatform;
inherit CoreFoundation Security;
} // stdenv.lib.optionalAttrs (stdenv.cc.isGNU && stdenv.hostPlatform.isi686) {
stdenv = overrideCC stdenv gcc6; # with gcc-7: undefined reference to `__divmoddi4'
});
});
};
}
Loading