diff options
author | Aaron Janse <aaron@ajanse.me> | 2020-10-08 14:32:49 -0700 |
---|---|---|
committer | Aaron Janse <aaron@ajanse.me> | 2020-10-08 14:32:49 -0700 |
commit | f8ea4e0c3dabd9551066bc8e74d225d90f8bf4f6 (patch) | |
tree | 88f8a52cd98450fac424c7a894050e1ec4ab78d0 /pkgs/build-support | |
parent | 38abb8f734ed93d37712c5e95671b139a33464f7 (diff) |
makeRustPlatform: support custom targets
Diffstat (limited to 'pkgs/build-support')
-rw-r--r-- | pkgs/build-support/rust/default.nix | 35 | ||||
-rw-r--r-- | pkgs/build-support/rust/sysroot/Cargo.lock | 20 | ||||
-rw-r--r-- | pkgs/build-support/rust/sysroot/cargo.py | 44 | ||||
-rw-r--r-- | pkgs/build-support/rust/sysroot/default.nix | 45 |
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 + ''; +} |