about summary refs log tree commit diff
path: root/nixpkgs/pkgs/build-support/rust/build-rust-package
diff options
context:
space:
mode:
Diffstat (limited to 'nixpkgs/pkgs/build-support/rust/build-rust-package')
-rw-r--r--nixpkgs/pkgs/build-support/rust/build-rust-package/default.nix175
-rw-r--r--nixpkgs/pkgs/build-support/rust/build-rust-package/patch-registry-deps/pkg-config8
-rw-r--r--nixpkgs/pkgs/build-support/rust/build-rust-package/sysroot/default.nix35
3 files changed, 218 insertions, 0 deletions
diff --git a/nixpkgs/pkgs/build-support/rust/build-rust-package/default.nix b/nixpkgs/pkgs/build-support/rust/build-rust-package/default.nix
new file mode 100644
index 000000000000..847e3580575b
--- /dev/null
+++ b/nixpkgs/pkgs/build-support/rust/build-rust-package/default.nix
@@ -0,0 +1,175 @@
+{ lib
+, importCargoLock
+, fetchCargoTarball
+, stdenv
+, callPackage
+, cargoBuildHook
+, cargoCheckHook
+, cargoInstallHook
+, cargoNextestHook
+, cargoSetupHook
+, cargo
+, cargo-auditable
+, buildPackages
+, rustc
+, libiconv
+, windows
+}:
+
+let
+  buildRustPackage =
+    { name ? "${args.pname}-${args.version}"
+
+      # Name for the vendored dependencies tarball
+    , cargoDepsName ? name
+
+    , src ? null
+    , srcs ? null
+    , preUnpack ? null
+    , unpackPhase ? null
+    , postUnpack ? null
+    , cargoPatches ? []
+    , patches ? []
+    , sourceRoot ? null
+    , logLevel ? ""
+    , buildInputs ? []
+    , nativeBuildInputs ? []
+    , cargoUpdateHook ? ""
+    , cargoDepsHook ? ""
+    , buildType ? "release"
+    , meta ? {}
+    , cargoLock ? null
+    , cargoVendorDir ? null
+    , checkType ? buildType
+    , buildNoDefaultFeatures ? false
+    , checkNoDefaultFeatures ? buildNoDefaultFeatures
+    , buildFeatures ? [ ]
+    , checkFeatures ? buildFeatures
+    , useNextest ? false
+    # Enable except on aarch64 pkgsStatic, where we use lld for reasons
+    , auditable ? !cargo-auditable.meta.broken && !(stdenv.hostPlatform.isStatic && stdenv.hostPlatform.isAarch64 && !stdenv.hostPlatform.isDarwin)
+
+    , depsExtraArgs ? {}
+
+    # 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).
+    # Otherwise, everything from the tarball would've been built/tested.
+    , buildAndTestSubdir ? null
+    , ... } @ args:
+
+    assert cargoVendorDir == null && cargoLock == null
+        -> !(args ? cargoSha256 && args.cargoSha256 != null) && !(args ? cargoHash && args.cargoHash != null)
+        -> throw "cargoSha256, cargoHash, cargoVendorDir, or cargoLock must be set";
+
+    let
+
+      cargoDeps =
+        if cargoVendorDir != null then null
+        else if cargoLock != null then importCargoLock cargoLock
+        else fetchCargoTarball ({
+          inherit src srcs sourceRoot preUnpack unpackPhase postUnpack cargoUpdateHook;
+          name = cargoDepsName;
+          patches = cargoPatches;
+        } // lib.optionalAttrs (args ? cargoHash) {
+          hash = args.cargoHash;
+        } // lib.optionalAttrs (args ? cargoSha256) {
+          sha256 = args.cargoSha256;
+        } // depsExtraArgs);
+
+      target = stdenv.hostPlatform.rust.rustcTargetSpec;
+      targetIsJSON = lib.hasSuffix ".json" target;
+      useSysroot = targetIsJSON && !__internal_dontAddSysroot;
+
+      sysroot = callPackage ./sysroot { } {
+        inherit target;
+        shortTarget = stdenv.hostPlatform.rust.cargoShortTarget;
+        RUSTFLAGS = args.RUSTFLAGS or "";
+        originalCargoToml = src + /Cargo.toml; # profile info is later extracted
+      };
+
+    in
+
+    # Tests don't currently work for `no_std`, and all custom sysroots are currently built without `std`.
+    # See https://os.phil-opp.com/testing/ for more information.
+    assert useSysroot -> !(args.doCheck or true);
+
+    stdenv.mkDerivation ((removeAttrs args [ "depsExtraArgs" "cargoUpdateHook" "cargoLock" ]) // lib.optionalAttrs useSysroot {
+      RUSTFLAGS = "--sysroot ${sysroot} " + (args.RUSTFLAGS or "");
+    } // {
+      inherit buildAndTestSubdir cargoDeps;
+
+      cargoBuildType = buildType;
+
+      cargoCheckType = checkType;
+
+      cargoBuildNoDefaultFeatures = buildNoDefaultFeatures;
+
+      cargoCheckNoDefaultFeatures = checkNoDefaultFeatures;
+
+      cargoBuildFeatures = buildFeatures;
+
+      cargoCheckFeatures = checkFeatures;
+
+      patchRegistryDeps = ./patch-registry-deps;
+
+      nativeBuildInputs = nativeBuildInputs ++ lib.optionals auditable [
+        (buildPackages.cargo-auditable-cargo-wrapper.override {
+          inherit cargo cargo-auditable;
+        })
+      ] ++ [
+        cargoBuildHook
+        (if useNextest then cargoNextestHook else cargoCheckHook)
+        cargoInstallHook
+        cargoSetupHook
+        rustc
+      ];
+
+      buildInputs = buildInputs
+        ++ lib.optionals stdenv.hostPlatform.isDarwin [ libiconv ]
+        ++ lib.optionals stdenv.hostPlatform.isMinGW [ windows.pthreads ];
+
+      patches = cargoPatches ++ patches;
+
+      PKG_CONFIG_ALLOW_CROSS =
+        if stdenv.buildPlatform != stdenv.hostPlatform then 1 else 0;
+
+      postUnpack = ''
+        eval "$cargoDepsHook"
+
+        export RUST_LOG=${logLevel}
+      '' + (args.postUnpack or "");
+
+      configurePhase = args.configurePhase or ''
+        runHook preConfigure
+        runHook postConfigure
+      '';
+
+      doCheck = args.doCheck or true;
+
+      strictDeps = true;
+
+      meta = {
+        # default to Rust's platforms
+        platforms = rustc.meta.platforms ++ [
+          # Platforms without host tools from
+          # https://doc.rust-lang.org/nightly/rustc/platform-support.html
+          "armv7a-darwin"
+          "armv5tel-linux" "armv7a-linux" "m68k-linux" "mips-linux"
+          "mips64-linux" "mipsel-linux" "mips64el-linux" "riscv32-linux"
+          "armv6l-netbsd" "mipsel-netbsd" "riscv64-netbsd"
+          "x86_64-redox"
+          "wasm32-wasi"
+        ];
+        badPlatforms = [
+          # Rust is currently unable to target the n32 ABI
+          lib.systems.inspect.patterns.isMips64n32
+        ];
+      } // meta;
+    }) // {
+      overrideRustAttrs = f: buildRustPackage (args // (f args));
+    };
+in buildRustPackage
diff --git a/nixpkgs/pkgs/build-support/rust/build-rust-package/patch-registry-deps/pkg-config b/nixpkgs/pkgs/build-support/rust/build-rust-package/patch-registry-deps/pkg-config
new file mode 100644
index 000000000000..fbb094304587
--- /dev/null
+++ b/nixpkgs/pkgs/build-support/rust/build-rust-package/patch-registry-deps/pkg-config
@@ -0,0 +1,8 @@
+for dir in pkg-config-*; do
+    [ -d "$dir" ] || continue
+
+    echo "Patching pkg-config registry dep"
+
+    substituteInPlace "$dir/src/lib.rs" \
+        --replace '"/usr"' '"'"$NIX_STORE"'/"'
+done
diff --git a/nixpkgs/pkgs/build-support/rust/build-rust-package/sysroot/default.nix b/nixpkgs/pkgs/build-support/rust/build-rust-package/sysroot/default.nix
new file mode 100644
index 000000000000..bb95b7bdc35c
--- /dev/null
+++ b/nixpkgs/pkgs/build-support/rust/build-rust-package/sysroot/default.nix
@@ -0,0 +1,35 @@
+{ lib, stdenv, rustPlatform, buildPackages }:
+
+{ shortTarget, originalCargoToml, target, RUSTFLAGS }:
+
+let
+  cargoSrc = import ../../sysroot/src.nix {
+    inherit lib stdenv rustPlatform buildPackages originalCargoToml;
+  };
+in rustPlatform.buildRustPackage {
+  inherit target RUSTFLAGS;
+
+  name = "custom-sysroot";
+  src =  cargoSrc;
+
+  RUSTC_BOOTSTRAP = 1;
+  __internal_dontAddSysroot = true;
+  cargoSha256 = "sha256-zgkwevitxsu1C4OgGTsqNSc0gDxaNXYK1WPbfER48d0=";
+
+  doCheck = false;
+
+  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)
+    host=${stdenv.buildPlatform.rust.rustcTarget}
+    cp -r $RUST_SYSROOT/lib/rustlib/$host $out
+  '';
+
+  # allows support for cross-compilation
+  meta.platforms = lib.platforms.all;
+}