build + xo-imgui: now working (except ex4) on ubuntu

This commit is contained in:
Roland Conybeare 2025-11-10 14:36:43 -05:00
commit 638707550b
5 changed files with 230 additions and 106 deletions

View file

@ -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

View file

@ -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.

View file

@ -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

View file

@ -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()

View file

@ -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)