rust: Add support for managing target JSON in Nix

wip/yesman
John Ericson 4 years ago
parent 6866f26c89
commit c0df12de5d
  1. 55
      doc/languages-frameworks/rust.section.md
  2. 2
      pkgs/build-support/rust/build-rust-crate/build-crate.nix
  3. 4
      pkgs/build-support/rust/build-rust-crate/configure-crate.nix
  4. 2
      pkgs/build-support/rust/default.nix
  5. 4
      pkgs/build-support/rust/sysroot/default.nix
  6. 10
      pkgs/development/compilers/rust/default.nix
  7. 6
      pkgs/development/compilers/rust/rustc.nix
  8. 3
      pkgs/development/libraries/relibc/default.nix

@ -63,9 +63,52 @@ The fetcher will verify that the `Cargo.lock` file is in sync with the `src`
attribute, and fail the build if not. It will also will compress the vendor
directory into a tar.gz archive.
### Building a crate for a different target
To build your crate with a different cargo `--target` simply specify the `target` attribute:
### Cross compilation
By default, Rust packages are compiled for the host platform, just like any
other package is. The `--target` passed to rust tools is computed from this.
By default, it takes the `stdenv.hostPlatform.config` and replaces components
where they are known to differ. But there are ways to customize the argument:
- To choose a different target by name, define
`stdenv.hostPlatform.rustc.arch.config` as that name (a string), and that
name will be used instead.
For example:
```nix
import <nixpkgs> {
crossSystem = (import <nixpkgs/lib>).systems.examples.armhf-embedded // {
rustc.arch.config = "thumbv7em-none-eabi";
};
}
```
will result in:
```shell
--target thumbv7em-none-eabi
```
- To pass a completely custom target, define
`stdenv.hostPlatform.rustc.arch.config` with its name, and
`stdenv.hostPlatform.rustc.arch.custom` with the value. The value will be
serialized to JSON in a file called
`${stdenv.hostPlatform.rustc.arch.config}.json`, and the path of that file
will be used instead.
For example:
```nix
import <nixpkgs> {
crossSystem = (import <nixpkgs/lib>).systems.examples.armhf-embedded // {
rustc.arch.config = "thumb-crazy";
rustc.arch.custom = { foo = ""; bar = ""; };
};
}
will result in:
```shell
--target /nix/store/asdfasdfsadf-thumb-crazy.json # contains {"foo":"","bar":""}
```
Finally, as an ad-hoc escape hatch, a computed target (string or JSON file
path) can be passed directly to `buildRustPackage`:
```nix
pkgs.rustPlatform.buildRustPackage {
@ -74,6 +117,12 @@ pkgs.rustPlatform.buildRustPackage {
}
```
This is useful to avoid rebuilding Rust tools, since they are actually target
agnostic and don't need to be rebuilt. But in the future, we should always
build the Rust tools and standard library crates separately so there is no
reason not to take the `stdenv.hostPlatform.rustc`-modifying approach, and the
ad-hoc escape hatch to `buildRustPackage` can be removed.
### Running package tests
When using `buildRustPackage`, the `checkPhase` is enabled by default and runs

@ -15,7 +15,7 @@
++ [(mkRustcDepArgs dependencies crateRenames)]
++ [(mkRustcFeatureArgs crateFeatures)]
++ extraRustcOpts
++ lib.optional (stdenv.hostPlatform != stdenv.buildPlatform) "--target ${rust.toRustTarget stdenv.hostPlatform} -C linker=${stdenv.hostPlatform.config}-gcc"
++ lib.optional (stdenv.hostPlatform != stdenv.buildPlatform) "--target ${rust.toRustTargetSpec stdenv.hostPlatform} -C linker=${stdenv.hostPlatform.config}-gcc"
# since rustc 1.42 the "proc_macro" crate is part of the default crate prelude
# https://github.com/rust-lang/cargo/commit/4d64eb99a4#diff-7f98585dbf9d30aa100c8318e2c77e79R1021-R1022
++ lib.optional (lib.elem "proc-macro" crateType) "--extern proc_macro"

@ -135,8 +135,8 @@ in ''
export CARGO_MANIFEST_DIR=$(pwd)
export DEBUG="${toString (!release)}"
export OPT_LEVEL="${toString optLevel}"
export TARGET="${rust.toRustTarget stdenv.hostPlatform}"
export HOST="${rust.toRustTarget stdenv.buildPlatform}"
export TARGET="${rust.toRustTargetSpec stdenv.hostPlatform}"
export HOST="${rust.toRustTargetSpec 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}

@ -30,7 +30,7 @@
, cargoBuildFlags ? []
, buildType ? "release"
, meta ? {}
, target ? rust.toRustTarget stdenv.hostPlatform
, target ? rust.toRustTargetSpec stdenv.hostPlatform
, cargoVendorDir ? null
, checkType ? buildType
, depsExtraArgs ? {}

@ -41,7 +41,7 @@ in rustPlatform.buildRustPackage {
done
export RUST_SYSROOT=$(rustc --print=sysroot)
export HOST=${rust.toRustTarget stdenv.buildPlatform}
cp -r $RUST_SYSROOT/lib/rustlib/$HOST $out
host=${rust.toRustTarget stdenv.buildPlatform}
cp -r $RUST_SYSROOT/lib/rustlib/$host $out
'';
}

@ -24,7 +24,8 @@
if platform.isDarwin then "macos"
else platform.parsed.kernel.name;
# Target triple. Rust has slightly different naming conventions than we use.
# Returns the name of the rust target, even if it is custom. Adjustments are
# because rust has slightly different naming conventions than we do.
toRustTarget = platform: with platform.parsed; let
cpu_ = platform.rustc.arch or {
"armv7a" = "armv7";
@ -34,6 +35,13 @@
in platform.rustc.config
or "${cpu_}-${vendor.name}-${kernel.name}${lib.optionalString (abi.name != "unknown") "-${abi.name}"}";
# Returns the name of the rust target if it is standard, or the json file
# containing the custom target spec.
toRustTargetSpec = platform:
if (platform.rustc.arch or {}) ? custom
then builtins.toFile (platform.rustc.config + ".json") (builtins.toJSON platform.rustc.arch.custom)
else toRustTarget platform;
# 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

@ -70,9 +70,9 @@ in stdenv.mkDerivation rec {
"--set=build.cargo=${rustPlatform.rust.cargo}/bin/cargo"
"--enable-rpath"
"--enable-vendor"
"--build=${rust.toRustTarget stdenv.buildPlatform}"
"--host=${rust.toRustTarget stdenv.hostPlatform}"
"--target=${rust.toRustTarget stdenv.targetPlatform}"
"--build=${rust.toRustTargetSpec stdenv.buildPlatform}"
"--host=${rust.toRustTargetSpec stdenv.hostPlatform}"
"--target=${rust.toRustTargetSpec stdenv.targetPlatform}"
"${setBuild}.cc=${ccForBuild}"
"${setHost}.cc=${ccForHost}"

@ -63,7 +63,8 @@ redoxRustPlatform.buildRustPackage rec {
DESTDIR=$out make install
'';
TARGET = buildPackages.rust.toRustTarget stdenvNoCC.targetPlatform;
# TODO: should be hostPlatform
TARGET = buildPackages.rust.toRustTargetSpec stdenvNoCC.targetPlatform;
cargoSha256 = "1fzz7ba3ga57x1cbdrcfrdwwjr70nh4skrpxp4j2gak2c3scj6rz";

Loading…
Cancel
Save