From f0fdecfbb45c74bfb6f46017563e7ec941b604e9 Mon Sep 17 00:00:00 2001 From: Ben Wolsieffer Date: Tue, 29 Sep 2020 01:15:06 -0400 Subject: [PATCH 1/2] buildRustCrate: fix target config environment variables on 32-bit ARM --- .../rust/build-rust-crate/configure-crate.nix | 11 +++++------ .../rust/build-rust-crate/default.nix | 10 ++-------- pkgs/development/compilers/rust/default.nix | 15 +++++++++++++-- 3 files changed, 20 insertions(+), 16 deletions(-) diff --git a/pkgs/build-support/rust/build-rust-crate/configure-crate.nix b/pkgs/build-support/rust/build-rust-crate/configure-crate.nix index a95b356646e..18587f7047c 100644 --- a/pkgs/build-support/rust/build-rust-crate/configure-crate.nix +++ b/pkgs/build-support/rust/build-rust-crate/configure-crate.nix @@ -1,4 +1,4 @@ -{ lib, stdenv, echo_colored, noisily, mkRustcDepArgs, mkRustcFeatureArgs }: +{ lib, stdenv, rust, echo_colored, noisily, mkRustcDepArgs, mkRustcFeatureArgs }: { build , buildDependencies @@ -17,7 +17,6 @@ , libName , libPath , release -, target_os , verbose , workspace_member }: let version_ = lib.splitString "-" crateVersion; @@ -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" @@ -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} diff --git a/pkgs/build-support/rust/build-rust-crate/default.nix b/pkgs/build-support/rust/build-rust-crate/default.nix index 0e06f5f89ab..9d98e085178 100644 --- a/pkgs/build-support/rust/build-rust-crate/default.nix +++ b/pkgs/build-support/rust/build-rust-crate/default.nix @@ -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. # @@ -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 { @@ -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 diff --git a/pkgs/development/compilers/rust/default.nix b/pkgs/development/compilers/rust/default.nix index d08b63dd643..f304187c25b 100644 --- a/pkgs/development/compilers/rust/default.nix +++ b/pkgs/development/compilers/rust/default.nix @@ -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}"}"; From 91bc6128b9af6812fd8696d7dee2f6746a9131fa Mon Sep 17 00:00:00 2001 From: Ben Wolsieffer Date: Tue, 29 Sep 2020 14:33:49 -0400 Subject: [PATCH 2/2] buildRustCrateTests: support cross-compilation --- .../rust/build-rust-crate/test/default.nix | 53 ++++++++++++------- 1 file changed, 33 insertions(+), 20 deletions(-) diff --git a/pkgs/build-support/rust/build-rust-crate/test/default.nix b/pkgs/build-support/rust/build-rust-crate/test/default.nix index 24ddc11459e..f6cd54c4ee3 100644 --- a/pkgs/build-support/rust/build-rust-crate/test/default.nix +++ b/pkgs/build-support/rust/build-rust-crate/test/default.nix @@ -1,4 +1,5 @@ { lib +, buildPackages , buildRustCrate , callPackage , releaseTools @@ -10,13 +11,14 @@ }: let - mkCrate = args: let + mkCrate = buildRustCrate: args: let p = { crateName = "nixtestcrate"; version = "0.1.0"; authors = [ "Test " ]; } // args; in buildRustCrate p; + mkHostCrate = mkCrate buildRustCrate; mkCargoToml = { name, crateVersion ? "0.1.0", path ? "Cargo.toml" }: @@ -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; @@ -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" '' ); @@ -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" ]`. @@ -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}"; @@ -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" '' @@ -307,7 +318,7 @@ let fn main() {} ''; dependencies = [ - (mkCrate { + (mkHostCrate { crateName = "somerlib"; type = [ "rlib" ]; src = mkLib "src/lib.rs"; @@ -315,7 +326,7 @@ let ]; }; buildScriptDeps = let - depCrate = boolVal: mkCrate { + depCrate = buildRustCrate: boolVal: mkCrate buildRustCrate { crateName = "bar"; src = mkFile "src/lib.rs" '' pub const baz: bool = ${boolVal}; @@ -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" ]; }; @@ -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"; @@ -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} ''; @@ -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" {