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
11 changes: 5 additions & 6 deletions pkgs/build-support/rust/build-rust-crate/configure-crate.nix
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{ lib, stdenv, echo_colored, noisily, mkRustcDepArgs, mkRustcFeatureArgs }:
{ lib, stdenv, rust, echo_colored, noisily, mkRustcDepArgs, mkRustcFeatureArgs }:
{
build
, buildDependencies
Expand All @@ -17,7 +17,6 @@
, libName
, libPath
, release
, target_os
, verbose
, workspace_member }:
let version_ = lib.splitString "-" crateVersion;
Expand Down Expand Up @@ -124,8 +123,8 @@ in ''
export CARGO_PKG_AUTHORS="${authors}"
export CARGO_PKG_DESCRIPTION="${crateDescription}"

export CARGO_CFG_TARGET_ARCH=${stdenv.hostPlatform.parsed.cpu.name}
export CARGO_CFG_TARGET_OS=${target_os}
export CARGO_CFG_TARGET_ARCH=${rust.toTargetArch stdenv.hostPlatform}
export CARGO_CFG_TARGET_OS=${rust.toTargetOs stdenv.hostPlatform}
export CARGO_CFG_TARGET_FAMILY="unix"
export CARGO_CFG_UNIX=1
export CARGO_CFG_TARGET_ENV="gnu"
Expand All @@ -136,8 +135,8 @@ in ''
export CARGO_MANIFEST_DIR=$(pwd)
export DEBUG="${toString (!release)}"
export OPT_LEVEL="${toString optLevel}"
export TARGET="${stdenv.hostPlatform.config}"
export HOST="${stdenv.hostPlatform.config}"
export TARGET="${rust.toRustTarget stdenv.hostPlatform}"
export HOST="${rust.toRustTarget stdenv.buildPlatform}"
export PROFILE=${if release then "release" else "debug"}
export OUT_DIR=$(pwd)/target/build/${crateName}.out
export CARGO_PKG_VERSION_MAJOR=${lib.elemAt version 0}
Expand Down
10 changes: 2 additions & 8 deletions pkgs/build-support/rust/build-rust-crate/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,6 @@
, cargo, jq }:

let
# This doesn't appear to be officially documented anywhere yet.
# See https://github.com/rust-lang-nursery/rust-forge/issues/101.
target_os = if stdenv.hostPlatform.isDarwin
then "macos"
else stdenv.hostPlatform.parsed.kernel.name;

# Create rustc arguments to link against the given list of dependencies
# and renames.
#
Expand Down Expand Up @@ -52,7 +46,7 @@ let
inherit (import ./log.nix { inherit lib; }) noisily echo_colored;

configureCrate = import ./configure-crate.nix {
inherit lib stdenv echo_colored noisily mkRustcDepArgs mkRustcFeatureArgs;
inherit lib stdenv rust echo_colored noisily mkRustcDepArgs mkRustcFeatureArgs;
};

buildCrate = import ./build-crate.nix {
Expand Down Expand Up @@ -284,7 +278,7 @@ stdenv.mkDerivation (rec {
inherit crateName buildDependencies completeDeps completeBuildDeps crateDescription
crateFeatures crateRenames libName build workspace_member release libPath crateVersion
extraLinkFlags extraRustcOpts
crateAuthors crateHomepage verbose colors target_os;
crateAuthors crateHomepage verbose colors;
};
buildPhase = buildCrate {
inherit crateName dependencies
Expand Down
53 changes: 33 additions & 20 deletions pkgs/build-support/rust/build-rust-crate/test/default.nix
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{ lib
, buildPackages
, buildRustCrate
, callPackage
, releaseTools
Expand All @@ -10,13 +11,14 @@
}:

let
mkCrate = args: let
mkCrate = buildRustCrate: args: let
p = {
crateName = "nixtestcrate";
version = "0.1.0";
authors = [ "Test <test@example.com>" ];
} // args;
in buildRustCrate p;
mkHostCrate = mkCrate buildRustCrate;

mkCargoToml =
{ name, crateVersion ? "0.1.0", path ? "Cargo.toml" }:
Expand Down Expand Up @@ -68,15 +70,15 @@ let
mkLib = name: mkFile name "pub fn test() -> i32 { return 23; }";

mkTest = crateArgs: let
crate = mkCrate (builtins.removeAttrs crateArgs ["expectedTestOutput"]);
crate = mkHostCrate (builtins.removeAttrs crateArgs ["expectedTestOutput"]);
hasTests = crateArgs.buildTests or false;
expectedTestOutputs = crateArgs.expectedTestOutputs or null;
binaries = map (v: ''"${v.name}"'') (crateArgs.crateBin or []);
binaries = map (v: lib.escapeShellArg v.name) (crateArgs.crateBin or []);
isLib = crateArgs ? libName || crateArgs ? libPath;
crateName = crateArgs.crateName or "nixtestcrate";
libName = crateArgs.libName or crateName;

libTestBinary = if !isLib then null else mkCrate {
libTestBinary = if !isLib then null else mkHostCrate {
crateName = "run-test-${crateName}";
dependencies = [ crate ];
src = mkBinExtern "src/main.rs" libName;
Expand All @@ -89,18 +91,27 @@ let
runCommand "run-buildRustCrate-${crateName}-test" {
nativeBuildInputs = [ crate ];
} (if !hasTests then ''
${lib.concatStringsSep "\n" binaries}
${lib.concatMapStringsSep "\n" (binary:
# Can't actually run the binary when cross-compiling
(lib.optionalString (stdenv.hostPlatform != stdenv.buildPlatform) "type ") + binary
) binaries}
${lib.optionalString isLib ''
test -e ${crate}/lib/*.rlib || exit 1
${libTestBinary}/bin/run-test-${crateName}
${lib.optionalString (stdenv.hostPlatform != stdenv.buildPlatform) "test -x "} \
${libTestBinary}/bin/run-test-${crateName}
''}
touch $out
'' else ''
'' else if stdenv.hostPlatform == stdenv.buildPlatform then ''
for file in ${crate}/tests/*; do
$file 2>&1 >> $out
done
set -e
${lib.concatMapStringsSep "\n" (o: "grep '${o}' $out || { echo 'output \"${o}\" not found in:'; cat $out; exit 23; }") expectedTestOutputs}
'' else ''
for file in ${crate}/tests/*; do
test -x "$file"
done
touch "$out"
''
);

Expand All @@ -109,7 +120,7 @@ let

`name` is used as part of the derivation name that performs the checking.

`crateArgs` is passed to `mkCrate` to build the crate with `buildRustCrate`.
`crateArgs` is passed to `mkHostCrate` to build the crate with `buildRustCrate`.

`expectedFiles` contains a list of expected file paths in the output. E.g.
`[ "./bin/my_binary" ]`.
Expand All @@ -124,7 +135,7 @@ let
assert (builtins.isList expectedFiles);

let
crate = mkCrate (builtins.removeAttrs crateArgs ["expectedTestOutput"]);
crate = mkHostCrate (builtins.removeAttrs crateArgs ["expectedTestOutput"]);
crateOutput = if output == null then crate else crate."${output}";
expectedFilesFile = writeTextFile {
name = "expected-files-${name}";
Expand Down Expand Up @@ -188,17 +199,17 @@ let
crateBinRename1 = {
crateBin = [{ name = "my-binary-rename1"; }];
src = mkBinExtern "src/main.rs" "foo_renamed";
dependencies = [ (mkCrate { crateName = "foo"; src = mkLib "src/lib.rs"; }) ];
dependencies = [ (mkHostCrate { crateName = "foo"; src = mkLib "src/lib.rs"; }) ];
crateRenames = { "foo" = "foo_renamed"; };
};
crateBinRename2 = {
crateBin = [{ name = "my-binary-rename2"; }];
src = mkBinExtern "src/main.rs" "foo_renamed";
dependencies = [ (mkCrate { crateName = "foo"; libName = "foolib"; src = mkLib "src/lib.rs"; }) ];
dependencies = [ (mkHostCrate { crateName = "foo"; libName = "foolib"; src = mkLib "src/lib.rs"; }) ];
crateRenames = { "foo" = "foo_renamed"; };
};
crateBinRenameMultiVersion = let
crateWithVersion = version: mkCrate {
crateWithVersion = version: mkHostCrate {
crateName = "my_lib";
inherit version;
src = mkFile "src/lib.rs" ''
Expand Down Expand Up @@ -307,15 +318,15 @@ let
fn main() {}
'';
dependencies = [
(mkCrate {
(mkHostCrate {
crateName = "somerlib";
type = [ "rlib" ];
src = mkLib "src/lib.rs";
})
];
};
buildScriptDeps = let
depCrate = boolVal: mkCrate {
depCrate = buildRustCrate: boolVal: mkCrate buildRustCrate {
crateName = "bar";
src = mkFile "src/lib.rs" ''
pub const baz: bool = ${boolVal};
Expand All @@ -339,8 +350,8 @@ let
'')
];
};
buildDependencies = [ (depCrate "true") ];
dependencies = [ (depCrate "false") ];
buildDependencies = [ (depCrate buildPackages.buildRustCrate "true") ];
dependencies = [ (depCrate buildRustCrate "false") ];
buildTests = true;
expectedTestOutputs = [ "test baz_false ... ok" ];
};
Expand Down Expand Up @@ -373,7 +384,7 @@ let
# Regression test for https://github.com/NixOS/nixpkgs/pull/88054
# Build script output should be rewritten as valid env vars.
buildScriptIncludeDirDeps = let
depCrate = mkCrate {
depCrate = mkHostCrate {
crateName = "bar";
src = symlinkJoin {
name = "build-script-and-include-dir-bar";
Expand Down Expand Up @@ -460,7 +471,7 @@ let
mkdir -p $out/lib
# Note: On darwin (which defaults to clang) we have to add
# `-undefined dynamic_lookup` as otherwise the compilation fails.
cc -shared \
$CC -shared \
${lib.optionalString stdenv.isDarwin "-undefined dynamic_lookup"} \
-o $out/lib/${name}${stdenv.hostPlatform.extensions.sharedLibrary} ${src}
'';
Expand Down Expand Up @@ -609,9 +620,11 @@ let
pkg = brotliCrates.brotli_2_5_0 {};
in runCommand "run-brotli-test-cmd" {
nativeBuildInputs = [ pkg ];
} ''
} (if stdenv.hostPlatform == stdenv.buildPlatform then ''
${pkg}/bin/brotli -c ${pkg}/bin/brotli > /dev/null && touch $out
'';
'' else ''
test -x '${pkg}/bin/brotli' && touch $out
'');
allocNoStdLibTest = let
pkg = brotliCrates.alloc_no_stdlib_1_3_0 {};
in runCommand "run-alloc-no-stdlib-test-cmd" {
Expand Down
15 changes: 13 additions & 2 deletions pkgs/development/compilers/rust/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,23 @@
, llvmPackages_5
, pkgsBuildTarget, pkgsBuildBuild
}: rec {
# https://doc.rust-lang.org/reference/conditional-compilation.html#target_arch
toTargetArch = platform:
if platform.isAarch32 then "arm"
else platform.parsed.cpu.name;

# https://doc.rust-lang.org/reference/conditional-compilation.html#target_os
toTargetOs = platform:
if platform.isDarwin then "macos"
else platform.parsed.kernel.name;

# Target triple. Rust has slightly different naming conventions than we use.
toRustTarget = platform: with platform.parsed; let
cpu_ = {
cpu_ = platform.rustc.arch or {
"armv7a" = "armv7";
"armv7l" = "armv7";
"armv6l" = "arm";
}.${cpu.name} or platform.rustc.arch or cpu.name;
}.${cpu.name} or cpu.name;
in platform.rustc.config
or "${cpu_}-${vendor.name}-${kernel.name}${lib.optionalString (abi.name != "unknown") "-${abi.name}"}";

Expand Down