mirror of
https://github.com/NixOS/nixpkgs.git
synced 2024-11-26 23:52:33 +00:00
rust: Add support for managing target JSON in Nix
This commit is contained in:
parent
6866f26c89
commit
c0df12de5d
|
@ -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
|
attribute, and fail the build if not. It will also will compress the vendor
|
||||||
directory into a tar.gz archive.
|
directory into a tar.gz archive.
|
||||||
|
|
||||||
### Building a crate for a different target
|
### Cross compilation
|
||||||
|
|
||||||
To build your crate with a different cargo `--target` simply specify the `target` attribute:
|
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
|
```nix
|
||||||
pkgs.rustPlatform.buildRustPackage {
|
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
|
### Running package tests
|
||||||
|
|
||||||
When using `buildRustPackage`, the `checkPhase` is enabled by default and runs
|
When using `buildRustPackage`, the `checkPhase` is enabled by default and runs
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
++ [(mkRustcDepArgs dependencies crateRenames)]
|
++ [(mkRustcDepArgs dependencies crateRenames)]
|
||||||
++ [(mkRustcFeatureArgs crateFeatures)]
|
++ [(mkRustcFeatureArgs crateFeatures)]
|
||||||
++ extraRustcOpts
|
++ 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
|
# 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
|
# https://github.com/rust-lang/cargo/commit/4d64eb99a4#diff-7f98585dbf9d30aa100c8318e2c77e79R1021-R1022
|
||||||
++ lib.optional (lib.elem "proc-macro" crateType) "--extern proc_macro"
|
++ lib.optional (lib.elem "proc-macro" crateType) "--extern proc_macro"
|
||||||
|
|
|
@ -135,8 +135,8 @@ in ''
|
||||||
export CARGO_MANIFEST_DIR=$(pwd)
|
export CARGO_MANIFEST_DIR=$(pwd)
|
||||||
export DEBUG="${toString (!release)}"
|
export DEBUG="${toString (!release)}"
|
||||||
export OPT_LEVEL="${toString optLevel}"
|
export OPT_LEVEL="${toString optLevel}"
|
||||||
export TARGET="${rust.toRustTarget stdenv.hostPlatform}"
|
export TARGET="${rust.toRustTargetSpec stdenv.hostPlatform}"
|
||||||
export HOST="${rust.toRustTarget stdenv.buildPlatform}"
|
export HOST="${rust.toRustTargetSpec stdenv.buildPlatform}"
|
||||||
export PROFILE=${if release then "release" else "debug"}
|
export PROFILE=${if release then "release" else "debug"}
|
||||||
export OUT_DIR=$(pwd)/target/build/${crateName}.out
|
export OUT_DIR=$(pwd)/target/build/${crateName}.out
|
||||||
export CARGO_PKG_VERSION_MAJOR=${lib.elemAt version 0}
|
export CARGO_PKG_VERSION_MAJOR=${lib.elemAt version 0}
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
, cargoBuildFlags ? []
|
, cargoBuildFlags ? []
|
||||||
, buildType ? "release"
|
, buildType ? "release"
|
||||||
, meta ? {}
|
, meta ? {}
|
||||||
, target ? rust.toRustTarget stdenv.hostPlatform
|
, target ? rust.toRustTargetSpec stdenv.hostPlatform
|
||||||
, cargoVendorDir ? null
|
, cargoVendorDir ? null
|
||||||
, checkType ? buildType
|
, checkType ? buildType
|
||||||
, depsExtraArgs ? {}
|
, depsExtraArgs ? {}
|
||||||
|
|
|
@ -41,7 +41,7 @@ in rustPlatform.buildRustPackage {
|
||||||
done
|
done
|
||||||
|
|
||||||
export RUST_SYSROOT=$(rustc --print=sysroot)
|
export RUST_SYSROOT=$(rustc --print=sysroot)
|
||||||
export HOST=${rust.toRustTarget stdenv.buildPlatform}
|
host=${rust.toRustTarget stdenv.buildPlatform}
|
||||||
cp -r $RUST_SYSROOT/lib/rustlib/$HOST $out
|
cp -r $RUST_SYSROOT/lib/rustlib/$host $out
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,8 @@
|
||||||
if platform.isDarwin then "macos"
|
if platform.isDarwin then "macos"
|
||||||
else platform.parsed.kernel.name;
|
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
|
toRustTarget = platform: with platform.parsed; let
|
||||||
cpu_ = platform.rustc.arch or {
|
cpu_ = platform.rustc.arch or {
|
||||||
"armv7a" = "armv7";
|
"armv7a" = "armv7";
|
||||||
|
@ -34,6 +35,13 @@
|
||||||
in platform.rustc.config
|
in platform.rustc.config
|
||||||
or "${cpu_}-${vendor.name}-${kernel.name}${lib.optionalString (abi.name != "unknown") "-${abi.name}"}";
|
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
|
# This just contains tools for now. But it would conceivably contain
|
||||||
# libraries too, say if we picked some default/recommended versions from
|
# 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
|
# `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"
|
"--set=build.cargo=${rustPlatform.rust.cargo}/bin/cargo"
|
||||||
"--enable-rpath"
|
"--enable-rpath"
|
||||||
"--enable-vendor"
|
"--enable-vendor"
|
||||||
"--build=${rust.toRustTarget stdenv.buildPlatform}"
|
"--build=${rust.toRustTargetSpec stdenv.buildPlatform}"
|
||||||
"--host=${rust.toRustTarget stdenv.hostPlatform}"
|
"--host=${rust.toRustTargetSpec stdenv.hostPlatform}"
|
||||||
"--target=${rust.toRustTarget stdenv.targetPlatform}"
|
"--target=${rust.toRustTargetSpec stdenv.targetPlatform}"
|
||||||
|
|
||||||
"${setBuild}.cc=${ccForBuild}"
|
"${setBuild}.cc=${ccForBuild}"
|
||||||
"${setHost}.cc=${ccForHost}"
|
"${setHost}.cc=${ccForHost}"
|
||||||
|
|
|
@ -63,7 +63,8 @@ redoxRustPlatform.buildRustPackage rec {
|
||||||
DESTDIR=$out make install
|
DESTDIR=$out make install
|
||||||
'';
|
'';
|
||||||
|
|
||||||
TARGET = buildPackages.rust.toRustTarget stdenvNoCC.targetPlatform;
|
# TODO: should be hostPlatform
|
||||||
|
TARGET = buildPackages.rust.toRustTargetSpec stdenvNoCC.targetPlatform;
|
||||||
|
|
||||||
cargoSha256 = "1fzz7ba3ga57x1cbdrcfrdwwjr70nh4skrpxp4j2gak2c3scj6rz";
|
cargoSha256 = "1fzz7ba3ga57x1cbdrcfrdwwjr70nh4skrpxp4j2gak2c3scj6rz";
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue