aboutsummaryrefslogtreecommitdiff
path: root/pkgs/build-support
diff options
context:
space:
mode:
authorAaron Janse <aaron@ajanse.me>2020-10-08 14:32:49 -0700
committerAaron Janse <aaron@ajanse.me>2020-10-08 14:32:49 -0700
commitf8ea4e0c3dabd9551066bc8e74d225d90f8bf4f6 (patch)
tree88f8a52cd98450fac424c7a894050e1ec4ab78d0 /pkgs/build-support
parent38abb8f734ed93d37712c5e95671b139a33464f7 (diff)
makeRustPlatform: support custom targets
Diffstat (limited to 'pkgs/build-support')
-rw-r--r--pkgs/build-support/rust/default.nix35
-rw-r--r--pkgs/build-support/rust/sysroot/Cargo.lock20
-rw-r--r--pkgs/build-support/rust/sysroot/cargo.py44
-rw-r--r--pkgs/build-support/rust/sysroot/default.nix45
4 files changed, 137 insertions, 7 deletions
diff --git a/pkgs/build-support/rust/default.nix b/pkgs/build-support/rust/default.nix
index f6177ce198da..10488f4d3726 100644
--- a/pkgs/build-support/rust/default.nix
+++ b/pkgs/build-support/rust/default.nix
@@ -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;
+
+ # 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;
- rustTarget = if target == null then rust.toRustTarget stdenv.hostPlatform 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}"}
diff --git a/pkgs/build-support/rust/sysroot/Cargo.lock b/pkgs/build-support/rust/sysroot/Cargo.lock
new file mode 100644
index 000000000000..3b576f6657f2
--- /dev/null
+++ b/pkgs/build-support/rust/sysroot/Cargo.lock
@@ -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"]
diff --git a/pkgs/build-support/rust/sysroot/cargo.py b/pkgs/build-support/rust/sysroot/cargo.py
new file mode 100644
index 000000000000..10ad94e4c542
--- /dev/null
+++ b/pkgs/build-support/rust/sysroot/cargo.py
@@ -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)
diff --git a/pkgs/build-support/rust/sysroot/default.nix b/pkgs/build-support/rust/sysroot/default.nix
new file mode 100644
index 000000000000..3bb86e9ad9a9
--- /dev/null
+++ b/pkgs/build-support/rust/sysroot/default.nix
@@ -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
+ '';
+}