{ description = "stable-diffusion.cpp as a NixOS programs.* module (system nixpkgs)"; outputs = { self, ... }: { nixosModules.default = { config, lib, pkgs, ... }: let cfg = config.programs.stable-diffusion-cpp; builtPackage = pkgs.stdenv.mkDerivation { pname = "stable-diffusion-cpp"; version = "git"; src = pkgs.fetchFromGitHub { owner = "leejet"; repo = "stable-diffusion.cpp"; rev = "master-453-4ff2c8c"; # pin to a commit for reproducibility hash = "sha256-0Hl3M6NQK1ZfIH4eIdy/XiPZTeBCnRCtode88NipPp4="; fetchSubmodules = true; }; nativeBuildInputs = with pkgs; [ cmake ninja pkg-config ]; buildInputs = (lib.optionals cfg.vulkan.enable (with pkgs; [ vulkan-headers vulkan-loader shaderc ])); cmakeFlags = [ "-DCMAKE_BUILD_TYPE=Release" "-DCMAKE_POLICY_VERSION_MINIMUM=3.5" "-DSD_VULKAN=${if cfg.vulkan.enable then "ON" else "OFF"}" ]; installPhase = '' runHook preInstall mkdir -p $out/bin cp -v bin/sd $out/bin/ || cp -v sd $out/bin/ runHook postInstall ''; }; selectedPackage = if cfg.package != null then cfg.package else builtPackage; extraEnvArgs = lib.concatStringsSep " \\\n " (lib.mapAttrsToList (k: v: "--set ${lib.escapeShellArg k} ${lib.escapeShellArg v}" ) cfg.extraEnv); wrappedPackage = pkgs.symlinkJoin { name = "${selectedPackage.pname or "stable-diffusion-cpp"}"; paths = [ selectedPackage ]; nativeBuildInputs = [ pkgs.makeWrapper ]; postBuild = '' if [ -x "$out/bin/sd" ]; then wrapProgram "$out/bin/sd" \ ${lib.optionalString (cfg.vulkan.enable && cfg.vulkan.icdFile != null) "--set-default VK_ICD_FILENAMES ${lib.escapeShellArg (toString cfg.vulkan.icdFile)}"} \ ${lib.optionalString (cfg.vulkan.enable && cfg.vulkan.prefixOpenGLXdgDataDirs) "--prefix XDG_DATA_DIRS : /run/opengl-driver/share"} \ ${extraEnvArgs} fi ''; }; finalPackage = if cfg.wrap then wrappedPackage else selectedPackage; in { options.programs.stable-diffusion-cpp = { enable = lib.mkEnableOption "stable-diffusion.cpp"; package = lib.mkOption { type = lib.types.nullOr lib.types.package; default = null; description = "Override the package used (otherwise build from upstream source)."; }; wrap = lib.mkOption { type = lib.types.bool; default = true; description = "Wrap the sd binary to inject environment variables."; }; extraEnv = lib.mkOption { type = lib.types.attrsOf lib.types.str; default = { }; description = "Extra environment variables added to the sd wrapper."; }; vulkan = { enable = lib.mkOption { type = lib.types.bool; default = true; description = "Build with Vulkan support (toggles -DSD_VULKAN and Vulkan deps)."; }; icdFile = lib.mkOption { type = lib.types.nullOr lib.types.path; default = null; example = /run/opengl-driver/share/vulkan/icd.d/intel_icd.x86_64.json; description = "Optional VK_ICD_FILENAMES value to select a Vulkan ICD."; }; prefixOpenGLXdgDataDirs = lib.mkOption { type = lib.types.bool; default = true; description = "Prefix XDG_DATA_DIRS with /run/opengl-driver/share (useful for Vulkan layers/ICDs on NixOS)."; }; }; }; config = lib.mkIf cfg.enable { environment.systemPackages = [ finalPackage ]; }; }; }; }