Skip to content
Merged
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
8 changes: 7 additions & 1 deletion doc/languages-frameworks/rust.section.md
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ sometimes it may be necessary to disable this so the tests run consecutively.
```nix
rustPlatform.buildRustPackage {
/* ... */
cargoParallelTestThreads = false;
dontUseCargoParallelTests = true;
Copy link
Member

Choose a reason for hiding this comment

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

Should we add that to the changelog?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I agree. There was another API change (removal of the target argument of buildRustPackage). I can do a PR for the release notes after this one that summarizes all the changes.

}
```

Expand Down Expand Up @@ -293,6 +293,12 @@ attributes can also be used:
variable `buildAndTestSubdir` can be used to build a crate in a
Cargo workspace. Additional maturin flags can be passed through
`maturinBuildFlags`.
* `cargoCheckHook`: run tests using Cargo. Additional flags can be
passed to Cargo using `checkFlags` and `checkFlagsArray`. By
default, tests are run in parallel. This can be disabled by setting
`dontUseCargoParallelTests`.
* `cargoInstallHook`: install binaries and static/shared libraries
that were built using `cargoBuildHook`.

### Examples

Expand Down
2 changes: 1 addition & 1 deletion pkgs/applications/networking/browsers/castor/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ rustPlatform.buildRustPackage rec {
postInstall = "make PREFIX=$out copy-data";

# Sometimes tests fail when run in parallel
cargoParallelTestThreads = false;
dontUseCargoParallelThreads = true;

meta = with lib; {
description = "A graphical client for plain-text protocols written in Rust with GTK. It currently supports the Gemini, Gopher and Finger protocols";
Expand Down
67 changes: 13 additions & 54 deletions pkgs/build-support/rust/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
, lib
, buildPackages
, cacert
, cargo
, cargoBuildHook
, cargoCheckHook
, cargoInstallHook
, cargoSetupHook
, fetchCargoTarball
, runCommandNoCC
Expand Down Expand Up @@ -35,13 +36,11 @@
, nativeBuildInputs ? []
, cargoUpdateHook ? ""
, cargoDepsHook ? ""
, cargoBuildFlags ? []
, buildType ? "release"
, meta ? {}
, cargoVendorDir ? null
, checkType ? buildType
, depsExtraArgs ? {}
, cargoParallelTestThreads ? true

# Toggles whether a custom sysroot is created when the target is a .json file.
, __internal_dontAddSysroot ? false
Expand Down Expand Up @@ -87,9 +86,6 @@ let
originalCargoToml = src + /Cargo.toml; # profile info is later extracted
};

releaseDir = "target/${shortTarget}/${buildType}";
tmpDir = "${releaseDir}-tmp";

in

# Tests don't currently work for `no_std`, and all custom sysroots are currently built without `std`.
Expand All @@ -99,16 +95,21 @@ assert useSysroot -> !(args.doCheck or true);
stdenv.mkDerivation ((removeAttrs args ["depsExtraArgs"]) // lib.optionalAttrs useSysroot {
RUSTFLAGS = "--sysroot ${sysroot} " + (args.RUSTFLAGS or "");
} // {
inherit buildAndTestSubdir cargoDeps releaseDir tmpDir;

cargoBuildFlags = lib.concatStringsSep " " cargoBuildFlags;
inherit buildAndTestSubdir cargoDeps;

cargoBuildType = "--${buildType}";
cargoBuildType = buildType;

patchRegistryDeps = ./patch-registry-deps;

nativeBuildInputs = nativeBuildInputs ++
[ cacert git cargo cargoBuildHook cargoSetupHook rustc ];
nativeBuildInputs = nativeBuildInputs ++ [
cacert
git
cargoBuildHook
cargoCheckHook
cargoInstallHook
cargoSetupHook
rustc
];

buildInputs = buildInputs ++ lib.optional stdenv.hostPlatform.isMinGW windows.pthreads;

Expand All @@ -128,52 +129,10 @@ stdenv.mkDerivation ((removeAttrs args ["depsExtraArgs"]) // lib.optionalAttrs u
runHook postConfigure
'';

checkPhase = args.checkPhase or (let
argstr = "${lib.optionalString (checkType == "release") "--release"} --target ${target} --frozen";
threads = if cargoParallelTestThreads then "$NIX_BUILD_CORES" else "1";
in ''
${lib.optionalString (buildAndTestSubdir != null) "pushd ${buildAndTestSubdir}"}
runHook preCheck
echo "Running cargo test ${argstr} -- ''${checkFlags} ''${checkFlagsArray+''${checkFlagsArray[@]}}"
cargo test -j $NIX_BUILD_CORES ${argstr} -- --test-threads=${threads} ''${checkFlags} ''${checkFlagsArray+"''${checkFlagsArray[@]}"}
runHook postCheck
${lib.optionalString (buildAndTestSubdir != null) "popd"}
'');

doCheck = args.doCheck or true;

strictDeps = true;

installPhase = args.installPhase or ''
runHook preInstall

# This needs to be done after postBuild: packages like `cargo` do a pushd/popd in
# the pre/postBuild-hooks that need to be taken into account before gathering
# all binaries to install.
mkdir -p $tmpDir
cp -r $releaseDir/* $tmpDir/
bins=$(find $tmpDir \
-maxdepth 1 \
-type f \
-executable ! \( -regex ".*\.\(so.[0-9.]+\|so\|a\|dylib\)" \))

# rename the output dir to a architecture independent one
mapfile -t targets < <(find "$NIX_BUILD_TOP" -type d | grep '${tmpDir}$')
for target in "''${targets[@]}"; do
rm -rf "$target/../../${buildType}"
ln -srf "$target" "$target/../../"
done
mkdir -p $out/bin $out/lib

xargs -r cp -t $out/bin <<< $bins
find $tmpDir \
-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
'';

passthru = { inherit cargoDeps; } // (args.passthru or {});

meta = {
Expand Down
8 changes: 5 additions & 3 deletions pkgs/build-support/rust/hooks/cargo-build-hook.sh
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
declare -a cargoBuildFlags

cargoBuildHook() {
echo "Executing cargoBuildHook"

Expand All @@ -17,16 +19,16 @@ cargoBuildHook() {
cargo build -j $NIX_BUILD_CORES \
--target @rustTargetPlatformSpec@ \
--frozen \
${cargoBuildType} \
--${cargoBuildType} \
${cargoBuildFlags}
)

runHook postBuild

if [ ! -z "${buildAndTestSubdir-}" ]; then
popd
fi

runHook postBuild

echo "Finished cargoBuildHook"
}

Expand Down
41 changes: 41 additions & 0 deletions pkgs/build-support/rust/hooks/cargo-check-hook.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
declare -a checkFlags

cargoCheckHook() {
echo "Executing cargoCheckHook"

runHook preCheck

if [[ -n "${buildAndTestSubdir-}" ]]; then
pushd "${buildAndTestSubdir}"
fi

if [[ -z ${dontUseCargoParallelTests-} ]]; then
threads=$NIX_BUILD_CORES
else
threads=1
fi

argstr="--${cargoBuildType} --target @rustTargetPlatformSpec@ --frozen";
Copy link
Contributor

Choose a reason for hiding this comment

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

Seems like you changed:

  • ${lib.optionalString (checkType == "release") "--release"} -> --${cargoBuildType}

But there are crates out there that on checkType, like cargo-deb. There may be others too.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is an oversight. We should pass checkType as cargoCheckType and then use that in the hook.

Copy link
Member

Choose a reason for hiding this comment

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

I don't know how many packages are out there using that, but I added this to work around issues with packages where cargo test only works with debug, so this shouldn't be dropped entirely IMHO.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I agree, it's an oversight. I'll do a PR that fixes this.

Copy link
Contributor Author

Choose a reason for hiding this comment

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


(
set -x
cargo test \
-j $NIX_BUILD_CORES \
${argstr} -- \
--test-threads=${threads} \
${checkFlags} \
${checkFlagsArray+"${checkFlagsArray[@]}"}
)

if [[ -n "${buildAndTestSubdir-}" ]]; then
popd
fi

echo "Finished cargoCheckHook"

runHook postCheck
}

if [ -z "${checkPhase-}" ]; then
checkPhase=cargoCheckHook
fi
49 changes: 49 additions & 0 deletions pkgs/build-support/rust/hooks/cargo-install-hook.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
cargoInstallPostBuildHook() {
echo "Executing cargoInstallPostBuildHook"

releaseDir=target/@shortTarget@/$cargoBuildType
tmpDir="${releaseDir}-tmp";

mkdir -p $tmpDir
cp -r ${releaseDir}/* $tmpDir/
bins=$(find $tmpDir \
-maxdepth 1 \
-type f \
-executable ! \( -regex ".*\.\(so.[0-9.]+\|so\|a\|dylib\)" \))

echo "Finished cargoInstallPostBuildHook"
}

cargoInstallHook() {
echo "Executing cargoInstallHook"

runHook preInstall

# rename the output dir to a architecture independent one

releaseDir=target/@shortTarget@/$cargoBuildType
tmpDir="${releaseDir}-tmp";

mapfile -t targets < <(find "$NIX_BUILD_TOP" -type d | grep "${tmpDir}$")
for target in "${targets[@]}"; do
rm -rf "$target/../../${cargoBuildType}"
ln -srf "$target" "$target/../../"
done
mkdir -p $out/bin $out/lib

xargs -r cp -t $out/bin <<< $bins
find $tmpDir \
-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

echo "Finished cargoInstallHook"
}


if [ -z "${installPhase-}" ]; then
installPhase=cargoInstallHook
postBuildHooks+=(cargoInstallPostBuildHook)
fi
18 changes: 18 additions & 0 deletions pkgs/build-support/rust/hooks/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,24 @@ in {
};
} ./cargo-build-hook.sh) {};

cargoCheckHook = callPackage ({ }:
makeSetupHook {
name = "cargo-check-hook.sh";
deps = [ cargo ];
substitutions = {
inherit rustTargetPlatformSpec;
};
} ./cargo-check-hook.sh) {};

cargoInstallHook = callPackage ({ }:
makeSetupHook {
name = "cargo-install-hook.sh";
deps = [ ];
substitutions = {
inherit shortTarget;
};
} ./cargo-install-hook.sh) {};

cargoSetupHook = callPackage ({ }:
makeSetupHook {
name = "cargo-setup-hook.sh";
Expand Down
5 changes: 3 additions & 2 deletions pkgs/development/compilers/rust/make-rust-platform.nix
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ rec {
};

buildRustPackage = callPackage ../../../build-support/rust {
inherit rustc cargo cargoBuildHook cargoSetupHook fetchCargoTarball;
inherit cargoBuildHook cargoCheckHook cargoInstallHook cargoSetupHook
fetchCargoTarball rustc;
};

rustcSrc = callPackage ./rust-src.nix {
Expand All @@ -26,5 +27,5 @@ rec {
# Hooks
inherit (callPackage ../../../build-support/rust/hooks {
inherit cargo;
}) cargoBuildHook cargoSetupHook maturinBuildHook;
}) cargoBuildHook cargoCheckHook cargoInstallHook cargoSetupHook maturinBuildHook;
}
4 changes: 2 additions & 2 deletions pkgs/development/compilers/rust/rls/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
, openssh, openssl, pkg-config, cmake, zlib, curl, libiconv
, CoreFoundation, Security }:

rustPlatform.buildRustPackage {
rustPlatform.buildRustPackage rec {
pname = "rls";
inherit (rustPlatform.rust.rustc) src version;

Expand All @@ -14,7 +14,7 @@ rustPlatform.buildRustPackage {

preBuild = ''
# client tests are flaky
rm tests/client.rs
rm ${buildAndTestSubdir}/tests/client.rs
'';

# a nightly compiler is required unless we use this cheat code.
Expand Down
2 changes: 1 addition & 1 deletion pkgs/development/interpreters/wasmer/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ rustPlatform.buildRustPackage rec {
# using the [makefile](https://github.com/wasmerio/wasmer/blob/master/Makefile).
# Enabling cranelift as this used to be the old default. At least one backend is
# needed for the run subcommand to work.
cargoBuildFlags = [ "--features 'backend-cranelift'" ];
cargoBuildFlags = [ "--features" "backend-cranelift" ];

LIBCLANG_PATH = "${llvmPackages.libclang}/lib";

Expand Down
20 changes: 7 additions & 13 deletions pkgs/development/tools/diesel-cli/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,9 @@ assert lib.assertMsg (sqliteSupport == true || postgresqlSupport == true || mysq

let
inherit (lib) optional optionals optionalString;
features = ''
${optionalString sqliteSupport "sqlite"} \
${optionalString postgresqlSupport "postgres"} \
${optionalString mysqlSupport "mysql"} \
'';
features = optional sqliteSupport "sqlite"
++ optional postgresqlSupport "postgres"
++ optional mysqlSupport "mysql";
in

rustPlatform.buildRustPackage rec {
Expand All @@ -35,24 +33,20 @@ rustPlatform.buildRustPackage rec {
./allow-warnings.patch
];

cargoBuildFlags = [ "--no-default-features --features \"${features}\"" ];
cargoBuildFlags = [ "--no-default-features" "--features" "${lib.concatStringsSep "," features}" ];
cargoPatches = [ ./cargo-lock.patch ];
cargoSha256 = "1vbb7r0dpmq8363i040bkhf279pz51c59kcq9v5qr34hs49ish8g";

nativeBuildInputs = [ pkg-config ];

buildInputs = [ openssl ]
++ optional stdenv.isDarwin Security
++ optional (stdenv.isDarwin && mysqlSupport) libiconv
++ optional sqliteSupport sqlite
++ optional postgresqlSupport postgresql
++ optionals mysqlSupport [ mysql zlib ];

# We must `cd diesel_cli`, we cannot use `--package diesel_cli` to build
# because --features fails to apply to the package:
# https://github.com/rust-lang/cargo/issues/5015
# https://github.com/rust-lang/cargo/issues/4753
preBuild = "cd diesel_cli";
postBuild = "cd ..";
buildAndTestSubdir = "diesel_cli";

checkPhase = optionalString sqliteSupport ''
(cd diesel_cli && cargo check --features sqlite)
Expand All @@ -65,7 +59,7 @@ rustPlatform.buildRustPackage rec {

# Fix the build with mariadb, which otherwise shows "error adding symbols:
# DSO missing from command line" errors for libz and libssl.
NIX_LDFLAGS = lib.optionalString mysqlSupport "-lz -lssl -lcrypto";
NIX_LDFLAGS = optionalString mysqlSupport "-lz -lssl -lcrypto";

meta = with lib; {
description = "Database tool for working with Rust projects that use Diesel";
Expand Down
2 changes: 1 addition & 1 deletion pkgs/development/tools/the-way/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ rustPlatform.buildRustPackage rec {

cargoSha256 = "sha256-jTZso61Lyt6jprBxBAhvchgOsgM9y1qBleTxUx1jCnE=";
checkFlagsArray = lib.optionals stdenv.isDarwin [ "--skip=copy" ];
cargoParallelTestThreads = false;
dontUseCargoParallelTests = true;

postInstall = ''
$out/bin/the-way config default tmp.toml
Expand Down