diff --git a/flake.lock b/flake.lock index 6ca9fd8..66be2e2 100644 --- a/flake.lock +++ b/flake.lock @@ -1,5 +1,34 @@ { "nodes": { + "crane": { + "inputs": { + "flake-compat": [ + "flake-compat" + ], + "flake-utils": [ + "flake-utils" + ], + "nixpkgs": [ + "nixpkgs" + ], + "rust-overlay": [ + "rust-overlay" + ] + }, + "locked": { + "lastModified": 1688772518, + "narHash": "sha256-ol7gZxwvgLnxNSZwFTDJJ49xVY5teaSvF7lzlo3YQfM=", + "owner": "ipetkov", + "repo": "crane", + "rev": "8b08e96c9af8c6e3a2b69af5a7fa168750fcf88e", + "type": "github" + }, + "original": { + "owner": "ipetkov", + "repo": "crane", + "type": "github" + } + }, "flake-compat": { "flake": false, "locked": { @@ -77,11 +106,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1689846679, - "narHash": "sha256-89uOAMBZK4jooekzMZcm4sGxZp9kThMvJI6wVf00RfI=", + "lastModified": 1689951833, + "narHash": "sha256-wdpIgb5X0p85RRne74TeUOp9ti7a1k9KDSe4NzsaAGk=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "17dd4c92ee12de80a1fe86ea30be723e4e06cd00", + "rev": "ebf4e87429ce7faa51a86a36a7b2e615c8bcc735", "type": "github" }, "original": { @@ -137,11 +166,36 @@ }, "root": { "inputs": { + "crane": "crane", "flake-compat": "flake-compat", "flake-parts": "flake-parts", "flake-utils": "flake-utils", "nixpkgs": "nixpkgs", - "pre-commit-hooks-nix": "pre-commit-hooks-nix" + "pre-commit-hooks-nix": "pre-commit-hooks-nix", + "rust-overlay": "rust-overlay" + } + }, + "rust-overlay": { + "inputs": { + "flake-utils": [ + "flake-utils" + ], + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1689906077, + "narHash": "sha256-2tjLXKoSK7O0LYHlA6GCWL0gy2kZZno4krg+KZpDh6U=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "c88b28944129eeff5e819bdc21248dc07eb0625d", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" } }, "systems": { diff --git a/flake.nix b/flake.nix index 11ff936..cf8b3ee 100644 --- a/flake.nix +++ b/flake.nix @@ -25,13 +25,27 @@ # avoid having multiple versions in our dependencies. flake-utils.url = "github:numtide/flake-utils"; + crane = { + url = "github:ipetkov/crane"; + inputs.nixpkgs.follows = "nixpkgs"; + inputs.rust-overlay.follows = "rust-overlay"; + inputs.flake-utils.follows = "flake-utils"; + inputs.flake-compat.follows = "flake-compat"; + }; + + rust-overlay = { + url = "github:oxalica/rust-overlay"; + inputs.nixpkgs.follows = "nixpkgs"; + inputs.flake-utils.follows = "flake-utils"; + }; + flake-compat = { url = "github:edolstra/flake-compat"; flake = false; }; }; - outputs = inputs@{ self, nixpkgs, flake-parts, ... }: + outputs = inputs@{ self, nixpkgs, crane, rust-overlay, flake-parts, ... }: flake-parts.lib.mkFlake { inherit inputs; } ({ moduleWithSystem, ... }: { imports = [ # Derive the output overlay automatically from all packages that we define. @@ -41,20 +55,27 @@ inputs.pre-commit-hooks-nix.flakeModule ]; - flake.nixosModules.lanzaboote = moduleWithSystem (perSystem@{ config }: + flake.nixosModules.lanzaboote = moduleWithSystem ( + perSystem@{ config }: { ... }: { - imports = [ ./nix/modules/lanzaboote.nix ]; + imports = [ + ./nix/modules/lanzaboote.nix + ]; boot.lanzaboote.package = perSystem.config.packages.tool; - }); + } + ); - flake.nixosModules.uki = moduleWithSystem (perSystem@{ config }: + flake.nixosModules.uki = moduleWithSystem ( + perSystem@{ config }: { lib, ... }: { - imports = [ ./nix/modules/uki.nix ]; + imports = [ + ./nix/modules/uki.nix + ]; - boot.loader.uki.stub = lib.mkDefault - "${perSystem.config.packages.fatStub}/bin/lanzaboote_stub.efi"; - }); + boot.loader.uki.stub = lib.mkDefault "${perSystem.config.packages.fatStub}/bin/lanzaboote_stub.efi"; + } + ); systems = [ "x86_64-linux" @@ -65,32 +86,94 @@ perSystem = { config, system, pkgs, ... }: let - pkgs = import nixpkgs { inherit system; }; - uefiPkgs = import nixpkgs { - inherit system; - crossSystem = { - # linuxArch is wrong here, it will yield arm64 instead of aarch64. - config = "${pkgs.stdenv.hostPlatform.qemuArch}-windows"; - rustc.config = "${pkgs.stdenv.hostPlatform.qemuArch}-unknown-uefi"; - libc = null; - useLLVM = true; - }; + pkgs = import nixpkgs { + system = system; + overlays = [ + rust-overlay.overlays.default + ]; }; - utils = import ./nix/packages/utils.nix; inherit (pkgs) lib; - stub = uefiPkgs.callPackage ./nix/packages/stub.nix { - # cargo-auditable fails to build with: could not execute process .... No such file or directory (os error 2) - rustPlatform = uefiPkgs.makeRustPlatform { - inherit (uefiPkgs.buildPackages) rustc; - cargo = uefiPkgs.buildPackages.cargo.override { - auditable = false; - }; + uefi-rust-stable = pkgs.rust-bin.fromRustupToolchainFile ./rust/stub/rust-toolchain.toml; + craneLib = crane.lib.x86_64-linux.overrideToolchain uefi-rust-stable; + + # Build attributes for a Rust application. + buildRustApp = lib.makeOverridable ( + { src + , target ? null + , doCheck ? true + , extraArgs ? { } + }: + let + commonArgs = { + inherit src; + CARGO_BUILD_TARGET = target; + inherit doCheck; + + # Workaround for https://github.com/ipetkov/crane/issues/262. + dummyrs = pkgs.writeText "dummy.rs" '' + #![allow(unused)] + + #![cfg_attr( + any(target_os = "none", target_os = "uefi"), + no_std, + no_main, + )] + + #[cfg_attr(any(target_os = "none", target_os = "uefi"), panic_handler)] + fn panic(_info: &::core::panic::PanicInfo<'_>) -> ! { + loop {} + } + + #[cfg_attr(any(target_os = "none", target_os = "uefi"), export_name = "efi_main")] + fn main() {} + ''; + } // extraArgs; + + cargoArtifacts = craneLib.buildDepsOnly commonArgs; + in + { + package = craneLib.buildPackage (commonArgs // { + inherit cargoArtifacts; + }); + + clippy = craneLib.cargoClippy (commonArgs // { + inherit cargoArtifacts; + cargoClippyExtraArgs = "-- --deny warnings"; + }); + + rustfmt = craneLib.cargoFmt (commonArgs // { inherit cargoArtifacts; }); + } + ); + + stubCrane = buildRustApp { + src = craneLib.cleanCargoSource ./rust/stub; + target = "x86_64-unknown-uefi"; + doCheck = false; + }; + + fatStubCrane = stubCrane.override { + extraArgs = { + cargoExtraArgs = "--no-default-features --features fat"; }; }; - fatStub = stub.override { fatVariant = true; }; - tool = pkgs.callPackage ./nix/packages/tool.nix { }; + + stub = stubCrane.package; + fatStub = fatStubCrane.package; + + toolCrane = buildRustApp { + src = ./rust/tool; + extraArgs = { + TEST_SYSTEMD = pkgs.systemd; + nativeCheckInputs = with pkgs; [ + binutils-unwrapped + sbsigntool + ]; + }; + }; + + tool = toolCrane.package; wrappedTool = pkgs.runCommand "lzbt" { @@ -101,9 +184,7 @@ # Clean PATH to only contain what we need to do objcopy. Also # tell lanzatool where to find our UEFI binaries. makeWrapper ${tool}/bin/lzbt $out/bin/lzbt \ - --set PATH ${ - lib.makeBinPath [ pkgs.binutils-unwrapped pkgs.sbsigntool ] - } \ + --set PATH ${lib.makeBinPath [ pkgs.binutils-unwrapped pkgs.sbsigntool ]} \ --set LANZABOOTE_STUB ${stub}/bin/lanzaboote_stub.efi ''; in @@ -114,23 +195,24 @@ lzbt = wrappedTool; }; - overlayAttrs = { inherit (config.packages) tool; }; + overlayAttrs = { + inherit (config.packages) tool; + }; checks = let nixosLib = import (pkgs.path + "/nixos/lib") { }; - runTest = module: - nixosLib.runTest { - imports = [ module ]; - hostPkgs = pkgs; - }; + runTest = module: nixosLib.runTest { + imports = [ module ]; + hostPkgs = pkgs; + }; in { - stubFmt = uefiPkgs.callPackage (utils.rustfmt stub) { }; - toolFmt = pkgs.callPackage (utils.rustfmt tool) { }; - toolClippy = pkgs.callPackage (utils.clippy tool) { }; - stubClippy = uefiPkgs.callPackage (utils.clippy stub) { }; - fatStubClippy = uefiPkgs.callPackage (utils.clippy fatStub) { }; + toolClippy = toolCrane.clippy; + stubClippy = stubCrane.clippy; + fatStubClippy = fatStubCrane.clippy; + toolFmt = toolCrane.rustfmt; + stubFmt = stubCrane.rustfmt; } // (import ./nix/tests/lanzaboote.nix { inherit pkgs; lanzabooteModule = self.nixosModules.lanzaboote; @@ -174,7 +256,10 @@ pkgs.cargo-release ]; - inputsFrom = [ config.packages.stub config.packages.tool ]; + inputsFrom = [ + config.packages.stub + config.packages.tool + ]; TEST_SYSTEMD = pkgs.systemd; }; diff --git a/nix/packages/stub.nix b/nix/packages/stub.nix deleted file mode 100644 index 83435a2..0000000 --- a/nix/packages/stub.nix +++ /dev/null @@ -1,29 +0,0 @@ -{ rustPlatform, stdenv, lib, fatVariant ? false }: - -rustPlatform.buildRustPackage -{ - pname = "lanzaboote_stub"; - version = "0.3.0"; - src = lib.cleanSource ../../rust/stub; - - # We don't want the thin code. - buildNoDefaultFeatures = true; - buildFeatures = if fatVariant then [ "fat" ] else [ "thin" ]; - - cargoLock = { - lockFile = ../../rust/stub/Cargo.lock; - }; - - # Necessary because our `cc-wrapper` doesn't understand MSVC link options. - RUSTFLAGS = "-Clinker=${stdenv.cc.bintools}/bin/${stdenv.cc.targetPrefix}ld.lld -Clinker-flavor=lld-link"; - # Necessary because otherwise we will get (useless) hardening options in front of - # -flavor link which will break the whole command-line processing for the ld.lld linker. - hardeningDisable = [ "all" ]; - - meta = with lib; { - description = "Lanzaboote UEFI stub for SecureBoot enablement on NixOS systems"; - homepage = "https://github.com/nix-community/lanzaboote"; - license = licenses.mit; - platforms = [ "x86_64-windows" "aarch64-windows" "i686-windows" ]; - }; -} diff --git a/nix/packages/tool.nix b/nix/packages/tool.nix deleted file mode 100644 index ce2faed..0000000 --- a/nix/packages/tool.nix +++ /dev/null @@ -1,30 +0,0 @@ -{ systemd -, binutils-unwrapped -, sbsigntool -, rustPlatform -, lib -}: - -rustPlatform.buildRustPackage -{ - pname = "lanzaboote_tool"; - version = "0.3.0"; - src = lib.cleanSource ../../rust/tool; - - TEST_SYSTEMD = systemd; - - cargoLock = { - lockFile = ../../rust/tool/Cargo.lock; - }; - - nativeCheckInputs = [ - binutils-unwrapped - sbsigntool - ]; - - meta = with lib; { - description = "Lanzaboote UEFI tooling for SecureBoot enablement on NixOS systems"; - homepage = "https://github.com/nix-community/lanzaboote"; - license = licenses.mit; - }; -} diff --git a/nix/packages/utils.nix b/nix/packages/utils.nix deleted file mode 100644 index a5b0e56..0000000 --- a/nix/packages/utils.nix +++ /dev/null @@ -1,39 +0,0 @@ -{ - clippy = rustPackage: { lib, rust, clippy }: - let - targetSpec = rust.toRustTargetSpec rustPackage.stdenv.hostPlatform; - inherit (lib) optionalString concatStringsSep; - in - rustPackage.overrideAttrs (old: { - nativeBuildInputs = (old.nativeBuildInputs or [ ]) ++ [ clippy ]; - - doCheck = false; - - buildPhase = '' - echo "checking via clippy..." - cargo clippy --target ${targetSpec} ${optionalString (old.buildNoDefaultFeatures or false) "--no-default-features "}${optionalString ((old.buildFeatures or null) != null) ''--features="${concatStringsSep " " old.buildFeatures}" ''}-- -D warnings - if grep -R 'dbg!' ./src; then - echo "use of dbg macro found in code!" - false - fi - ''; - - installPhase = '' - touch $out - ''; - }); - rustfmt = rustPackage: { rustfmt }: rustPackage.overrideAttrs (old: { - nativeBuildInputs = (old.nativeBuildInputs or [ ]) ++ [ rustfmt ]; - - doCheck = false; - - buildPhase = '' - echo "checking formatting..." - cargo fmt --all -- --check - ''; - - installPhase = '' - touch $out - ''; - }); -}