{ inputs = { 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; inherit (outputs) overlays; 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).extend rust-overlay.overlays.default; genPkgs = func: (forSystems (system: func (pkgsFor system))); buildTimeDeps = pkgs: with pkgs; [ pkg-config clang mold wayland clang ]; linkTimeDeps = pkgs: with pkgs; [ mold wayland clang udev alsa-lib vulkan-loader libxkbcommon xorg.libX11 xorg.libXcursor xorg.libXi xorg.libXrandr ]; in { checks = genPkgs (pkgs: { git-hooks = git-hooks.lib.${pkgs.system}.run { src = ./.; hooks = { alejandra.enable = true; # NOTE: These do not work well with `nix flake check` due to pure environments # https://github.com/cachix/git-hooks.nix/issues/452 # cargo-check.enable = true; # clippy = { # enable = true; # packageOverrides.cargo = pkgs.cargo; # packageOverrides.clippy = pkgs.rustPackages.clippy; # }; rustfmt = { enable = true; packageOverrides.rustfmt = pkgs.rustfmt; }; }; }; build = outputs.packages.${pkgs.system}.default; build-no-crane = outputs.packages.${pkgs.system}.kodotag-no-crane; }); 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; buildInputs = linkTimeDeps pkgs; src = ./.; 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 ''; }; default = outputs.packages.${pkgs.system}.kodotag-no-crane; }); devShells = genPkgs (pkgs: { default = pkgs.mkShell { inherit (self.checks.${pkgs.system}.git-hooks) shellHook; inputsFrom = [outputs.packages.${pkgs.system}.default]; packages = with pkgs; [ rustPackages.clippy rust-analyzer rustfmt ]; LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath (linkTimeDeps pkgs); }; }); overlays = { default = final: prev: {}; }; formatter = genPkgs (p: p.alejandra); }; }