this repo has no description
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Phase 0: Add flake.nix, devShell, NixOS module, and .envrc

Implements Phase 0 (Nix Packaging + DevShell) from the plan:

- flake.nix: Uses flakelight with nixpkgs-unstable, x86_64-linux only.
Autoloads package, devShell, and nixosModule from nix/ directory.
Exposes darling-sdk as a separate package output.

- nix/package.nix: Full darling package adapted from nixie-dev/darling-nix.
Includes ccWrapperBypass for Darwin cross-compilation, SDK splitting
via postInstall, and nix-store leak checks in postFixup.

- nix/devShell.nix: Comprehensive dev environment with clangStdenv,
all build deps + libraries, debug tools (gdb, strace, rizin),
code exploration (rg, fd, jq), Nix IDE (nil, nixfmt), and
C/C++ IDE (clangd). Sets CMAKE_EXPORT_COMPILE_COMMANDS=1.

- nix/nixosModule.nix: programs.darling.enable with unprivileged
user namespace config, FUSE setup, and optional persistent
prefix via systemd service.

- .envrc: 'use flake' for direnv/Zed integration.

- .gitignore: Add .direnv/, result, result-*.

+477
+1
.envrc
··· 1 + use flake
+5
.gitignore
··· 77 77 78 78 .idea 79 79 cmake-build-* 80 + 81 + # Nix / direnv 82 + .direnv/ 83 + result 84 + result-*
+48
flake.lock
··· 1 + { 2 + "nodes": { 3 + "flakelight": { 4 + "inputs": { 5 + "nixpkgs": [ 6 + "nixpkgs" 7 + ] 8 + }, 9 + "locked": { 10 + "lastModified": 1773062095, 11 + "narHash": "sha256-u+cK9IoJokO4YzQwMc2s8Vti0RL/LVSrROOEn2opc5U=", 12 + "owner": "nix-community", 13 + "repo": "flakelight", 14 + "rev": "c99e4d5f40e578cb2d8f460ea2bbd5dc26316d24", 15 + "type": "github" 16 + }, 17 + "original": { 18 + "owner": "nix-community", 19 + "repo": "flakelight", 20 + "type": "github" 21 + } 22 + }, 23 + "nixpkgs": { 24 + "locked": { 25 + "lastModified": 1772963539, 26 + "narHash": "sha256-9jVDGZnvCckTGdYT53d/EfznygLskyLQXYwJLKMPsZs=", 27 + "owner": "NixOS", 28 + "repo": "nixpkgs", 29 + "rev": "9dcb002ca1690658be4a04645215baea8b95f31d", 30 + "type": "github" 31 + }, 32 + "original": { 33 + "owner": "NixOS", 34 + "ref": "nixos-unstable", 35 + "repo": "nixpkgs", 36 + "type": "github" 37 + } 38 + }, 39 + "root": { 40 + "inputs": { 41 + "flakelight": "flakelight", 42 + "nixpkgs": "nixpkgs" 43 + } 44 + } 45 + }, 46 + "root": "root", 47 + "version": 7 48 + }
+32
flake.nix
··· 1 + { 2 + description = "Darling - macOS compatibility layer for Linux"; 3 + 4 + inputs = { 5 + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; 6 + flakelight = { 7 + url = "github:nix-community/flakelight"; 8 + inputs.nixpkgs.follows = "nixpkgs"; 9 + }; 10 + }; 11 + 12 + outputs = 13 + { flakelight, ... }@inputs: 14 + flakelight ./. { 15 + inherit inputs; 16 + 17 + systems = [ "x86_64-linux" ]; 18 + 19 + pname = "darling"; 20 + 21 + # Disable builtin formatters — the repo has 100+ submodules with 22 + # broken symlinks when not checked out, which causes the formatting 23 + # check to fail on `diff` of missing files. 24 + flakelight.builtinFormatters = false; 25 + 26 + # Default package is autoloaded from ./nix/package.nix 27 + # Default devShell is autoloaded from ./nix/devShell.nix 28 + # NixOS module is autoloaded from ./nix/nixosModule.nix 29 + 30 + packages.darling-sdk = pkgs: pkgs.darling.sdk; 31 + }; 32 + }
+76
nix/devShell.nix
··· 1 + # Development shell for working on Darling. 2 + # 3 + # Provides all build dependencies, debugging tools, and editor 4 + # integration (clangd, nil, nixfmt) so that `nix develop` or 5 + # direnv gives a fully-equipped environment. 6 + pkgs: { 7 + stdenv = pkgs.clangStdenv; 8 + 9 + packages = with pkgs; [ 10 + # ── Build dependencies ────────────────────────────────────── 11 + cmake 12 + ninja 13 + pkg-config 14 + bison 15 + flex 16 + python3 17 + makeWrapper 18 + 19 + # ── Libraries (needed by cmake at configure time) ────────── 20 + freetype 21 + libjpeg 22 + libpng 23 + libtiff 24 + giflib 25 + libX11 26 + libXext 27 + libXrandr 28 + libXcursor 29 + libxkbfile 30 + cairo 31 + libglvnd 32 + fontconfig 33 + dbus 34 + libGLU 35 + fuse 36 + ffmpeg 37 + pulseaudio 38 + libbsd 39 + openssl 40 + xdg-user-dirs 41 + 42 + # ── Debugging & analysis ──────────────────────────────────── 43 + gdb 44 + strace 45 + rizin 46 + file 47 + 48 + # ── Code exploration ──────────────────────────────────────── 49 + ripgrep 50 + fd 51 + jq 52 + 53 + # ── Nix tooling (for Zed / editor integration) ───────────── 54 + nil 55 + nixfmt 56 + 57 + # ── C/C++ tooling (for Zed / clangd) ─────────────────────── 58 + clang-tools 59 + ]; 60 + 61 + env = { 62 + # Make cmake produce compile_commands.json so clangd works. 63 + CMAKE_EXPORT_COMPILE_COMMANDS = "1"; 64 + }; 65 + 66 + shellHook = '' 67 + echo "🍎 darling-nix devShell loaded" 68 + echo " clang: $(clang --version | head -1)" 69 + echo " cmake: $(cmake --version | head -1)" 70 + echo "" 71 + echo "Quick start:" 72 + echo " mkdir -p build && cd build" 73 + echo " cmake -G Ninja .." 74 + echo " ninja -j\$(nproc)" 75 + ''; 76 + }
+95
nix/nixosModule.nix
··· 1 + # NixOS module for Darling — macOS compatibility layer for Linux. 2 + # 3 + # This module: 4 + # - Installs the Darling package 5 + # - Configures darlingserver (userspace-only mode, no kernel module) 6 + # - Optionally sets up a persistent prefix via a systemd service 7 + # - Ensures required kernel features (overlayfs, user namespaces) are enabled 8 + { 9 + config, 10 + lib, 11 + pkgs, 12 + ... 13 + }: 14 + let 15 + cfg = config.programs.darling; 16 + in 17 + { 18 + options.programs.darling = { 19 + enable = lib.mkEnableOption "Darling, the macOS compatibility layer for Linux"; 20 + 21 + package = lib.mkPackageOption pkgs "darling" { }; 22 + 23 + prefix = { 24 + enable = lib.mkEnableOption "persistent Darling prefix via systemd service"; 25 + 26 + path = lib.mkOption { 27 + type = lib.types.path; 28 + default = "/var/lib/darling"; 29 + description = '' 30 + Path where the persistent Darling prefix is stored. 31 + This directory holds the macOS-like filesystem tree that 32 + Darling overlays at runtime. 33 + ''; 34 + }; 35 + 36 + user = lib.mkOption { 37 + type = lib.types.str; 38 + default = "root"; 39 + description = '' 40 + User under which the darling-prefix service runs. 41 + The prefix is per-user in Darling, so this determines 42 + which user's prefix is initialised at boot. 43 + ''; 44 + }; 45 + }; 46 + 47 + settings = { 48 + unprivilegedUserNamespaces = lib.mkOption { 49 + type = lib.types.bool; 50 + default = true; 51 + description = '' 52 + Whether to enable unprivileged user namespaces 53 + (`kernel.unprivileged_userns_clone`). Required for 54 + darlingserver to operate without a kernel module. 55 + ''; 56 + }; 57 + }; 58 + }; 59 + 60 + config = lib.mkIf cfg.enable { 61 + # Install the darling package system-wide. 62 + environment.systemPackages = [ cfg.package ]; 63 + 64 + # darlingserver needs overlayfs and user namespaces to work 65 + # without its (deprecated) kernel module. 66 + boot.kernel.sysctl = lib.mkIf cfg.settings.unprivilegedUserNamespaces { 67 + "kernel.unprivileged_userns_clone" = 1; 68 + }; 69 + 70 + # Ensure FUSE is available (darling-dmg uses it). 71 + environment.etc."fuse.conf".text = lib.mkDefault '' 72 + user_allow_other 73 + ''; 74 + 75 + # Optional persistent prefix service. 76 + systemd.services.darling-prefix = lib.mkIf cfg.prefix.enable { 77 + description = "Initialise persistent Darling prefix"; 78 + wantedBy = [ "multi-user.target" ]; 79 + after = [ "local-fs.target" ]; 80 + 81 + serviceConfig = { 82 + Type = "oneshot"; 83 + RemainAfterExit = true; 84 + User = cfg.prefix.user; 85 + ExecStart = "${cfg.package}/bin/darling --prefix ${cfg.prefix.path} shell true"; 86 + ExecStop = "${cfg.package}/bin/darling --prefix ${cfg.prefix.path} shutdown"; 87 + }; 88 + }; 89 + 90 + # Create the prefix directory if the service is enabled. 91 + systemd.tmpfiles.rules = lib.mkIf cfg.prefix.enable [ 92 + "d ${cfg.prefix.path} 0755 ${cfg.prefix.user} root -" 93 + ]; 94 + }; 95 + }
+220
nix/package.nix
··· 1 + { 2 + clangStdenv, 3 + lib, 4 + runCommandWith, 5 + writeShellScript, 6 + src, 7 + freetype, 8 + libjpeg, 9 + libpng, 10 + libtiff, 11 + giflib, 12 + libX11, 13 + libXext, 14 + libXrandr, 15 + libXcursor, 16 + libxkbfile, 17 + cairo, 18 + libglvnd, 19 + fontconfig, 20 + dbus, 21 + libGLU, 22 + fuse, 23 + ffmpeg, 24 + pulseaudio, 25 + makeWrapper, 26 + python3, 27 + cmake, 28 + ninja, 29 + pkg-config, 30 + bison, 31 + flex, 32 + libbsd, 33 + openssl, 34 + xdg-user-dirs, 35 + addDriverRunpath, 36 + }: 37 + let 38 + stdenv = clangStdenv; 39 + 40 + # The build system invokes clang to compile Darwin executables. 41 + # In this case, our cc-wrapper must not be used -- if we detect a 42 + # `-target *darwin*` flag we call the *unwrapped* compiler so that 43 + # nixpkgs' cc-wrapper doesn't inject Linux-specific flags. 44 + ccWrapperBypass = 45 + runCommandWith 46 + { 47 + inherit stdenv; 48 + name = "cc-wrapper-bypass"; 49 + runLocal = false; 50 + derivationArgs = { 51 + template = writeShellScript "template" '' 52 + for (( i=1; i<=$#; i++)); do 53 + j=$((i+1)) 54 + if [[ "''${!i}" == "-target" && "''${!j}" == *"darwin"* ]]; then 55 + # their flags must take precedence 56 + exec @unwrapped@ "$@" $NIX_CFLAGS_COMPILE 57 + fi 58 + done 59 + exec @wrapped@ "$@" 60 + ''; 61 + }; 62 + } 63 + '' 64 + unwrapped_bin=${stdenv.cc.cc}/bin 65 + wrapped_bin=${stdenv.cc}/bin 66 + 67 + mkdir -p $out/bin 68 + 69 + unwrapped=$unwrapped_bin/$CC wrapped=$wrapped_bin/$CC \ 70 + substituteAll $template $out/bin/$CC 71 + unwrapped=$unwrapped_bin/$CXX wrapped=$wrapped_bin/$CXX \ 72 + substituteAll $template $out/bin/$CXX 73 + 74 + chmod +x $out/bin/$CC $out/bin/$CXX 75 + ''; 76 + 77 + wrappedLibs = [ 78 + freetype 79 + libjpeg 80 + libpng 81 + libtiff 82 + giflib 83 + libX11 84 + libXext 85 + libXrandr 86 + libXcursor 87 + libxkbfile 88 + cairo 89 + libglvnd 90 + fontconfig 91 + dbus 92 + libGLU 93 + fuse 94 + ffmpeg 95 + pulseaudio 96 + ]; 97 + in 98 + stdenv.mkDerivation { 99 + pname = "darling"; 100 + version = "unstable-2025"; 101 + 102 + # When building from the flake, `src` is the flake source directory. 103 + # All git submodules must be checked out: 104 + # git submodule update --init --recursive 105 + inherit src; 106 + 107 + outputs = [ 108 + "out" 109 + "sdk" 110 + ]; 111 + 112 + postPatch = '' 113 + # Be careful -- patching everything indiscriminately 114 + # would affect Darwin scripts as well. 115 + chmod +x src/external/bootstrap_cmds/migcom.tproj/mig.sh 116 + patchShebangs \ 117 + src/external/bootstrap_cmds/migcom.tproj/mig.sh \ 118 + src/external/darlingserver/scripts \ 119 + src/external/openssl_certificates/scripts 120 + 121 + substituteInPlace src/startup/CMakeLists.txt --replace SETUID "" 122 + substituteInPlace src/external/basic_cmds/CMakeLists.txt --replace SETGID "" 123 + ''; 124 + 125 + nativeBuildInputs = [ 126 + bison 127 + ccWrapperBypass 128 + cmake 129 + flex 130 + makeWrapper 131 + ninja 132 + pkg-config 133 + python3 134 + ]; 135 + 136 + buildInputs = wrappedLibs ++ [ 137 + libbsd 138 + openssl 139 + stdenv.cc.libc.linuxHeaders 140 + ]; 141 + 142 + # Breaks valid paths like 143 + # Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include 144 + dontFixCmake = true; 145 + 146 + # src/external/objc4 forces OBJC_IS_DEBUG_BUILD=1, which conflicts with NDEBUG 147 + cmakeBuildType = " "; 148 + 149 + cmakeFlags = [ 150 + "-DTARGET_i386=OFF" 151 + "-DCOMPILE_PY2_BYTECODE=OFF" 152 + "-DDARLINGSERVER_XDG_USER_DIR_CMD=${xdg-user-dirs}/bin/xdg-user-dir" 153 + ]; 154 + 155 + env.NIX_CFLAGS_COMPILE = "-Wno-macro-redefined -Wno-unused-command-line-argument"; 156 + 157 + # Linux .so's are dlopen'd by wrapgen during the build 158 + env.LD_LIBRARY_PATH = lib.makeLibraryPath wrappedLibs; 159 + 160 + # Breaks shebangs of Darwin scripts 161 + dontPatchShebangs = true; 162 + 163 + postInstall = '' 164 + # Install the SDK as a separate output 165 + mkdir -p $sdk 166 + 167 + sdkDir=$(readlink -f ../Developer) 168 + 169 + while read -r path; do 170 + dst="$sdk/Developer/''${path#$sdkDir}" 171 + 172 + if [[ -L "$path" ]]; then 173 + target=$(readlink -m "$path") 174 + if [[ -e "$target" && "$target" == "$NIX_BUILD_TOP"* && "$target" != "$sdkDir"* ]]; then 175 + cp -r -L "$path" "$dst" 176 + elif [[ -e "$target" ]]; then 177 + cp -d "$path" "$dst" 178 + else 179 + >&2 echo "Ignoring symlink $path -> $target" 180 + fi 181 + elif [[ -f $path ]]; then 182 + cp "$path" "$dst" 183 + elif [[ -d $path ]]; then 184 + mkdir -p "$dst" 185 + fi 186 + done < <(find $sdkDir) 187 + 188 + mkdir -p $sdk/bin 189 + cp src/external/cctools-port/cctools/ld64/src/*-ld $sdk/bin 190 + cp src/external/cctools-port/cctools/ar/*-{ar,ranlib} $sdk/bin 191 + ''; 192 + 193 + postFixup = '' 194 + echo "Checking for references to $NIX_STORE in Darling root..." 195 + 196 + set +e 197 + grep -r --exclude=mldr "$NIX_STORE" $out/libexec/darling 198 + ret=$? 199 + set -e 200 + 201 + if [[ $ret == 0 ]]; then 202 + echo "Found references to $NIX_STORE in Darling root (see above)" 203 + exit 1 204 + fi 205 + 206 + patchelf --add-rpath "${lib.makeLibraryPath wrappedLibs}:${addDriverRunpath.driverLink}/lib" \ 207 + $out/libexec/darling/usr/libexec/darling/mldr 208 + ''; 209 + 210 + dontCheckForBrokenSymlinks = true; 211 + 212 + meta = with lib; { 213 + description = "Open-source Darwin/macOS emulation layer for Linux"; 214 + homepage = "https://www.darlinghq.org"; 215 + changelog = "https://github.com/darlinghq/darling/releases"; 216 + license = licenses.gpl3Plus; 217 + platforms = [ "x86_64-linux" ]; 218 + mainProgram = "darling"; 219 + }; 220 + }