diff --git a/pkgs/build-support/rust/build-rust-package/default.nix b/pkgs/build-support/rust/build-rust-package/default.nix index 909ec8f4c05f8..bc459ef7550f6 100644 --- a/pkgs/build-support/rust/build-rust-package/default.nix +++ b/pkgs/build-support/rust/build-rust-package/default.nix @@ -18,206 +18,213 @@ windows, }: -{ - 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, - cargoRoot ? null, - logLevel ? "", - buildInputs ? [ ], - nativeBuildInputs ? [ ], - cargoUpdateHook ? "", - cargoDepsHook ? "", - buildType ? "release", - meta ? { }, - useFetchCargoVendor ? false, - cargoDeps ? null, - cargoLock ? null, - cargoVendorDir ? null, - checkType ? buildType, - buildNoDefaultFeatures ? false, - checkNoDefaultFeatures ? buildNoDefaultFeatures, - buildFeatures ? [ ], - checkFeatures ? buildFeatures, - useNextest ? false, - auditable ? !cargo-auditable.meta.broken, - - 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 && cargoDeps == null && cargoLock == null - -> - !(args ? cargoSha256 && args.cargoSha256 != null) && !(args ? cargoHash && args.cargoHash != null) - -> throw "cargoHash, cargoVendorDir, cargoDeps, or cargoLock must be set"; - +# These things may be useful to put inside lib. let + # inherit the listed names of an attrset into an new attrset, but only if the name actually exists + takeAttrs = names: lib.filterAttrs (n: _: lib.elem n names); + + # essentially lib.extends, but without doing `prev //` with the result + transforms = + transformation: rattrs: # <-- inputs + final: + transformation final (rattrs final); +in - cargoDeps' = - if cargoVendorDir != null then - null - else if cargoDeps != null then - cargoDeps - else if cargoLock != null then - importCargoLock cargoLock - else if useFetchCargoVendor then - fetchCargoVendor ( - { - inherit - src - srcs - sourceRoot - cargoRoot - preUnpack - unpackPhase - postUnpack - ; - name = cargoDepsName; - patches = cargoPatches; - hash = args.cargoHash; - } - // depsExtraArgs - ) - else - fetchCargoTarball ( - { - inherit - src - srcs - sourceRoot - cargoRoot - preUnpack - unpackPhase - postUnpack - cargoUpdateHook - ; - name = cargoDepsName; - patches = cargoPatches; - } - // lib.optionalAttrs (args ? cargoHash) { - hash = args.cargoHash; - } - // lib.optionalAttrs (args ? cargoSha256) { - sha256 = lib.warn "cargoSha256 is deprecated. Please use cargoHash with SRI hash instead" args.cargoSha256; - } - // depsExtraArgs - ); +let 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 - }; + # outputs what attrs should be passed to mkDerivation given the attrs supplied to buildRustPackage + transformAttrs = + finalAttrs: inputAttrs: + # the following attrset contains the default values that will be passed to mkDerivation, unless the user sets the given value + { + cargoDepsName = finalAttrs.name or "${finalAttrs.pname}-${finalAttrs.version}"; + + cargoPatches = [ ]; + + useFetchCargoVendor = false; + + cargoDeps = + if (finalAttrs ? cargoVendorDir && finalAttrs.cargoVendorDir != null) then + null + else if + (finalAttrs ? passthru && finalAttrs.passthru ? cargoLock && finalAttrs.passthru.cargoLock != null) + then + importCargoLock finalAttrs.passthru.cargoLock + else if finalAttrs.useFetchCargoVendor then + fetchCargoVendor ( + (takeAttrs [ + "src" + "srcs" + "sourceRoot" + "cargoRoot" + "preUnpack" + "unpackPhase" + "postUnpack" + ] finalAttrs) + // { + name = finalAttrs.cargoDepsName; + patches = finalAttrs.cargoPatches; + hash = finalAttrs.cargoHash; + } + // finalAttrs.passthru.depsExtraArgs or { } + ) + else if + ( + (finalAttrs ? cargoHash && finalAttrs.cargoHash != null) + || (finalAttrs ? cargoSha256 && finalAttrs.cargoSha256 != null) + ) + then + fetchCargoTarball ( + (takeAttrs [ + "src" + "srcs" + "sourceRoot" + "cargoRoot" + "preUnpack" + "unpackPhase" + "postUnpack" + "cargoUpdateHook" # TODO: maybe remove in the future + ] finalAttrs) + // { + name = finalAttrs.cargoDepsName; + patches = finalAttrs.cargoPatches; + } + // lib.optionalAttrs (finalAttrs ? cargoHash) { + hash = finalAttrs.cargoHash; + } + // lib.optionalAttrs (finalAttrs ? cargoSha256) { + sha256 = lib.warn "cargoSha256 is deprecated. Please use cargoHash with SRI hash instead" finalAttrs.cargoSha256; + } + // finalAttrs.passthru.depsExtraArgs or { } + ) + else + throw "cargoHash, cargoVendorDir, or cargoLock must be set"; + + # 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; + # TODO: ^^^^^^ shouldn't this become prefixed? (NOTE: this name is used by the maturin hook and cargo-tauri hook too) + # TODO: this doesn't *need* to be here, since it's only every used by hooks + # it's may be helpful to keep it here for documentation purposes + # but maybe it would be better to move the documentation into the hooks? + + # TODO: should we disable having the prefixed attrs in inputAttrs? + # the current behaviour would shadow the unprefixed values, which seems fine + cargoBuildType = inputAttrs.buildType or "release"; + cargoBuildFeatures = inputAttrs.buildFeatures or [ ]; + cargoBuildNoDefaultFeatures = inputAttrs.buildNoDefaultFeatures or false; + + cargoCheckType = finalAttrs.cargoBuildType; + cargoCheckFeatures = finalAttrs.cargoBuildFeatures; + cargoCheckNoDefaultFeatures = finalAttrs.cargoBuildNoDefaultFeatures; + + auditable = !cargo-auditable.meta.broken; + + useNextest = false; + + PKG_CONFIG_ALLOW_CROSS = if stdenv.buildPlatform != stdenv.hostPlatform then 1 else 0; + + doCheck = true; + + strictDeps = true; + + # Toggles whether a custom sysroot is created when the target is a .json file. + __internal_dontAddSysroot = false; + + # Will be appended to the RUSTFLAGS environment variable. Should not really be overridden by users. + # This is done in order to support both RUSTFLAGS and env.RUSTFLAGS + # TODO: should this be uppercase? this is supposed to just be a shell variable + # TODO: better names? __extraRustFlags? or should this just be interpolated straight into postUnpack? + EXTRA_RUSTFLAGS = + let + sysroot = + # 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 !finalAttrs.doCheck; + callPackage ./sysroot { } { + inherit target; + shortTarget = stdenv.hostPlatform.rust.cargoShortTarget; + RUSTFLAGS = finalAttrs.RUSTFLAGS or ""; # TODO: what about env.*? + originalCargoToml = finalAttrs.src + /Cargo.toml; # profile info is later extracted + }; + in + toString ( + lib.optionals (stdenv.hostPlatform.isDarwin && finalAttrs.cargoBuildType == "debug") [ + "-C split-debuginfo=packed" + ] + ++ lib.optionals (targetIsJSON && !finalAttrs.__internal_dontAddSysroot) [ "--sysroot ${sysroot}" ] + ); + + } + # this is the attrset specified by the user, with some exceptional names removed + # these are usually moved to be accessible under another name + // lib.removeAttrs inputAttrs [ + # these get get prefixed, e.g.: buildType -> cargoBuildType + "buildType" + "buildFeatures" + "buildNoDefaultFeatures" + "checkType" + "checkFeatures" + "checkNoDefaultFeatures" + # these get moved into passthru.* instead + "cargoLock" + "depsExtraArgs" + ] + # the following attrset is overlayed on top of the inputs, extending it with extra/modified values + // { + nativeBuildInputs = + inputAttrs.nativeBuildInputs or [ ] + ++ lib.optionals finalAttrs.auditable [ + (buildPackages.cargo-auditable-cargo-wrapper.override { + inherit cargo cargo-auditable; + }) + ] + ++ [ + cargoBuildHook + (if finalAttrs.useNextest then cargoNextestHook else cargoCheckHook) + cargoInstallHook + cargoSetupHook + rustc + ]; + + buildInputs = + inputAttrs.buildInputs or [ ] + ++ lib.optionals stdenv.hostPlatform.isDarwin [ libiconv ] + ++ lib.optionals stdenv.hostPlatform.isMinGW [ windows.pthreads ]; + + patches = finalAttrs.cargoPatches ++ inputAttrs.patches or [ ]; + + postUnpack = '' + eval "$cargoDepsHook" -in + export RUST_LOG="$logLevel" + # TODO: ^^^^ I moved this here as a shell substitution, but this should probably be somewhere else -# 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" - "cargoDeps" - "cargoLock" - ]) - // lib.optionalAttrs useSysroot { - RUSTFLAGS = "--sysroot ${sysroot} " + (args.RUSTFLAGS or ""); - } - // lib.optionalAttrs (stdenv.hostPlatform.isDarwin && buildType == "debug") { - RUSTFLAGS = - "-C split-debuginfo=packed " - + lib.optionalString useSysroot "--sysroot ${sysroot} " - + (args.RUSTFLAGS or ""); - } - // { - cargoDeps = cargoDeps'; - inherit buildAndTestSubdir; - - cargoBuildType = buildType; - - cargoCheckType = checkType; - - cargoBuildNoDefaultFeatures = buildNoDefaultFeatures; - - cargoCheckNoDefaultFeatures = checkNoDefaultFeatures; - - cargoBuildFeatures = buildFeatures; - - cargoCheckFeatures = checkFeatures; - - 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 RUSTFLAGS+="$EXTRA_RUSTFLAGS" - export RUST_LOG=${logLevel} - '' - + (args.postUnpack or ""); + ${inputAttrs.postUnpack or ""} + ''; - configurePhase = - args.configurePhase or '' + configurePhase = '' runHook preConfigure runHook postConfigure ''; - doCheck = args.doCheck or true; - - strictDeps = true; + passthru = takeAttrs [ "cargoLock" "depsExtraArgs" ] inputAttrs // inputAttrs.passthru or { }; - meta = meta // { - badPlatforms = meta.badPlatforms or [ ] ++ rustc.badTargetPlatforms; - # default to Rust's platforms - platforms = lib.intersectLists meta.platforms or lib.platforms.all rustc.targetPlatforms; + meta = inputAttrs.meta or { } // { + badPlatforms = inputAttrs.meta.badPlatforms or [ ] ++ rustc.badTargetPlatforms; + # default to Rust's platforms + platforms = lib.intersectLists (inputAttrs.meta.platforms or lib.platforms.all + ) rustc.targetPlatforms; + }; }; - } -) + +in + +attrsOrFn: stdenv.mkDerivation (transforms transformAttrs (lib.toFunction attrsOrFn)) diff --git a/pkgs/by-name/ca/cargo-tauri/package.nix b/pkgs/by-name/ca/cargo-tauri/package.nix index e28826dc4bb6f..2e05819723675 100644 --- a/pkgs/by-name/ca/cargo-tauri/package.nix +++ b/pkgs/by-name/ca/cargo-tauri/package.nix @@ -11,14 +11,14 @@ webkitgtk_4_1, }: -rustPlatform.buildRustPackage rec { +rustPlatform.buildRustPackage (finalAttrs: { pname = "tauri"; version = "2.2.1"; src = fetchFromGitHub { owner = "tauri-apps"; repo = "tauri"; - tag = "tauri-v${version}"; + tag = "tauri-v${finalAttrs.version}"; hash = "sha256-v9o+oqs6OZWhHv+PExo9juzTt7W80YOTkynzwvxpHGM="; }; @@ -35,14 +35,13 @@ rustPlatform.buildRustPackage rec { ]; cargoBuildFlags = [ "--package tauri-cli" ]; - cargoTestFlags = cargoBuildFlags; passthru = { # See ./doc/hooks/tauri.section.md - hook = callPackage ./hook.nix { }; + hook = callPackage ./hook.nix { cargo-tauri = finalAttrs.finalPackage; }; tests = { - hook = callPackage ./test-app.nix { }; + hook = callPackage ./test-app.nix { cargo-tauri = finalAttrs.finalPackage; }; }; updateScript = nix-update-script { @@ -56,7 +55,7 @@ rustPlatform.buildRustPackage rec { meta = { description = "Build smaller, faster, and more secure desktop applications with a web frontend"; homepage = "https://tauri.app/"; - changelog = "https://github.com/tauri-apps/tauri/releases/tag/tauri-v${version}"; + changelog = "https://github.com/tauri-apps/tauri/releases/tag/tauri-v${finalAttrs.version}"; license = with lib.licenses; [ asl20 # or mit @@ -68,4 +67,4 @@ rustPlatform.buildRustPackage rec { ]; mainProgram = "cargo-tauri"; }; -} +}) diff --git a/pkgs/by-name/ca/cargo-tauri_1/package.nix b/pkgs/by-name/ca/cargo-tauri_1/package.nix index 3ec0a69ddcbd6..517687bcbbd71 100644 --- a/pkgs/by-name/ca/cargo-tauri_1/package.nix +++ b/pkgs/by-name/ca/cargo-tauri_1/package.nix @@ -1,10 +1,8 @@ { lib, stdenv, - rustPlatform, fetchFromGitHub, cargo-tauri, - cargo-tauri_1, gtk3, libsoup_2_4, openssl, @@ -26,14 +24,12 @@ cargo-tauri.overrideAttrs ( # https://discourse.nixos.org/t/difficulty-using-buildrustpackage-with-a-src-containing-multiple-cargo-workspaces/10202 sourceRoot = "${newAttrs.src.name}/tooling/cli"; - cargoDeps = rustPlatform.fetchCargoTarball { - inherit (newAttrs) - pname - version - src - sourceRoot - ; - hash = "sha256-OIXC4kwGIemIL8KaqK5SUDZZrOX3PX0w3h9bNiM/pCw="; + useFetchCargoVendor = false; + cargoHash = "sha256-OIXC4kwGIemIL8KaqK5SUDZZrOX3PX0w3h9bNiM/pCw="; + + passthru = { + inherit (oldAttrs.passthru) hook; + cargoLock = null; # we could have just ommitted it, but this is more explicit }; buildInputs = @@ -43,20 +39,5 @@ cargo-tauri.overrideAttrs ( libsoup_2_4 webkitgtk_4_0 ]; - - passthru = { - hook = cargo-tauri.hook.override { cargo-tauri = cargo-tauri_1; }; - }; - - meta = { - inherit (oldAttrs.meta) - description - homepage - changelog - license - maintainers - mainProgram - ; - }; } ) diff --git a/pkgs/by-name/ui/uiua/package.nix b/pkgs/by-name/ui/uiua/package.nix index 87a0bbccf4b11..683b116b2ab37 100644 --- a/pkgs/by-name/ui/uiua/package.nix +++ b/pkgs/by-name/ui/uiua/package.nix @@ -30,76 +30,74 @@ let .${uiua_versionType}; in -# buildRustPackage doesn't support finalAttrs, so we can't use finalPackage for the tests -lib.fix ( - uiua: - rustPlatform.buildRustPackage rec { - pname = "uiua"; - inherit (versionInfo) version cargoHash; +rustPlatform.buildRustPackage (finalAttrs: { + pname = "uiua"; + inherit (versionInfo) version cargoHash; - src = fetchFromGitHub { - owner = "uiua-lang"; - repo = "uiua"; - inherit (versionInfo) tag hash; - }; + src = fetchFromGitHub { + owner = "uiua-lang"; + repo = "uiua"; + inherit (versionInfo) tag hash; + }; - nativeBuildInputs = - lib.optionals (webcamSupport || stdenv.hostPlatform.isDarwin) [ rustPlatform.bindgenHook ] - ++ lib.optionals audioSupport [ pkg-config ]; + nativeBuildInputs = + lib.optionals (webcamSupport || stdenv.hostPlatform.isDarwin) [ rustPlatform.bindgenHook ] + ++ lib.optionals audioSupport [ pkg-config ]; - buildInputs = - [ libffi ] # we force dynamic linking our own libffi below - ++ lib.optionals (audioSupport && stdenv.hostPlatform.isLinux) [ alsa-lib ]; + buildInputs = + [ libffi ] # we force dynamic linking our own libffi below + ++ lib.optionals (audioSupport && stdenv.hostPlatform.isLinux) [ alsa-lib ]; - buildFeatures = - [ "libffi/system" ] # force libffi to be linked dynamically instead of rebuilding it - ++ lib.optional audioSupport "audio" - ++ lib.optional webcamSupport "webcam" - ++ lib.optional windowSupport "window"; + buildFeatures = + [ "libffi/system" ] # force libffi to be linked dynamically instead of rebuilding it + ++ lib.optional audioSupport "audio" + ++ lib.optional webcamSupport "webcam" + ++ lib.optional windowSupport "window"; - postFixup = - let - runtimeDependencies = lib.optionals windowSupport [ - libGL - libxkbcommon - wayland - xorg.libX11 - xorg.libXcursor - xorg.libXi - xorg.libXrandr - ]; - in - lib.optionalString (runtimeDependencies != [ ] && stdenv.hostPlatform.isLinux) '' - patchelf --add-rpath ${lib.makeLibraryPath runtimeDependencies} $out/bin/uiua - ''; - - nativeInstallCheckInputs = [ versionCheckHook ]; - versionCheckProgramArg = "--version"; - doInstallCheck = true; - - passthru.updateScript = versionInfo.updateScript; - passthru.tests.run = runCommand "uiua-test-run" { nativeBuildInputs = [ uiua ]; } '' - uiua init - diff -U3 --color=auto <(uiua run main.ua) <(echo '"Hello, World!"') - touch $out + postFixup = + let + runtimeDependencies = lib.optionals windowSupport [ + libGL + libxkbcommon + wayland + xorg.libX11 + xorg.libXcursor + xorg.libXi + xorg.libXrandr + ]; + in + lib.optionalString (runtimeDependencies != [ ] && stdenv.hostPlatform.isLinux) '' + patchelf --add-rpath ${lib.makeLibraryPath runtimeDependencies} $out/bin/uiua ''; - meta = { - changelog = "https://github.com/uiua-lang/uiua/blob/${src.rev}/changelog.md"; - description = "Stack-oriented array programming language with a focus on simplicity, beauty, and tacit code"; - longDescription = '' - Uiua combines the stack-oriented and array-oriented paradigms in a single - language. Combining these already terse paradigms results in code with a very - high information density and little syntactic noise. + nativeInstallCheckInputs = [ versionCheckHook ]; + versionCheckProgramArg = "--version"; + doInstallCheck = true; + + passthru.updateScript = versionInfo.updateScript; + passthru.tests.run = + runCommand "uiua-test-run" { nativeBuildInputs = [ finalAttrs.finalPackage ]; } + '' + uiua init + diff -U3 --color=auto <(uiua run main.ua) <(echo '"Hello, World!"') + touch $out ''; - homepage = "https://www.uiua.org/"; - license = lib.licenses.mit; - mainProgram = "uiua"; - maintainers = with lib.maintainers; [ - cafkafk - tomasajt - defelo - ]; - }; - } -) + + meta = { + changelog = "https://github.com/uiua-lang/uiua/blob/${finalAttrs.src.rev}/changelog.md"; + description = "Stack-oriented array programming language with a focus on simplicity, beauty, and tacit code"; + longDescription = '' + Uiua combines the stack-oriented and array-oriented paradigms in a single + language. Combining these already terse paradigms results in code with a very + high information density and little syntactic noise. + ''; + homepage = "https://www.uiua.org/"; + license = lib.licenses.mit; + mainProgram = "uiua"; + maintainers = with lib.maintainers; [ + cafkafk + tomasajt + defelo + ]; + }; +})