build: macOS support for the Nix flake

Add aarch64-darwin to the flake systems so packages, apps and both
devShells are exposed on Apple Silicon Macs. The Wayland/X11/EGL
runtime libraries, the /run/opengl-driver search paths, the freedesktop
packaging and the wrapProgram post-fixup are Linux-only and stay that
way: on macOS winit talks to AppKit, wgpu renders through Metal, and
the GPU drivers ship with the OS, so the darwin package needs no
wrapper. x86_64-darwin is deliberately not added: current nixpkgs
unstable no longer evaluates rustc for that platform (26.11
deprecation), so the package would fail on toolchain evaluation.

docs/nix.md: platform list updated, macOS paragraph in the graphics
section, desktop-entry paragraph qualified as Linux-only.
This commit is contained in:
Levon Kirakosyan authored and bherbruck committed 2026-10-12 10:06:03 -04:00
1 parent 874315db8e
commit c308a1ba7a
2 files changed
+63 -45

No files matched your search

+55 -42
View File
@@ -1,5 +1,5 @@
{
description = "SolidCraft — native app development shell and package for Linux";
description = "SolidCraft — native app development shell and package for Linux and macOS";
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
@@ -9,10 +9,11 @@
systems = [
"x86_64-linux"
"aarch64-linux"
"aarch64-darwin"
];
forAllSystems = f: nixpkgs.lib.genAttrs systems (system: f nixpkgs.legacyPackages.${system});
# Why this shell exists. winit opens the window by dlopen'ing the Wayland client libraries,
# Linux only. Why this shell exists. winit opens the window by dlopen'ing the Wayland client libraries,
# wgpu renders through the EGL loader (libEGL.so.1), and rfd's file dialogs reach
# xdg-desktop-portal through libdbus-1; a plain `cargo run` under NixOS finds none of them,
# because there is no /usr/lib and nothing puts them on LD_LIBRARY_PATH:
@@ -29,34 +30,44 @@
# `xvfb-run` on a machine with no display at all.
runtimeLibs =
pkgs:
(with pkgs; [
wayland
libxkbcommon
libglvnd
vulkan-loader
dbus
])
++ (with pkgs; [
# xorg.libX11 and friends are deprecated aliases in current nixpkgs.
libx11
libxcursor
libxi
libxrandr
libxrender
libxext
libxcb
]);
driverLibDir = "/run/opengl-driver/lib";
driverShareDir = "/run/opengl-driver/share";
libraryPath = pkgs: "${pkgs.lib.makeLibraryPath (runtimeLibs pkgs)}:${driverLibDir}";
pkgs.lib.optionals pkgs.stdenv.isLinux (
(with pkgs; [
wayland
libxkbcommon
libglvnd
vulkan-loader
dbus
])
++ (with pkgs; [
# xorg.libX11 and friends are deprecated aliases in current nixpkgs.
libx11
libxcursor
libxi
libxrandr
libxrender
libxext
libxcb
])
);
# macOS needs none of the above: winit talks to AppKit, wgpu renders through Metal, and the
# OS ships its GPU drivers, so the darwin package and shells skip the wrapper and paths.
driverLibDir = pkgs: if pkgs.stdenv.isLinux then "/run/opengl-driver/lib" else "";
driverShareDir = pkgs: if pkgs.stdenv.isLinux then "/run/opengl-driver/share" else "";
libraryPath =
pkgs:
if pkgs.stdenv.isLinux then "${pkgs.lib.makeLibraryPath (runtimeLibs pkgs)}:${driverLibDir pkgs}" else "";
shellHook = ''
if [ ! -d ${driverLibDir} ]; then
echo "SolidCraft: ${driverLibDir} is missing — on NixOS enable hardware.graphics; on other distributions use a matching nixGL driver wrapper." >&2
fi
shellHook = pkgs: ''
${pkgs.lib.optionalString pkgs.stdenv.isLinux ''
if [ ! -d ${driverLibDir pkgs} ]; then
echo "SolidCraft: ${driverLibDir pkgs} is missing — on NixOS enable hardware.graphics; on other distributions use a matching nixGL driver wrapper." >&2
fi
''}
command -v cc >/dev/null || echo "solvecraft: no C linker on PATH, cargo cannot link — use nix develop .#rust" >&2
echo "solvecraft: cargo run --release -p solvecraft -- --sample"
export XDG_DATA_DIRS="${driverShareDir}:''${XDG_DATA_DIRS:-/usr/local/share:/usr/share}"
${pkgs.lib.optionalString pkgs.stdenv.isLinux ''
export XDG_DATA_DIRS="${driverShareDir pkgs}:''${XDG_DATA_DIRS:-/usr/local/share:/usr/share}"
''}
'';
in
{
@@ -68,7 +79,7 @@
default = pkgs.mkShellNoCC {
name = "solidcraft";
LD_LIBRARY_PATH = libraryPath pkgs;
inherit shellHook;
shellHook = shellHook pkgs;
};
# For a machine with no Rust at all: `nix develop .#rust`. Its own target directory, so
@@ -85,7 +96,7 @@
# Under target/, which .gitignore already covers.
CARGO_TARGET_DIR = "target/nix";
shellHook = ''
${shellHook}
${shellHook pkgs}
echo "solvecraft: $(rustc --version), building into target/nix"
'';
};
@@ -123,25 +134,27 @@
buildInputs = runtimeLibs pkgs;
postInstall = ''
install -Dm644 packaging/linux/ai.storyteller.solvecraft.desktop \
$out/share/applications/ai.storyteller.solvecraft.desktop
install -Dm644 packaging/linux/ai.storyteller.solvecraft.mime.xml \
$out/share/mime/packages/ai.storyteller.solvecraft.xml
for size in 16 24 32 48 64 128 256 512; do
icon=$out/share/icons/hicolor/''${size}x''${size}/apps/ai.storyteller.solvecraft.png
mkdir -p "$(dirname "$icon")"
$out/bin/solvecraft-cli icon --size "$size" --out "$icon" >/dev/null
done
ln -s solvecraft $out/bin/solidcraft
${pkgs.lib.optionalString pkgs.stdenv.isLinux ''
install -Dm644 packaging/linux/ai.storyteller.solvecraft.desktop \
$out/share/applications/ai.storyteller.solvecraft.desktop
install -Dm644 packaging/linux/ai.storyteller.solvecraft.mime.xml \
$out/share/mime/packages/ai.storyteller.solvecraft.xml
for size in 16 24 32 48 64 128 256 512; do
icon=$out/share/icons/hicolor/''${size}x''${size}/apps/ai.storyteller.solvecraft.png
mkdir -p "$(dirname "$icon")"
$out/bin/solvecraft-cli icon --size "$size" --out "$icon" >/dev/null
done
''}
'';
# The app reaches the window through dlopen'd libraries, so the packaged binary needs the
# same LD_LIBRARY_PATH the shell exports.
postFixup = ''
# Linux only: the app reaches the window through dlopen'd libraries, so the packaged
# binary needs the same LD_LIBRARY_PATH the shell exports. macOS needs no wrapper.
postFixup = pkgs.lib.optionalString pkgs.stdenv.isLinux ''
wrapProgram $out/bin/solvecraft \
--prefix LD_LIBRARY_PATH : "${libraryPath pkgs}" \
--set-default XDG_DATA_DIRS /usr/local/share:/usr/share \
--prefix XDG_DATA_DIRS : "$out/share:${driverShareDir}"
--prefix XDG_DATA_DIRS : "$out/share:${driverShareDir pkgs}"
'';
meta = {