summary refs log tree commit diff
path: root/pkgs/build-support/rust
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/rust
parent38abb8f734ed93d37712c5e95671b139a33464f7 (diff)
downloadnixpkgs-f8ea4e0c3dabd9551066bc8e74d225d90f8bf4f6.tar
nixpkgs-f8ea4e0c3dabd9551066bc8e74d225d90f8bf4f6.tar.gz
nixpkgs-f8ea4e0c3dabd9551066bc8e74d225d90f8bf4f6.tar.bz2
nixpkgs-f8ea4e0c3dabd9551066bc8e74d225d90f8bf4f6.tar.lz
nixpkgs-f8ea4e0c3dabd9551066bc8e74d225d90f8bf4f6.tar.xz
nixpkgs-f8ea4e0c3dabd9551066bc8e74d225d90f8bf4f6.tar.zst
nixpkgs-f8ea4e0c3dabd9551066bc8e74d225d90f8bf4f6.zip
makeRustPlatform: support custom targets
Diffstat (limited to 'pkgs/build-support/rust')
-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 f6177ce198d..10488f4d372 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 00000000000..3b576f6657f
--- /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 00000000000..10ad94e4c54
--- /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 00000000000..3bb86e9ad9a
--- /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
+  '';
+}