Repository navigation
Expand file tree
/
Copy pathshell.nix
More file actions
222 lines (201 loc) · 8.9 KB
/
Copy pathshell.nix
File metadata and controls
222 lines (201 loc) · 8.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
# SPDX-FileCopyrightText: 2025 Povl Filip Sonne-Frederiksen
#
# SPDX-License-Identifier: GPL-3.0-or-later
{
pkgs,
self,
system,
...
}: let
# One merged CUDA root for the dev shell (cudaSupport only).
#
# The package build compiles against the individual CUDA redist packages
# (cf6d7fd9, which keeps nvcc and the merged toolkit out of rux's runtime
# closure). That works inside the derivation only because nixpkgs'
# setupCUDAToolkitCompilers hook runs in configurePhase and hands CMake
# -DCUDAToolkit_INCLUDE_DIR / -DCUDAToolkit_ROOT lists spanning every
# package. A dev shell never runs configurePhase, so a plain cmake (or the
# `configure` helper below) sees only the bare cuda_nvcc. CMake's own
# FindCUDAToolkit copes, but LibTorch's bundled copy
# (Caffe2/FindCUDAToolkit.cmake) takes the toolkit root from the CUDA
# compiler and needs <root>/include/cuda_runtime.h and cublas_v2.h, so it
# fails with "Could NOT find CUDAToolkit (missing: CUDAToolkit_INCLUDE_DIR)".
#
# Merging the package's own CUDA inputs (passthru.cudaToolkitPackages, same
# store paths, every output) into one directory and pointing the compiler
# at it gives that finder the layout it expects. This exists only in the
# shell: the package derivation and its runtime closure are unchanged.
reusex = self.packages.${system}.default;
cudaDevToolkit = pkgs.symlinkJoin {
name = "reusex-devshell-cuda-${pkgs.cudaPackages.cudaMajorMinorVersion}";
paths = pkgs.lib.concatMap (p: map (o: p.${o}) p.outputs) reusex.cudaToolkitPackages;
};
cudaEnv = pkgs.lib.optionalAttrs (reusex.cudaToolkitPackages != []) {
# CUDACXX seeds CMAKE_CUDA_COMPILER on a fresh configure; the toolkit root
# CMake derives from it is what Caffe2's FindCUDAToolkit uses.
CUDACXX = "${cudaDevToolkit}/bin/nvcc";
# Read by CMake's FindCUDAToolkit (CMP0074) and by FindCUDA, which
# LibTorch also calls; they would otherwise resolve to the nvcc on PATH.
CUDAToolkit_ROOT = "${cudaDevToolkit}";
CUDA_PATH = "${cudaDevToolkit}";
};
motd = ''
echo ""
echo " ┌─────────────────────────────────────────────┐"
echo " │ ReUseX development shell │"
echo " └─────────────────────────────────────────────┘"
echo " configure [Release|Debug] cmake + compile_commands.json"
echo " build cmake --build --parallel"
echo " run-tests build, then ctest"
echo " gui-dev Vite dev server for apps/rux/frontend"
echo " clean remove build/"
echo " format clang-format all C++ sources"
echo " lint cppcheck static analysis"
echo " docs build Doxygen docs"
echo " menu show this menu"
echo ""
'';
# Convenience scripts available in any shell (bash, fish, zsh).
scripts = pkgs.lib.attrValues {
menu = pkgs.writeShellScriptBin "menu" motd;
configure = pkgs.writeShellScriptBin "configure" ''
cmake -B "$PWD/build" -GNinja \
-DCMAKE_BUILD_TYPE=''${1:-Release} \
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
"''${@:2}"
ln -sf "$PWD/build/compile_commands.json" "$PWD/compile_commands.json"
'';
build = pkgs.writeShellScriptBin "build" ''
cmake --build "$PWD/build" --parallel "$@"
'';
run-tests = pkgs.writeShellScriptBin "run-tests" ''
cmake --build "$PWD/build" --parallel \
&& ctest --test-dir "$PWD/build" --output-on-failure --parallel "$@"
'';
gui-dev = pkgs.writeShellScriptBin "gui-dev" ''
npm --prefix "$PWD/apps/rux/frontend" run dev "$@"
'';
clean = pkgs.writeShellScriptBin "clean" ''
rm -rf "$PWD/build" && echo "Build directory removed."
'';
format = pkgs.writeShellScriptBin "format" ''
find "$PWD/libs" "$PWD/apps" \( -name '*.cpp' -o -name '*.hpp' \) \
| xargs clang-format -i && echo "Done."
'';
lint = pkgs.writeShellScriptBin "lint" ''
cppcheck --enable=all --suppress=missingIncludeSystem \
--suppress=unmatchedSuppression --inline-suppr \
--check-level=exhaustive \
-I "$PWD/libs/reusex/include" \
-I "$PWD/build/include" \
-I "$PWD/build/generated" \
-I "$PWD/apps/rux/include" \
"$PWD/libs/" "$PWD/apps/"
'';
docs = pkgs.writeShellScriptBin "docs" ''
cmake --build "$PWD/build" --target doc "$@"
'';
};
in
pkgs.mkShell {
inputsFrom = [reusex];
env = cudaEnv;
buildInputs = self.checks.${system}.pre-commit-check.enabledPackages;
packages =
scripts
++ (with pkgs; [
# Python 3.11 (matches Blender) - must come first to take precedence
blender.pythonPackages.python
# Documentation tools
help2man # For generating man pages from --help output
pandoc
sphinx
graphviz # For Doxygen diagrams and visualization
# Debugging and analysis tools
gdb
valgrind
kdePackages.kcachegrind
heaptrack # Memory profiler with GUI
# Build tools
cmake-format # Format CMakeLists.txt files
ccache # Cache C++ compilation to speed up rebuilds
ninja # Faster build system alternative to Make
bear # Generate compile_commands.json for LSP/clangd
# Frontend toolchain for apps/rux/frontend (`npm run dev` / `npm test`).
# Node 22 matches what package-lock.json and pkgs/reusex-gui-frontend use.
nodejs_22
# C++ development tools
clang-tools # Includes clang-format, clang-tidy, clang-rename
cppcheck # Static analysis for C++
include-what-you-use # Check #include dependencies
# Performance profiling
perf # Performance profiling
hotspot # GUI for perf data visualization
# Development tools
libnotify # Send notification when build finishes
sqlite
ffmpeg
openusd
jq # JSON processor for scripts
ripgrep # Fast code search (faster than grep)
fd # Fast file finder (faster than find)
hyperfine # Command-line benchmarking
# Version control tools
tig # Text-mode interface for git
git-filter-repo # Advanced git history rewriting
gitui # Terminal UI for git (alternative)
#qt6.full
#qtcreator
# PDF generation (used at runtime by ruxd for Ressourcekortlægning #456)
typst
# DevOps tools
nix-update
sqlitebrowser
hugin
github-copilot-cli
claude-code
gh
doxygen
tree
git-lfs
# Code coverage
lcov
gcovr # Alternative coverage report generator
# Python development
python3Packages.black # Python code formatter
python3Packages.pytest # Testing framework
python3Packages.mypy # Type checking
]);
shellHook =
''
export VIRTUAL_ENV_PROMPT="ReUseX"
# Run ctest in parallel by default, even for a bare `ctest` typed in
# build/ (#268). Almost all of this suite's wall time is per-process
# dynamic-loader overhead rather than test work — one process per
# TEST_CASE, ~360 of them — so it scales nearly linearly with cores:
# ~12 min serial vs ~75 s at -j8. An explicit `--parallel N` on the
# command line still wins over this.
export CTEST_PARALLEL_LEVEL="''${CTEST_PARALLEL_LEVEL:-$(nproc)}"
# NixOS keeps the real libcuda.so outside Nix, at /run/opengl-driver/lib.
# Binaries built in this shell (./build/apps/rux/rux, ctest binaries) are
# not wrapped with addDriverRunpath, so without this they load the stub
# libcuda.so from cuda_cudart and crash with cudaErrorStubLibrary.
if [ -d /run/opengl-driver/lib ]; then
export LD_LIBRARY_PATH="/run/opengl-driver/lib''${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
fi
${motd}
''
+ self.checks.${system}.pre-commit-check.shellHook
+ ''
# Force core.hooksPath to an ABSOLUTE path (#317). pre-commit-hooks.nix's
# installationScript (above) stores a path relative to the toplevel
# working directory, which is correct for the main checkout but wrong
# for a linked worktree: `.git` there is a FILE (gitdir pointer), not
# a directory, so the relative path resolves to nothing and git
# silently runs no hooks. Re-pin it to the absolute git-common-dir on
# every shell entry; idempotent, silent on success.
if command -v git >/dev/null 2>&1 && git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
git config --local core.hooksPath "$(git rev-parse --path-format=absolute --git-common-dir)/hooks"
fi
'';
}