makeRustPlatform: support custom targets
This commit is contained in:
parent
38abb8f734
commit
f8ea4e0c3d
4 changed files with 137 additions and 7 deletions
|
@ -4,6 +4,10 @@
|
|||
, cargo
|
||||
, diffutils
|
||||
, fetchCargoTarball
|
||||
, runCommandNoCC
|
||||
, rustPlatform
|
||||
, callPackage
|
||||
, remarshal
|
||||
, git
|
||||
, rust
|
||||
, rustc
|
||||
|
@ -26,12 +30,15 @@
|
|||
, cargoBuildFlags ? []
|
||||
, buildType ? "release"
|
||||
, meta ? {}
|
||||
, target ? null
|
||||
, target ? rust.toRustTarget stdenv.hostPlatform
|
||||
, cargoVendorDir ? null
|
||||
, checkType ? buildType
|
||||
, depsExtraArgs ? {}
|
||||
, cargoParallelTestThreads ? true
|
||||
|
||||
# Toggles whether a custom sysroot is created when the target is a .json file.
|
||||
, __internal_dontAddSysroot ? false
|
||||
|
||||
# Needed to `pushd`/`popd` into a subdir of a tarball if this subdir
|
||||
# contains a Cargo.toml, but isn't part of a workspace (which is e.g. the
|
||||
# case for `rustfmt`/etc from the `rust-sources).
|
||||
|
@ -68,14 +75,26 @@ let
|
|||
else ''
|
||||
cargoDepsCopy="$sourceRoot/${cargoVendorDir}"
|
||||
'';
|
||||
|
||||
targetIsJSON = stdenv.lib.hasSuffix ".json" target;
|
||||
|
||||
rustTarget = if target == null then rust.toRustTarget stdenv.hostPlatform else target;
|
||||
# see https://github.com/rust-lang/cargo/blob/964a16a28e234a3d397b2a7031d4ab4a428b1391/src/cargo/core/compiler/compile_kind.rs#L151-L168
|
||||
# the "${}" is needed to transform the path into a /nix/store path before baseNameOf
|
||||
shortTarget = if targetIsJSON then
|
||||
(stdenv.lib.removeSuffix ".json" (builtins.baseNameOf "${target}"))
|
||||
else target;
|
||||
|
||||
sysroot = (callPackage ./sysroot {}) {
|
||||
inherit target shortTarget;
|
||||
RUSTFLAGS = args.RUSTFLAGS or "";
|
||||
originalCargoToml = src + /Cargo.toml; # profile info is later extracted
|
||||
};
|
||||
|
||||
ccForBuild="${buildPackages.stdenv.cc}/bin/${buildPackages.stdenv.cc.targetPrefix}cc";
|
||||
cxxForBuild="${buildPackages.stdenv.cc}/bin/${buildPackages.stdenv.cc.targetPrefix}c++";
|
||||
ccForHost="${stdenv.cc}/bin/${stdenv.cc.targetPrefix}cc";
|
||||
cxxForHost="${stdenv.cc}/bin/${stdenv.cc.targetPrefix}c++";
|
||||
releaseDir = "target/${rustTarget}/${buildType}";
|
||||
releaseDir = "target/${shortTarget}/${buildType}";
|
||||
tmpDir = "${releaseDir}-tmp";
|
||||
|
||||
# Specify the stdenv's `diff` by abspath to ensure that the user's build
|
||||
|
@ -115,7 +134,7 @@ stdenv.mkDerivation ((removeAttrs args ["depsExtraArgs"]) // {
|
|||
[target."${rust.toRustTarget stdenv.buildPlatform}"]
|
||||
"linker" = "${ccForBuild}"
|
||||
${stdenv.lib.optionalString (stdenv.buildPlatform.config != stdenv.hostPlatform.config) ''
|
||||
[target."${rustTarget}"]
|
||||
[target."${shortTarget}"]
|
||||
"linker" = "${ccForHost}"
|
||||
${# https://github.com/rust-lang/rust/issues/46651#issuecomment-433611633
|
||||
stdenv.lib.optionalString (stdenv.hostPlatform.isMusl && stdenv.hostPlatform.isAarch64) ''
|
||||
|
@ -183,9 +202,11 @@ stdenv.mkDerivation ((removeAttrs args ["depsExtraArgs"]) // {
|
|||
"CXX_${rust.toRustTarget stdenv.buildPlatform}"="${cxxForBuild}" \
|
||||
"CC_${rust.toRustTarget stdenv.hostPlatform}"="${ccForHost}" \
|
||||
"CXX_${rust.toRustTarget stdenv.hostPlatform}"="${cxxForHost}" \
|
||||
cargo build -j $NIX_BUILD_CORES \
|
||||
${stdenv.lib.optionalString
|
||||
(targetIsJSON && !__internal_dontAddSysroot) "RUSTFLAGS=\"--sysroot ${sysroot} $RUSTFLAGS\" "
|
||||
}cargo build -j $NIX_BUILD_CORES \
|
||||
${stdenv.lib.optionalString (buildType == "release") "--release"} \
|
||||
--target ${rustTarget} \
|
||||
--target ${target} \
|
||||
--frozen ${concatStringsSep " " cargoBuildFlags}
|
||||
)
|
||||
|
||||
|
@ -205,7 +226,7 @@ stdenv.mkDerivation ((removeAttrs args ["depsExtraArgs"]) // {
|
|||
'';
|
||||
|
||||
checkPhase = args.checkPhase or (let
|
||||
argstr = "${stdenv.lib.optionalString (checkType == "release") "--release"} --target ${rustTarget} --frozen";
|
||||
argstr = "${stdenv.lib.optionalString (checkType == "release") "--release"} --target ${target} --frozen";
|
||||
threads = if cargoParallelTestThreads then "$NIX_BUILD_CORES" else "1";
|
||||
in ''
|
||||
${stdenv.lib.optionalString (buildAndTestSubdir != null) "pushd ${buildAndTestSubdir}"}
|
||||
|
|
20
pkgs/build-support/rust/sysroot/Cargo.lock
generated
Normal file
20
pkgs/build-support/rust/sysroot/Cargo.lock
generated
Normal file
|
@ -0,0 +1,20 @@
|
|||
[[package]]
|
||||
name = "alloc"
|
||||
version = "0.0.0"
|
||||
dependencies = ["compiler_builtins", "core"]
|
||||
|
||||
[[package]]
|
||||
name = "compiler_builtins"
|
||||
version = "0.1.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7bc4ac2c824d2bfc612cba57708198547e9a26943af0632aff033e0693074d5c"
|
||||
dependencies = ["rustc-std-workspace-core"]
|
||||
|
||||
[[package]]
|
||||
name = "core"
|
||||
version = "0.0.0"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-std-workspace-core"
|
||||
version = "1.99.0"
|
||||
dependencies = ["core"]
|
44
pkgs/build-support/rust/sysroot/cargo.py
Normal file
44
pkgs/build-support/rust/sysroot/cargo.py
Normal file
|
@ -0,0 +1,44 @@
|
|||
import os
|
||||
import toml
|
||||
|
||||
rust_src = os.environ['RUSTC_SRC']
|
||||
orig_cargo = os.environ['ORIG_CARGO']
|
||||
|
||||
base = {
|
||||
'package': {
|
||||
'name': 'alloc',
|
||||
'version': '0.0.0',
|
||||
'authors': ['The Rust Project Developers'],
|
||||
'edition': '2018',
|
||||
},
|
||||
'dependencies': {
|
||||
'compiler_builtins': {
|
||||
'version': '0.1.0',
|
||||
'features': ['rustc-dep-of-std', 'mem'],
|
||||
},
|
||||
'core': {
|
||||
'path': os.path.join(rust_src, 'libcore'),
|
||||
},
|
||||
},
|
||||
'lib': {
|
||||
'name': 'alloc',
|
||||
'path': os.path.join(rust_src, 'liballoc/lib.rs'),
|
||||
},
|
||||
'patch': {
|
||||
'crates-io': {
|
||||
'rustc-std-workspace-core': {
|
||||
'path': os.path.join(rust_src, 'tools/rustc-std-workspace-core'),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
with open(orig_cargo, 'r') as f:
|
||||
src = toml.loads(f.read())
|
||||
if 'profile' in src:
|
||||
base['profile'] = src['profile']
|
||||
|
||||
out = toml.dumps(base)
|
||||
|
||||
with open('Cargo.toml', 'x') as f:
|
||||
f.write(out)
|
45
pkgs/build-support/rust/sysroot/default.nix
Normal file
45
pkgs/build-support/rust/sysroot/default.nix
Normal file
|
@ -0,0 +1,45 @@
|
|||
{ stdenv, rust, rustPlatform, buildPackages }:
|
||||
|
||||
{ shortTarget, originalCargoToml, target, RUSTFLAGS }:
|
||||
|
||||
let rustSrc = stdenv.mkDerivation {
|
||||
name = "rust-src";
|
||||
src = rustPlatform.rust.rustc.src;
|
||||
preferLocalBuild = true;
|
||||
phases = [ "unpackPhase" "installPhase" ];
|
||||
installPhase = "cp -r src $out";
|
||||
};
|
||||
cargoSrc = stdenv.mkDerivation {
|
||||
name = "cargo-src";
|
||||
preferLocalBuild = true;
|
||||
phases = [ "installPhase" ];
|
||||
installPhase = ''
|
||||
RUSTC_SRC=${rustSrc} ORIG_CARGO=${originalCargoToml} \
|
||||
${buildPackages.python3.withPackages (ps: with ps; [ toml ])}/bin/python3 ${./cargo.py}
|
||||
mkdir -p $out
|
||||
cp Cargo.toml $out/Cargo.toml
|
||||
cp ${./Cargo.lock} $out/Cargo.lock
|
||||
'';
|
||||
};
|
||||
in rustPlatform.buildRustPackage {
|
||||
inherit target RUSTFLAGS;
|
||||
|
||||
name = "custom-sysroot";
|
||||
src = cargoSrc;
|
||||
|
||||
RUSTC_BOOTSTRAP = 1;
|
||||
__internal_dontAddSysroot = true;
|
||||
cargoSha256 = "1snkfsx3jb1p5izwlfwkgp8hxhgpa35nmx939sp5730vf9whqqwg";
|
||||
|
||||
installPhase = ''
|
||||
export LIBS_DIR=$out/lib/rustlib/${shortTarget}/lib
|
||||
mkdir -p $LIBS_DIR
|
||||
for f in target/${shortTarget}/release/deps/*.{rlib,rmeta}; do
|
||||
cp $f $LIBS_DIR
|
||||
done
|
||||
|
||||
export RUST_SYSROOT=$(rustc --print=sysroot)
|
||||
export HOST=${rust.toRustTarget stdenv.buildPlatform}
|
||||
cp -r $RUST_SYSROOT/lib/rustlib/$HOST $out
|
||||
'';
|
||||
}
|
Loading…
Reference in a new issue