From 638707550b1b065d3bab4d78a7026502b5f3b814 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 10 Nov 2025 14:36:43 -0500 Subject: [PATCH] build + xo-imgui: now working (except ex4) on ubuntu --- README.md | 44 ++++++- default.nix | 184 +++++++++++++++------------- xo-imgui/TROUBLESHOOTING | 67 +++++++++- xo-imgui/example/ex4/CMakeLists.txt | 34 ++--- xo-imgui/src/imgui/CMakeLists.txt | 7 +- 5 files changed, 230 insertions(+), 106 deletions(-) diff --git a/README.md b/README.md index aabf6103..808a7f04 100644 --- a/README.md +++ b/README.md @@ -14,14 +14,27 @@ Intended for local development work, with source in immediate subdirectories. ### Nix shell (reproducible development environment) -If `nix` is available, can get several reproducible build environments +If `nix` is available, can get several reproducible build environments. + +Pick one for a session: ``` $ cd xo-umbrella2 $ nix-shell -A shell0 # just nix stdenv: make,gcc,bash etc. $ nix-shell -A shell1 # stable environment $ nix-shell -A shell2 # stable environment + emacs + lsp -$ nix-shell -A shell # bleeding edge environment +$ nix-shell -A shell3 # stable environment + emacs + lsp + xorg/opengl/vulkan/imgui stack (wsl2-only) +$ nix-shell -A shell4 # wsl2-specific. like shell3, vkcube works (at least on WSL) +$ nix-shell -A shell5 # wsl2-specific. uses dxg driver for "hardware acceleration" +$ nix-shell -A shell # (deprecated) bleeding edge environment +``` + +Run emacs (for example) from within chosen seesion. +We need this ordering because nix-shell determines vital details like location of shared libraries, +including libraries used by running IDE. + +``` +$ emacs ``` ### Cmake build @@ -41,10 +54,17 @@ $ cmake --build .build0 $ cmake --install .build0 # phase 2 $ cmake -B .build -S . -DCMAKE_INSTALL_PREFIX=${PREFIX} -DXO_ENABLE_EXAMPLES=1 -$ cmake --build .build +$ cmake --build .build --verbose $ cmake --install .build ``` +or with Vulkan examples +``` +# at start of phase 2 +$ cmake -B .build -S . -DCMAKE_INSTALL_PREFIX=${PREFIX} -DXO_ENABLE_EXAMPLES=1 -DXO_ENABLE_VULKAN=1 +``` + + ### Nix Build Nix build uses toplevel `default.nix`, @@ -87,6 +107,24 @@ $ nix-build -A xo-userenv-slow Same result as `$nix-build -A xo-userenv`, but builds each package serially using `xo-build`. +#### Nix + Vulkan + +Currently (Nov 2025) only affects `xo-umbrella2/xo-imgui`. + +Non-trivial, because: +1. must use host OS for gpu drivers. nixpkgs has drivers, but they're setup to work from nixos. +2. want to use nixpkgs for the GPU-independent portion of graphics stack. + +Complication because host gpu drivers in a "big swimming pool" such as `/usr/lib/x86_64-linux-gnu/` +that contains both libraries that must come from host OS (e.g. `libGLX_nvidia`) and libraries +that must come from nixpkgs (e.g. `libc`) + +Finesse by introducing a directory-of-symlinks, see `xo-umbrella2/etc/{hostegl, hostubuntu}`. +These currently setup by hand, so likely to need manual attention on another host. + +An ordinary cmake build may cheerfully use the host-provided graphics stack, +in return for higher risk of DLL hell. + ### Coverage Build Prepare build diff --git a/default.nix b/default.nix index f9133118..9ab4a382 100644 --- a/default.nix +++ b/default.nix @@ -316,6 +316,91 @@ let 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 + + 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:xo4 + + # 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 + + # 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 "nix_mesa=${pkgs.mesa}" + nix_mesa=${pkgs.mesa} + + ${shell-hook-text-after} + ''; + }; in { pkgs = pkgs; @@ -546,89 +631,24 @@ in }; # vkcube works here - shell4 = pkgs.mkShell { - buildInputs = docutils ++ xodeps ++ devutils ++ ideutils ++ x11utils ++ gldeps ++ vkdeps ++ imguideps; + 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" + ''; + }; - 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 - - 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:xo4 - - # 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 - - # 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=${pkgs.mesa}/lib:/usr/lib/wsl/lib:${xo_topdir}/etc/hostwsl2:${glpath}:$LD_LIBRARY_PATH - - 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" - - echo "nix_mesa=${pkgs.mesa}" - nix_mesa=${pkgs.mesa} - ''; - - # TODO: consider a nix project to generate this directory. nixwsl + # 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" + ''; }; # like shell4 but drop etc/hostwsl2 symlink dir. diff --git a/xo-imgui/TROUBLESHOOTING b/xo-imgui/TROUBLESHOOTING index f0e2f0fd..a0c58804 100644 --- a/xo-imgui/TROUBLESHOOTING +++ b/xo-imgui/TROUBLESHOOTING @@ -35,17 +35,55 @@ For WSL2 (nvidia GPU) $ nixGL gxinfo | grep 'OpenGL vendor' OpenGL vendor string: Mesa -4. check WSL driver +3a. on ubuntu + + $ cat /proc/driver/nvidia/version # for kernel module version + [xo-umbrella2:main :nixcpp:nxfs proj/xo-umbrella2]$ cat /proc/driver/nvidia/version + NVRM version: NVIDIA UNIX Open Kernel Module for x86_64 580.65.06 Release Build (dvs-builder@U22-I3-AF03-09-1) Sun Jul 27 06:54:38 UTC 2025 + GCC version: gcc version 13.3.0 (Ubuntu 13.3.0-6ubuntu2~24.04) + + $ nvidia-smi --version + NVML library version: 580.95 + +3b. on windows11+wsl2: + + check WSL driver $ cat /proc/version Linux version 6.6.87.2-microsoft-standard-WSL2 (root@439a258ad544) (gcc (GCC) 11.2.0, GNU ld (GNU Binutils) 2.37) #1 SMP PREEMPT_DYNAMIC Thu Jun 5 18:30:46 UTC 2025 (not sure how this helps) +4. is GLX setup? + + $ glxinfo | head -20 + + $ ldd $(which glxinfo) # will stop at libglvnd.so, though + + $ strace -e openat glxinfo 2>&1 + + look for libraries that aren't found. + +4a. on ubuntu + + want xo-umbrella2/etc/hostubuntu with host symlinks for: + + libEGL_nvidia, libGLX_nvidia, libGL, libGLX_indirect, libGLX_nvidia, libGLX, + libnvidia-glcore, libnvidia-glsi, libnvidia-gpucomp, libnvidia-tls + + $ __GL_SYNC_TO_VBLANK=0 glxgears + 57207 frames in 5.0 seconds = 11441.171 FPS + 5. can vulkan start? - $ vulkaninfo + $ vulkaninfo --summary + $ vkcube +5a. on ubuntu + + works, needed libnvidia-glvkspirv.so + +5b. on WSL (fails to find .so libs, e.g. libLLVM-15.so.1) $ nixGLNvidia vulkaninfo @@ -61,3 +99,28 @@ or similarly 7. Can look at exact symbol resolution nixGLMesa vkcube 2>&1 | grep -A5 -B5 vkGetDeviceProcAddr + +8. once glxgears and vkcube run, try building + running + + xo-imgui/example/ex1 # imgui demo app, opengl + xo-imgui/example/ex2 # imgui incremental GC demo + + [xo-umbrella2:main :nixcpp:nxfs:xo4 proj/xo-umbrella2]$ .build/xo-imgui/example/ex2/imgui_ex2 + 14:23:32.933846 +(0) main + Hello, world! + SDL version: 2.32.56 + SDL video driver: x11 + SDL_CreateWindow done + Requested OpenGL vtersion: 3.0 + SDL_GL_CreateContext done + glewInit done + OpenGL version: [4.6.0 NVIDIA 580.95.05] + loading font [/home/roland/nixroot/nix/store/if267lm2m7q7gs1gjvlkc1i69cs3ipg9-dejavu-fonts-2.37/share/fonts/truetype/DejaVuSans.ttf] + font loaded + +9. to build vulkan examples set XO_ENABLE_VULKAN + + cmake -B .build -DCMAKE_INSTALL_PREFIX=$PREFIX -DXO_ENABLE_EXAMPLES=1 -DXO_ENABLE_VULKAN=1 + + xo-imgui/example/ex3 # imgui demo app, using vulkan + xo-imgui/example/ex4 # NOT WORKING ON UBUNTU nov 2025 diff --git a/xo-imgui/example/ex4/CMakeLists.txt b/xo-imgui/example/ex4/CMakeLists.txt index 4bc2353d..a95704ba 100644 --- a/xo-imgui/example/ex4/CMakeLists.txt +++ b/xo-imgui/example/ex4/CMakeLists.txt @@ -1,19 +1,21 @@ if (XO_ENABLE_EXAMPLES) - # target executable - set(SELF_EXE imgui_ex4) - add_executable(${SELF_EXE} imgui_ex4.cpp - AppState.cpp - DrawState.cpp - GcStateDescription.cpp - AnimateGcCopyCb.cpp - GenerationLayout.cpp - ) - xo_include_options2(${SELF_EXE}) + if (XO_ENABLE_VULKAN) + # target executable + set(SELF_EXE imgui_ex4) + add_executable(${SELF_EXE} imgui_ex4.cpp + AppState.cpp + DrawState.cpp + GcStateDescription.cpp + AnimateGcCopyCb.cpp + GenerationLayout.cpp + ) + xo_include_options2(${SELF_EXE}) - xo_self_dependency(${SELF_EXE} xo_imgui) - xo_dependency(${SELF_EXE} xo_object) - xo_dependency(${SELF_EXE} randomgen) - xo_dependency(${SELF_EXE} xo_flatstring) - xo_dependency(${SELF_EXE} xo_alloc) - xo_dependency(${SELF_EXE} indentlog) + xo_self_dependency(${SELF_EXE} xo_imgui) + xo_dependency(${SELF_EXE} xo_object) + xo_dependency(${SELF_EXE} randomgen) + xo_dependency(${SELF_EXE} xo_flatstring) + xo_dependency(${SELF_EXE} xo_alloc) + xo_dependency(${SELF_EXE} indentlog) + endif() endif() diff --git a/xo-imgui/src/imgui/CMakeLists.txt b/xo-imgui/src/imgui/CMakeLists.txt index 414d1a6d..049a5daa 100644 --- a/xo-imgui/src/imgui/CMakeLists.txt +++ b/xo-imgui/src/imgui/CMakeLists.txt @@ -2,15 +2,16 @@ find_path(IMGUI_INCLUDE_DIR NAMES imgui/imgui.h -# HINTS ${PROJECT_SOURCE_DIR}/include # merge loser - HINTS ${XO_UMBRELLA_SOURCE_DIR} + HINTS ${PROJECT_SOURCE_DIR}/include +# HINTS ${XO_UMBRELLA_SOURCE_DIR}/xo-imgui/include DOC "path to imgui header") if (IMGUI_INCLUDE_DIR) message(STATUS "found imgui/imgui.h in IMGUI_INCLUDE_DIR=[${IMGUI_INCLUDE_DIR}]") else() - message(FATAL_ERROR "unable to find imgui.h") + message(FATAL_ERROR + "unable to find imgui.h XO_UMBRELLA_SOURCE_DIR=[${XO_UMBRELLA_SOURCE_DIR}]") endif() if (XO_ENABLE_VULKAN)