From a0289ee5467bc4c1b6fe61797898e1161e519485 Mon Sep 17 00:00:00 2001 From: Daniel Flanagan Date: Wed, 31 Jul 2024 21:00:21 -0500 Subject: [PATCH] Add a crane build for incremental builds? --- .gitignore | 1 + flake.lock | 44 +++++++++++++++++++++++++++++++- flake.nix | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 114 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index 228f69f..4e1b6e3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +/result /target /.direnv /.pre-commit-config.yaml diff --git a/flake.lock b/flake.lock index ca8a66a..1ba1a1f 100644 --- a/flake.lock +++ b/flake.lock @@ -1,5 +1,25 @@ { "nodes": { + "crane": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1721842668, + "narHash": "sha256-k3oiD2z2AAwBFLa4+xfU+7G5fisRXfkvrMTCJrjZzXo=", + "owner": "ipetkov", + "repo": "crane", + "rev": "529c1a0b1f29f0d78fa3086b8f6a134c71ef3aaf", + "type": "github" + }, + "original": { + "owner": "ipetkov", + "repo": "crane", + "type": "github" + } + }, "flake-compat": { "flake": false, "locked": { @@ -94,8 +114,30 @@ }, "root": { "inputs": { + "crane": "crane", "git-hooks": "git-hooks", - "nixpkgs": "nixpkgs" + "nixpkgs": "nixpkgs", + "rust-overlay": "rust-overlay" + } + }, + "rust-overlay": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1722391647, + "narHash": "sha256-JTi7l1oxnatF1uX/gnGMlRnyFMtylRw4MqhCUdoN2K4=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "0fd4a5d2098faa516a9b83022aec7db766cd1de8", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" } } }, diff --git a/flake.nix b/flake.nix index 82f38a4..d98d55f 100644 --- a/flake.nix +++ b/flake.nix @@ -3,10 +3,16 @@ nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; git-hooks.url = "github:cachix/git-hooks.nix"; git-hooks.inputs.nixpkgs.follows = "nixpkgs"; + crane.url = "github:ipetkov/crane"; + crane.inputs.nixpkgs.follows = "nixpkgs"; + rust-overlay.url = "github:oxalica/rust-overlay"; + rust-overlay.inputs.nixpkgs.follows = "nixpkgs"; }; outputs = { self, git-hooks, + rust-overlay, + crane, nixpkgs, }: let inherit (self) outputs; @@ -14,7 +20,7 @@ systems = ["aarch64-linux" "aarch64-darwin" "x86_64-darwin" "x86_64-linux"]; forSystems = nixpkgs.lib.genAttrs systems; - pkgsFor = system: (import nixpkgs {inherit system;}).extend overlays.default; + pkgsFor = system: ((import nixpkgs {inherit system;}).extend overlays.default).extend rust-overlay.overlays.default; genPkgs = func: (forSystems (system: func (pkgsFor system))); buildTimeDeps = pkgs: with pkgs; [ @@ -61,8 +67,68 @@ build = outputs.packages.${pkgs.system}.default; }); - packages = genPkgs (pkgs: { - kodotag = pkgs.rustPlatform.buildRustPackage { + packages = genPkgs (pkgs: let + rustToolchainFor = p: + p.rust-bin.selectLatestNightlyWith (toolchain: + toolchain.default.override { + extensions = ["rust-src"]; + targets = ["x86_64-unknown-linux-gnu"]; + }); + rustToolchain = rustToolchainFor pkgs; + craneLib = (crane.mkLib pkgs).overrideToolchain rustToolchainFor; + + src = let + # per https://github.com/ipetkov/crane/blob/529c1a0b1f29f0d78fa3086b8f6a134c71ef3aaf/docs/source-filtering.md we need the font file since we bake it into the binary as the default bevy font + fontFilter = path: _type: builtins.match ".*ttf$" path != null; + filteredSources = path: type: + (fontFilter path type) || (craneLib.filterCargoSources path type); + in + pkgs.lib.cleanSourceWith { + src = ./.; # The original, unfiltered source + + filter = filteredSources; + name = "source"; # Be reproducible, regardless of the directory name + }; + in { + kodotag = craneLib.buildPackage { + # TODO: incremental rust builds with nix would be awesome + pname = "kodotag"; + version = "0.1.0"; + + inherit src; + strictDeps = true; + cargoVendorDir = craneLib.vendorMultipleCargoDeps { + inherit (craneLib.findCargoFiles src) cargoConfigs; + cargoLockList = [ + ./Cargo.lock + + # Unfortunately this approach requires IFD (import-from-derivation) + # otherwise Nix will refuse to read the Cargo.lock from our toolchain + # (unless we build with `--impure`). + # + # Another way around this is to manually copy the rustlib `Cargo.lock` + # to the repo and import it with `./path/to/rustlib/Cargo.lock` which + # will avoid IFD entirely but will require manually keeping the file + # up to date! + "${rustToolchain.passthru.availableComponents.rust-src}/lib/rustlib/src/rust/Cargo.lock" + ]; + }; + # cargoExtraArgs = "-Z build-std --target x86_64-unknown-linux-gnu"; + + nativeBuildInputs = buildTimeDeps pkgs; + buildInputs = linkTimeDeps pkgs; + hash = pkgs.lib.fakeHash; + # cargoHash = ""; + cargoHash = "sha256-d7luBIWHWn2ZpmSnIgpuLXsy1URUIojpPFboMtqa2ps="; + + # a hack to avoid using mold as our linker when building with nix + postUnpack = '' + ls -la + rm -r ./*/.cargo + ''; + }; + + kodotag-no-crane = pkgs.rustPlatform.buildRustPackage { pname = "kodotag"; version = "0.1.0"; nativeBuildInputs = buildTimeDeps pkgs; @@ -79,7 +145,7 @@ ''; }; - default = outputs.packages.${pkgs.system}.kodotag; + default = outputs.packages.${pkgs.system}.kodotag-no-crane; }); devShells = genPkgs (pkgs: {