29 , enableEXR ? !stdenv.hostPlatform.isDarwin
32 , enableJPEG2000 ? true
38 , enableVA ? !stdenv.hostPlatform.isDarwin
40 , enableContrib ? true
42 , enableCuda ? config.cudaSupport
43 , enableCublas ? enableCuda
44 , enableCudnn ? false # NOTE: CUDNN has a large impact on closure size so we disable it by default
45 , enableCufft ? enableCuda
47 , nvidia-optical-flow-sdk
50 , enableUnfree ? false
52 , enablePython ? false
62 , enableGStreamer ? true
68 , enableTesseract ? false
75 , enableGPhoto2 ? false
77 , enableDC1394 ? false
83 , runAccuracyTests ? true
84 , runPerformanceTests ? false
85 # Modules to enable via BUILD_LIST to build a customized opencv.
86 # An empty lists means this setting is ommited which matches upstreams default.
87 , enabledModules ? [ ]
91 , VideoDecodeAcceleration
100 inherit (lib.attrsets) mapAttrsToList optionalAttrs;
101 inherit (lib.lists) last optionals;
102 inherit (lib.meta) getExe;
103 inherit (lib.strings) cmakeBool cmakeFeature cmakeOptionType concatStrings concatStringsSep optionalString;
104 inherit (lib.trivial) flip;
108 # It's necessary to consistently use backendStdenv when building with CUDA
109 # support, otherwise we get libstdc++ errors downstream
110 stdenv = throw "Use effectiveStdenv instead";
111 effectiveStdenv = if enableCuda then cudaPackages.backendStdenv else inputs.stdenv;
113 src = fetchFromGitHub {
117 hash = "sha256-3qqu4xlRyMbPKHHTIT+iRRGtpFlcv0NU8GNZpgjdi6k=";
120 contribSrc = fetchFromGitHub {
122 repo = "opencv_contrib";
124 hash = "sha256-K74Ghk4uDqj4OWEzDxT2R3ERi+jkAWZszzezRenfuZ8=";
127 testDataSrc = fetchFromGitHub {
129 repo = "opencv_extra";
131 hash = "sha256-pActKi7aN5EOZq2Fpf5mALnZq71c037/R3Q6wJ4uCfQ=";
134 # Contrib must be built in order to enable Tesseract support:
135 buildContrib = enableContrib || enableTesseract || enableOvis;
137 # See opencv/3rdparty/ippicv/ippicv.cmake
139 src = fetchFromGitHub {
141 repo = "opencv_3rdparty";
142 rev = "0cc4aa06bf2bef4b05d237c69a5a96b9cd0cb85a";
143 hash = "sha256-/kHivOgCkY9YdcRRaVgytXal3ChE9xFfGAB0CfFO5ec=";
145 files = let name = platform: "ippicv_2021.10.0_${platform}_20230919_general.tgz"; in
146 if effectiveStdenv.hostPlatform.system == "x86_64-linux" then
147 { ${name "lnx_intel64"} = "606a19b207ebedfe42d59fd916cc4850"; }
148 else if effectiveStdenv.hostPlatform.system == "i686-linux" then
149 { ${name "lnx_ia32"} = "ea08487b810baad2f68aca87b74a2db9"; }
150 else if effectiveStdenv.hostPlatform.system == "x86_64-darwin" then
151 { ${name "mac_intel64"} = "14f01c5a4780bfae9dde9b0aaf5e56fc"; }
153 throw "ICV is not available for this platform (or not yet supported by this package)";
154 dst = ".cache/ippicv";
157 # See opencv_contrib/modules/xfeatures2d/cmake/download_vgg.cmake
159 src = fetchFromGitHub {
161 repo = "opencv_3rdparty";
162 rev = "fccf7cd6a4b12079f73bbfb21745f9babcd4eb1d";
163 hash = "sha256-fjdGM+CxV1QX7zmF2AiR9NDknrP2PjyaxtjT21BVLmU=";
166 "vgg_generated_48.i" = "e8d0dcd54d1bcfdc29203d011a797179";
167 "vgg_generated_64.i" = "7126a5d9a8884ebca5aea5d63d677225";
168 "vgg_generated_80.i" = "7cd47228edec52b6d82f46511af325c5";
169 "vgg_generated_120.i" = "151805e03568c9f490a5e3a872777b75";
171 dst = ".cache/xfeatures2d/vgg";
174 # See opencv_contrib/modules/xfeatures2d/cmake/download_boostdesc.cmake
176 src = fetchFromGitHub {
178 repo = "opencv_3rdparty";
179 rev = "34e4206aef44d50e6bbcd0ab06354b52e7466d26";
180 sha256 = "13yig1xhvgghvxspxmdidss5lqiikpjr0ddm83jsi0k85j92sn62";
183 "boostdesc_bgm.i" = "0ea90e7a8f3f7876d450e4149c97c74f";
184 "boostdesc_bgm_bi.i" = "232c966b13651bd0e46a1497b0852191";
185 "boostdesc_bgm_hd.i" = "324426a24fa56ad9c5b8e3e0b3e5303e";
186 "boostdesc_binboost_064.i" = "202e1b3e9fec871b04da31f7f016679f";
187 "boostdesc_binboost_128.i" = "98ea99d399965c03d555cef3ea502a0b";
188 "boostdesc_binboost_256.i" = "e6dcfa9f647779eb1ce446a8d759b6ea";
189 "boostdesc_lbgm.i" = "0ae0675534aa318d9668f2a179c2a052";
191 dst = ".cache/xfeatures2d/boostdesc";
194 # See opencv_contrib/modules/face/CMakeLists.txt
196 src = fetchFromGitHub {
198 repo = "opencv_3rdparty";
199 rev = "8afa57abc8229d611c4937165d20e2a2d9fc5a12";
200 hash = "sha256-m9yF4kfmpRJybohdRwUTmboeU+SbZQ6F6gm32PDWNBg=";
203 "face_landmark_model.dat" = "7505c44ca4eb54b4ab1e4777cb96ac05";
208 # See opencv/modules/gapi/cmake/DownloadADE.cmake
211 url = "https://github.com/opencv/ade/archive/${name}";
212 hash = "sha256-WG/GudVpkO10kOJhoKXFMj672kggvyRYCIpezal3wcE=";
214 name = "v0.1.2d.zip";
215 md5 = "dbb095a8bf3008e91edbbf45d8d34885";
219 # See opencv_contrib/modules/wechat_qrcode/CMakeLists.txt
221 src = fetchFromGitHub {
223 repo = "opencv_3rdparty";
224 rev = "a8b69ccc738421293254aec5ddb38bd523503252";
225 hash = "sha256-/n6zHwf0Rdc4v9o4rmETzow/HTv+81DnHP+nL56XiTY=";
228 "detect.caffemodel" = "238e2b2d6f3c18d6c3a30de0c31e23cf";
229 "detect.prototxt" = "6fb4976b32695f9f5c6305c19f12537d";
230 "sr.caffemodel" = "cbfcd60361a73beb8c583eea7e8e6664";
231 "sr.prototxt" = "69db99927a70df953b471daaba03fbef";
233 dst = ".cache/wechat_qrcode";
236 # See opencv/cmake/OpenCVDownload.cmake
237 installExtraFiles = {dst, files, src, ...}: ''
239 '' + concatStrings (flip mapAttrsToList files (name: md5: ''
240 ln -s "${src}/${name}" "${dst}/${md5}-${name}"
242 installExtraFile = {dst, md5, name, src, ...}: ''
244 ln -s "${src}" "${dst}/${md5}-${name}"
247 withOpenblas = (enableBlas && blas.provider.pname == "openblas");
248 #multithreaded openblas conflicts with opencv multithreading, which manifest itself in hung tests
249 #https://github.com/OpenMathLib/OpenBLAS/wiki/Faq/4bded95e8dc8aadc70ce65267d1093ca7bdefc4c#multi-threaded
250 openblas_ = blas.provider.override { singleThreaded = true; };
252 inherit (cudaPackages) cudaFlags;
253 inherit (cudaFlags) cmakeCudaArchitecturesString cudaCapabilities;
257 effectiveStdenv.mkDerivation {
264 ] ++ optionals (runAccuracyTests || runPerformanceTests) [
267 cudaPropagateToOutput = "cxxdev";
269 postUnpack = optionalString buildContrib ''
270 cp --no-preserve=mode -r "${contribSrc}/modules" "$NIX_BUILD_TOP/source/opencv_contrib"
273 # Ensures that we use the system OpenEXR rather than the vendored copy of the source included with OpenCV.
275 ./cmake-don-t-use-OpenCVFindOpenEXR.patch
276 ] ++ optionals enableCuda [
277 ./cuda_opt_flow.patch
280 # This prevents cmake from using libraries in impure paths (which
281 # causes build failure on non NixOS)
283 sed -i '/Add these standard paths to the search paths for FIND_LIBRARY/,/^\s*$/{d}' CMakeLists.txt
287 installExtraFile ade +
288 optionalString enableIpp (installExtraFiles ippicv) + (
289 optionalString buildContrib ''
290 cmakeFlagsArray+=("-DOPENCV_EXTRA_MODULES_PATH=$NIX_BUILD_TOP/source/opencv_contrib")
292 ${installExtraFiles vgg}
293 ${installExtraFiles boostdesc}
294 ${installExtraFiles face}
295 ${installExtraFiles wechat_qrcode}
300 [ -e modules/core/version_string.inc ]
301 echo '"(build info elided)"' > modules/core/version_string.inc
311 ] ++ optionals enablePython [
312 pythonPackages.python
313 ] ++ optionals (effectiveStdenv.buildPlatform == effectiveStdenv.hostPlatform) [
315 ] ++ optionals enableGtk2 [
317 ] ++ optionals enableGtk3 [
319 ] ++ optionals enableVtk [
321 ] ++ optionals enableJPEG [
323 ] ++ optionals enablePNG [
325 ] ++ optionals enableTIFF [
327 ] ++ optionals enableWebP [
329 ] ++ optionals enableEXR [
332 ] ++ optionals enableJPEG2000 [
334 ] ++ optionals enableFfmpeg [
336 ] ++ optionals (enableFfmpeg && effectiveStdenv.hostPlatform.isDarwin) [
338 VideoDecodeAcceleration
339 ] ++ optionals (enableGStreamer && effectiveStdenv.hostPlatform.isLinux) [
341 gst_all_1.gst-plugins-base
342 gst_all_1.gst-plugins-good
347 ] ++ optionals enableOvis [
349 ] ++ optionals enableGPhoto2 [
351 ] ++ optionals enableDC1394 [
353 ] ++ optionals enableEigen [
355 ] ++ optionals enableVA [
357 ] ++ optionals enableBlas [
359 ] ++ optionals enableTesseract [
360 # There is seemingly no compile-time flag for Tesseract. It's
361 # simply enabled automatically if contrib is built, and it detects
362 # tesseract & leptonica.
365 ] ++ optionals enableTbb [
367 ] ++ optionals effectiveStdenv.hostPlatform.isDarwin [
371 VideoDecodeAcceleration
375 ] ++ optionals enableDocs [
378 ] ++ optionals enableCuda [
379 cudaPackages.cuda_cudart
380 cudaPackages.cuda_cccl # <thrust/*>
381 cudaPackages.libnpp # npp.h
382 nvidia-optical-flow-sdk
383 ] ++ optionals enableCublas [
384 # May start using the default $out instead once
385 # https://github.com/NixOS/nixpkgs/issues/271792
387 cudaPackages.libcublas # cublas_v2.h
388 ] ++ optionals enableCudnn [
389 cudaPackages.cudnn # cudnn.h
390 ] ++ optionals enableCufft [
391 cudaPackages.libcufft # cufft.h
394 propagatedBuildInputs = optionals enablePython [ pythonPackages.numpy ];
396 nativeBuildInputs = [
400 ] ++ optionals enablePython [
403 pythonPackages.setuptools
404 ] ++ optionals enableCuda [
405 cudaPackages.cuda_nvcc
408 env.NIX_CFLAGS_COMPILE = optionalString enableEXR "-I${ilmbase.dev}/include/OpenEXR";
410 # Configure can't find the library without this.
411 OpenBLAS_HOME = optionalString withOpenblas openblas_.dev;
412 OpenBLAS = optionalString withOpenblas openblas_;
415 (cmakeBool "OPENCV_GENERATE_PKGCONFIG" true)
416 (cmakeBool "WITH_OPENMP" true)
417 (cmakeBool "BUILD_PROTOBUF" false)
418 (cmakeOptionType "path" "Protobuf_PROTOC_EXECUTABLE" (getExe buildPackages.protobuf_21))
419 (cmakeBool "PROTOBUF_UPDATE_FILES" true)
420 (cmakeBool "OPENCV_ENABLE_NONFREE" enableUnfree)
421 (cmakeBool "BUILD_TESTS" runAccuracyTests)
422 (cmakeBool "BUILD_PERF_TESTS" runPerformanceTests)
423 (cmakeBool "CMAKE_SKIP_BUILD_RPATH" true)
424 (cmakeBool "BUILD_DOCS" enableDocs)
425 # "OpenCV disables pkg-config to avoid using of host libraries. Consider using PKG_CONFIG_LIBDIR to specify target SYSROOT"
426 # but we have proper separation of build and host libs :), fixes cross
427 (cmakeBool "OPENCV_ENABLE_PKG_CONFIG" true)
428 (cmakeBool "WITH_IPP" enableIpp)
429 (cmakeBool "WITH_TIFF" enableTIFF)
430 (cmakeBool "WITH_WEBP" enableWebP)
431 (cmakeBool "WITH_JPEG" enableJPEG)
432 (cmakeBool "WITH_PNG" enablePNG)
433 (cmakeBool "WITH_OPENEXR" enableEXR)
434 (cmakeBool "WITH_OPENJPEG" enableJPEG2000)
435 (cmakeBool "WITH_JASPER" false) # OpenCV falls back to a vendored copy of Jasper when OpenJPEG is disabled
436 (cmakeBool "WITH_TBB" enableTbb)
439 (cmakeBool "WITH_CUDA" enableCuda)
440 (cmakeBool "WITH_CUBLAS" enableCublas)
441 (cmakeBool "WITH_CUDNN" enableCudnn)
442 (cmakeBool "WITH_CUFFT" enableCufft)
445 (cmakeBool "ENABLE_LTO" enableLto)
446 (cmakeBool "ENABLE_THIN_LTO" (
448 # Only clang supports thin LTO, so we must either be using clang through the effectiveStdenv,
449 effectiveStdenv.cc.isClang ||
450 # or through the backend effectiveStdenv.
451 (enableCuda && effectiveStdenv.cc.isClang)
454 ] ++ optionals enableCuda [
455 (cmakeBool "CUDA_FAST_MATH" true)
456 (cmakeFeature "CUDA_NVCC_FLAGS" "--expt-relaxed-constexpr")
458 # OpenCV respects at least three variables:
459 # -DCUDA_GENERATION takes a single arch name, e.g. Volta
460 # -DCUDA_ARCH_BIN takes a semi-colon separated list of real arches, e.g. "8.0;8.6"
461 # -DCUDA_ARCH_PTX takes the virtual arch, e.g. "8.6"
462 (cmakeFeature "CUDA_ARCH_BIN" cmakeCudaArchitecturesString)
463 (cmakeFeature "CUDA_ARCH_PTX" (last cudaCapabilities))
465 (cmakeOptionType "path" "NVIDIA_OPTICAL_FLOW_2_0_HEADERS_PATH" nvidia-optical-flow-sdk.outPath)
466 ] ++ optionals effectiveStdenv.hostPlatform.isDarwin [
467 (cmakeBool "WITH_OPENCL" false)
468 (cmakeBool "WITH_LAPACK" false)
470 # Disable unnecessary vendoring that's enabled by default only for Darwin.
471 # Note that the opencvFlag feature flags listed above still take
472 # precedence, so we can safely list everything here.
473 (cmakeBool "BUILD_ZLIB" false)
474 (cmakeBool "BUILD_TIFF" false)
475 (cmakeBool "BUILD_OPENJPEG" false)
476 (cmakeBool "BUILD_JASPER" false)
477 (cmakeBool "BUILD_JPEG" false)
478 (cmakeBool "BUILD_PNG" false)
479 (cmakeBool "BUILD_WEBP" false)
480 ] ++ optionals (!effectiveStdenv.hostPlatform.isDarwin) [
481 (cmakeOptionType "path" "OPENCL_LIBRARY" "${ocl-icd}/lib/libOpenCL.so")
482 ] ++ optionals enablePython [
483 (cmakeOptionType "path" "OPENCV_PYTHON_INSTALL_PATH" pythonPackages.python.sitePackages)
484 ] ++ optionals (enabledModules != [ ]) [
485 (cmakeFeature "BUILD_LIST" (concatStringsSep "," enabledModules))
488 postBuild = optionalString enableDocs ''
493 optionalString (runAccuracyTests || runPerformanceTests) ''
495 cp -R $src/samples $package_tests/
496 '' + optionalString runAccuracyTests ''
497 mv ./bin/*test* $package_tests/
498 '' + optionalString runPerformanceTests ''
499 mv ./bin/*perf* $package_tests/
502 # By default $out/lib/pkgconfig/opencv4.pc looks something like this:
504 # prefix=/nix/store/g0wnfyjjh4rikkvp22cpkh41naa43i4i-opencv-4.0.0
505 # exec_prefix=${prefix}
506 # libdir=${exec_prefix}//nix/store/g0wnfyjjh4rikkvp22cpkh41naa43i4i-opencv-4.0.0/lib
507 # includedir_old=${prefix}//nix/store/g0wnfyjjh4rikkvp22cpkh41naa43i4i-opencv-4.0.0/include/opencv4/opencv
508 # includedir_new=${prefix}//nix/store/g0wnfyjjh4rikkvp22cpkh41naa43i4i-opencv-4.0.0/include/opencv4
510 # Libs: -L${exec_prefix}//nix/store/g0wnfyjjh4rikkvp22cpkh41naa43i4i-opencv-4.0.0/lib ...
511 # Note that ${exec_prefix} is set to $out but that $out is also appended to
512 # ${exec_prefix}. This causes linker errors in downstream packages so we strip
513 # of $out after the ${exec_prefix} and ${prefix} prefixes:
515 sed -i "s|{exec_prefix}/$out|{exec_prefix}|;s|{prefix}/$out|{prefix}|" \
516 "$out/lib/pkgconfig/opencv4.pc"
519 # fix deps not progagating from opencv4.cxxdev if cuda is disabled
520 # see https://github.com/NixOS/nixpkgs/issues/276691
521 + optionalString (!enableCuda) ''
522 mkdir -p "$cxxdev/nix-support"
523 echo "''${!outputDev}" >> "$cxxdev/nix-support/propagated-build-inputs"
525 # remove the requirement that the exact same version of CUDA is used in packages
526 # consuming OpenCV's CMakes files
527 + optionalString enableCuda ''
528 substituteInPlace "$out/lib/cmake/opencv4/OpenCVConfig.cmake" \
530 'find_host_package(CUDA ''${OpenCV_CUDA_VERSION} EXACT REQUIRED)' \
531 'find_host_package(CUDA REQUIRED)' \
533 'message(FATAL_ERROR "OpenCV static library was compiled with CUDA' \
534 'message("OpenCV static library was compiled with CUDA'
536 # install python distribution information, so other packages can `import opencv`
537 + optionalString enablePython ''
538 pushd $NIX_BUILD_TOP/$sourceRoot/modules/python/package
539 python -m pip wheel --verbose --no-index --no-deps --no-clean --no-build-isolation --wheel-dir dist .
542 python -m pip install ./*.whl --no-index --no-warn-script-location --prefix="$out" --no-cache
549 cudaSupport = enableCuda;
552 inherit (gst_all_1) gst-plugins-bad;
554 // optionalAttrs (!effectiveStdenv.hostPlatform.isDarwin) { inherit qimgv; }
555 // optionalAttrs (!enablePython) { pythonEnabled = pythonPackages.opencv4; }
556 // optionalAttrs (effectiveStdenv.buildPlatform != "x86_64-darwin") {
557 opencv4-tests = callPackage ./tests.nix {
558 inherit enableGStreamer enableGtk2 enableGtk3 runAccuracyTests runPerformanceTests testDataSrc;
562 // optionalAttrs (enableCuda) {
563 no-libstdcxx-errors = callPackage ./libstdcxx-test.nix { attrName = "opencv4"; };
565 } // optionalAttrs enablePython { pythonPath = [ ]; };
568 description = "Open Computer Vision Library with more than 500 algorithms";
569 homepage = "https://opencv.org/";
570 license = if enableUnfree then lib.licenses.unfree else lib.licenses.bsd3;
571 maintainers = with lib.maintainers; [ basvandijk ];
572 platforms = with lib.platforms; linux ++ darwin;