nixpkgs mirror (for testing)
github.com/NixOS/nixpkgs
nix
1{
2 SDL,
3 addDriverRunpath,
4 alembic,
5 apple-sdk_15,
6 blender,
7 boost,
8 brotli,
9 callPackage,
10 cmake,
11 colladaSupport ? true,
12 config,
13 cudaPackages,
14 cudaSupport ? config.cudaSupport,
15 dbus,
16 embree,
17 fetchzip,
18 fetchFromGitHub,
19 ffmpeg,
20 fftw,
21 fftwFloat,
22 freetype,
23 gettext,
24 glew,
25 gmp,
26 hipSupport ? false,
27 jackaudioSupport ? false,
28 jemalloc,
29 lib,
30 libGL,
31 libGLU,
32 libX11,
33 libXext,
34 libXi,
35 libXrender,
36 libXxf86vm,
37 libdecor,
38 libepoxy,
39 libffi,
40 libharu,
41 libjack2,
42 libjpeg,
43 libpng,
44 libsamplerate,
45 libsndfile,
46 libspnav,
47 libtiff,
48 libwebp,
49 libxkbcommon,
50 llvmPackages,
51 makeWrapper,
52 manifold,
53 mesa,
54 nix-update-script,
55 openUsdSupport ? !stdenv.hostPlatform.isDarwin,
56 openal,
57 opencollada-blender,
58 opencolorio,
59 openexr,
60 openimagedenoise,
61 openimageio,
62 openjpeg,
63 openpgl,
64 opensubdiv,
65 openvdb,
66 openxr-loader,
67 pkg-config,
68 potrace,
69 pugixml,
70 python3Packages, # must use instead of python3.pkgs, see https://github.com/NixOS/nixpkgs/issues/211340
71 rocmPackages, # comes with a significantly larger closure size
72 runCommand,
73 shaderc,
74 spaceNavSupport ? stdenv.hostPlatform.isLinux,
75 sse2neon,
76 stdenv,
77 tbb_2022,
78 vulkan-headers,
79 vulkan-loader,
80 wayland,
81 wayland-protocols,
82 wayland-scanner,
83 waylandSupport ? stdenv.hostPlatform.isLinux,
84 zlib,
85 zstd,
86}:
87
88let
89 stdenv' = if cudaSupport then cudaPackages.backendStdenv else stdenv;
90
91 embreeSupport =
92 (!stdenv.hostPlatform.isAarch64 && stdenv.hostPlatform.isLinux) || stdenv.hostPlatform.isDarwin;
93 openImageDenoiseSupport =
94 (!stdenv.hostPlatform.isAarch64 && stdenv.hostPlatform.isLinux) || stdenv.hostPlatform.isDarwin;
95 vulkanSupport = !stdenv.hostPlatform.isDarwin;
96
97 python3 = python3Packages.python;
98 pyPkgsOpenusd = python3Packages.openusd.override { withOsl = false; };
99
100 libdecor' = libdecor.overrideAttrs (old: {
101 # Blender uses private APIs, need to patch to expose them
102 patches = (old.patches or [ ]) ++ [ ./libdecor.patch ];
103 });
104
105 # See build_files/config/pipeline_config.yaml in upstream source for version
106 optix = fetchFromGitHub {
107 owner = "NVIDIA";
108 repo = "optix-dev";
109 tag = "v8.0.0";
110 hash = "sha256-SXkXZHzQH8JOkXypjjxNvT/lUlWZkCuhh6hNCHE7FkY=";
111 };
112
113 tbb = tbb_2022;
114in
115
116stdenv'.mkDerivation (finalAttrs: {
117 pname = "blender";
118 version = "4.5.1";
119
120 src = fetchzip {
121 name = "source";
122 url = "https://download.blender.org/source/blender-${finalAttrs.version}.tar.xz";
123 hash = "sha256-x1zeBQ0aTBFUpB7c4XfP6b2p+ENRFEnTGa4m/7Pl24k=";
124 };
125
126 postPatch =
127 (lib.optionalString stdenv.hostPlatform.isDarwin ''
128 : > build_files/cmake/platform/platform_apple_xcode.cmake
129 substituteInPlace source/creator/CMakeLists.txt \
130 --replace-fail '${"$"}{LIBDIR}/python' \
131 '${python3}' \
132 --replace-fail '${"$"}{LIBDIR}/materialx/' '${python3Packages.materialx}/'
133 substituteInPlace build_files/cmake/platform/platform_apple.cmake \
134 --replace-fail '${"$"}{LIBDIR}/brotli/lib/libbrotlicommon-static.a' \
135 '${lib.getLib brotli}/lib/libbrotlicommon.dylib' \
136 --replace-fail '${"$"}{LIBDIR}/brotli/lib/libbrotlidec-static.a' \
137 '${lib.getLib brotli}/lib/libbrotlidec.dylib'
138 '')
139 + (lib.optionalString hipSupport ''
140 substituteInPlace extern/hipew/src/hipew.c --replace-fail '"/opt/rocm/hip/lib/libamdhip64.so.${lib.versions.major rocmPackages.clr.version}"' '"${rocmPackages.clr}/lib/libamdhip64.so"'
141 substituteInPlace extern/hipew/src/hipew.c --replace-fail '"opt/rocm/hip/bin"' '"${rocmPackages.clr}/bin"'
142 '');
143
144 env.NIX_CFLAGS_COMPILE = "-I${python3}/include/${python3.libPrefix}";
145
146 cmakeFlags = [
147 "-DMaterialX_DIR=${python3Packages.materialx}/lib/cmake/MaterialX"
148 "-DPYTHON_INCLUDE_DIR=${python3}/include/${python3.libPrefix}"
149 "-DPYTHON_LIBPATH=${python3}/lib"
150 "-DPYTHON_LIBRARY=${python3.libPrefix}"
151 "-DPYTHON_NUMPY_INCLUDE_DIRS=${python3Packages.numpy_1}/${python3.sitePackages}/numpy/core/include"
152 "-DPYTHON_NUMPY_PATH=${python3Packages.numpy_1}/${python3.sitePackages}"
153 "-DPYTHON_VERSION=${python3.pythonVersion}"
154 "-DWITH_ALEMBIC=ON"
155 "-DWITH_ASSERT_ABORT=OFF"
156 "-DWITH_BUILDINFO=OFF"
157 "-DWITH_CODEC_FFMPEG=ON"
158 "-DWITH_CODEC_SNDFILE=ON"
159 "-DWITH_CPU_CHECK=OFF"
160 "-DWITH_CYCLES_DEVICE_OPTIX=${if cudaSupport then "ON" else "OFF"}"
161 "-DWITH_CYCLES_EMBREE=${if embreeSupport then "ON" else "OFF"}"
162 "-DWITH_CYCLES_OSL=OFF"
163 "-DWITH_FFTW3=ON"
164 "-DWITH_HYDRA=${if openUsdSupport then "ON" else "OFF"}"
165 "-DWITH_IMAGE_OPENJPEG=ON"
166 "-DWITH_INSTALL_PORTABLE=OFF"
167 "-DWITH_JACK=${if jackaudioSupport then "ON" else "OFF"}"
168 "-DWITH_LIBS_PRECOMPILED=OFF"
169 "-DWITH_MOD_OCEANSIM=ON"
170 "-DWITH_OPENCOLLADA=${if colladaSupport then "ON" else "OFF"}"
171 "-DWITH_OPENCOLORIO=ON"
172 "-DWITH_OPENIMAGEDENOISE=${if openImageDenoiseSupport then "ON" else "OFF"}"
173 "-DWITH_OPENSUBDIV=ON"
174 "-DWITH_OPENVDB=ON"
175 "-DWITH_PIPEWIRE=OFF"
176 "-DWITH_PULSEAUDIO=OFF"
177 "-DWITH_PYTHON_INSTALL=OFF"
178 "-DWITH_PYTHON_INSTALL_NUMPY=OFF"
179 "-DWITH_PYTHON_INSTALL_REQUESTS=OFF"
180 "-DWITH_SDL=OFF"
181 "-DWITH_STRICT_BUILD_OPTIONS=ON"
182 "-DWITH_TBB=ON"
183 "-DWITH_USD=${if openUsdSupport then "ON" else "OFF"}"
184
185 # Blender supplies its own FindAlembic.cmake (incompatible with the Alembic-supplied config file)
186 "-DALEMBIC_INCLUDE_DIR=${lib.getDev alembic}/include"
187 "-DALEMBIC_LIBRARY=${lib.getLib alembic}/lib/libAlembic${stdenv.hostPlatform.extensions.sharedLibrary}"
188 ]
189 ++ lib.optionals waylandSupport [
190 "-DWITH_GHOST_WAYLAND=ON"
191 "-DWITH_GHOST_WAYLAND_DBUS=ON"
192 "-DWITH_GHOST_WAYLAND_DYNLOAD=OFF"
193 "-DWITH_GHOST_WAYLAND_LIBDECOR=ON"
194 ]
195 ++ lib.optionals stdenv.hostPlatform.isDarwin [
196 "-DLIBDIR=/does-not-exist"
197 "-DSSE2NEON_INCLUDE_DIR=${sse2neon}/lib"
198 ]
199 ++ lib.optional stdenv.cc.isClang "-DPYTHON_LINKFLAGS=" # Clang doesn't support "-export-dynamic"
200 ++ lib.optionals cudaSupport [
201 "-DOPTIX_ROOT_DIR=${optix}"
202 "-DWITH_CYCLES_CUDA_BINARIES=ON"
203 ];
204
205 preConfigure = ''
206 (
207 expected_python_version=$(grep -E --only-matching 'set\(_PYTHON_VERSION_SUPPORTED [0-9.]+\)' build_files/cmake/Modules/FindPythonLibsUnix.cmake | grep -E --only-matching '[0-9.]+')
208 actual_python_version=$(python -c 'import sys; print(".".join(map(str, sys.version_info[0:2])))')
209 if ! [[ "$actual_python_version" = "$expected_python_version" ]]; then
210 echo "wrong Python version, expected '$expected_python_version', got '$actual_python_version'" >&2
211 exit 1
212 fi
213 )
214 '';
215
216 nativeBuildInputs = [
217 cmake
218 llvmPackages.llvm.dev
219 makeWrapper
220 python3Packages.wrapPython
221 ]
222 ++ lib.optionals cudaSupport [
223 addDriverRunpath
224 cudaPackages.cuda_nvcc
225 ]
226 ++ lib.optionals waylandSupport [
227 pkg-config
228 wayland-scanner
229 ];
230
231 buildInputs = [
232 alembic
233 boost
234 ffmpeg
235 fftw
236 fftwFloat
237 freetype
238 gettext
239 glew
240 gmp
241 jemalloc
242 libepoxy
243 libharu
244 libjpeg
245 libpng
246 libsamplerate
247 libsndfile
248 libtiff
249 libwebp
250 (manifold.override { tbb_2021 = tbb; })
251 opencolorio
252 openexr
253 openimageio
254 openjpeg
255 (openpgl.override { inherit tbb; })
256 (opensubdiv.override { inherit cudaSupport; })
257 (openvdb.override { inherit tbb; })
258 potrace
259 pugixml
260 python3
261 python3Packages.materialx
262 tbb
263 zlib
264 zstd
265 ]
266 ++ lib.optional embreeSupport embree
267 ++ lib.optional openImageDenoiseSupport (openimagedenoise.override { inherit cudaSupport tbb; })
268 ++ (
269 if (!stdenv.hostPlatform.isDarwin) then
270 [
271 libGL
272 libGLU
273 libX11
274 libXext
275 libXi
276 libXrender
277 libXxf86vm
278 openal
279 openxr-loader
280 ]
281 else
282 [
283 SDL
284 # blender chooses Metal features based on runtime system version
285 # lets use the latest SDK and let Blender handle falling back on older systems.
286 apple-sdk_15
287 brotli
288 llvmPackages.openmp
289 sse2neon
290 ]
291 )
292 ++ lib.optionals cudaSupport [ cudaPackages.cuda_cudart ]
293 ++ lib.optionals openUsdSupport [ pyPkgsOpenusd ]
294 ++ lib.optionals waylandSupport [
295 dbus
296 libdecor'
297 libffi
298 libxkbcommon
299 wayland
300 wayland-protocols
301 ]
302 ++ lib.optional colladaSupport opencollada-blender
303 ++ lib.optional jackaudioSupport libjack2
304 ++ lib.optional spaceNavSupport libspnav
305 ++ lib.optionals vulkanSupport [
306 shaderc
307 vulkan-headers
308 vulkan-loader
309 ];
310
311 pythonPath =
312 let
313 ps = python3Packages;
314 in
315 [
316 ps.materialx
317 ps.numpy_1
318 ps.requests
319 ps.zstandard
320 ]
321 ++ lib.optionals openUsdSupport [ pyPkgsOpenusd ];
322
323 blenderExecutable =
324 placeholder "out"
325 + (
326 if stdenv.hostPlatform.isDarwin then
327 "/Applications/Blender.app/Contents/MacOS/Blender"
328 else
329 "/bin/blender"
330 );
331
332 postInstall =
333 lib.optionalString stdenv.hostPlatform.isDarwin ''
334 mkdir $out/Applications
335 mv $out/Blender.app $out/Applications
336 ''
337 + ''
338 buildPythonPath "$pythonPath"
339 wrapProgram $blenderExecutable \
340 --prefix PATH : $program_PATH \
341 --prefix PYTHONPATH : "$program_PYTHONPATH" \
342 --add-flags '--python-use-system-env'
343 '';
344
345 # Set RUNPATH so that libcuda and libnvrtc in /run/opengl-driver(-32)/lib can be
346 # found. See the explanation in libglvnd.
347 postFixup =
348 lib.optionalString cudaSupport ''
349 for program in $out/bin/blender $out/bin/.blender-wrapped; do
350 isELF "$program" || continue
351 addDriverRunpath "$program"
352 done
353 ''
354 + lib.optionalString stdenv.hostPlatform.isDarwin ''
355 makeWrapper $out/Applications/Blender.app/Contents/MacOS/Blender $out/bin/blender
356 '';
357
358 passthru = {
359 python = python3;
360 pythonPackages = python3Packages;
361
362 withPackages =
363 f:
364 (callPackage ./wrapper.nix { }).override {
365 blender = finalAttrs.finalPackage;
366 extraModules = (f python3Packages);
367 };
368
369 tests = {
370 render = runCommand "${finalAttrs.pname}-test" { nativeBuildInputs = [ mesa.llvmpipeHook ]; } ''
371 set -euo pipefail
372 cat <<'PYTHON' > scene-config.py
373 import bpy
374 bpy.context.scene.eevee.taa_render_samples = 32
375 bpy.context.scene.cycles.samples = 32
376 if ${if (stdenv.hostPlatform.isAarch64 && stdenv.hostPlatform.isLinux) then "True" else "False"}:
377 bpy.context.scene.cycles.use_denoising = False
378 bpy.context.scene.render.resolution_x = 100
379 bpy.context.scene.render.resolution_y = 100
380 bpy.context.scene.render.threads_mode = 'FIXED'
381 bpy.context.scene.render.threads = 1
382 PYTHON
383
384 mkdir $out
385 for engine in BLENDER_EEVEE_NEXT CYCLES; do
386 echo "Rendering with $engine..."
387 # Beware that argument order matters
388 ${lib.getExe finalAttrs.finalPackage} \
389 --background \
390 -noaudio \
391 --factory-startup \
392 --python-exit-code 1 \
393 --python scene-config.py \
394 --engine "$engine" \
395 --render-output "$out/$engine" \
396 --render-frame 1
397 done
398 '';
399 tester-cudaAvailable = cudaPackages.writeGpuTestPython { } ''
400 import subprocess
401 subprocess.run([${
402 lib.concatMapStringsSep ", " (x: ''"${x}"'') [
403 (lib.getExe (blender.override { cudaSupport = true; }))
404 "--background"
405 "-noaudio"
406 "--python-exit-code"
407 "1"
408 "--python"
409 "${./test-cuda.py}"
410 ]
411 }], check=True) # noqa: E501
412 '';
413 };
414
415 updateScript = nix-update-script {
416 extraArgs = [
417 "--url=https://projects.blender.org/blender/blender"
418 ];
419 };
420 };
421
422 meta = {
423 broken = stdenv.hostPlatform.isDarwin;
424 description = "3D Creation/Animation/Publishing System";
425 homepage = "https://www.blender.org";
426 # They comment two licenses: GPLv2 and Blender License, but they
427 # say: "We've decided to cancel the BL offering for an indefinite period."
428 # OptiX, enabled with cudaSupport, is non-free.
429 license =
430 with lib.licenses;
431 [ gpl2Plus ] ++ lib.optional cudaSupport (unfree // { shortName = "NVidia OptiX EULA"; });
432
433 platforms = [
434 "aarch64-linux"
435 "x86_64-darwin"
436 "x86_64-linux"
437 "aarch64-darwin"
438 ];
439 maintainers = with lib.maintainers; [
440 amarshall
441 veprbl
442 ];
443 mainProgram = "blender";
444 };
445})