diff --git a/default.nix b/default.nix index c0666ee3..594d98a1 100644 --- a/default.nix +++ b/default.nix @@ -1,8 +1,11 @@ -#{ pkgs ? import { overlays = [ (final: prev: { llvmPackages = prev.llvmPackages_17; }) ]; } }: -#pkgs.mkShell { -# buildInputs = [ pkgs.coreutils ]; -#} - +# default.nix - xo development environment +# +# Constructs pkgs with build-from-source overlays (for local nixpkgs), +# then delegates to shells.nix for dev shell definitions. +# +# For pre-built nixpkgs (e.g. CI or binary cache), use shells.nix directly +# with a plain pkgs that has xo-overlay applied. +# { # official 24.05 release # nearly works on macos, clang17, llvm18 except for sphinx-contrib.ditaa # on roly-chicago-24: using nixos-25.05, local nixpkgs @@ -112,10 +115,6 @@ let }); }; - # xo packages defined in xo.nix; wrap as overlay so pkgs.xo-* works - xo-overlay = self: super: - import ./xo.nix { pkgs = self; }; - in let pkgs = import nixpkgs-path { @@ -131,864 +130,9 @@ let fish-overlay # nixgl-overlay # llvm-overlay - xo-overlay + # note: xo-overlay applied inside shells.nix ]; }; - # bona fide bux in git 2.50.1 - # bug when using: - # git subtree split ... - # git subtree needs to review a set of commits, filtering for those that - # intersect with target prefix. e.g. - # git subtree split --prefix=xo-indentlog -b _demux/xo-indentlog - # - # 1. the split function is building a map old->new from commits in current repo, - # to a smaller set of commits in the split repo: - # it intends finding commits that intersect with anything in prefix, - # adding old->new map entries for each such commit. - # - # 2. subtree (incorrectly?) decides it needs to cache a commit that does not - # actually intersect prefix. Calls its cache_set() twice with the same newrev. - # 2nd calls aborts, assumes cache should not already contain an oldrev key. - # - # 3. fix is to permit multiple calls to cache_set() with the same old->new - # mapping. Keep the abort if called twice with different target commits. - # - patched-git = pkgs.git.overrideAttrs (old: { - postInstall = (old.postInstall or "") + '' - patch $out/libexec/git-core/git-subtree ${./patches/git-subtree-cache-fix.patch} - ''; - }); in - -let - xo_topdir = toString ./.; - - fonts = pkgs.makeFontsConf { - fontDirectories = [ - pkgs.inconsolata-lgc - pkgs.noto-fonts - pkgs.noto-fonts-emoji - pkgs.dejavu_fonts - ]; - }; - - # xo deps - xodeps = [ - pkgs.python3Packages.python - # note: pybind11 won't build on roly-chicago-24a in nix sandbox, runs out of pty devices - # - pkgs.python3Packages.pybind11 - pkgs.python3Packages.json5 - pkgs.python3Packages.jinja2 - pkgs.llvmPackages_18.llvm.dev - pkgs.replxx - pkgs.libwebsockets - pkgs.jsoncpp - pkgs.eigen - pkgs.libunwind - ] ++ (if pkgs.stdenv.isLinux then [ - pkgs.elfutils.dev # for libdw (DWARF debug info lookup) - ] else [ - pkgs.llvmPackages_18.libunwind.dev - ]) ++ [ - pkgs.zlib - pkgs.libbsd - ]; - - # emacs - emacs4xo = (pkgs.emacsPackagesFor pkgs.emacs30).emacsWithPackages (epkgs: with epkgs; [ - lsp-mode - lsp-ui - lsp-ivy - flycheck - ivy - rg - transient # magit dep - nix-mode - yaml-mode - htmlize - magit - exec-path-from-shell - highlight - surround - projectile - treemacs - treemacs-projectile - company - cmake-mode - which-key - xterm-color - yasnippet - ] ++ pkgs.lib.optionals pkgs.stdenv.isLinux [ - notmuch - ]); - - # xo ide utils - ideutils = [ - pkgs.gsettings-desktop-schemas - emacs4xo - # pkgs.emacs-pgtk # wayland with treesitter; alternatively pkgs.emacs30 for emacs+tree-sitter - pkgs.tree-sitter # CLI tool, but not grammars - pkgs.llvmPackages_18.clang-tools # clangd for lsp-mode - pkgs.notmuch - pkgs.emacsPackages.notmuch - pkgs.inconsolata-lgc - pkgs.fontconfig -] -++ (if pkgs.stdenv.isLinux then [ - pkgs.ghostty -] else []) -++ [ - pkgs.timg - pkgs.fish - pkgs.nushell - ]; - - # xo general-purpose devutils - devutils = [ - pkgs.nix-tree # note: needs GHC - #pkgs.nix - - patched-git # instead of pkgs.git - pkgs.gh # github cli - pkgs.cloc - pkgs.bloaty - - pkgs.catch2 - pkgs.cli11 - - pkgs.btop - ] - ++ (if pkgs.stdenv.isLinux then [ - pkgs.gdb - pkgs.strace - pkgs.lcov # gcov-format coverage post-processing - ] else [ - pkgs.llvmPackages_18.lldb - pkgs.llvmPackages_18.llvm # llvm-profdata, llvm-cov for source-based coverage - ]) - ++ [ - pkgs.which - pkgs.man - pkgs.man-pages - pkgs.less - pkgs.ripgrep - pkgs.openssh - - pkgs.ccache -] -++ (if pkgs.stdenv.isLinux then [ - pkgs.distcc -] else []) - ++ [ - pkgs.cmake - pkgs.pkg-config - pkgs.unzip - ]; - - # xo docutils - docutils = - pkgs.lib.optionals pkgs.stdenv.isLinux [ - pkgs.python3Packages.sphinxcontrib-ditaa - ] ++ - [ - pkgs.python3Packages.python - pkgs.python3Packages.pillow - pkgs.python3Packages.breathe - #pkgs.python3Packages.sphinx-autobuild # needs patch for typeguard; defer for now - pkgs.python3Packages.sphinx-rtd-theme - pkgs.python3Packages.sphinxcontrib-plantuml - pkgs.doxygen - pkgs.graphviz - pkgs.ditaa - pkgs.sphinx - ]; - - # xo x11utils - x11utils = - [ - pkgs.xorg.xcbutil - pkgs.xorg.xcbutilwm # xcb window manager utilities - pkgs.xorg.xcbutilimage - pkgs.xorg.xclock - pkgs.xorg.xdpyinfo - ]; - - # xo opengl utils - gldeps = - [ - # glew: used for opengl apps; not needed for vulkan apps (even when those apps use opengl) - pkgs.glew - ] ++ pkgs.lib.optionals pkgs.stdenv.isLinux [ - pkgs.mesa-demos - ] ++ [ - pkgs.libGL - ]; - - vkdeps = - pkgs.lib.optionals pkgs.stdenv.isDarwin [ - pkgs.darwin.moltenvk - ] ++ - [ pkgs.vulkan-tools - pkgs.vulkan-loader - pkgs.vulkan-headers - pkgs.vulkan-validation-layers - ]; - - imguideps = - [ -# pkgs.imgui # incorporated directly into xo dev tree, see xo-imgui/include/imgui - pkgs.SDL2.dev - pkgs.xorg.libX11.dev # e.g. for X11/Xlib.h; needed by SDL2 - - pkgs.dejavu_fonts # also must set DEJAVU_FONTS_PATH for imgui_ex2 - ]; - - shell4-assembly = - { ld-library-path-before, - vk-icd-filenames, - shell-hook-text-after, - } : - - pkgs.mkShell { - buildInputs = docutils ++ xodeps ++ devutils ++ ideutils ++ x11utils ++ gldeps ++ vkdeps ++ imguideps; - - shellHook = - let - # dependencies of host system libraries - # (e.g. from /usr/lib/x86_64-linux-gnu) that we want to satisfy from nix; - # sufficient for glxgears - # - # be careful here: easy to insert something that breaks xo cmake build - # - # with minimal list - # (libXau, libXdmcp, libX11, libXext, libXfixes, libXxf86vm, libxml2, libffi, - # elfutils, ncurses, expat, zstd, zlib, libbsd, gcc.cc.lib) - # glxgears runs at ~170fps - # - glpath = pkgs.lib.makeLibraryPath ([ - pkgs.wayland # for libwayland-client.so - - pkgs.xorg.libXau - pkgs.xorg.libXdmcp - pkgs.xorg.libX11 # e.g. for libX11-xcb.so - pkgs.xorg.libXext - pkgs.xorg.libXfixes - pkgs.xorg.libXxf86vm - pkgs.xorg.libxcb - - pkgs.libxml2 - pkgs.libffi - - ] ++ (if pkgs.stdenv.isLinux then [ pkgs.elfutils ] else []) - ++ [ - pkgs.ncurses # for libtinfo.so - pkgs.expat - pkgs.zstd - pkgs.zlib # for libz.so - pkgs.libbsd - - pkgs.gcc.cc.lib # for libstdc++.so (won't blow up cmake, only touching LD_LIBRARY_PATH) - ]); - in - '' - # CXENV: cosmetic: coordinates with ~/proj/env/dotfiles/bashrc to drive PS1 - export CXENV=$CXENV:xo4 - - # override SOURCE_DATE_EPOCH to current time (otherwise will get 1980) - export SOURCE_DATE_EPOCH=$(date +%s) - - # fonts - export FONTCONFIG_FILE=${fonts} - export FONTCONFIG_PATH=${pkgs.fontconfig.out}/etc/fonts - export DEJAVU_FONTS_PATH=${pkgs.dejavu_fonts}/share/fonts - ${pkgs.fontconfig}/bin/fc-cache -f - - # nix-provided GPU libraries only work out-of-the-box on nixos. - # For non-nixos build, need to use host-provided versions of these libraries. - # Complications: - # 1. host location is likely something like /usr/lib/x86_64-linux-gnu, - # in which case interposing that directly will change link behavior for unrelated shared libraries - # (e.g. risk getting stale non-nix libc.so etc). Use a curated symlink directory to finesse. - # 2. host-installed libraries may not set RUNPATH (they don't need to if installed in system-wide default location). - # We need to also add nix-store LD_LIBRARY_PATH entries for indirect dependencies of system-provided libraries. - # - export LD_LIBRARY_PATH=${ld-library-path-before}:${glpath}:$LD_LIBRARY_PATH - - export VK_ICD_FILENAMES="${vk-icd-filenames}" - - # need this on OSX, + claude wants it for both wsl2, ubuntu - export VK_LAYER_PATH=${pkgs.vulkan-validation-layers}/share/vulkan/explicit_layer.d - - # hardware acceleration - export LIBGL_ALWAYS_SOFTWARE=0 - export MESA_LOADER_DRIVER_OVERRIDE="" - - echo "tree_sitter=${pkgs.tree-sitter}" - tree_sitter=${pkgs.tree-sitter} - echo "nix_mesa=${pkgs.mesa}" - nix_mesa=${pkgs.mesa} - - ${shell-hook-text-after} - ''; - }; -in -{ - pkgs = pkgs; - xo = { - cmake = pkgs.xo-cmake; - indentlog = pkgs.xo-indentlog; - reflectutil = pkgs.xo-reflectutil; - randomgen = pkgs.xo-randomgen; - arena = pkgs.xo-arena; - facet = pkgs.xo-facet; - allocutil = pkgs.xo-allocutil; - refcnt = pkgs.xo-refcnt; - subsys = pkgs.xo-subsys; - testutil = pkgs.xo-testutil; - flatstring = pkgs.xo-flatstring; - pyutil = pkgs.xo-pyutil; - reflect = pkgs.xo-reflect; - pyreflect = pkgs.xo-pyreflect; - ratio = pkgs.xo-ratio; - unit = pkgs.xo-unit; - pyunit = pkgs.xo-pyunit; - callback = pkgs.xo-callback; - printable2 = pkgs.xo-printable2; - alloc = pkgs.xo-alloc; - alloc2 = pkgs.xo-alloc2; - stringtable2 = pkgs.xo-stringtable2; - gc = pkgs.xo-gc; - object = pkgs.xo-object; - type = pkgs.xo-type; - object2 = pkgs.xo-object2; - procedure2 = pkgs.xo-procedure2; - numeric = pkgs.xo-numeric; - ordinaltree = pkgs.xo-ordinaltree; - tokenizer2 = pkgs.xo-tokenizer2; - - webutil = pkgs.xo-webutil; - pywebutil = pkgs.xo-pywebutil; - printjson = pkgs.xo-printjson; - pyprintjson = pkgs.xo-pyprintjson; - reactor = pkgs.xo-reactor; - pyreactor = pkgs.xo-pyreactor; - websock = pkgs.xo-websock; - pywebsock = pkgs.xo-pywebsock; - statistics = pkgs.xo-statistics; - distribution = pkgs.xo-distribution; - pydistribution = pkgs.xo-pydistribution; - simulator = pkgs.xo-simulator; - pysimulator = pkgs.xo-pysimulator; - process = pkgs.xo-process; - pyprocess = pkgs.xo-pyprocess; - kalmanfilter = pkgs.xo-kalmanfilter; - pykalmanfilter = pkgs.xo-pykalmanfilter; - expression = pkgs.xo-expression; - pyexpression = pkgs.xo-pyexpression; - tokenizer = pkgs.xo-tokenizer; - reader = pkgs.xo-reader; - jit = pkgs.xo-jit; - pyjit = pkgs.xo-pyjit; - }; - - # works, but only if build with --option sandbox=false - # to workaround pcre broken. overlay above does work, - # but is not applied to stdenv devs - # - shellpre = pkgs.mkShell { - buildInputs = [ - # NOTE: pkgs.pcre2, pkgs.dejagnu, pkgs.libffi - # also won't build in genuine sandbox - - pkgs.nix-tree # needs GHC btw - patched-git # instead of pkgs.git - pkgs.openssh - pkgs.cloc - pkgs.lcov - pkgs.gdb - pkgs.strace - - pkgs.ripgrep - - pkgs.clang # 19.1.7 - pkgs.ninja # will this work? tbd - pkgs.cmake - pkgs.distcc - pkgs.pkg-config - pkgs.unzip - ]; - - # includes stdenv, so will have gcc,gawk,tar,gzip etc. - shellHook = '' - # CXENV: cosmetic: coordinates with ~/proj/env/dotfiles/bashrc to drive PS1 - export CXENV=$CXENV:xopre - - # override SOURCE_DATE_EPOCH to current time (otherwise will get 1980) - export SOURCE_DATE_EPOCH=$(date +%s) - ''; - }; - - # minimal shell - just enough to verify gcc works. - # not sufficient to build xo - # - # $ nix-shell -A shell0 # requires nixpkgs.runCommand - # - shell0 = pkgs.mkShell { - buildInputs = devutils; - - # includes stdenv, so will have gcc,gawk,tar,gzip etc - shellHook = '' - # CXENV: cosmetic: coordinates with ~/proj/env/dotfiles/bashrc to drive PS1 - export CXENV=$CXENV:xo0 - - # override SOURCE_DATE_EPOCH to current time (otherwise will get 1980) - export SOURCE_DATE_EPOCH=$(date +%s) - ''; - }; - - # stable shell. can build xo without docs - # - shell1a = pkgs.mkShell { - buildInputs = xodeps ++ devutils; - - shellHook = '' - # CXENV: cosmetic: coordinates with ~/proj/env/dotfiles/bashrc to drive PS1 - export CXENV=$CXENV:xo1a - - # override SOUCE_DATE_EPOCH to current time (otherwise will get 1980) - export SOURCE_DATE_EPOCH=$(date +%s) - ''; - }; - - # minimal shell, intended to be stable - shell1 = pkgs.mkShell { - buildInputs = docutils ++ xodeps ++ devutils; - - # includes stdenv, so will have gcc,gawk,tar,gzip etc - shellHook = '' - # CXENV: cosmetic: coordinates with ~/proj/env/dotfiles/bashrc to drive PS1 - export CXENV=$CXENV:xo1 - - # override SOUCE_DATE_EPOCH to current time (otherwise will get 1980) - export SOURCE_DATE_EPOCH=$(date +%s) - ''; - }; - - # minimal shell + ide stuff, intended to be stable - shell2 = pkgs.mkShell { - buildInputs = docutils ++ xodeps ++ devutils ++ ideutils; - - # includes stdenv, so will have gcc,gawk,tar,gzip etc - shellHook = '' - # CXENV: cosmetic: coordinates with ~/proj/env/dotfiles/bashrc to drive PS1 - export CXENV=$CXENV:xo2 - - # override SOUCE_DATE_EPOCH to current time (otherwise will get 1980) - export SOURCE_DATE_EPOCH=$(date +%s) - - export FONTCONFIG_FILE=${fonts} - export FONTCONFIG_PATH=${pkgs.fontconfig.out}/etc/fonts - ${pkgs.fontconfig}/bin/fc-cache -f - ''; - }; - - # xo shell with opengl support - shell3 = pkgs.mkShell { - buildInputs = docutils ++ xodeps ++ devutils ++ ideutils ++ x11utils ++ gldeps ++ vkdeps ++ imguideps; - - shellHook = - let - # dependencies of host system libraries - # (e.g. from /usr/lib/x86_64-linux-gnu) that we want to satisfy from nix; - # sufficient for glxgears - # - # be careful here: easy to insert something that breaks xo cmake build - # - # with minimal list - # (libXau, libXdmcp, libX11, libXext, libXfixes, libXxf86vm, libxml2, libffi, - # elfutils, ncurses, expat, zstd, zlib, libbsd, gcc.cc.lib) - # glxgears runs at ~170fps - # - glpath = pkgs.lib.makeLibraryPath ([ - pkgs.wayland # for libwayland-client.so - - pkgs.xorg.libXau - pkgs.xorg.libXdmcp - pkgs.xorg.libX11 # e.g. for libX11-xcb.so - pkgs.xorg.libXext - pkgs.xorg.libXfixes - pkgs.xorg.libXxf86vm - - pkgs.libxml2 - pkgs.libffi - - ] ++ (if pkgs.stdenv.isLinux then [ pkgs.elfutils ] else []) - ++ [ - pkgs.ncurses # for libtinfo.so - pkgs.expat - pkgs.zstd - pkgs.zlib # for libz.so - pkgs.libbsd - - pkgs.gcc.cc.lib # for libstdc++.so (won't blow up cmake, only touching LD_LIBRARY_PATH) - ]); - in - '' - # CXENV: cosmetic: coordinates with ~/proj/env/dotfiles/bashrc to drive PS1 - export CXENV=$CXENV:xo3 - - # override SOUCE_DATE_EPOCH to current time (otherwise will get 1980) - export SOURCE_DATE_EPOCH=$(date +%s) - - # fonts - export FONTCONFIG_FILE=${fonts} - export FONTCONFIG_PATH=${pkgs.fontconfig.out}/etc/fonts - ${pkgs.fontconfig}/bin/fc-cache -f - - # nix-provided GPU libraries only work out-of-the-box on nixos. - # For non-nixos build, need to use host-provided versions of these libraries. - # Complications: - # 1. host location is likely something like /usr/lib/x86_64-linux-gnu, - # in which case interposing that directly will change link behavior for unrelated shared libraries - # (e.g. risk getting stale non-nix libc.so etc). Use a curated symlink directory to finesse. - # 2. host-installed libraries may not set RUNPATH (they don't need to if installed in system-wide default location). - # We need to also add nix-store LD_LIBRARY_PATH entries for indirect dependencies of system-provided libraries. - # - export LD_LIBRARY_PATH=/usr/lib/wsl/lib:${xo_topdir}/etc/hostwsl:${glpath}:$LD_LIBRARY_PATH - - # for vulkan on wsl, need to use llvm pipe rendering. - # (asof sep 2025 hardware rendering is supported, but with compute-only in mind i.e. for cuda) - # export VK_ICD_FILENAMES=/usr/share/vulkan/icd.d/lvp_icd.x86_64.json - export VK_ICD_FILENAMES="${pkgs.mesa}/share/vulkan/icd.d/dzn_icd.x86_64.json" - - # need this on OSX, + claude wants it for wsl2. but looks sketchy to me - export VK_LAYER_PATH=${pkgs.vulkan-validation-layers}/share/vulkan/explicit_layer.d - - # hardware acceleration - export LIBGL_ALWAYS_SOFTWARE=0 - export MESA_LOADER_DRIVER_OVERRIDE="" - - # wsl2-specific gpu setup - export MESA_D3D12_DEFAULT_ADAPTER_NAME=DX - - echo "using d3d12 vulkan driver: $VK_ICD_FILENAMES" - ''; - - # TODO: consider a nix project to generate this directory. nixwsl - }; - - # vkcube works here - shell4-wsl = shell4-assembly { - ld-library-path-before = "${pkgs.mesa}/lib:/usr/lib/wsl/lib:${xo_topdir}/etc/hostwsl2"; - vk-icd-filenames = "${pkgs.mesa}/share/vulkan/icd.d/dzn_icd.x86_64.json"; - shell-hook-text-after = '' - export MESA_D3D12_DEFAULT_ADAPTER_NAME=DX - echo "using d3d12 vulkan driver: $VK_ICD_FILENAMES" - ''; - }; - - # nov 2025 - try to get xo-imgui working on native ubuntu - shell4-nvidia = shell4-assembly { - ld-library-path-before = "${xo_topdir}/etc/hostubuntu:${pkgs.mesa}/lib"; - vk-icd-filenames = "/usr/share/vulkan/icd.d/nvidia_icd.json"; - shell-hook-text-after = '' - export __GLX_VENDOR_LIBRARY_NAME=nvidia - #export __EGL_VENDOR_LIBRARY_DIRS=/usr/share/glvnd/egl_vendor.d # maybe - echo "using nvidia for libglvnd" - ''; - }; - - # nov 2025 - try to get xo-imgui working on osx again - # WIP ! plan: - # 1 - get this to work as standalone copy of shell4-assembly - # 2 - merge to look like shell4-wsl / shell4-nvidia - # - #shell4-osx = pkgs.mkShell.override { stdenv = pkgs.jitStdenv; } { .. } # very high attack surface area - shell4-osx = - let - clangStdenv = pkgs.overrideCC pkgs.stdenv pkgs.llvmPackages_18.clang; - in - let jitStdenv = if pkgs.stdenv.isDarwin then clangStdenv else pkgs.stdenv; - in - (pkgs.mkShell.override { stdenv = jitStdenv; }) - { - buildInputs = docutils ++ xodeps ++ devutils ++ ideutils ++ x11utils ++ gldeps ++ vkdeps ++ imguideps; - - shellHook = - '' - export CXENV=$CXENV:xo4-WIP - - # override SOUCE_DATE_EPOCH to current time (otherwise will get 1980) - export SOURCE_DATE_EPOCH=$(date +%s) - - # fonts - export FONTCONFIG_FILE=${fonts} - export FONTCONFIG_PATH=${pkgs.fontconfig.out}/etc/fonts - export DEJAVU_FONTS_PATH=${pkgs.dejavu_fonts}/share/fonts - ${pkgs.fontconfig}/bin/fc-cache -f - - # would set vk-icd-filename to this + call shell4-assembly - export VK_ICD_FILENAMES=${pkgs.darwin.moltenvk}/share/vulkan/icd.d/MoltenVK_icd.json - - # already baked in to shell4-assembly - export VK_LAYER_PATH=${pkgs.vulkan-validation-layers}/share/vulkan/explicit_layer.d - - # dependencies on host system libraries - # glpath = pkgs.lib.makeLibraryPath [ ]; - - # debugserver interacts with a local process to debug it. - # requires code signing, so nix can't replicate it. - export LLDB_DEBUGSERVER_PATH=/Library/Developer/CommandLineTools/Library/PrivateFrameworks/LLDB.framework/Versions/A/Resources/debugserver - - # choose a temp directory that can outlive nix-shell - export TMPDIR=$(getconf DARWIN_USER_TEMP_DIR) - export TMP=$TMPDIR - ''; - }; - - # like shell4 but drop etc/hostwsl2 symlink dir. - # looks like nixpkgs mesa not built for wsl2 dxg - # works with opengl (llvmpipe) and vulkan - # - shell5 = pkgs.mkShell { - buildInputs = docutils ++ xodeps ++ devutils ++ ideutils ++ x11utils ++ gldeps ++ vkdeps ++ imguideps ++ imguideps; - - shellHook = - let - # dependencies of host system libraries - # (e.g. from /usr/lib/x86_64-linux-gnu) that we want to satisfy from nix; - # sufficient for glxgears - # - # be careful here: easy to insert something that breaks xo cmake build - # - # with minimal list - # (libXau, libXdmcp, libX11, libXext, libXfixes, libXxf86vm, libxml2, libffi, - # elfutils, ncurses, expat, zstd, zlib, libbsd, gcc.cc.lib) - # glxgears runs at ~170fps - # - glpath = pkgs.lib.makeLibraryPath [ - pkgs.wayland # for libwayland-client.so - - pkgs.mesa - - pkgs.xorg.libXau - pkgs.xorg.libXdmcp - pkgs.xorg.libX11 # e.g. for libX11-xcb.so - pkgs.xorg.libXext - pkgs.xorg.libXfixes - pkgs.xorg.libXxf86vm - pkgs.xorg.libxcb - - pkgs.libxml2 - pkgs.libffi - - pkgs.elfutils # for libelf.so - pkgs.ncurses # for libtinfo.so - pkgs.expat - pkgs.zstd - pkgs.zlib # for libz.so - pkgs.libbsd - - pkgs.gcc.cc.lib # for libstdc++.so (won't blow up cmake, only touching LD_LIBRARY_PATH) - ]; - in - '' - # CXENV: cosmetic: coordinates with ~/proj/env/dotfiles/bashrc to drive PS1 - export CXENV=$CXENV:xo5 - - # override SOUCE_DATE_EPOCH to current time (otherwise will get 1980) - export SOURCE_DATE_EPOCH=$(date +%s) - - # fonts - export FONTCONFIG_FILE=${fonts} - export FONTCONFIG_PATH=${pkgs.fontconfig.out}/etc/fonts - export DEJAVU_FONTS_PATH=${pkgs.dejavu_fonts}/share/fonts - ${pkgs.fontconfig}/bin/fc-cache -f - - # works but only get glx using llvmpipe. - # vkcube uses dzn (see VK_ICD_FILENAMES) however! - export LD_LIBRARY_PATH=/usr/lib/wsl/lib:${glpath}:$LD_LIBRARY_PATH - - # need this on OSX, + claude wants it for wsl2. but looks sketchy to me - export VK_LAYER_PATH=${pkgs.vulkan-validation-layers}/share/vulkan/explicit_layer.d - export VK_ICD_FILENAMES="${pkgs.mesa}/share/vulkan/icd.d/dzn_icd.x86_64.json" - - # hardware acceleration (so far ineffective w/ nixpkgs mesa) - export LIBGL_ALWAYS_SOFTWARE=0 - export MESA_LOADER_DRIVER_OVERRIDE="d3d12" - - # wsl2-specific gpu setup (so far ineffective w/ nixpkgs mesa) - export MESA_D3D12_DEFAULT_ADAPTER_NAME=DX - - echo "using d3d12 vulkan driver: $VK_ICD_FILENAMES" - - echo "nix_mesa=${pkgs.mesa}" - nix_mesa=${pkgs.mesa} - - echo "nix_libgl=${pkgs.libGL}" - nix_libgl=${pkgs.libGL} - - echo "nix_vk_validation: VK_LAYER_PATH=${pkgs.vulkan-validation-layers}/share/vulkan/explicit_layer.d" - nix_vk_validation=${pkgs.vulkan-validation-layers}/share/vulkan/explicit_layer.d - ''; - - # don't seem to need this -- doesn't invoke mesa hardware accel - #echo "nix_nixgl=${pkgs.nixgl.nixGLMesa}" - #nix_nixgl=${pkgs.nixgl.nixGLMesa} - }; - - # Old shell from failed vulkan-on-wsl attempts. - # Descends from working OSX though, so keep until we coordinate with that - # - shell = pkgs.mkShell { - # maybe should create a python environment: - # let - # pythonenv = pkgs.python3.withPackages (pset: [ pset.sphinx pset.breathe ..etc.. ]) - # in - # buildInputs = [ pythonenv ..etc.. ]; - # - - buildInputs = [ - #pkgs.nix - - pkgs.nushell - ] - ++ docutils - ++ devutils - ++ xodeps - ++ ideutils - ++ (if pkgs.stdenv.isLinux then [ pkgs.emscripten ] else []) - ++ x11utils - ++ gldeps - ++ imguideps - ++ - [ - # pkgs.nixgl.auto.nixGLDefault # this + libGL + mesa-demos -> 'nixGL glxgears' works out-of-the-box - # pkgs.nixgl.auto.nixGLNvidia - # pkgs.nixgl.nixVulkanIntel # mesa+vulkan - # pkgs.nixgl.nixGLMesa - # pkgs.nixgl.nixGLNvidia # try this explicitly for wsl2 - # *might* also need xorg.libXext.dev, xorg.libXrender.dev, xorg.xorgproto - ] - ++ (if pkgs.stdenv.isLinux then [ pkgs.stdenv.cc.cc.lib pkgs.glibc ] else []) - ++ vkdeps - ++ (if pkgs.stdenv.isDarwin then [ pkgs.darwin.moltenvk ] else []) - ++ [ - pkgs.xorg.xcbutil - pkgs.xorg.xcbutilwm # xcb window manager utilities - pkgs.xorg.xcbutilimage - - # fonts for imgui - # pkgs.gucharmap - pkgs.noto-fonts - #pkgs.noto-fonts-lgc # lgc for latin,greek,cyrillic (but doesn't exist in pinned nixpkgs) - #pkgs.noto-fonts-cjk # cjk for chinese,japanese,korean - pkgs.noto-fonts-emoji - pkgs.dejavu_fonts - ]; - - shellHook = '' - # CXENV: cosmetic: coordinates with ~/proj/env/dotfiles/bashrc to drive PS1 - export CXENV=$CXENV:xo - - # override SOUCE_DATE_EPOCH to current time (otherwise will get 1980) - export SOURCE_DATE_EPOCH=$(date +%s) - - # software-only pipeline - #export SDL_VIDEODRIVER=x11 - #export LIBGL_ALWAYS_SOFTWARE=1 - - #export SDL_VIDEO_X11_FORCE_EGL=0 - #export SDL_VIDEO_X11_VISUALID=0x023 - - #export LIBGL_ALWAYS_INDIRECT=1 - #export WSLG_FORCE_EGL=1 - #export GLFW_USE_EGL=1 - - export VULKAN_SDK=${pkgs.vulkan-headers} - - # for Vulkan on OSX only.. - ${pkgs.lib.optionalString pkgs.stdenv.isDarwin '' - export VK_ICD_FILENAMES=${pkgs.darwin.moltenvk}/share/vulkan/icd.d/MoltenVK_icd.json - export VK_LAYER_PATH=${pkgs.vulkan-validation-layers}/share/vulkan/explicit_layer.d - ''} - - # do need VK_LAYER_PATH on OSX. Not sure if we need it on wsl2 - #export VK_LAYER_PATH=${pkgs.vulkan-validation-layers}/share/vulkan/explicit_layer.d - - # nixGL experiment (on wsl2). Doesn't work out of the box, but maybe with some help.. - # TODO: put this in its own generated wrapper. - # TODO: if/when this works, refactor to use something like - # let vklibpath = pkgs.lib.makeLibraryPath [ pkgs.foo pkgs.libffi pkgs.glibc ... ]; - # with - # export LD_LIBRARY_PATH="$vklibpath:$LD_LIBRARY_PATH" - # NOTE: nixGL doesn't really know how to handle a wsl2 host, in particular doesn't know - # about /usr/lib/wsl/lib - # - ${pkgs.lib.optionalString pkgs.stdenv.isLinux '' -# export LD_LIBRARY_PATH=${pkgs.glibc}:$LD_LIBRARY_PATH -# export LD_LIBRARY_PATH=${xo_topdir}/etc/hostwsl:$LD_LIBRARY_PATH -# export LD_LIBRARY_PATH=${pkgs.vulkan-loader}/lib:$LD_LIBRARY_PATH -# export LD_LIBRARY_PATH=/usr/lib/wsl/lib:$LD_LIBRARY_PATH -# export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${pkgs.mesa}/lib -# export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${pkgs.libffi}/lib -# export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${pkgs.wayland}/lib -# export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${pkgs.xorg.libXext}/lib -# export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${pkgs.xorg.libXau}/lib -# export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${pkgs.xorg.libXdmcp}/lib -# export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${pkgs.xorg.libXfixes}/lib -# export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${pkgs.xorg.libXxf86vm}/lib -# export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${pkgs.xorg.libX11}/lib -# export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${pkgs.gcc.cc.lib}/lib -# export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${pkgs.ncurses}/lib -# export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${pkgs.expat}/lib -# export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${pkgs.elfutils.out}/lib -# export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${pkgs.libxml2.out}/lib -# export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${pkgs.icu}/lib -# export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${pkgs.libmd} -# export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${pkgs.xz.out}/lib -# export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${pkgs.zstd.out}/lib -# export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${pkgs.zlib}/lib -# export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${pkgs.libbsd}/lib -# #export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${pkgs.libedit}/lib # gets libedit.so.0, but system wants libedit.so.2 -# #export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${pkgs.lm_sensors} # wanted libsensors.so.5, this package doesn't provide it - - export VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation - - # lvp_icd.x86_64.json: llvm pipe rendering (software) - export VK_ICD_FILENAMES=/usr/share/vulkan/icd.d/lvp_icd.x86_64.json - - export VK_LD_PRELOAD=${pkgs.vulkan-loader}/lib/libvulkan.so.1 - - ## mesa software rendering settings - # export GALLIUM_DRIVER=llvmpipe - # export MESA_GL_VERSION_OVERRIDE=3.3 - # export LIBGL_ALWAYS_SOFTWARE=1 - - # export VK_LOADER_DEBUG=all # or info - # export MESA_DEBUG=1 - # export EGL_LOG_LEVEL=debug - # export LIBGL_DEBUG=verbose - # vkcube --wsi xcb - ''} - - # just for info - export mesa_drivers=${pkgs.mesa.drivers} - - export FONTCONFIG_FILE=${fonts} - export FONTCONFIG_PATH=${pkgs.fontconfig.out}/etc/fonts - export NOTO_FONTS_PATH=${pkgs.noto-fonts}/share/fonts - export DEJAVU_FONTS_PATH=${pkgs.dejavu_fonts}/share/fonts - - # refresh font cache - ${pkgs.fontconfig}/bin/fc-cache -fv - - echo "FONTCONFIG_PATH=$FONTCONFIG_PATH" - echo "NOTO_FONTS_PATH=$NOTO_FONTS_PATH" - - echo "xo development environment loaded!" - ''; - }; -} + import ./shells.nix { inherit pkgs; } diff --git a/shells.nix b/shells.nix new file mode 100644 index 00000000..9815e818 --- /dev/null +++ b/shells.nix @@ -0,0 +1,770 @@ +# shells.nix - dev shell definitions +# Accepts a pkgs instance (xo-overlay applied internally) +# Returns attrset of dev shells + xo package references +# +{ pkgs ? import {} }: + +let + # rename, we're about to shadow + pkgs0 = pkgs; +in +let + # apply xo package overlay; makes pkgs.xo-* available + pkgs = pkgs0.extend (self: super: import ./xo.nix { pkgs = self; }); + # bona fide bug in git 2.50.1 + # bug when using: + # git subtree split ... + # git subtree needs to review a set of commits, filtering for those that + # intersect with target prefix. e.g. + # git subtree split --prefix=xo-indentlog -b _demux/xo-indentlog + # + # 1. the split function is building a map old->new from commits in current repo, + # to a smaller set of commits in the split repo: + # it intends finding commits that intersect with anything in prefix, + # adding old->new map entries for each such commit. + # + # 2. subtree (incorrectly?) decides it needs to cache a commit that does not + # actually intersect prefix. Calls its cache_set() twice with the same newrev. + # 2nd calls aborts, assumes cache should not already contain an oldrev key. + # + # 3. fix is to permit multiple calls to cache_set() with the same old->new + # mapping. Keep the abort if called twice with different target commits. + # + patched-git = pkgs.git.overrideAttrs (old: { + postInstall = (old.postInstall or "") + '' + patch $out/libexec/git-core/git-subtree ${./patches/git-subtree-cache-fix.patch} + ''; + }); + + xo_topdir = toString ./.; + + fonts = pkgs.makeFontsConf { + fontDirectories = [ + pkgs.inconsolata-lgc + pkgs.noto-fonts + pkgs.noto-fonts-emoji + pkgs.dejavu_fonts + ]; + }; + + # xo deps + xodeps = [ + pkgs.python3Packages.python + # note: pybind11 won't build on roly-chicago-24a in nix sandbox, runs out of pty devices + # + pkgs.python3Packages.pybind11 + pkgs.python3Packages.json5 + pkgs.python3Packages.jinja2 + pkgs.llvmPackages_18.llvm.dev + pkgs.replxx + pkgs.libwebsockets + pkgs.jsoncpp + pkgs.eigen + pkgs.libunwind + ] ++ (if pkgs.stdenv.isLinux then [ + pkgs.elfutils.dev # for libdw (DWARF debug info lookup) + ] else [ + pkgs.llvmPackages_18.libunwind.dev + ]) ++ [ + pkgs.zlib + pkgs.libbsd + ]; + + # emacs + emacs4xo = (pkgs.emacsPackagesFor pkgs.emacs30).emacsWithPackages (epkgs: with epkgs; [ + lsp-mode + lsp-ui + lsp-ivy + flycheck + ivy + rg + transient # magit dep + nix-mode + yaml-mode + htmlize + magit + exec-path-from-shell + highlight + surround + projectile + treemacs + treemacs-projectile + company + cmake-mode + which-key + xterm-color + yasnippet + ] ++ pkgs.lib.optionals pkgs.stdenv.isLinux [ + notmuch + ]); + + # xo ide utils + ideutils = [ + pkgs.gsettings-desktop-schemas + emacs4xo + # pkgs.emacs-pgtk # wayland with treesitter; alternatively pkgs.emacs30 for emacs+tree-sitter + pkgs.tree-sitter # CLI tool, but not grammars + pkgs.llvmPackages_18.clang-tools # clangd for lsp-mode + pkgs.notmuch + pkgs.emacsPackages.notmuch + pkgs.inconsolata-lgc + pkgs.fontconfig + ] + ++ (if pkgs.stdenv.isLinux then [ + pkgs.ghostty + ] else []) + ++ [ + pkgs.timg + pkgs.fish + pkgs.nushell + ]; + + # xo general-purpose devutils + devutils = [ + pkgs.nix-tree # note: needs GHC + #pkgs.nix + + patched-git # instead of pkgs.git + pkgs.gh # github cli + pkgs.cloc + pkgs.bloaty + + pkgs.catch2 + pkgs.cli11 + + pkgs.btop + ] + ++ (if pkgs.stdenv.isLinux then [ + pkgs.gdb + pkgs.strace + pkgs.lcov # gcov-format coverage post-processing + ] else [ + pkgs.llvmPackages_18.lldb + pkgs.llvmPackages_18.llvm # llvm-profdata, llvm-cov for source-based coverage + ]) + ++ [ + pkgs.which + pkgs.man + pkgs.man-pages + pkgs.less + pkgs.ripgrep + pkgs.openssh + + pkgs.ccache + ] + ++ (if pkgs.stdenv.isLinux then [ + pkgs.distcc + ] else []) + ++ [ + pkgs.cmake + pkgs.pkg-config + pkgs.unzip + ]; + + # xo docutils + docutils = + pkgs.lib.optionals pkgs.stdenv.isLinux [ + pkgs.python3Packages.sphinxcontrib-ditaa + ] ++ + [ + pkgs.python3Packages.python + pkgs.python3Packages.pillow + pkgs.python3Packages.breathe + #pkgs.python3Packages.sphinx-autobuild # needs patch for typeguard; defer for now + pkgs.python3Packages.sphinx-rtd-theme + pkgs.python3Packages.sphinxcontrib-plantuml + pkgs.doxygen + pkgs.graphviz + pkgs.ditaa + pkgs.sphinx + ]; + + # xo x11utils + x11utils = + [ + pkgs.xorg.xcbutil + pkgs.xorg.xcbutilwm # xcb window manager utilities + pkgs.xorg.xcbutilimage + pkgs.xorg.xclock + pkgs.xorg.xdpyinfo + ]; + + # xo opengl utils + gldeps = + [ + # glew: used for opengl apps; not needed for vulkan apps (even when those apps use opengl) + pkgs.glew + ] ++ pkgs.lib.optionals pkgs.stdenv.isLinux [ + pkgs.mesa-demos + ] ++ [ + pkgs.libGL + ]; + + vkdeps = + pkgs.lib.optionals pkgs.stdenv.isDarwin [ + pkgs.darwin.moltenvk + ] ++ + [ pkgs.vulkan-tools + pkgs.vulkan-loader + pkgs.vulkan-headers + pkgs.vulkan-validation-layers + ]; + + imguideps = + [ +# pkgs.imgui # incorporated directly into xo dev tree, see xo-imgui/include/imgui + pkgs.SDL2.dev + pkgs.xorg.libX11.dev # e.g. for X11/Xlib.h; needed by SDL2 + + pkgs.dejavu_fonts # also must set DEJAVU_FONTS_PATH for imgui_ex2 + ]; + + shell4-assembly = + { ld-library-path-before, + vk-icd-filenames, + shell-hook-text-after, + } : + + pkgs.mkShell { + buildInputs = docutils ++ xodeps ++ devutils ++ ideutils ++ x11utils ++ gldeps ++ vkdeps ++ imguideps; + + shellHook = + let + # dependencies of host system libraries + # (e.g. from /usr/lib/x86_64-linux-gnu) that we want to satisfy from nix; + # sufficient for glxgears + # + # be careful here: easy to insert something that breaks xo cmake build + # + # with minimal list + # (libXau, libXdmcp, libX11, libXext, libXfixes, libXxf86vm, libxml2, libffi, + # elfutils, ncurses, expat, zstd, zlib, libbsd, gcc.cc.lib) + # glxgears runs at ~170fps + # + glpath = pkgs.lib.makeLibraryPath ([ + pkgs.wayland # for libwayland-client.so + + pkgs.xorg.libXau + pkgs.xorg.libXdmcp + pkgs.xorg.libX11 # e.g. for libX11-xcb.so + pkgs.xorg.libXext + pkgs.xorg.libXfixes + pkgs.xorg.libXxf86vm + pkgs.xorg.libxcb + + pkgs.libxml2 + pkgs.libffi + + ] ++ (if pkgs.stdenv.isLinux then [ pkgs.elfutils ] else []) + ++ [ + pkgs.ncurses # for libtinfo.so + pkgs.expat + pkgs.zstd + pkgs.zlib # for libz.so + pkgs.libbsd + + pkgs.gcc.cc.lib # for libstdc++.so (won't blow up cmake, only touching LD_LIBRARY_PATH) + ]); + in + '' + # CXENV: cosmetic: coordinates with ~/proj/env/dotfiles/bashrc to drive PS1 + export CXENV=$CXENV:xo4 + + # override SOURCE_DATE_EPOCH to current time (otherwise will get 1980) + export SOURCE_DATE_EPOCH=$(date +%s) + + # fonts + export FONTCONFIG_FILE=${fonts} + export FONTCONFIG_PATH=${pkgs.fontconfig.out}/etc/fonts + export DEJAVU_FONTS_PATH=${pkgs.dejavu_fonts}/share/fonts + ${pkgs.fontconfig}/bin/fc-cache -f + + # nix-provided GPU libraries only work out-of-the-box on nixos. + # For non-nixos build, need to use host-provided versions of these libraries. + # Complications: + # 1. host location is likely something like /usr/lib/x86_64-linux-gnu, + # in which case interposing that directly will change link behavior for unrelated shared libraries + # (e.g. risk getting stale non-nix libc.so etc). Use a curated symlink directory to finesse. + # 2. host-installed libraries may not set RUNPATH (they don't need to if installed in system-wide default location). + # We need to also add nix-store LD_LIBRARY_PATH entries for indirect dependencies of system-provided libraries. + # + export LD_LIBRARY_PATH=${ld-library-path-before}:${glpath}:$LD_LIBRARY_PATH + + export VK_ICD_FILENAMES="${vk-icd-filenames}" + + # need this on OSX, + claude wants it for both wsl2, ubuntu + export VK_LAYER_PATH=${pkgs.vulkan-validation-layers}/share/vulkan/explicit_layer.d + + # hardware acceleration + export LIBGL_ALWAYS_SOFTWARE=0 + export MESA_LOADER_DRIVER_OVERRIDE="" + + echo "tree_sitter=${pkgs.tree-sitter}" + tree_sitter=${pkgs.tree-sitter} + echo "nix_mesa=${pkgs.mesa}" + nix_mesa=${pkgs.mesa} + + ${shell-hook-text-after} + ''; + }; +in +{ + inherit pkgs; + + xo = { + cmake = pkgs.xo-cmake; + indentlog = pkgs.xo-indentlog; + reflectutil = pkgs.xo-reflectutil; + randomgen = pkgs.xo-randomgen; + arena = pkgs.xo-arena; + facet = pkgs.xo-facet; + allocutil = pkgs.xo-allocutil; + refcnt = pkgs.xo-refcnt; + subsys = pkgs.xo-subsys; + testutil = pkgs.xo-testutil; + flatstring = pkgs.xo-flatstring; + pyutil = pkgs.xo-pyutil; + reflect = pkgs.xo-reflect; + pyreflect = pkgs.xo-pyreflect; + ratio = pkgs.xo-ratio; + unit = pkgs.xo-unit; + pyunit = pkgs.xo-pyunit; + callback = pkgs.xo-callback; + printable2 = pkgs.xo-printable2; + alloc = pkgs.xo-alloc; + alloc2 = pkgs.xo-alloc2; + stringtable2 = pkgs.xo-stringtable2; + gc = pkgs.xo-gc; + object = pkgs.xo-object; + type = pkgs.xo-type; + object2 = pkgs.xo-object2; + procedure2 = pkgs.xo-procedure2; + numeric = pkgs.xo-numeric; + ordinaltree = pkgs.xo-ordinaltree; + tokenizer2 = pkgs.xo-tokenizer2; + + webutil = pkgs.xo-webutil; + pywebutil = pkgs.xo-pywebutil; + printjson = pkgs.xo-printjson; + pyprintjson = pkgs.xo-pyprintjson; + reactor = pkgs.xo-reactor; + pyreactor = pkgs.xo-pyreactor; + websock = pkgs.xo-websock; + pywebsock = pkgs.xo-pywebsock; + statistics = pkgs.xo-statistics; + distribution = pkgs.xo-distribution; + pydistribution = pkgs.xo-pydistribution; + simulator = pkgs.xo-simulator; + pysimulator = pkgs.xo-pysimulator; + process = pkgs.xo-process; + pyprocess = pkgs.xo-pyprocess; + kalmanfilter = pkgs.xo-kalmanfilter; + pykalmanfilter = pkgs.xo-pykalmanfilter; + expression = pkgs.xo-expression; + pyexpression = pkgs.xo-pyexpression; + tokenizer = pkgs.xo-tokenizer; + reader = pkgs.xo-reader; + jit = pkgs.xo-jit; + pyjit = pkgs.xo-pyjit; + }; + + # works, but only if build with --option sandbox=false + # to workaround pcre broken. overlay above does work, + # but is not applied to stdenv devs + # + shellpre = pkgs.mkShell { + buildInputs = [ + # NOTE: pkgs.pcre2, pkgs.dejagnu, pkgs.libffi + # also won't build in genuine sandbox + + pkgs.nix-tree # needs GHC btw + patched-git # instead of pkgs.git + pkgs.openssh + pkgs.cloc + pkgs.lcov + pkgs.gdb + pkgs.strace + + pkgs.ripgrep + + pkgs.clang # 19.1.7 + pkgs.ninja # will this work? tbd + pkgs.cmake + pkgs.distcc + pkgs.pkg-config + pkgs.unzip + ]; + + # includes stdenv, so will have gcc,gawk,tar,gzip etc. + shellHook = '' + # CXENV: cosmetic: coordinates with ~/proj/env/dotfiles/bashrc to drive PS1 + export CXENV=$CXENV:xopre + + # override SOURCE_DATE_EPOCH to current time (otherwise will get 1980) + export SOURCE_DATE_EPOCH=$(date +%s) + ''; + }; + + # minimal shell - just enough to verify gcc works. + # not sufficient to build xo + # + # $ nix-shell -A shell0 # requires nixpkgs.runCommand + # + shell0 = pkgs.mkShell { + buildInputs = devutils; + + # includes stdenv, so will have gcc,gawk,tar,gzip etc + shellHook = '' + # CXENV: cosmetic: coordinates with ~/proj/env/dotfiles/bashrc to drive PS1 + export CXENV=$CXENV:xo0 + + # override SOURCE_DATE_EPOCH to current time (otherwise will get 1980) + export SOURCE_DATE_EPOCH=$(date +%s) + ''; + }; + + # stable shell. can build xo without docs + # + shell1a = pkgs.mkShell { + buildInputs = xodeps ++ devutils; + + shellHook = '' + # CXENV: cosmetic: coordinates with ~/proj/env/dotfiles/bashrc to drive PS1 + export CXENV=$CXENV:xo1a + + # override SOUCE_DATE_EPOCH to current time (otherwise will get 1980) + export SOURCE_DATE_EPOCH=$(date +%s) + ''; + }; + + # minimal shell, intended to be stable + shell1 = pkgs.mkShell { + buildInputs = docutils ++ xodeps ++ devutils; + + # includes stdenv, so will have gcc,gawk,tar,gzip etc + shellHook = '' + # CXENV: cosmetic: coordinates with ~/proj/env/dotfiles/bashrc to drive PS1 + export CXENV=$CXENV:xo1 + + # override SOUCE_DATE_EPOCH to current time (otherwise will get 1980) + export SOURCE_DATE_EPOCH=$(date +%s) + ''; + }; + + # minimal shell + ide stuff, intended to be stable + shell2 = pkgs.mkShell { + buildInputs = docutils ++ xodeps ++ devutils ++ ideutils; + + # includes stdenv, so will have gcc,gawk,tar,gzip etc + shellHook = '' + # CXENV: cosmetic: coordinates with ~/proj/env/dotfiles/bashrc to drive PS1 + export CXENV=$CXENV:xo2 + + # override SOUCE_DATE_EPOCH to current time (otherwise will get 1980) + export SOURCE_DATE_EPOCH=$(date +%s) + + export FONTCONFIG_FILE=${fonts} + export FONTCONFIG_PATH=${pkgs.fontconfig.out}/etc/fonts + ${pkgs.fontconfig}/bin/fc-cache -f + ''; + }; + + # xo shell with opengl support + shell3 = pkgs.mkShell { + buildInputs = docutils ++ xodeps ++ devutils ++ ideutils ++ x11utils ++ gldeps ++ vkdeps ++ imguideps; + + shellHook = + let + glpath = pkgs.lib.makeLibraryPath ([ + pkgs.wayland # for libwayland-client.so + + pkgs.xorg.libXau + pkgs.xorg.libXdmcp + pkgs.xorg.libX11 # e.g. for libX11-xcb.so + pkgs.xorg.libXext + pkgs.xorg.libXfixes + pkgs.xorg.libXxf86vm + + pkgs.libxml2 + pkgs.libffi + + ] ++ (if pkgs.stdenv.isLinux then [ pkgs.elfutils ] else []) + ++ [ + pkgs.ncurses # for libtinfo.so + pkgs.expat + pkgs.zstd + pkgs.zlib # for libz.so + pkgs.libbsd + + pkgs.gcc.cc.lib # for libstdc++.so (won't blow up cmake, only touching LD_LIBRARY_PATH) + ]); + in + '' + # CXENV: cosmetic: coordinates with ~/proj/env/dotfiles/bashrc to drive PS1 + export CXENV=$CXENV:xo3 + + # override SOUCE_DATE_EPOCH to current time (otherwise will get 1980) + export SOURCE_DATE_EPOCH=$(date +%s) + + # fonts + export FONTCONFIG_FILE=${fonts} + export FONTCONFIG_PATH=${pkgs.fontconfig.out}/etc/fonts + ${pkgs.fontconfig}/bin/fc-cache -f + + # nix-provided GPU libraries only work out-of-the-box on nixos. + # For non-nixos build, need to use host-provided versions of these libraries. + # Complications: + # 1. host location is likely something like /usr/lib/x86_64-linux-gnu, + # in which case interposing that directly will change link behavior for unrelated shared libraries + # (e.g. risk getting stale non-nix libc.so etc). Use a curated symlink directory to finesse. + # 2. host-installed libraries may not set RUNPATH (they don't need to if installed in system-wide default location). + # We need to also add nix-store LD_LIBRARY_PATH entries for indirect dependencies of system-provided libraries. + # + export LD_LIBRARY_PATH=/usr/lib/wsl/lib:${xo_topdir}/etc/hostwsl:${glpath}:$LD_LIBRARY_PATH + + # for vulkan on wsl, need to use llvm pipe rendering. + # (asof sep 2025 hardware rendering is supported, but with compute-only in mind i.e. for cuda) + # export VK_ICD_FILENAMES=/usr/share/vulkan/icd.d/lvp_icd.x86_64.json + export VK_ICD_FILENAMES="${pkgs.mesa}/share/vulkan/icd.d/dzn_icd.x86_64.json" + + # need this on OSX, + claude wants it for wsl2. but looks sketchy to me + export VK_LAYER_PATH=${pkgs.vulkan-validation-layers}/share/vulkan/explicit_layer.d + + # hardware acceleration + export LIBGL_ALWAYS_SOFTWARE=0 + export MESA_LOADER_DRIVER_OVERRIDE="" + + # wsl2-specific gpu setup + export MESA_D3D12_DEFAULT_ADAPTER_NAME=DX + + echo "using d3d12 vulkan driver: $VK_ICD_FILENAMES" + ''; + + # TODO: consider a nix project to generate this directory. nixwsl + }; + + # vkcube works here + shell4-wsl = shell4-assembly { + ld-library-path-before = "${pkgs.mesa}/lib:/usr/lib/wsl/lib:${xo_topdir}/etc/hostwsl2"; + vk-icd-filenames = "${pkgs.mesa}/share/vulkan/icd.d/dzn_icd.x86_64.json"; + shell-hook-text-after = '' + export MESA_D3D12_DEFAULT_ADAPTER_NAME=DX + echo "using d3d12 vulkan driver: $VK_ICD_FILENAMES" + ''; + }; + + # nov 2025 - try to get xo-imgui working on native ubuntu + shell4-nvidia = shell4-assembly { + ld-library-path-before = "${xo_topdir}/etc/hostubuntu:${pkgs.mesa}/lib"; + vk-icd-filenames = "/usr/share/vulkan/icd.d/nvidia_icd.json"; + shell-hook-text-after = '' + export __GLX_VENDOR_LIBRARY_NAME=nvidia + #export __EGL_VENDOR_LIBRARY_DIRS=/usr/share/glvnd/egl_vendor.d # maybe + echo "using nvidia for libglvnd" + ''; + }; + + # nov 2025 - try to get xo-imgui working on osx again + # WIP ! plan: + # 1 - get this to work as standalone copy of shell4-assembly + # 2 - merge to look like shell4-wsl / shell4-nvidia + # + #shell4-osx = pkgs.mkShell.override { stdenv = pkgs.jitStdenv; } { .. } # very high attack surface area + shell4-osx = + let + clangStdenv = pkgs.overrideCC pkgs.stdenv pkgs.llvmPackages_18.clang; + in + let jitStdenv = if pkgs.stdenv.isDarwin then clangStdenv else pkgs.stdenv; + in + (pkgs.mkShell.override { stdenv = jitStdenv; }) + { + buildInputs = docutils ++ xodeps ++ devutils ++ ideutils ++ x11utils ++ gldeps ++ vkdeps ++ imguideps; + + shellHook = + '' + export CXENV=$CXENV:xo4-WIP + + # override SOUCE_DATE_EPOCH to current time (otherwise will get 1980) + export SOURCE_DATE_EPOCH=$(date +%s) + + # fonts + export FONTCONFIG_FILE=${fonts} + export FONTCONFIG_PATH=${pkgs.fontconfig.out}/etc/fonts + export DEJAVU_FONTS_PATH=${pkgs.dejavu_fonts}/share/fonts + ${pkgs.fontconfig}/bin/fc-cache -f + + # would set vk-icd-filename to this + call shell4-assembly + export VK_ICD_FILENAMES=${pkgs.darwin.moltenvk}/share/vulkan/icd.d/MoltenVK_icd.json + + # already baked in to shell4-assembly + export VK_LAYER_PATH=${pkgs.vulkan-validation-layers}/share/vulkan/explicit_layer.d + + # dependencies on host system libraries + # glpath = pkgs.lib.makeLibraryPath [ ]; + + # debugserver interacts with a local process to debug it. + # requires code signing, so nix can't replicate it. + export LLDB_DEBUGSERVER_PATH=/Library/Developer/CommandLineTools/Library/PrivateFrameworks/LLDB.framework/Versions/A/Resources/debugserver + + # choose a temp directory that can outlive nix-shell + export TMPDIR=$(getconf DARWIN_USER_TEMP_DIR) + export TMP=$TMPDIR + ''; + }; + + # like shell4 but drop etc/hostwsl2 symlink dir. + # looks like nixpkgs mesa not built for wsl2 dxg + # works with opengl (llvmpipe) and vulkan + # + shell5 = pkgs.mkShell { + buildInputs = docutils ++ xodeps ++ devutils ++ ideutils ++ x11utils ++ gldeps ++ vkdeps ++ imguideps ++ imguideps; + + shellHook = + let + glpath = pkgs.lib.makeLibraryPath [ + pkgs.wayland # for libwayland-client.so + + pkgs.mesa + + pkgs.xorg.libXau + pkgs.xorg.libXdmcp + pkgs.xorg.libX11 # e.g. for libX11-xcb.so + pkgs.xorg.libXext + pkgs.xorg.libXfixes + pkgs.xorg.libXxf86vm + pkgs.xorg.libxcb + + pkgs.libxml2 + pkgs.libffi + + pkgs.elfutils # for libelf.so + pkgs.ncurses # for libtinfo.so + pkgs.expat + pkgs.zstd + pkgs.zlib # for libz.so + pkgs.libbsd + + pkgs.gcc.cc.lib # for libstdc++.so (won't blow up cmake, only touching LD_LIBRARY_PATH) + ]; + in + '' + # CXENV: cosmetic: coordinates with ~/proj/env/dotfiles/bashrc to drive PS1 + export CXENV=$CXENV:xo5 + + # override SOUCE_DATE_EPOCH to current time (otherwise will get 1980) + export SOURCE_DATE_EPOCH=$(date +%s) + + # fonts + export FONTCONFIG_FILE=${fonts} + export FONTCONFIG_PATH=${pkgs.fontconfig.out}/etc/fonts + export DEJAVU_FONTS_PATH=${pkgs.dejavu_fonts}/share/fonts + ${pkgs.fontconfig}/bin/fc-cache -f + + # works but only get glx using llvmpipe. + # vkcube uses dzn (see VK_ICD_FILENAMES) however! + export LD_LIBRARY_PATH=/usr/lib/wsl/lib:${glpath}:$LD_LIBRARY_PATH + + # need this on OSX, + claude wants it for wsl2. but looks sketchy to me + export VK_LAYER_PATH=${pkgs.vulkan-validation-layers}/share/vulkan/explicit_layer.d + export VK_ICD_FILENAMES="${pkgs.mesa}/share/vulkan/icd.d/dzn_icd.x86_64.json" + + # hardware acceleration (so far ineffective w/ nixpkgs mesa) + export LIBGL_ALWAYS_SOFTWARE=0 + export MESA_LOADER_DRIVER_OVERRIDE="d3d12" + + # wsl2-specific gpu setup (so far ineffective w/ nixpkgs mesa) + export MESA_D3D12_DEFAULT_ADAPTER_NAME=DX + + echo "using d3d12 vulkan driver: $VK_ICD_FILENAMES" + + echo "nix_mesa=${pkgs.mesa}" + nix_mesa=${pkgs.mesa} + + echo "nix_libgl=${pkgs.libGL}" + nix_libgl=${pkgs.libGL} + + echo "nix_vk_validation: VK_LAYER_PATH=${pkgs.vulkan-validation-layers}/share/vulkan/explicit_layer.d" + nix_vk_validation=${pkgs.vulkan-validation-layers}/share/vulkan/explicit_layer.d + ''; + + # don't seem to need this -- doesn't invoke mesa hardware accel + #echo "nix_nixgl=${pkgs.nixgl.nixGLMesa}" + #nix_nixgl=${pkgs.nixgl.nixGLMesa} + }; + + # Old shell from failed vulkan-on-wsl attempts. + # Descends from working OSX though, so keep until we coordinate with that + # + shell = pkgs.mkShell { + buildInputs = [ + #pkgs.nix + + pkgs.nushell + ] + ++ docutils + ++ devutils + ++ xodeps + ++ ideutils + ++ (if pkgs.stdenv.isLinux then [ pkgs.emscripten ] else []) + ++ x11utils + ++ gldeps + ++ imguideps + ++ + [ + ] + ++ (if pkgs.stdenv.isLinux then [ pkgs.stdenv.cc.cc.lib pkgs.glibc ] else []) + ++ vkdeps + ++ (if pkgs.stdenv.isDarwin then [ pkgs.darwin.moltenvk ] else []) + ++ [ + pkgs.xorg.xcbutil + pkgs.xorg.xcbutilwm # xcb window manager utilities + pkgs.xorg.xcbutilimage + + # fonts for imgui + pkgs.noto-fonts + pkgs.noto-fonts-emoji + pkgs.dejavu_fonts + ]; + + shellHook = '' + # CXENV: cosmetic: coordinates with ~/proj/env/dotfiles/bashrc to drive PS1 + export CXENV=$CXENV:xo + + # override SOUCE_DATE_EPOCH to current time (otherwise will get 1980) + export SOURCE_DATE_EPOCH=$(date +%s) + + export VULKAN_SDK=${pkgs.vulkan-headers} + + # for Vulkan on OSX only.. + ${pkgs.lib.optionalString pkgs.stdenv.isDarwin '' + export VK_ICD_FILENAMES=${pkgs.darwin.moltenvk}/share/vulkan/icd.d/MoltenVK_icd.json + export VK_LAYER_PATH=${pkgs.vulkan-validation-layers}/share/vulkan/explicit_layer.d + ''} + + ${pkgs.lib.optionalString pkgs.stdenv.isLinux '' + export VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation + + # lvp_icd.x86_64.json: llvm pipe rendering (software) + export VK_ICD_FILENAMES=/usr/share/vulkan/icd.d/lvp_icd.x86_64.json + + export VK_LD_PRELOAD=${pkgs.vulkan-loader}/lib/libvulkan.so.1 + ''} + + # just for info + export mesa_drivers=${pkgs.mesa.drivers} + + export FONTCONFIG_FILE=${fonts} + export FONTCONFIG_PATH=${pkgs.fontconfig.out}/etc/fonts + export NOTO_FONTS_PATH=${pkgs.noto-fonts}/share/fonts + export DEJAVU_FONTS_PATH=${pkgs.dejavu_fonts}/share/fonts + + # refresh font cache + ${pkgs.fontconfig}/bin/fc-cache -fv + + echo "FONTCONFIG_PATH=$FONTCONFIG_PATH" + echo "NOTO_FONTS_PATH=$NOTO_FONTS_PATH" + + echo "xo development environment loaded!" + ''; + }; +}