From 9fe204b887c7ea30a2d3aea9a31b700f69f3bd38 Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Mon, 9 Dec 2024 16:39:17 +0100 Subject: [PATCH] feat: switch to `nixfmt` https://github.com/NixOS/rfcs/pull/166 Signed-off-by: Roman Volosatovs --- checks/default.nix | 79 +- examples/rust-complex/flake.nix | 3 +- examples/rust-hello-multibin/flake.nix | 3 +- examples/rust-hello/flake.nix | 3 +- examples/rust-lib/flake.nix | 3 +- examples/rust-workspace/flake.nix | 3 +- flake.nix | 56 +- lib/default.nix | 43 +- lib/extendDerivations.nix | 44 +- lib/mkFlake.nix | 236 +++--- lib/rust/crateBins.nix | 188 ++--- lib/rust/default.nix | 123 ++-- lib/rust/defaultPkgsFor.nix | 191 ++--- lib/rust/mkAttrs.nix | 975 +++++++++++++------------ lib/rust/mkChecks.nix | 11 +- lib/rust/mkFlake.nix | 373 +++++----- lib/rust/mkOverlay.nix | 9 +- lib/rust/mkPackages.nix | 11 +- templates/default.nix | 3 +- templates/rust/flake.nix | 5 +- 20 files changed, 1235 insertions(+), 1127 deletions(-) diff --git a/checks/default.nix b/checks/default.nix index 31519345..d229d0cc 100644 --- a/checks/default.nix +++ b/checks/default.nix @@ -6,8 +6,10 @@ }: with flake-utils.lib.system; with nixlib.lib; -with self.lib; let - assertRustOutputs = flake: name: +with self.lib; +let + assertRustOutputs = + flake: name: assert name != "default"; assert name != "rust"; assert flake ? checks; @@ -18,14 +20,14 @@ with self.lib; let assert flake.overlays ? default; assert flake.overlays ? fenix; assert flake.overlays ? rust-overlay; - system: - assert flake.checks.${system} ? clippy; - assert flake.checks.${system} ? fmt; - assert flake.checks.${system} ? nextest; - assert flake.devShells.${system} ? default; - mapAttrs' (n: nameValuePair "${name}-check-${n}") flake.checks.${system} - // mapAttrs' (n: nameValuePair "${name}-shell-${n}") flake.devShells.${system} - // mapAttrs' (n: nameValuePair "${name}-package-${n}") flake.packages.${system}; + system: + assert flake.checks.${system} ? clippy; + assert flake.checks.${system} ? fmt; + assert flake.checks.${system} ? nextest; + assert flake.devShells.${system} ? default; + mapAttrs' (n: nameValuePair "${name}-check-${n}") flake.checks.${system} + // mapAttrs' (n: nameValuePair "${name}-shell-${n}") flake.devShells.${system} + // mapAttrs' (n: nameValuePair "${name}-package-${n}") flake.packages.${system}; flakes.rust.complex = (import ../examples/rust-complex/flake.nix).outputs { nixify = self; @@ -47,33 +49,38 @@ with self.lib; let nixify = self; }; in - genAttrs [ +genAttrs + [ aarch64-darwin aarch64-linux x86_64-darwin x86_64-linux ] - (system: let - isDarwin = system == aarch64-darwin || system == x86_64-darwin; - assertRustPackages = attrs: name: x: - assert attrs.${system} ? "${name}-aarch64-apple-darwin" || !isDarwin; - assert attrs.${system} ? "${name}-aarch64-apple-darwin-oci" || !isDarwin; - assert attrs.${system} ? "${name}-aarch64-unknown-linux-gnu"; - assert attrs.${system} ? "${name}-aarch64-unknown-linux-gnu-oci"; - assert attrs.${system} ? "${name}-aarch64-unknown-linux-musl"; - assert attrs.${system} ? "${name}-aarch64-unknown-linux-musl-oci"; - assert attrs.${system} ? "${name}-armv7-unknown-linux-musleabihf"; - assert attrs.${system} ? "${name}-armv7-unknown-linux-musleabihf-oci"; - assert attrs.${system} ? "${name}-x86_64-apple-darwin" || system != x86_64-darwin; - assert attrs.${system} ? "${name}-x86_64-apple-darwin-oci" || system != x86_64-darwin; - assert attrs.${system} ? "${name}-x86_64-pc-windows-gnu"; - assert attrs.${system} ? "${name}-x86_64-pc-windows-gnu-oci"; - assert attrs.${system} ? "${name}-x86_64-unknown-linux-gnu"; - assert attrs.${system} ? "${name}-x86_64-unknown-linux-gnu-oci"; - assert attrs.${system} ? "${name}-x86_64-unknown-linux-musl"; - assert attrs.${system} ? "${name}-x86_64-unknown-linux-musl-oci"; - assert attrs.${system} ? ${name}; x; - in + ( + system: + let + isDarwin = system == aarch64-darwin || system == x86_64-darwin; + assertRustPackages = + attrs: name: x: + assert attrs.${system} ? "${name}-aarch64-apple-darwin" || !isDarwin; + assert attrs.${system} ? "${name}-aarch64-apple-darwin-oci" || !isDarwin; + assert attrs.${system} ? "${name}-aarch64-unknown-linux-gnu"; + assert attrs.${system} ? "${name}-aarch64-unknown-linux-gnu-oci"; + assert attrs.${system} ? "${name}-aarch64-unknown-linux-musl"; + assert attrs.${system} ? "${name}-aarch64-unknown-linux-musl-oci"; + assert attrs.${system} ? "${name}-armv7-unknown-linux-musleabihf"; + assert attrs.${system} ? "${name}-armv7-unknown-linux-musleabihf-oci"; + assert attrs.${system} ? "${name}-x86_64-apple-darwin" || system != x86_64-darwin; + assert attrs.${system} ? "${name}-x86_64-apple-darwin-oci" || system != x86_64-darwin; + assert attrs.${system} ? "${name}-x86_64-pc-windows-gnu"; + assert attrs.${system} ? "${name}-x86_64-pc-windows-gnu-oci"; + assert attrs.${system} ? "${name}-x86_64-unknown-linux-gnu"; + assert attrs.${system} ? "${name}-x86_64-unknown-linux-gnu-oci"; + assert attrs.${system} ? "${name}-x86_64-unknown-linux-musl"; + assert attrs.${system} ? "${name}-x86_64-unknown-linux-musl-oci"; + assert attrs.${system} ? ${name}; + x; + in assert flakes.rust.complex.checks.${system} ? doctest; assert flakes.rust.complex.packages.${system} ? default; assert flakes.rust.hello-multibin.packages.${system} ? default; @@ -84,9 +91,13 @@ in assert flakes.rust.lib.packages.${system} ? rust-lib-wasm32-wasip2; assert flakes.rust.workspace.packages.${system} ? default; assert flakes.rust.workspace.packages.${system} ? rust-workspace-wasm32-wasip2; - (assertRustPackages flakes.rust.complex.packages "rust-complex") + (assertRustPackages flakes.rust.complex.packages "rust-complex") (assertRustPackages flakes.rust.hello-multibin.packages "rust-hello-multibin") (assertRustPackages flakes.rust.hello.packages "rust-hello") (assertRustPackages flakes.rust.lib.packages "rust-lib") (assertRustPackages flakes.rust.workspace.packages "rust-workspace") - foldl (checks: example: checks // (assertRustOutputs flakes.rust.${example} "rust-${example}" system)) {} (attrNames flakes.rust)) + foldl + (checks: example: checks // (assertRustOutputs flakes.rust.${example} "rust-${example}" system)) + { } + (attrNames flakes.rust) + ) diff --git a/examples/rust-complex/flake.nix b/examples/rust-complex/flake.nix index 71cbd502..ef6c4500 100644 --- a/examples/rust-complex/flake.nix +++ b/examples/rust-complex/flake.nix @@ -1,7 +1,8 @@ { inputs.nixify.url = "github:rvolosatovs/nixify"; - outputs = {nixify, ...}: + outputs = + { nixify, ... }: nixify.lib.rust.mkFlake { src = ./.; diff --git a/examples/rust-hello-multibin/flake.nix b/examples/rust-hello-multibin/flake.nix index 57ff8894..b2c72b10 100644 --- a/examples/rust-hello-multibin/flake.nix +++ b/examples/rust-hello-multibin/flake.nix @@ -1,7 +1,8 @@ { inputs.nixify.url = "github:rvolosatovs/nixify"; - outputs = {nixify, ...}: + outputs = + { nixify, ... }: nixify.lib.rust.mkFlake { src = ./.; }; diff --git a/examples/rust-hello/flake.nix b/examples/rust-hello/flake.nix index 8101e50e..48eec948 100644 --- a/examples/rust-hello/flake.nix +++ b/examples/rust-hello/flake.nix @@ -1,7 +1,8 @@ { inputs.nixify.url = "github:rvolosatovs/nixify"; - outputs = {nixify, ...}: + outputs = + { nixify, ... }: nixify.lib.rust.mkFlake { src = ./.; excludePaths = [ diff --git a/examples/rust-lib/flake.nix b/examples/rust-lib/flake.nix index 5a59e42a..7c721530 100644 --- a/examples/rust-lib/flake.nix +++ b/examples/rust-lib/flake.nix @@ -1,7 +1,8 @@ { inputs.nixify.url = "github:rvolosatovs/nixify"; - outputs = {nixify, ...}: + outputs = + { nixify, ... }: nixify.lib.rust.mkFlake { src = ./.; cargoLock = ./Cargo.test.lock; diff --git a/examples/rust-workspace/flake.nix b/examples/rust-workspace/flake.nix index 63219099..a23dcb64 100644 --- a/examples/rust-workspace/flake.nix +++ b/examples/rust-workspace/flake.nix @@ -1,7 +1,8 @@ { inputs.nixify.url = "github:rvolosatovs/nixify"; - outputs = {nixify, ...}: + outputs = + { nixify, ... }: nixify.lib.rust.mkFlake { src = ./.; name = "rust-workspace"; diff --git a/flake.nix b/flake.nix index bfb334b9..81ab24da 100644 --- a/flake.nix +++ b/flake.nix @@ -32,38 +32,40 @@ inputs.rust-overlay.inputs.nixpkgs.follows = "nixpkgs-nixos"; inputs.rust-overlay.url = "github:oxalica/rust-overlay"; - outputs = inputs: let - lib = import ./lib inputs; - in + outputs = + inputs: + let + lib = import ./lib inputs; + in with lib; - mkFlake { - excludePaths = [ - ".github" - ".gitignore" - "flake.lock" - "flake.nix" - "LICENSE" - "README.md" - ]; + mkFlake { + excludePaths = [ + ".github" + ".gitignore" + "flake.lock" + "flake.nix" + "LICENSE" + "README.md" + ]; - withDevShells = { + withDevShells = + { pkgs, devShells, ... }: - extendDerivations { - buildInputs = with pkgs; [ - buildah - wasmtime - zig - ]; - } - devShells; - } - // { - inherit lib; + extendDerivations { + buildInputs = with pkgs; [ + buildah + wasmtime + zig + ]; + } devShells; + } + // { + inherit lib; - checks = import ./checks inputs; - templates = import ./templates inputs; - }; + checks = import ./checks inputs; + templates = import ./templates inputs; + }; } diff --git a/lib/default.nix b/lib/default.nix index 98e16951..a6492831 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -3,10 +3,11 @@ nixlib, nix-filter, ... -} @ inputs: +}@inputs: with flake-utils.lib.system; with nixlib.lib; -with builtins; let +with builtins; +let f = self': { eq = x: y: x == y; @@ -16,24 +17,24 @@ with builtins; let extendDerivations = import ./extendDerivations.nix inputs; - filterSource = { - include ? null, - exclude ? self'.defaultExcludePaths, - src, - }: - nix-filter.lib.filter ({ + filterSource = + { + include ? null, + exclude ? self'.defaultExcludePaths, + src, + }: + nix-filter.lib.filter ( + { inherit exclude; root = src; } // optionalAttrs (include != null) { inherit include; - }); + } + ); readTOML = file: fromTOML (readFile file); - readTOMLOr = path: def: - if pathExists path - then self'.readTOML path - else def; + readTOMLOr = path: def: if pathExists path then self'.readTOML path else def; defaultExcludePaths = [ ".codecov.yml" @@ -44,7 +45,7 @@ with builtins; let "flake.nix" ]; - defaultNixpkgsConfig = {}; + defaultNixpkgsConfig = { }; defaultSystems = [ aarch64-darwin @@ -53,12 +54,12 @@ with builtins; let x86_64-linux ]; - defaultWithApps = {apps, ...}: apps; - defaultWithChecks = {checks, ...}: checks; - defaultWithDevShells = {devShells, ...}: devShells; - defaultWithFormatter = {formatter, ...}: formatter; - defaultWithOverlays = {overlays, ...}: overlays; - defaultWithPackages = {packages, ...}: packages; + defaultWithApps = { apps, ... }: apps; + defaultWithChecks = { checks, ... }: checks; + defaultWithDevShells = { devShells, ... }: devShells; + defaultWithFormatter = { formatter, ... }: formatter; + defaultWithOverlays = { overlays, ... }: overlays; + defaultWithPackages = { packages, ... }: packages; }; in - fix f +fix f diff --git a/lib/extendDerivations.nix b/lib/extendDerivations.nix index ccd38051..5066dfdc 100644 --- a/lib/extendDerivations.nix +++ b/lib/extendDerivations.nix @@ -5,23 +5,27 @@ }: with nixlib.lib; with builtins; - { - buildInputs ? [], - depsBuildBuild ? [], - env ? null, - inputsFrom ? [], - nativeBuildInputs ? [], - packages ? [], - }: - mapAttrs (n: v: - v.overrideAttrs (attrs: - { - buildInputs = (attrs.buildInputs or []) ++ buildInputs; - depsBuildBuild = (attrs.depsBuildBuild or []) ++ depsBuildBuild; - inputsFrom = (attrs.inputsFrom or []) ++ inputsFrom; - nativeBuildInputs = (attrs.nativeBuildInputs or []) ++ nativeBuildInputs; - packages = (attrs.packages or []) ++ packages; - } - // optionalAttrs (env != null) { - env = (attrs.env or {}) // env; - })) +{ + buildInputs ? [ ], + depsBuildBuild ? [ ], + env ? null, + inputsFrom ? [ ], + nativeBuildInputs ? [ ], + packages ? [ ], +}: +mapAttrs ( + n: v: + v.overrideAttrs ( + attrs: + { + buildInputs = (attrs.buildInputs or [ ]) ++ buildInputs; + depsBuildBuild = (attrs.depsBuildBuild or [ ]) ++ depsBuildBuild; + inputsFrom = (attrs.inputsFrom or [ ]) ++ inputsFrom; + nativeBuildInputs = (attrs.nativeBuildInputs or [ ]) ++ nativeBuildInputs; + packages = (attrs.packages or [ ]) ++ packages; + } + // optionalAttrs (env != null) { + env = (attrs.env or { }) // env; + } + ) +) diff --git a/lib/mkFlake.nix b/lib/mkFlake.nix index 5db22a0a..32c83da9 100644 --- a/lib/mkFlake.nix +++ b/lib/mkFlake.nix @@ -5,7 +5,8 @@ nixpkgs-darwin, nixpkgs-nixos, ... -}: { +}: +{ defaultExcludePaths, defaultSystems, defaultWithApps, @@ -20,134 +21,139 @@ with flake-utils.lib.system; with nixlib.lib; with builtins; with self.lib; - { - excludePaths ? defaultExcludePaths, - includePaths ? null, - nixpkgsConfig ? defaultNixpkgsConfig, - overlays ? [], - pname ? null, - src ? null, - systems ? defaultSystems, - version ? null, - withApps ? defaultWithApps, - withChecks ? defaultWithChecks, - withDevShells ? defaultWithDevShells, - withFormatter ? defaultWithFormatter, - withOverlays ? defaultWithOverlays, - withPackages ? defaultWithPackages, - }: let - commonArgs = - optionalAttrs (pname != null) { - inherit pname; - } - // optionalAttrs (version != null) { - inherit version; - } - // optionalAttrs (src != null) { - src = filterSource { - inherit src; - exclude = excludePaths; - include = includePaths; - }; +{ + excludePaths ? defaultExcludePaths, + includePaths ? null, + nixpkgsConfig ? defaultNixpkgsConfig, + overlays ? [ ], + pname ? null, + src ? null, + systems ? defaultSystems, + version ? null, + withApps ? defaultWithApps, + withChecks ? defaultWithChecks, + withDevShells ? defaultWithDevShells, + withFormatter ? defaultWithFormatter, + withOverlays ? defaultWithOverlays, + withPackages ? defaultWithPackages, +}: +let + commonArgs = + optionalAttrs (pname != null) { + inherit pname; + } + // optionalAttrs (version != null) { + inherit version; + } + // optionalAttrs (src != null) { + src = filterSource { + inherit src; + exclude = excludePaths; + include = includePaths; }; - in - { - overlays = withOverlays (commonArgs - // { - overlays = {}; - }); + }; +in +{ + overlays = withOverlays ( + commonArgs + // { + overlays = { }; } - // flake-utils.lib.eachSystem systems - ( - system: let - pkgs = - import ( - if system == aarch64-darwin || system == x86_64-darwin - then nixpkgs-darwin - else nixpkgs-nixos - ) { - inherit - overlays - system - ; - config = nixpkgsConfig; - }; + ); +} +// flake-utils.lib.eachSystem systems ( + system: + let + pkgs = + import + (if system == aarch64-darwin || system == x86_64-darwin then nixpkgs-darwin else nixpkgs-nixos) + { + inherit + overlays + system + ; + config = nixpkgsConfig; + }; - commonPkgsArgs = - commonArgs - // { - inherit - pkgs - ; - }; + commonPkgsArgs = commonArgs // { + inherit + pkgs + ; + }; + + checks = withChecks ( + commonPkgsArgs + // { + checks = { }; + } + ); + + formatter = withFormatter ( + commonPkgsArgs + // { + formatter = pkgs.nixfmt-rfc-style; + } + ); + + packages = withPackages ( + commonPkgsArgs + // { + packages = { }; + } + ); + in + { + inherit + formatter + checks + packages + ; - checks = withChecks (commonPkgsArgs - // { - checks = {}; - }); + apps = withApps ( + commonPkgsArgs + // { + inherit + packages + ; - formatter = withFormatter (commonPkgsArgs - // { - formatter = pkgs.alejandra; - }); + apps = optionalAttrs (packages ? default) { + default = flake-utils.lib.mkApp { + drv = packages.default; + }; + }; + } + ); - packages = withPackages (commonPkgsArgs - // { - packages = {}; - }); - in { + devShells = withDevShells ( + commonPkgsArgs + // { inherit formatter checks packages ; - apps = withApps ( - commonPkgsArgs - // { - inherit - packages - ; - - apps = optionalAttrs (packages ? default) { - default = flake-utils.lib.mkApp { - drv = packages.default; - }; - }; - } - ); - - devShells = withDevShells ( - commonPkgsArgs - // { - inherit + devShells.default = pkgs.mkShell ( + { + packages = [ formatter - checks - packages + ]; + } + // optionalAttrs (packages ? default) { + inherit (packages.default) + buildInputs + depsBuildBuild + nativeBuildInputs ; - - devShells.default = pkgs.mkShell ( - { - packages = [ - formatter - ]; - } - // optionalAttrs (packages ? default) { - inherit - (packages.default) - buildInputs - depsBuildBuild - nativeBuildInputs - ; - } - // optionalAttrs (pname != null) { - inherit pname; - } - // optionalAttrs (version != null) { - inherit version; - } - ); + } + // optionalAttrs (pname != null) { + inherit pname; + } + // optionalAttrs (version != null) { + inherit version; } ); } - ) + ); + } +) diff --git a/lib/rust/crateBins.nix b/lib/rust/crateBins.nix index fc7fb724..f8c2af3d 100644 --- a/lib/rust/crateBins.nix +++ b/lib/rust/crateBins.nix @@ -10,100 +10,111 @@ with builtins; with nix-log.lib; with self.lib; with self.lib.rust; - { - build ? defaultBuildConfig, - src, - }: let - build' = defaultBuildConfig // build; - packagesSelected = length build'.packages > 0; - readCargoToml = src: readTOMLOr "${src}/Cargo.toml" {}; +{ + build ? defaultBuildConfig, + src, +}: +let + build' = defaultBuildConfig // build; + packagesSelected = length build'.packages > 0; + readCargoToml = src: readTOMLOr "${src}/Cargo.toml" { }; - f = src: let + f = + src: + let cargoToml = readCargoToml src; isPackage = cargoToml ? package; includeCrate = - if build'.workspace || !isPackage - then true - else if packagesSelected - then any (p: p == cargoToml.package.name) build'.packages - else true; + if build'.workspace || !isPackage then + true + else if packagesSelected then + any (p: p == cargoToml.package.name) build'.packages + else + true; autobins = isPackage && cargoToml.package.autobins or true; - bin = optionals isPackage cargoToml.bin or []; + bin = optionals isPackage cargoToml.bin or [ ]; - unglob' = prefix: parts: - if parts == [] - then [prefix] - else let - h = head parts; - t = tail parts; - in - if hasInfix "*" h - then let - regex = "^${replaceStrings ["*"] [".*"] h}$"; - names = filter (name: match regex name != null) (attrNames (readDir prefix)); + unglob' = + prefix: parts: + if parts == [ ] then + [ prefix ] + else + let + h = head parts; + t = tail parts; in + if hasInfix "*" h then + let + regex = "^${replaceStrings [ "*" ] [ ".*" ] h}$"; + names = filter (name: match regex name != null) (attrNames (readDir prefix)); + in map (h': unglob' "${prefix}/${h'}" t) names - else unglob' "${prefix}/${h}" t; + else + unglob' "${prefix}/${h}" t; - unglob = glob: let - prefix = optionalString (!(hasPrefix "/" glob)) src; - parts = splitString "/" glob; - in + unglob = + glob: + let + prefix = optionalString (!(hasPrefix "/" glob)) src; + parts = splitString "/" glob; + in optionals (glob != "") (unglob' prefix parts); - workspaceMembers = cargoToml.workspace.members or []; + workspaceMembers = cargoToml.workspace.members or [ ]; workspaceMembers' = flatten (map unglob workspaceMembers); # normalise with `..` support, unlike the nixpkgs one - normalise' = p: - if hasPrefix "/" p - then throw "absolute paths not supported" - else let - merged = concatStringsSep "/" ( - # Reverse the source components and fold from the right to simplify merge - reverseList ( - foldr ( - c: p: - if c == ".." - then tail p - else if c == "." || c == "" - then p - else [c] ++ p + normalise' = + p: + if hasPrefix "/" p then + throw "absolute paths not supported" + else + let + merged = concatStringsSep "/" ( + # Reverse the source components and fold from the right to simplify merge + reverseList ( + foldr ( + c: p: + if c == ".." then + tail p + else if c == "." || c == "" then + p + else + [ c ] ++ p + ) (reverseList (splitString "/" src)) (splitString "/" p) ) - (reverseList (splitString "/" src)) (splitString "/" p) - ) - ); - in + ); + in removePrefix "." (normalise (removePrefix "/" merged)); - collectPathDeps = attrs: let - depAttrs = - filterAttrs (k: _: k == "build-dependencies" || k == "dependencies" || k == "dev-dependencies") - attrs; - deps = collect (dep: dep ? path && normalise' dep.path != src) depAttrs; - in + collectPathDeps = + attrs: + let + depAttrs = filterAttrs ( + k: _: k == "build-dependencies" || k == "dependencies" || k == "dev-dependencies" + ) attrs; + deps = collect (dep: dep ? path && normalise' dep.path != src) depAttrs; + in trace' "collectPathDeps" { inherit depAttrs deps ; - } - map ({path, ...}: - if hasPrefix "/" path - then path - else "${src}/${path}") - deps; + } map ({ path, ... }: if hasPrefix "/" path then path else "${src}/${path}") deps; pathDeps = collectPathDeps cargoToml - ++ optionals (cargoToml ? target) (flatten (attrValues (mapAttrs (_: v: collectPathDeps v) cargoToml.target))) + ++ optionals (cargoToml ? target) ( + flatten (attrValues (mapAttrs (_: v: collectPathDeps v) cargoToml.target)) + ) ++ optionals (cargoToml ? workspace) (collectPathDeps cargoToml.workspace); workspace = unique (workspaceMembers' ++ pathDeps); in - trace' "crateBins" { + trace' "crateBins" + { inherit autobins bin @@ -115,36 +126,45 @@ with self.lib.rust; ; } optionals - includeCrate ( + includeCrate + ( # NOTE: `listToAttrs` seems to discard keys already present in the set attrValues ( optionalAttrs (autobins && pathExists "${src}/src/main.rs") { "src/main.rs" = cargoToml.package.name; } - // listToAttrs (optionals (autobins && pathExists "${src}/src/bin") (map (name: - nameValuePair "src/bin/${name}" (removeSuffix ".rs" name)) - (attrNames (filterAttrs (name: type: type == "regular" && hasSuffix ".rs" name || type == "directory") (readDir "${src}/src/bin"))))) - // listToAttrs (map ( + // listToAttrs ( + optionals (autobins && pathExists "${src}/src/bin") ( + map (name: nameValuePair "src/bin/${name}" (removeSuffix ".rs" name)) ( + attrNames ( + filterAttrs (name: type: type == "regular" && hasSuffix ".rs" name || type == "directory") ( + readDir "${src}/src/bin" + ) + ) + ) + ) + ) + // listToAttrs ( + map ( { name, path ? null, ... }: - if path != null - then nameValuePair path name - else if autobins && pathExists "${src}/src/main.rs" && name == cargoToml.package.name - then nameValuePair "src/main.rs" name - else if autobins && pathExists "${src}/src/bin/${name}.rs" - then nameValuePair "src/bin/${name}.rs" name - else if autobins && pathExists "${src}/src/bin/${name}/main.rs" - then nameValuePair "src/bin/${name}/main.rs" name - else throw "failed to determine `${name}` binary path, please file a bug report and explicitly set `path` in `Cargo.toml` to temporarily work around this issue" - ) - bin) + if path != null then + nameValuePair path name + else if autobins && pathExists "${src}/src/main.rs" && name == cargoToml.package.name then + nameValuePair "src/main.rs" name + else if autobins && pathExists "${src}/src/bin/${name}.rs" then + nameValuePair "src/bin/${name}.rs" name + else if autobins && pathExists "${src}/src/bin/${name}/main.rs" then + nameValuePair "src/bin/${name}/main.rs" name + else + throw "failed to determine `${name}` binary path, please file a bug report and explicitly set `path` in `Cargo.toml` to temporarily work around this issue" + ) bin + ) ) ) - ++ optionals (build'.workspace || !isPackage || packagesSelected) (flatten (map f workspace)); - in - if build ? bins && length build.bins > 0 - then build.bins - else unique (f src) + ++ optionals (build'.workspace || !isPackage || packagesSelected) (flatten (map f workspace)); +in +if build ? bins && length build.bins > 0 then build.bins else unique (f src) diff --git a/lib/rust/default.nix b/lib/rust/default.nix index 7a2562b2..15f48411 100644 --- a/lib/rust/default.nix +++ b/lib/rust/default.nix @@ -4,30 +4,37 @@ crane, nixlib, ... -} @ inputs: +}@inputs: with nixlib.lib; with builtins; -with self.lib; let +with self.lib; +let defaultRustupToolchain.toolchain.channel = "stable"; - defaultRustupToolchain.toolchain.components = ["rustfmt" "clippy"]; + defaultRustupToolchain.toolchain.components = [ + "rustfmt" + "clippy" + ]; # crateBins returns a list of binaries that would be produced by cargo build crateBins = import ./crateBins.nix inputs; # mkCargoFlags constructs a set of cargo flags from `config` - mkCargoFlags = config: + mkCargoFlags = + config: with config; - concatStrings ( - optionals (config ? targets) (map (target: "--target ${target} ") config.targets) - ++ optionals (config ? packages) (map (package: "--package ${package} ") config.packages) - ++ optionals (config ? excludes) (map (exclude: "--exclude ${exclude} ") config.excludes) - ++ optionals (config ? bins) (map (bin: "--bin ${bin} ") config.bins) - ++ optional (config ? features && length config.features > 0) "--features ${concatStringsSep "," config.features} " - ++ optional (config ? allFeatures && config.allFeatures) "--all-features " - ++ optional (config ? allTargets && config.allTargets) "--all-targets " - ++ optional (config ? noDefaultFeatures && config.noDefaultFeatures) "--no-default-features " - ++ optional (config ? workspace && config.workspace) "--workspace " - ); + concatStrings ( + optionals (config ? targets) (map (target: "--target ${target} ") config.targets) + ++ optionals (config ? packages) (map (package: "--package ${package} ") config.packages) + ++ optionals (config ? excludes) (map (exclude: "--exclude ${exclude} ") config.excludes) + ++ optionals (config ? bins) (map (bin: "--bin ${bin} ") config.bins) + ++ optional ( + config ? features && length config.features > 0 + ) "--features ${concatStringsSep "," config.features} " + ++ optional (config ? allFeatures && config.allFeatures) "--all-features " + ++ optional (config ? allTargets && config.allTargets) "--all-targets " + ++ optional (config ? noDefaultFeatures && config.noDefaultFeatures) "--no-default-features " + ++ optional (config ? workspace && config.workspace) "--workspace " + ); # mkCraneLib constructs a crane library for specified `pkgs`. mkCraneLib = pkgs: rustToolchain: (crane.mkLib pkgs).overrideToolchain rustToolchain; @@ -39,18 +46,22 @@ with self.lib; let mkPackages = import ./mkPackages.nix inputs; # extract package name from parsed Cargo.toml - pnameFromCargoToml = cargoToml: + pnameFromCargoToml = + cargoToml: cargoToml.package.name - or (throw "`name` must either be specified in `Cargo.toml` `[package]` section or passed as an argument"); + or (throw "`name` must either be specified in `Cargo.toml` `[package]` section or passed as an argument"); withRustOverlayToolchain = pkgs: pkgs.rust-bin.fromRustupToolchain; - withFenixToolchain = pkgs: { - channel ? defaultRustupToolchain.toolchain.channel, - components ? defaultRustupToolchain.toolchain.components, - targets ? [], - ... - } @ args: - with pkgs; let + withFenixToolchain = + pkgs: + { + channel ? defaultRustupToolchain.toolchain.channel, + components ? defaultRustupToolchain.toolchain.components, + targets ? [ ], + ... + }@args: + with pkgs; + let channels.stable = "stable"; channels.beta = "beta"; channels.nightly = "latest"; @@ -59,15 +70,21 @@ with self.lib; let targets' = map (target: fenix.targets.${target}.${channel'}.rust-std) targets; toolchain = fenix.combine ( [ - (fenix.${channel'}.withComponents (components ++ ["cargo"])) + (fenix.${channel'}.withComponents (components ++ [ "cargo" ])) ] ++ targets' ); in - if channels ? ${channel} - then toolchain - else warn "only one of ${toJSON (attrNames channels)} `channel` specifications are supported for `fenix`, falling back to rust-overlay (which may break some cross-compilation scenarios)" withRustOverlayToolchain pkgs args; -in { + if channels ? ${channel} then + toolchain + else + warn + "only one of ${toJSON (attrNames channels)} `channel` specifications are supported for `fenix`, falling back to rust-overlay (which may break some cross-compilation scenarios)" + withRustOverlayToolchain + pkgs + args; +in +{ inherit crateBins defaultRustupToolchain @@ -87,7 +104,7 @@ in { commonDebugArgs.CARGO_PROFILE = "dev"; # commonReleaseArgs is a set of common arguments to release builds - commonReleaseArgs = {}; + commonReleaseArgs = { }; # version used when not specified in Cargo.toml defaultVersion = "0.0.0-unspecified"; @@ -99,50 +116,48 @@ in { defaultBuildConfig.allFeatures = false; defaultBuildConfig.allTargets = false; - defaultBuildConfig.bins = []; - defaultBuildConfig.excludes = []; - defaultBuildConfig.features = []; + defaultBuildConfig.bins = [ ]; + defaultBuildConfig.excludes = [ ]; + defaultBuildConfig.features = [ ]; defaultBuildConfig.noDefaultFeatures = false; - defaultBuildConfig.packages = []; + defaultBuildConfig.packages = [ ]; defaultBuildConfig.workspace = false; defaultClippyConfig.allFeatures = false; - defaultClippyConfig.allow = []; + defaultClippyConfig.allow = [ ]; defaultClippyConfig.allTargets = false; - defaultClippyConfig.deny = []; - defaultClippyConfig.features = []; - defaultClippyConfig.forbid = []; + defaultClippyConfig.deny = [ ]; + defaultClippyConfig.features = [ ]; + defaultClippyConfig.forbid = [ ]; defaultClippyConfig.noDefaultFeatures = false; - defaultClippyConfig.packages = []; - defaultClippyConfig.targets = []; - defaultClippyConfig.warn = []; + defaultClippyConfig.packages = [ ]; + defaultClippyConfig.targets = [ ]; + defaultClippyConfig.warn = [ ]; defaultClippyConfig.workspace = false; defaultDocConfig.allFeatures = false; defaultDocConfig.allTargets = false; - defaultDocConfig.excludes = []; - defaultDocConfig.features = []; + defaultDocConfig.excludes = [ ]; + defaultDocConfig.features = [ ]; defaultDocConfig.noDefaultFeatures = false; - defaultDocConfig.packages = []; + defaultDocConfig.packages = [ ]; defaultDocConfig.workspace = false; defaultTestConfig.allFeatures = false; defaultTestConfig.allTargets = false; defaultTestConfig.doc = false; - defaultTestConfig.excludes = []; - defaultTestConfig.features = []; + defaultTestConfig.excludes = [ ]; + defaultTestConfig.features = [ ]; defaultTestConfig.noDefaultFeatures = false; - defaultTestConfig.packages = []; - defaultTestConfig.targets = []; + defaultTestConfig.packages = [ ]; + defaultTestConfig.targets = [ ]; defaultTestConfig.workspace = false; - defaultBuildOverrides = _: const {}; + defaultBuildOverrides = _: const { }; - defaultExcludePaths = - defaultExcludePaths - ++ [ - "rust-toolchain.toml" - ]; + defaultExcludePaths = defaultExcludePaths ++ [ + "rust-toolchain.toml" + ]; # From https://doc.rust-lang.org/nightly/rustc/platform-support.html targets.aarch64-apple-darwin = "aarch64-apple-darwin"; diff --git a/lib/rust/defaultPkgsFor.nix b/lib/rust/defaultPkgsFor.nix index ff736cd4..df4de119 100644 --- a/lib/rust/defaultPkgsFor.nix +++ b/lib/rust/defaultPkgsFor.nix @@ -8,94 +8,103 @@ }: with flake-utils.lib.system; with self.lib.rust.targets; - pkgs: target: let - hostPlatform = pkgs.stdenv.hostPlatform; - in - if hostPlatform.config == target - then pkgs - else if hostPlatform.isAarch32 && hostPlatform.isLinux && hostPlatform.isMusl && target == armv7-unknown-linux-musleabihf - then pkgs - else if hostPlatform.isAarch64 && hostPlatform.isLinux && hostPlatform.isGnu && target == aarch64-unknown-linux-gnu - then pkgs - else if hostPlatform.isAarch64 && hostPlatform.isLinux && hostPlatform.isAndroid && target == aarch64-linux-android - then pkgs - else if hostPlatform.isAarch64 && hostPlatform.isLinux && target == aarch64-unknown-linux-musl - then - if hostPlatform.isMusl - then pkgs - else pkgs.pkgsCross.aarch64-multiplatform-musl - else if hostPlatform.isx86_64 && hostPlatform.isLinux && hostPlatform.isGnu && target == x86_64-unknown-linux-gnu - then pkgs - else if hostPlatform.isx86_64 && hostPlatform.isLinux && target == x86_64-unknown-linux-musl - then - if hostPlatform.isMusl - then pkgs - else pkgs.pkgsCross.musl64 - else if hostPlatform.isx86_64 && hostPlatform.isWindows && target == x86_64-pc-windows-gnu - then pkgs - else if target == aarch64-apple-darwin - then pkgs.pkgsCross.aarch64-darwin - else if target == aarch64-apple-ios - then pkgs.pkgsCross.iphone64 - else if target == aarch64-linux-android - then pkgs.pkgsCross.aarch64-android-prebuilt - else if target == aarch64-unknown-linux-gnu - then pkgs.pkgsCross.aarch64-multiplatform - else if target == aarch64-unknown-linux-musl - then pkgs.pkgsCross.aarch64-multiplatform-musl - else if target == arm-unknown-linux-gnueabihf - then pkgs.pkgsCross.raspberryPi - else if target == arm-unknown-linux-musleabihf - then pkgs.pkgsCross.muslpi - else if target == armv7s-apple-ios - then pkgs.pkgsCross.iphone32 - else if target == armv7-unknown-linux-musleabihf - then pkgs.pkgsCross.armv7l-hf-multiplatform - else if target == armv7-unknown-linux-gnueabihf - then pkgs.pkgsCross.armv7l-hf-multiplatform - else if target == mips-unknown-linux-gnu - then pkgs.pkgsCross.mips-linux-gnu - else if target == mipsel-unknown-linux-gnu - then pkgs.pkgsCross.mipsel-linux-gnu - else if target == mips64-unknown-linux-gnuabi64 - then pkgs.pkgsCross.mips64-linux-gnuabi64 - else if target == mips64el-unknown-linux-gnuabi64 - then pkgs.pkgsCross.mips64el-linux-gnuabi64 - else if target == powerpc64-unknown-linux-gnu - then pkgs.pkgsCross.ppc64 - else if target == powerpc64-unknown-linux-musl - then pkgs.pkgsCross.ppc64-musl - else if target == powerpc64le-unknown-linux-gnu - then pkgs.pkgsCross.powernv - else if target == powerpc64le-unknown-linux-musl - then pkgs.pkgsCross.musl-power - else if target == riscv64gc-unknown-linux-gnu - then pkgs.pkgsCross.riscv64 - else if target == s390x-unknown-linux-gnu - then pkgs.pkgsCross.s390x - else if target == s390x-unknown-linux-musl - then pkgs.pkgsCross.s390x - else if target == x86_64-apple-darwin - then pkgs.pkgsCross.x86_64-darwin - else if target == x86_64-apple-ios - then pkgs.pkgsCross.iphone64-simulator - else if target == x86_64-pc-windows-gnu - then pkgs.pkgsCross.mingwW64 - else if target == x86_64-unknown-linux-gnu - then pkgs.pkgsCross.gnu64 - else if target == x86_64-unknown-linux-musl - then pkgs.pkgsCross.musl64 - else if target == wasm32-unknown-unknown || target == wasm32-wasip1 || target == wasm32-wasip2 - then pkgs.pkgsCross.wasi32 - else - import ( - if pkgs.stdenv.buildPlatform.isDarwin - then nixpkgs-darwin - else nixpkgs-nixos - ) { - crossSystem.config = - if target == riscv64gc-unknown-linux-musl - then "riscv64-unknown-linux-musl" - else target; - localSystem = hostPlatform.system; - } +pkgs: target: +let + hostPlatform = pkgs.stdenv.hostPlatform; +in +if hostPlatform.config == target then + pkgs +else if + hostPlatform.isAarch32 + && hostPlatform.isLinux + && hostPlatform.isMusl + && target == armv7-unknown-linux-musleabihf +then + pkgs +else if + hostPlatform.isAarch64 + && hostPlatform.isLinux + && hostPlatform.isGnu + && target == aarch64-unknown-linux-gnu +then + pkgs +else if + hostPlatform.isAarch64 + && hostPlatform.isLinux + && hostPlatform.isAndroid + && target == aarch64-linux-android +then + pkgs +else if hostPlatform.isAarch64 && hostPlatform.isLinux && target == aarch64-unknown-linux-musl then + if hostPlatform.isMusl then pkgs else pkgs.pkgsCross.aarch64-multiplatform-musl +else if + hostPlatform.isx86_64 + && hostPlatform.isLinux + && hostPlatform.isGnu + && target == x86_64-unknown-linux-gnu +then + pkgs +else if hostPlatform.isx86_64 && hostPlatform.isLinux && target == x86_64-unknown-linux-musl then + if hostPlatform.isMusl then pkgs else pkgs.pkgsCross.musl64 +else if hostPlatform.isx86_64 && hostPlatform.isWindows && target == x86_64-pc-windows-gnu then + pkgs +else if target == aarch64-apple-darwin then + pkgs.pkgsCross.aarch64-darwin +else if target == aarch64-apple-ios then + pkgs.pkgsCross.iphone64 +else if target == aarch64-linux-android then + pkgs.pkgsCross.aarch64-android-prebuilt +else if target == aarch64-unknown-linux-gnu then + pkgs.pkgsCross.aarch64-multiplatform +else if target == aarch64-unknown-linux-musl then + pkgs.pkgsCross.aarch64-multiplatform-musl +else if target == arm-unknown-linux-gnueabihf then + pkgs.pkgsCross.raspberryPi +else if target == arm-unknown-linux-musleabihf then + pkgs.pkgsCross.muslpi +else if target == armv7s-apple-ios then + pkgs.pkgsCross.iphone32 +else if target == armv7-unknown-linux-musleabihf then + pkgs.pkgsCross.armv7l-hf-multiplatform +else if target == armv7-unknown-linux-gnueabihf then + pkgs.pkgsCross.armv7l-hf-multiplatform +else if target == mips-unknown-linux-gnu then + pkgs.pkgsCross.mips-linux-gnu +else if target == mipsel-unknown-linux-gnu then + pkgs.pkgsCross.mipsel-linux-gnu +else if target == mips64-unknown-linux-gnuabi64 then + pkgs.pkgsCross.mips64-linux-gnuabi64 +else if target == mips64el-unknown-linux-gnuabi64 then + pkgs.pkgsCross.mips64el-linux-gnuabi64 +else if target == powerpc64-unknown-linux-gnu then + pkgs.pkgsCross.ppc64 +else if target == powerpc64-unknown-linux-musl then + pkgs.pkgsCross.ppc64-musl +else if target == powerpc64le-unknown-linux-gnu then + pkgs.pkgsCross.powernv +else if target == powerpc64le-unknown-linux-musl then + pkgs.pkgsCross.musl-power +else if target == riscv64gc-unknown-linux-gnu then + pkgs.pkgsCross.riscv64 +else if target == s390x-unknown-linux-gnu then + pkgs.pkgsCross.s390x +else if target == s390x-unknown-linux-musl then + pkgs.pkgsCross.s390x +else if target == x86_64-apple-darwin then + pkgs.pkgsCross.x86_64-darwin +else if target == x86_64-apple-ios then + pkgs.pkgsCross.iphone64-simulator +else if target == x86_64-pc-windows-gnu then + pkgs.pkgsCross.mingwW64 +else if target == x86_64-unknown-linux-gnu then + pkgs.pkgsCross.gnu64 +else if target == x86_64-unknown-linux-musl then + pkgs.pkgsCross.musl64 +else if target == wasm32-unknown-unknown || target == wasm32-wasip1 || target == wasm32-wasip2 then + pkgs.pkgsCross.wasi32 +else + import (if pkgs.stdenv.buildPlatform.isDarwin then nixpkgs-darwin else nixpkgs-nixos) { + crossSystem.config = + if target == riscv64gc-unknown-linux-musl then "riscv64-unknown-linux-musl" else target; + localSystem = hostPlatform.system; + } diff --git a/lib/rust/mkAttrs.nix b/lib/rust/mkAttrs.nix index 7c3b14b9..5f5220d1 100644 --- a/lib/rust/mkAttrs.nix +++ b/lib/rust/mkAttrs.nix @@ -14,62 +14,64 @@ with nix-log.lib; with self.lib; with self.lib.rust; with self.lib.rust.targets; - { - audit ? defaultAuditConfig, - build ? defaultBuildConfig, - buildOverrides ? defaultBuildOverrides, - cargoLock ? null, - clippy ? defaultClippyConfig, - doc ? defaultDocConfig, - doCheck ? true, - pkgsFor ? defaultPkgsFor, - pname ? null, - rustupToolchain ? defaultRustupToolchain, - src, - targets ? null, - test ? defaultTestConfig, - version ? null, - withToolchain ? defaultWithToolchain, - }: let - cargoToml = readTOML "${src}/Cargo.toml"; - pname' = - if pname != null - then pname - else pnameFromCargoToml cargoToml; - - version' = - if version != null - then version - else if cargoToml.package.version.workspace or false - then cargoToml.package.workspace.version or defaultVersion - else cargoToml.package.version or defaultVersion; - - rustupToolchain' = rustupToolchain.toolchain or {}; - - bins = crateBins { - inherit - build - src - ; - }; - - callCrane = { - craneArgs ? {}, +{ + audit ? defaultAuditConfig, + build ? defaultBuildConfig, + buildOverrides ? defaultBuildOverrides, + cargoLock ? null, + clippy ? defaultClippyConfig, + doc ? defaultDocConfig, + doCheck ? true, + pkgsFor ? defaultPkgsFor, + pname ? null, + rustupToolchain ? defaultRustupToolchain, + src, + targets ? null, + test ? defaultTestConfig, + version ? null, + withToolchain ? defaultWithToolchain, +}: +let + cargoToml = readTOML "${src}/Cargo.toml"; + pname' = if pname != null then pname else pnameFromCargoToml cargoToml; + + version' = + if version != null then + version + else if cargoToml.package.version.workspace or false then + cargoToml.package.workspace.version or defaultVersion + else + cargoToml.package.version or defaultVersion; + + rustupToolchain' = rustupToolchain.toolchain or { }; + + bins = crateBins { + inherit + build + src + ; + }; + + callCrane = + { + craneArgs ? { }, craneLib, overrideArgs, - }: f: let + }: + f: + let buildArgs = "-j $NIX_BUILD_CORES ${mkCargoFlags build}"; docArgs = "-j $NIX_BUILD_CORES ${mkCargoFlags doc}"; testArgs = "-j $NIX_BUILD_CORES ${mkCargoFlags test}"; clippyArgs = "-j $NIX_BUILD_CORES ${mkCargoFlags clippy} -- ${ with clippy; - concatStrings ( - optionals (clippy ? allow) (map (lint: "--allow ${lint} ") allow) - ++ optionals (clippy ? deny) (map (lint: "--deny ${lint} ") deny) - ++ optionals (clippy ? forbid) (map (lint: "--forbid ${lint} ") forbid) - ++ optionals (clippy ? warn) (map (lint: "--warn ${lint} ") warn) - ) + concatStrings ( + optionals (clippy ? allow) (map (lint: "--allow ${lint} ") allow) + ++ optionals (clippy ? deny) (map (lint: "--deny ${lint} ") deny) + ++ optionals (clippy ? forbid) (map (lint: "--forbid ${lint} ") forbid) + ++ optionals (clippy ? warn) (map (lint: "--warn ${lint} ") warn) + ) }"; commonArgs = @@ -104,216 +106,224 @@ with self.lib.rust.targets; } // craneArgs; - craneArgs' = - commonArgs // buildOverrides overrideArgs commonArgs; + craneArgs' = commonArgs // buildOverrides overrideArgs commonArgs; in - trace' "callCrane" { - inherit - buildArgs - checkArgs - clippyArgs - docArgs - testArgs - ; - } - f - craneArgs'; + trace' "callCrane" { + inherit + buildArgs + checkArgs + clippyArgs + docArgs + testArgs + ; + } f craneArgs'; - callCraneWithDeps = { - craneArgs ? {}, + callCraneWithDeps = + { + craneArgs ? { }, craneLib, overrideArgs, - }: let - cargoArtifacts = - callCrane { - inherit - craneArgs - craneLib - overrideArgs - ; - } - craneLib.buildDepsOnly; - in - trace "callCraneWithDeps" - callCrane { + }: + let + cargoArtifacts = callCrane { inherit + craneArgs craneLib overrideArgs ; - craneArgs = - { - inherit cargoArtifacts; + } craneLib.buildDepsOnly; + in + trace "callCraneWithDeps" callCrane { + inherit + craneLib + overrideArgs + ; + craneArgs = { + inherit cargoArtifacts; - passthru = - { - inherit cargoArtifacts; - } - // (craneArgs.passthru or {}); - } - // craneArgs; - }; + passthru = { + inherit cargoArtifacts; + } // (craneArgs.passthru or { }); + } // craneArgs; + }; - # buildPackage builds using `craneLib`. - buildPackage = { - craneArgs ? {}, + # buildPackage builds using `craneLib`. + buildPackage = + { + craneArgs ? { }, craneLib, overrideArgs, }: - trace "buildPackage" - callCraneWithDeps { - inherit - craneArgs - craneLib - overrideArgs - ; + trace "buildPackage" callCraneWithDeps { + inherit + craneArgs + craneLib + overrideArgs + ; + } craneLib.buildPackage; +in +final: +let + # hostRustToolchain is the default Rust toolchain. + hostRustToolchain = withToolchain final rustupToolchain'; + + # hostCraneLib is the crane library for the host native triple. + hostCraneLib = trace' "hostCraneLib" { + final.stdenv.hostPlatform.config = final.stdenv.hostPlatform.config; + } mkCraneLib final hostRustToolchain; + + mkHostArgs = + craneArgs: + trace' "mkHostArgs" + { + inherit craneArgs; } - craneLib.buildPackage; - in - final: let - # hostRustToolchain is the default Rust toolchain. - hostRustToolchain = withToolchain final rustupToolchain'; - - # hostCraneLib is the crane library for the host native triple. - hostCraneLib = - trace' "hostCraneLib" { - final.stdenv.hostPlatform.config = final.stdenv.hostPlatform.config; - } - mkCraneLib - final - hostRustToolchain; - - mkHostArgs = craneArgs: - trace' "mkHostArgs" { - inherit craneArgs; - } - { - inherit craneArgs; - - craneLib = hostCraneLib; - - overrideArgs.pkgs = final; - }; - - callHostCrane = craneArgs: - trace' "callHostCrane" { - inherit craneArgs; - } - callCrane (mkHostArgs craneArgs); + { + inherit craneArgs; - callHostCraneWithDeps = craneArgs: - trace' "callHostCraneWithDeps" { - inherit craneArgs; - } - callCraneWithDeps (mkHostArgs craneArgs); + craneLib = hostCraneLib; - callHostCraneCheckWithDeps = craneArgs: - trace' "callHostCraneCheckWithDeps" { - inherit craneArgs; - } - callHostCraneWithDeps (craneArgs - // { - doCheck = true; # without performing the actual testing, this check is useless - }); + overrideArgs.pkgs = final; + }; - checks = - { - clippy = callHostCraneWithDeps {} hostCraneLib.cargoClippy; - doc = callHostCraneWithDeps {} hostCraneLib.cargoDoc; - fmt = callHostCrane {} hostCraneLib.cargoFmt; - nextest = callHostCraneCheckWithDeps {} hostCraneLib.cargoNextest; - } - // (optionalAttrs (test ? doc && test.doc || test ? allTargets && test.allTargets)) - { - doctest = - callHostCraneCheckWithDeps { - cargoTestExtraArgs = "-j $NIX_BUILD_CORES ${mkCargoFlags (test - // { - allTargets = false; - })}"; - } - hostCraneLib.cargoDocTest; + callHostCrane = + craneArgs: + trace' "callHostCrane" { + inherit craneArgs; + } callCrane (mkHostArgs craneArgs); + + callHostCraneWithDeps = + craneArgs: + trace' "callHostCraneWithDeps" { + inherit craneArgs; + } callCraneWithDeps (mkHostArgs craneArgs); + + callHostCraneCheckWithDeps = + craneArgs: + trace' "callHostCraneCheckWithDeps" + { + inherit craneArgs; + } + callHostCraneWithDeps + ( + craneArgs + // { + doCheck = true; # without performing the actual testing, this check is useless } - // (optionalAttrs (pathExists "${src}/Cargo.lock") { - # TODO: Use `cargoLock` if `Cargo.lock` missing - audit = - callHostCrane { - advisory-db = audit.database; + ); + + checks = + { + clippy = callHostCraneWithDeps { } hostCraneLib.cargoClippy; + doc = callHostCraneWithDeps { } hostCraneLib.cargoDoc; + fmt = callHostCrane { } hostCraneLib.cargoFmt; + nextest = callHostCraneCheckWithDeps { } hostCraneLib.cargoNextest; + } + // (optionalAttrs (test ? doc && test.doc || test ? allTargets && test.allTargets)) { + doctest = callHostCraneCheckWithDeps { + cargoTestExtraArgs = "-j $NIX_BUILD_CORES ${ + mkCargoFlags ( + test + // { + allTargets = false; } - hostCraneLib.cargoAudit; - }); - - buildHostPackage = craneArgs: - trace' "buildHostPackage" { - inherit craneArgs; - } - callHostCraneWithDeps - craneArgs - hostCraneLib.buildPackage; - - hostBin = buildHostPackage commonReleaseArgs; - hostDebugBin = buildHostPackage commonDebugArgs; - - mkPackages = prev: let - rustupToolchainTargets = rustupToolchain'.targets or []; - - rustupToolchainWithTarget = target: - trace' "rustupToolchainWithTarget" { + ) + }"; + } hostCraneLib.cargoDocTest; + } + // (optionalAttrs (pathExists "${src}/Cargo.lock") { + # TODO: Use `cargoLock` if `Cargo.lock` missing + audit = callHostCrane { + advisory-db = audit.database; + } hostCraneLib.cargoAudit; + }); + + buildHostPackage = + craneArgs: + trace' "buildHostPackage" { + inherit craneArgs; + } callHostCraneWithDeps craneArgs hostCraneLib.buildPackage; + + hostBin = buildHostPackage commonReleaseArgs; + hostDebugBin = buildHostPackage commonDebugArgs; + + mkPackages = + prev: + let + rustupToolchainTargets = rustupToolchain'.targets or [ ]; + + rustupToolchainWithTarget = + target: + trace' "rustupToolchainWithTarget" + { inherit target; } ( - if any (eq target) rustupToolchainTargets - then rustupToolchain' - else if target == aarch64-apple-darwin && prev.stdenv.buildPlatform.system == aarch64-darwin - then rustupToolchain' - else if target == aarch64-unknown-linux-gnu && prev.stdenv.buildPlatform.system == aarch64-linux - then rustupToolchain' - else if target == x86_64-apple-darwin && prev.stdenv.buildPlatform.system == x86_64-darwin - then rustupToolchain' - else if target == x86_64-pc-windows-gnu && prev.stdenv.buildPlatform.system == x86_64-windows - then rustupToolchain' - else if target == x86_64-unknown-linux-gnu && prev.stdenv.buildPlatform.system == x86_64-linux - then rustupToolchain' + if any (eq target) rustupToolchainTargets then + rustupToolchain' + else if target == aarch64-apple-darwin && prev.stdenv.buildPlatform.system == aarch64-darwin then + rustupToolchain' + else if + target == aarch64-unknown-linux-gnu && prev.stdenv.buildPlatform.system == aarch64-linux + then + rustupToolchain' + else if target == x86_64-apple-darwin && prev.stdenv.buildPlatform.system == x86_64-darwin then + rustupToolchain' + else if target == x86_64-pc-windows-gnu && prev.stdenv.buildPlatform.system == x86_64-windows then + rustupToolchain' + else if target == x86_64-unknown-linux-gnu && prev.stdenv.buildPlatform.system == x86_64-linux then + rustupToolchain' else rustupToolchain' // { - targets = rustupToolchainTargets ++ [target]; + targets = rustupToolchainTargets ++ [ target ]; } ); - rustToolchainFor = target: let + rustToolchainFor = + target: + let rustupToolchain = rustupToolchainWithTarget target; in - trace' "rustupToolchainFor" { - inherit target; - } - withToolchain - final - rustupToolchain; - - # buildPackageFor builds for `target`. - # `extraArgs` are passed through to `buildPackage` verbatim. - # NOTE: Upstream only provides binary caches for a subset of supported systems. - buildPackageFor = { + trace' "rustupToolchainFor" { + inherit target; + } withToolchain final rustupToolchain; + + # buildPackageFor builds for `target`. + # `extraArgs` are passed through to `buildPackage` verbatim. + # NOTE: Upstream only provides binary caches for a subset of supported systems. + buildPackageFor = + { craneArgs, craneLib, pkgsCross, target, - }: let - kebab2snake = replaceStrings ["-"] ["_"]; - - useRosetta = final.stdenv.buildPlatform.isDarwin && final.stdenv.buildPlatform.isAarch64 && pkgsCross.stdenv.hostPlatform.isDarwin && pkgsCross.stdenv.hostPlatform.isx86_64; - useEmu = final.stdenv.buildPlatform.system != pkgsCross.stdenv.hostPlatform.system && !useRosetta && !pkgsCross.stdenv.hostPlatform.isDarwin; - - crossZigCC = let - target' = - if target == aarch64-apple-darwin - then "aarch64-macos" - else if target == aarch64-apple-ios - then "aarch64-ios" - else if target == x86_64-apple-darwin - then "x86_64-macos" - else throw "unsupported target ${target}"; - in + }: + let + kebab2snake = replaceStrings [ "-" ] [ "_" ]; + + useRosetta = + final.stdenv.buildPlatform.isDarwin + && final.stdenv.buildPlatform.isAarch64 + && pkgsCross.stdenv.hostPlatform.isDarwin + && pkgsCross.stdenv.hostPlatform.isx86_64; + useEmu = + final.stdenv.buildPlatform.system != pkgsCross.stdenv.hostPlatform.system + && !useRosetta + && !pkgsCross.stdenv.hostPlatform.isDarwin; + + crossZigCC = + let + target' = + if target == aarch64-apple-darwin then + "aarch64-macos" + else if target == aarch64-apple-ios then + "aarch64-ios" + else if target == x86_64-apple-darwin then + "x86_64-macos" + else + throw "unsupported target ${target}"; + in # NOTE: Prior art: # https://actually.fyi/posts/zig-makes-rust-cross-compilation-just-work # https://github.com/rust-cross/cargo-zigbuild @@ -336,36 +346,34 @@ with self.lib.rust.targets; } # Use `rust-lld` linker and Zig C compiler for Darwin targets // ( - if pkgsCross.stdenv.hostPlatform.isDarwin - then { - depsBuildBuild = [ - crossZigCC - ]; - - disallowedReferences = [ - crossZigCC - ]; - - preBuild = - '' - export HOME=$(mktemp -d) - '' - + optionalString pkgsCross.stdenv.hostPlatform.isDarwin '' - export SDKROOT="${macos-sdk}" - ''; - - "CC_${target}" = "${target}-zigcc"; - - "CARGO_TARGET_${toUpper (kebab2snake target)}_LINKER" = "rust-lld"; - } + if pkgsCross.stdenv.hostPlatform.isDarwin then + { + depsBuildBuild = [ + crossZigCC + ]; + + disallowedReferences = [ + crossZigCC + ]; + + preBuild = + '' + export HOME=$(mktemp -d) + '' + + optionalString pkgsCross.stdenv.hostPlatform.isDarwin '' + export SDKROOT="${macos-sdk}" + ''; + + "CC_${target}" = "${target}-zigcc"; + + "CARGO_TARGET_${toUpper (kebab2snake target)}_LINKER" = "rust-lld"; + } else ( { - depsBuildBuild = - [ - pkgsCross.stdenv.cc - ] - ++ optional pkgsCross.stdenv.hostPlatform.isWindows pkgsCross.windows.pthreads; + depsBuildBuild = [ + pkgsCross.stdenv.cc + ] ++ optional pkgsCross.stdenv.hostPlatform.isWindows pkgsCross.windows.pthreads; disallowedReferences = [ pkgsCross.stdenv.cc @@ -397,195 +405,185 @@ with self.lib.rust.targets; strictDeps = true; nativeCheckInputs = optional useEmu ( - if pkgsCross.stdenv.hostPlatform.isWasm - then final.wasmtime - else if pkgsCross.stdenv.hostPlatform.isWindows - then final.wine64 - else final.qemu + if pkgsCross.stdenv.hostPlatform.isWasm then + final.wasmtime + else if pkgsCross.stdenv.hostPlatform.isWindows then + final.wine64 + else + final.qemu ); } // optionalAttrs (doCheck && target == aarch64-apple-darwin) { doCheck = warn "testing not currently supported when cross-compiling for `${target}`" false; } - // optionalAttrs (doCheck && pkgsCross.stdenv.hostPlatform.isDarwin && !final.stdenv.buildPlatform.isDarwin) { - doCheck = warn "testing not currently supported when cross-compiling for `${target}` from non-Darwin platform" false; - } + // + optionalAttrs + (doCheck && pkgsCross.stdenv.hostPlatform.isDarwin && !final.stdenv.buildPlatform.isDarwin) + { + doCheck = warn "testing not currently supported when cross-compiling for `${target}` from non-Darwin platform" false; + } // optionalAttrs (doCheck && useEmu) ( - if target == arm-unknown-linux-gnueabihf - then + if target == arm-unknown-linux-gnueabihf then { CARGO_TARGET_ARM_UNKNOWN_LINUX_GNUEABIHF_RUNNER = "qemu-arm"; } // optionalAttrs final.stdenv.buildPlatform.isDarwin { doCheck = warn "testing not currently supported when cross-compiling for `${target}` on Darwin" false; } - else if target == arm-unknown-linux-musleabihf - then + else if target == arm-unknown-linux-musleabihf then { CARGO_TARGET_ARM_UNKNOWN_LINUX_MUSLEABIHF_RUNNER = "qemu-arm"; } // optionalAttrs final.stdenv.buildPlatform.isDarwin { doCheck = warn "testing not currently supported when cross-compiling for `${target}` on Darwin" false; } - else if target == armv7-unknown-linux-gnueabihf - then + else if target == armv7-unknown-linux-gnueabihf then { CARGO_TARGET_ARMV7_UNKNOWN_LINUX_GNUEABIHF_RUNNER = "qemu-arm"; } // optionalAttrs final.stdenv.buildPlatform.isDarwin { doCheck = warn "testing not currently supported when cross-compiling for `${target}` on Darwin" false; } - else if target == armv7-unknown-linux-musleabihf - then + else if target == armv7-unknown-linux-musleabihf then { CARGO_TARGET_ARMV7_UNKNOWN_LINUX_MUSLEABIHF_RUNNER = "qemu-arm"; } // optionalAttrs final.stdenv.buildPlatform.isDarwin { doCheck = warn "testing not currently supported when cross-compiling for `${target}` on Darwin" false; } - else if target == aarch64-linux-android - then { - doCheck = warn "testing not currently supported when cross-compiling for `${target}`" false; - } - else if target == aarch64-unknown-linux-gnu - then + else if target == aarch64-linux-android then + { + doCheck = warn "testing not currently supported when cross-compiling for `${target}`" false; + } + else if target == aarch64-unknown-linux-gnu then { CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_RUNNER = "qemu-aarch64"; } // optionalAttrs final.stdenv.buildPlatform.isDarwin { doCheck = warn "testing not currently supported when cross-compiling for `${target}` on Darwin" false; } - else if target == aarch64-unknown-linux-musl - then + else if target == aarch64-unknown-linux-musl then { CARGO_TARGET_AARCH64_UNKNOWN_LINUX_MUSL_RUNNER = "qemu-aarch64"; } // optionalAttrs final.stdenv.buildPlatform.isDarwin { doCheck = warn "testing not currently supported when cross-compiling for `${target}` on Darwin" false; } - else if target == mips-unknown-linux-gnu - then + else if target == mips-unknown-linux-gnu then { CARGO_TARGET_MIPS_UNKNOWN_LINUX_GNU_RUNNER = "qemu-mips"; } // optionalAttrs final.stdenv.buildPlatform.isDarwin { doCheck = warn "testing not currently supported when cross-compiling for `${target}` on Darwin" false; } - else if target == mips64-unknown-linux-gnuabi64 - then + else if target == mips64-unknown-linux-gnuabi64 then { CARGO_TARGET_MIPS64_UNKNOWN_LINUX_GNUABI64_RUNNER = "qemu-mips64"; } // optionalAttrs final.stdenv.buildPlatform.isDarwin { doCheck = warn "testing not currently supported when cross-compiling for `${target}` on Darwin" false; } - else if target == mips64el-unknown-linux-gnuabi64 - then + else if target == mips64el-unknown-linux-gnuabi64 then { CARGO_TARGET_MIPS64EL_UNKNOWN_LINUX_GNUABI64_RUNNER = "qemu-mips64el"; } // optionalAttrs final.stdenv.buildPlatform.isDarwin { doCheck = warn "testing not currently supported when cross-compiling for `${target}` on Darwin" false; } - else if target == mipsel-unknown-linux-gnu - then + else if target == mipsel-unknown-linux-gnu then { CARGO_TARGET_MIPSEL_UNKNOWN_LINUX_GNU_RUNNER = "qemu-mipsel"; } // optionalAttrs final.stdenv.buildPlatform.isDarwin { doCheck = warn "testing not currently supported when cross-compiling for `${target}` on Darwin" false; } - else if target == powerpc64-unknown-linux-gnu - then + else if target == powerpc64-unknown-linux-gnu then { CARGO_TARGET_POWERPC64_UNKNOWN_LINUX_GNU_RUNNER = "qemu-ppc64"; } // optionalAttrs final.stdenv.buildPlatform.isDarwin { doCheck = warn "testing not currently supported when cross-compiling for `${target}` on Darwin" false; } - else if target == powerpc64-unknown-linux-musl - then + else if target == powerpc64-unknown-linux-musl then { CARGO_TARGET_POWERPC64_UNKNOWN_LINUX_MUSL_RUNNER = "qemu-ppc64"; } // optionalAttrs final.stdenv.buildPlatform.isDarwin { doCheck = warn "testing not currently supported when cross-compiling for `${target}` on Darwin" false; } - else if target == powerpc64le-unknown-linux-gnu - then + else if target == powerpc64le-unknown-linux-gnu then { CARGO_TARGET_POWERPC64LE_UNKNOWN_LINUX_GNU_RUNNER = "qemu-ppc64le"; } // optionalAttrs final.stdenv.buildPlatform.isDarwin { doCheck = warn "testing not currently supported when cross-compiling for `${target}` on Darwin" false; } - else if target == powerpc64le-unknown-linux-musl - then + else if target == powerpc64le-unknown-linux-musl then { CARGO_TARGET_POWERPC64LE_UNKNOWN_LINUX_MUSL_RUNNER = "qemu-ppc64le"; } // optionalAttrs final.stdenv.buildPlatform.isDarwin { doCheck = warn "testing not currently supported when cross-compiling for `${target}` on Darwin" false; } - else if target == riscv64gc-unknown-linux-gnu - then + else if target == riscv64gc-unknown-linux-gnu then { CARGO_TARGET_RISCV64GC_UNKNOWN_LINUX_GNU_RUNNER = "qemu-riscv64"; } // optionalAttrs final.stdenv.buildPlatform.isDarwin { doCheck = warn "testing not currently supported when cross-compiling for `${target}` on Darwin" false; } - else if target == s390x-unknown-linux-gnu - then + else if target == s390x-unknown-linux-gnu then { CARGO_TARGET_S390X_UNKNOWN_LINUX_GNU_RUNNER = "qemu-s390x"; } // optionalAttrs final.stdenv.buildPlatform.isDarwin { doCheck = warn "testing not currently supported when cross-compiling for `${target}` on Darwin" false; } - else if target == wasm32-unknown-unknown - then { - doCheck = warn "testing not currently supported when cross-compiling for `${target}`" false; - } - else if target == wasm32-wasip1 - then { - CARGO_TARGET_WASM32_WASIP1_RUNNER = "wasmtime run -C cache=n"; - } - else if target == wasm32-wasip2 - then { - CARGO_TARGET_WASM32_WASIP2_RUNNER = "wasmtime run -C cache=n"; - } - else if target == x86_64-unknown-linux-gnu - then + else if target == wasm32-unknown-unknown then + { + doCheck = warn "testing not currently supported when cross-compiling for `${target}`" false; + } + else if target == wasm32-wasip1 then + { + CARGO_TARGET_WASM32_WASIP1_RUNNER = "wasmtime run -C cache=n"; + } + else if target == wasm32-wasip2 then + { + CARGO_TARGET_WASM32_WASIP2_RUNNER = "wasmtime run -C cache=n"; + } + else if target == x86_64-unknown-linux-gnu then { CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUNNER = "qemu-x86_64"; } // optionalAttrs final.stdenv.buildPlatform.isDarwin { doCheck = warn "testing not currently supported when cross-compiling for `${target}` on Darwin" false; } - else if target == x86_64-unknown-linux-musl - then + else if target == x86_64-unknown-linux-musl then { CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_RUNNER = "qemu-x86_64"; } // optionalAttrs final.stdenv.buildPlatform.isDarwin { doCheck = warn "testing not currently supported when cross-compiling for `${target}` on Darwin" false; } - else if target == x86_64-pc-windows-gnu - then { - # TODO: This works locally, but for some reason does not within the sanbox - doCheck = warn "testing not currently supported when cross-compiling for `${target}`" false; - - CARGO_TARGET_X86_64_PC_WINDOWS_GNU_RUNNER = final.writeScript "wine-wrapper" '' - export WINEPREFIX="$(mktemp -d)" - exec wine64 $@ - ''; - } - else warn "do not know which test runner to use for target `${target}`, set `CARGO_TARGET_${toUpper (kebab2snake target)}_RUNNER` to appropriate `qemu` binary name" {} + else if target == x86_64-pc-windows-gnu then + { + # TODO: This works locally, but for some reason does not within the sanbox + doCheck = warn "testing not currently supported when cross-compiling for `${target}`" false; + + CARGO_TARGET_X86_64_PC_WINDOWS_GNU_RUNNER = final.writeScript "wine-wrapper" '' + export WINEPREFIX="$(mktemp -d)" + exec wine64 $@ + ''; + } + else + warn + "do not know which test runner to use for target `${target}`, set `CARGO_TARGET_${toUpper (kebab2snake target)}_RUNNER` to appropriate `qemu` binary name" + { } ) ); in - trace' "buildPackageFor" { + trace' "buildPackageFor" + { inherit craneArgs target @@ -595,7 +593,8 @@ with self.lib.rust.targets; final.stdenv.buildPlatform.config = final.stdenv.buildPlatform.config; pkgsCross.stdenv.hostPlatform.config = pkgsCross.stdenv.hostPlatform.config; } - buildPackage { + buildPackage + { inherit craneLib ; @@ -610,10 +609,12 @@ with self.lib.rust.targets; craneArgs = targetArgs // craneArgs; }; - targets' = let + targets' = + let default.${aarch64-apple-darwin} = true; default.${aarch64-apple-ios} = false; - default.${aarch64-linux-android} = prev.stdenv.hostPlatform.isLinux && prev.stdenv.hostPlatform.isx86_64; + default.${aarch64-linux-android} = + prev.stdenv.hostPlatform.isLinux && prev.stdenv.hostPlatform.isx86_64; default.${aarch64-unknown-linux-gnu} = true; default.${aarch64-unknown-linux-musl} = true; default.${arm-unknown-linux-gnueabi} = false; @@ -652,173 +653,189 @@ with self.lib.rust.targets; default.${x86_64-unknown-linux-gnu} = true; default.${x86_64-unknown-linux-musl} = true; - selected = - default - // optionalAttrs (targets != null) targets; + selected = default // optionalAttrs (targets != null) targets; in - mapAttrs' (target: enabled: - warnIf (enabled && !(default ? ${target})) '' - target `${target}` is not supported - set `targets.${target} = false` to remove this warning'' (nameValuePair target enabled)) - selected; - - targetBins = let - mkOutputs = target: let - pkgsCross = pkgsFor final target; - rustToolchain = rustToolchainFor target; - craneLib = mkCraneLib final rustToolchain; - - withPassthru = craneArgs: {passthru ? {}, ...} @ pkg: - pkg - // { - passthru = - passthru - // { + mapAttrs' ( + target: enabled: + warnIf (enabled && !(default ? ${target})) '' + target `${target}` is not supported + set `targets.${target} = false` to remove this warning'' (nameValuePair target enabled) + ) selected; + + targetBins = + let + mkOutputs = + target: + let + pkgsCross = pkgsFor final target; + rustToolchain = rustToolchainFor target; + craneLib = mkCraneLib final rustToolchain; + + withPassthru = + craneArgs: + { + passthru ? { }, + ... + }@pkg: + pkg + // { + passthru = + passthru + // { + inherit + pkgsCross + rustToolchain + target + ; + } + // optionalAttrs (craneArgs ? CARGO_PROFILE) { + inherit (craneArgs) + CARGO_PROFILE + ; + }; + }; + + buildPackageFor' = + craneArgs: + let + pkg = buildPackageFor { inherit + craneArgs + craneLib pkgsCross - rustToolchain target ; - } - // optionalAttrs (craneArgs ? CARGO_PROFILE) { - inherit - (craneArgs) - CARGO_PROFILE - ; }; - }; - - buildPackageFor' = craneArgs: let - pkg = buildPackageFor { - inherit - craneArgs - craneLib - pkgsCross - target - ; - }; + in + withPassthru craneArgs pkg; in - withPassthru craneArgs pkg; - in optionalAttrs (targets' ? ${target} && targets'.${target}) { "${pname'}-${target}" = buildPackageFor' commonReleaseArgs; "${pname'}-debug-${target}" = buildPackageFor' commonDebugArgs; }; packages = map mkOutputs (attrValues rust.targets); in - foldr mergeAttrs {} packages; - - targetDeps = mapAttrs' (name: bin: nameValuePair "${name}-deps" bin.cargoArtifacts) targetBins; - - # https://github.com/docker-library/official-images#architectures-other-than-amd64 - # https://go.dev/doc/install/source#environment - # https://github.com/docker-library/bashbrew/blob/7e160dca3123caecf32c33ba31821dd2aa3716cd/architecture/oci-platform.go#L14-L27 - # TODO: Update `buildImage` to support setting a platform struct - #ociArchitecture.${aarch64-apple-darwin} = "darwin-arm64v8"; - #ociArchitecture.${aarch64-unknown-linux-gnu} = "arm64v8"; - #ociArchitecture.${aarch64-unknown-linux-musl} = "arm64v8"; - #ociArchitecture.${armv7-unknown-linux-musleabihf} = "arm32v7"; - #ociArchitecture.${x86_64-apple-darwin} = "darwin-amd64"; - #ociArchitecture.${x86_64-pc-windows-gnu} = "windows-amd64"; - ociArchitecture.${aarch64-apple-darwin} = "arm64"; - ociArchitecture.${aarch64-linux-android} = "arm64"; - ociArchitecture.${aarch64-unknown-linux-gnu} = "arm64"; - ociArchitecture.${aarch64-unknown-linux-musl} = "arm64"; - ociArchitecture.${armv7-unknown-linux-musleabihf} = "arm"; - ociArchitecture.${wasm32-unknown-unknown} = "wasm"; - ociArchitecture.${wasm32-wasip1} = "wasm"; - ociArchitecture.${wasm32-wasip2} = "wasm"; - ociArchitecture.${x86_64-apple-darwin} = "amd64"; - ociArchitecture.${x86_64-pc-windows-gnu} = "amd64"; - ociArchitecture.${x86_64-unknown-linux-gnu} = "amd64"; - ociArchitecture.${x86_64-unknown-linux-musl} = "amd64"; - - bins' = genAttrs bins (_: {}); - targetImages = ( - mapAttrs' ( - target: pkg: let - img = final.dockerTools.buildImage ({ + foldr mergeAttrs { } packages; + + targetDeps = mapAttrs' (name: bin: nameValuePair "${name}-deps" bin.cargoArtifacts) targetBins; + + # https://github.com/docker-library/official-images#architectures-other-than-amd64 + # https://go.dev/doc/install/source#environment + # https://github.com/docker-library/bashbrew/blob/7e160dca3123caecf32c33ba31821dd2aa3716cd/architecture/oci-platform.go#L14-L27 + # TODO: Update `buildImage` to support setting a platform struct + #ociArchitecture.${aarch64-apple-darwin} = "darwin-arm64v8"; + #ociArchitecture.${aarch64-unknown-linux-gnu} = "arm64v8"; + #ociArchitecture.${aarch64-unknown-linux-musl} = "arm64v8"; + #ociArchitecture.${armv7-unknown-linux-musleabihf} = "arm32v7"; + #ociArchitecture.${x86_64-apple-darwin} = "darwin-amd64"; + #ociArchitecture.${x86_64-pc-windows-gnu} = "windows-amd64"; + ociArchitecture.${aarch64-apple-darwin} = "arm64"; + ociArchitecture.${aarch64-linux-android} = "arm64"; + ociArchitecture.${aarch64-unknown-linux-gnu} = "arm64"; + ociArchitecture.${aarch64-unknown-linux-musl} = "arm64"; + ociArchitecture.${armv7-unknown-linux-musleabihf} = "arm"; + ociArchitecture.${wasm32-unknown-unknown} = "wasm"; + ociArchitecture.${wasm32-wasip1} = "wasm"; + ociArchitecture.${wasm32-wasip2} = "wasm"; + ociArchitecture.${x86_64-apple-darwin} = "amd64"; + ociArchitecture.${x86_64-pc-windows-gnu} = "amd64"; + ociArchitecture.${x86_64-unknown-linux-gnu} = "amd64"; + ociArchitecture.${x86_64-unknown-linux-musl} = "amd64"; + + bins' = genAttrs bins (_: { }); + targetImages = ( + mapAttrs' ( + target: pkg: + let + img = final.dockerTools.buildImage ( + { + name = pname'; + tag = "${version'}-${pkg.passthru.target}"; + copyToRoot = final.buildEnv { name = pname'; - tag = "${version'}-${pkg.passthru.target}"; - copyToRoot = final.buildEnv { - name = pname'; - paths = [pkg]; - }; - config.Env = ["PATH=${pkg}/bin"]; - } - // optionalAttrs (bins' ? ${pname'}) { - config.Cmd = [pname']; - } - // optionalAttrs (length bins == 1) { - config.Cmd = bins; - } - // optionalAttrs (ociArchitecture ? ${pkg.passthru.target}) { - architecture = ociArchitecture.${pkg.passthru.target}; - }); - in - nameValuePair "${target}-oci" (img - // { - passthru = pkg.passthru // img.passthru; - }) - ) - targetBins - ); - - multiArchTargets = [ - aarch64-unknown-linux-musl - armv7-unknown-linux-musleabihf - #x86_64-pc-windows-gnu # TODO: Re-enable once we can set OS - x86_64-unknown-linux-musl - ]; - in - { - "${pname'}" = hostBin; - "${pname'}-debug" = hostDebugBin; - } - // targetDeps - // targetBins - // targetImages - // optionalAttrs (any (target: targetImages ? "${pname'}-${target}-oci") multiArchTargets) - { - "build-${pname'}-oci" = let - build = final.writeShellScriptBin "build-${pname'}-oci" '' - set -xe - - build() { - ${final.buildah}/bin/buildah manifest create "''${1}" - ${concatMapStringsSep "\n" ( - target: let - name = "${pname'}-${target}-oci"; - in - optionalString (targetImages ? ${name}) '' - ${final.buildah}/bin/buildah manifest add "''${1}" docker-archive:${targetImages."${name}"} - ${final.buildah}/bin/buildah pull docker-archive:${targetImages."${name}"} - '' - ) - multiArchTargets} + paths = [ pkg ]; + }; + config.Env = [ "PATH=${pkg}/bin" ]; } - build "''${1:-${pname'}:${version'}}" - ''; - in (build + // optionalAttrs (bins' ? ${pname'}) { + config.Cmd = [ pname' ]; + } + // optionalAttrs (length bins == 1) { + config.Cmd = bins; + } + // optionalAttrs (ociArchitecture ? ${pkg.passthru.target}) { + architecture = ociArchitecture.${pkg.passthru.target}; + } + ); + in + nameValuePair "${target}-oci" ( + img // { - inherit - version - ; - }); - }; - - packages = mkPackages final; - in { - inherit - buildHostPackage - callCrane - callCraneWithDeps - callHostCrane - callHostCraneWithDeps - checks - hostCraneLib - hostRustToolchain - packages - ; - overlay = mkPackages; + passthru = pkg.passthru // img.passthru; + } + ) + ) targetBins + ); + + multiArchTargets = [ + aarch64-unknown-linux-musl + armv7-unknown-linux-musleabihf + #x86_64-pc-windows-gnu # TODO: Re-enable once we can set OS + x86_64-unknown-linux-musl + ]; + in + { + "${pname'}" = hostBin; + "${pname'}-debug" = hostDebugBin; } + // targetDeps + // targetBins + // targetImages + // optionalAttrs (any (target: targetImages ? "${pname'}-${target}-oci") multiArchTargets) { + "build-${pname'}-oci" = + let + build = final.writeShellScriptBin "build-${pname'}-oci" '' + set -xe + + build() { + ${final.buildah}/bin/buildah manifest create "''${1}" + ${concatMapStringsSep "\n" ( + target: + let + name = "${pname'}-${target}-oci"; + in + optionalString (targetImages ? ${name}) '' + ${final.buildah}/bin/buildah manifest add "''${1}" docker-archive:${targetImages."${name}"} + ${final.buildah}/bin/buildah pull docker-archive:${targetImages."${name}"} + '' + ) multiArchTargets} + } + build "''${1:-${pname'}:${version'}}" + ''; + in + ( + build + // { + inherit + version + ; + } + ); + }; + + packages = mkPackages final; +in +{ + inherit + buildHostPackage + callCrane + callCraneWithDeps + callHostCrane + callHostCraneWithDeps + checks + hostCraneLib + hostRustToolchain + packages + ; + overlay = mkPackages; +} diff --git a/lib/rust/mkChecks.nix b/lib/rust/mkChecks.nix index 6480f499..4681cc19 100644 --- a/lib/rust/mkChecks.nix +++ b/lib/rust/mkChecks.nix @@ -1,6 +1,7 @@ -{self, ...}: +{ self, ... }: with self.lib.rust; - args: pkgs: let - attrs = mkAttrs args pkgs; - in - attrs.checks +args: pkgs: +let + attrs = mkAttrs args pkgs; +in +attrs.checks diff --git a/lib/rust/mkFlake.nix b/lib/rust/mkFlake.nix index af89f12b..488f36b4 100644 --- a/lib/rust/mkFlake.nix +++ b/lib/rust/mkFlake.nix @@ -12,194 +12,207 @@ with nixlib.lib; with builtins; with self.lib; with self.lib.rust; - { - audit ? defaultAuditConfig, - build ? defaultBuildConfig, - buildOverrides ? defaultBuildOverrides, - cargoLock ? null, - clippy ? defaultClippyConfig, - doc ? defaultDocConfig, - doCheck ? true, - excludePaths ? defaultExcludePaths, - includePaths ? null, - name ? null, - nixpkgsConfig ? defaultNixpkgsConfig, - overlays ? [], - pkgsFor ? defaultPkgsFor, - rustupToolchain ? null, - src, - systems ? defaultSystems, - targets ? null, - test ? defaultTestConfig, - withApps ? defaultWithApps, - withChecks ? defaultWithChecks, - withDevShells ? defaultWithDevShells, - withFormatter ? defaultWithFormatter, - withOverlays ? defaultWithOverlays, - withPackages ? defaultWithPackages, - withToolchain ? defaultWithToolchain, - }: let - cargoToml = readTOML "${src}/Cargo.toml"; - pname = - if name != null - then name - else pnameFromCargoToml cargoToml; - version = - if cargoToml.package.version.workspace or false - then cargoToml.package.workspace.version or defaultVersion - else cargoToml.package.version or defaultVersion; +{ + audit ? defaultAuditConfig, + build ? defaultBuildConfig, + buildOverrides ? defaultBuildOverrides, + cargoLock ? null, + clippy ? defaultClippyConfig, + doc ? defaultDocConfig, + doCheck ? true, + excludePaths ? defaultExcludePaths, + includePaths ? null, + name ? null, + nixpkgsConfig ? defaultNixpkgsConfig, + overlays ? [ ], + pkgsFor ? defaultPkgsFor, + rustupToolchain ? null, + src, + systems ? defaultSystems, + targets ? null, + test ? defaultTestConfig, + withApps ? defaultWithApps, + withChecks ? defaultWithChecks, + withDevShells ? defaultWithDevShells, + withFormatter ? defaultWithFormatter, + withOverlays ? defaultWithOverlays, + withPackages ? defaultWithPackages, + withToolchain ? defaultWithToolchain, +}: +let + cargoToml = readTOML "${src}/Cargo.toml"; + pname = if name != null then name else pnameFromCargoToml cargoToml; + version = + if cargoToml.package.version.workspace or false then + cargoToml.package.workspace.version or defaultVersion + else + cargoToml.package.version or defaultVersion; - rustupToolchain' = - if rustupToolchain == null - then readTOMLOr "${src}/rust-toolchain.toml" defaultRustupToolchain - else rustupToolchain; + rustupToolchain' = + if rustupToolchain == null then + readTOMLOr "${src}/rust-toolchain.toml" defaultRustupToolchain + else + rustupToolchain; - src' = filterSource { - inherit src; - exclude = excludePaths; - include = includePaths; - }; + src' = filterSource { + inherit src; + exclude = excludePaths; + include = includePaths; + }; - # partially-applied `mkAttrs` - mkAttrs' = mkAttrs { - inherit - build - buildOverrides - cargoLock - clippy - doc - doCheck - pkgsFor - pname - targets - test - version - withToolchain - ; - src = src'; - rustupToolchain = rustupToolchain'; - }; - in - self.lib.mkFlake { - inherit - excludePaths - includePaths - nixpkgsConfig - pname - systems - version - withFormatter - ; - src = src'; + # partially-applied `mkAttrs` + mkAttrs' = mkAttrs { + inherit + build + buildOverrides + cargoLock + clippy + doc + doCheck + pkgsFor + pname + targets + test + version + withToolchain + ; + src = src'; + rustupToolchain = rustupToolchain'; + }; +in +self.lib.mkFlake { + inherit + excludePaths + includePaths + nixpkgsConfig + pname + systems + version + withFormatter + ; + src = src'; - overlays = - overlays - ++ [ - rust-overlay.overlays.default - fenix.overlays.default - ]; + overlays = overlays ++ [ + rust-overlay.overlays.default + fenix.overlays.default + ]; - withApps = { - apps, - packages, - pkgs, - ... - } @ cx: - withApps (cx - // { - apps = - apps - # TODO: Add cross apps - // optionalAttrs (packages ? "${pname}") { - ${pname} = flake-utils.lib.mkApp { - drv = packages."${pname}"; - }; - } - // optionalAttrs (packages ? "${pname}-debug") { - "${pname}-debug" = flake-utils.lib.mkApp { - drv = packages."${pname}-debug"; - }; - }; - }); + withApps = + { + apps, + packages, + pkgs, + ... + }@cx: + withApps ( + cx + // { + apps = + apps + # TODO: Add cross apps + // optionalAttrs (packages ? "${pname}") { + ${pname} = flake-utils.lib.mkApp { + drv = packages."${pname}"; + }; + } + // optionalAttrs (packages ? "${pname}-debug") { + "${pname}-debug" = flake-utils.lib.mkApp { + drv = packages."${pname}-debug"; + }; + }; + } + ); - withChecks = { - checks, - pkgs, - ... - } @ cx: let - attrs = mkAttrs' pkgs; - in - withChecks (cx - // { - checks = checks // attrs.checks; - }); + withChecks = + { + checks, + pkgs, + ... + }@cx: + let + attrs = mkAttrs' pkgs; + in + withChecks ( + cx + // { + checks = checks // attrs.checks; + } + ); - withDevShells = { - checks, - devShells, - packages, - pkgs, - ... - } @ cx: let - attrs = mkAttrs' pkgs; - in - withDevShells (cx - // { - devShells = - extendDerivations ( - { - packages = [ - attrs.hostRustToolchain - ]; - } - // optionalAttrs (checks ? ${pname}) { - inherit - (checks.${pname}) - buildInputs - depsBuildBuild - nativeBuildInputs - ; - } - ) - devShells; - }); + withDevShells = + { + checks, + devShells, + packages, + pkgs, + ... + }@cx: + let + attrs = mkAttrs' pkgs; + in + withDevShells ( + cx + // { + devShells = extendDerivations ( + { + packages = [ + attrs.hostRustToolchain + ]; + } + // optionalAttrs (checks ? ${pname}) { + inherit (checks.${pname}) + buildInputs + depsBuildBuild + nativeBuildInputs + ; + } + ) devShells; + } + ); - withOverlays = {overlays, ...} @ cx: - withOverlays (cx + withOverlays = + { overlays, ... }@cx: + withOverlays ( + cx + // { + overlays = + let + overlay = final: prev: (mkAttrs' final).overlay prev; + in + overlays // { - overlays = let - overlay = final: prev: (mkAttrs' final).overlay prev; - in - overlays - // { - ${pname} = overlay; - default = overlay; - fenix = fenix.overlays.default; - rust-overlay = rust-overlay.overlays.default; - }; - }); + ${pname} = overlay; + default = overlay; + fenix = fenix.overlays.default; + rust-overlay = rust-overlay.overlays.default; + }; + } + ); - withPackages = { - packages, - pkgs, - ... - } @ cx: let - attrs = mkAttrs' pkgs; - attrPkgs = optionalAttrs (attrs ? packages) attrs.packages; - in - withPackages (cx - // { - inherit - (attrs) - hostRustToolchain - ; + withPackages = + { + packages, + pkgs, + ... + }@cx: + let + attrs = mkAttrs' pkgs; + attrPkgs = optionalAttrs (attrs ? packages) attrs.packages; + in + withPackages ( + cx + // { + inherit (attrs) + hostRustToolchain + ; - buildLib = attrs.lib; - packages = - packages - // attrPkgs - // optionalAttrs (attrPkgs ? ${pname}) { - default = attrPkgs.${pname}; - }; - }); - } + buildLib = attrs.lib; + packages = + packages + // attrPkgs + // optionalAttrs (attrPkgs ? ${pname}) { + default = attrPkgs.${pname}; + }; + } + ); +} diff --git a/lib/rust/mkOverlay.nix b/lib/rust/mkOverlay.nix index a37bb824..f9ada284 100644 --- a/lib/rust/mkOverlay.nix +++ b/lib/rust/mkOverlay.nix @@ -6,7 +6,8 @@ with builtins; with nixlib.lib; with self.lib.rust; - args: final: let - attrs = mkAttrs args final; - in - attrs.overlay +args: final: +let + attrs = mkAttrs args final; +in +attrs.overlay diff --git a/lib/rust/mkPackages.nix b/lib/rust/mkPackages.nix index 7e143da9..053c8406 100644 --- a/lib/rust/mkPackages.nix +++ b/lib/rust/mkPackages.nix @@ -1,6 +1,7 @@ -{self, ...}: +{ self, ... }: with self.lib.rust; - args: pkgs: let - attrs = mkAttrs args pkgs; - in - attrs.packages +args: pkgs: +let + attrs = mkAttrs args pkgs; +in +attrs.packages diff --git a/templates/default.nix b/templates/default.nix index a79b08ad..cae4c21b 100644 --- a/templates/default.nix +++ b/templates/default.nix @@ -1,4 +1,5 @@ -{...}: { +{ ... }: +{ rust.description = "A basic Rust template"; rust.path = ./rust; } diff --git a/templates/rust/flake.nix b/templates/rust/flake.nix index f45eb1ad..b2c72b10 100644 --- a/templates/rust/flake.nix +++ b/templates/rust/flake.nix @@ -1,7 +1,8 @@ { - inputs.nixify.url = github:rvolosatovs/nixify; + inputs.nixify.url = "github:rvolosatovs/nixify"; - outputs = {nixify, ...}: + outputs = + { nixify, ... }: nixify.lib.rust.mkFlake { src = ./.; };