diff options
Diffstat (limited to 'nixpkgs/pkgs/build-support/rust/build-rust-package')
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; +} |