Merge pull request #268619 from tweag/lib-descriptions
[NixPkgs.git] / pkgs / development / libraries / opencv / 3.x.nix
blobe3f458d0d7339e2d76011abc8d86f343455d9a98
1 { lib, stdenv
2 , fetchFromGitHub
3 , fetchpatch
4 , callPackage
5 , cmake, pkg-config, unzip, zlib, pcre, hdf5
6 , glog, boost, gflags, protobuf_21
7 , config
9 , enableJPEG      ? true, libjpeg
10 , enablePNG       ? true, libpng
11 , enableTIFF      ? true, libtiff
12 , enableWebP      ? true, libwebp
13 , enableEXR ?     !stdenv.isDarwin, openexr, ilmbase
14 , enableEigen     ? true, eigen
15 , enableOpenblas  ? true, openblas, blas, lapack
16 , enableContrib   ? true
18 , enableCuda      ? config.cudaSupport
19 , cudaPackages ? { }
20 , enableUnfree    ? false
21 , enableIpp       ? false
22 , enablePython    ? false, pythonPackages ? null
23 , enableGtk2      ? false, gtk2
24 , enableGtk3      ? false, gtk3
25 , enableFfmpeg    ? false, ffmpeg
26 , enableGStreamer ? false, gst_all_1
27 , enableTesseract ? false, tesseract, leptonica
28 , enableTbb       ? false, tbb
29 , enableOvis      ? false, ogre
30 , enableGPhoto2   ? false, libgphoto2
31 , enableDC1394    ? false, libdc1394
32 , enableDocs      ? false, doxygen, graphviz-nox
34 , AVFoundation, Cocoa, VideoDecodeAcceleration, bzip2, CoreMedia, MediaToolbox, Accelerate
37 assert blas.implementation == "openblas" && lapack.implementation == "openblas";
39 assert enablePython -> pythonPackages != null;
41 let
42   inherit (cudaPackages) cudatoolkit;
43   inherit (cudaPackages.cudaFlags) cudaCapabilities;
45   version = "3.4.18";
47   src = fetchFromGitHub {
48     owner  = "opencv";
49     repo   = "opencv";
50     rev    = version;
51     hash   = "sha256-PgwAZNoPknFT0jCLt3TCzend6OYFY3iUIzDf/FptAYA=";
52   };
54   contribSrc = fetchFromGitHub {
55     owner  = "opencv";
56     repo   = "opencv_contrib";
57     rev    = version;
58     hash   = "sha256-TEF/GHglOmsshlC6q4iw14ZMpvA0SaKwlidomAN+sRc=";
59   };
61   # Contrib must be built in order to enable Tesseract support:
62   buildContrib = enableContrib || enableTesseract;
64   useSystemProtobuf = ! stdenv.isDarwin;
66   # See opencv/3rdparty/ippicv/ippicv.cmake
67   ippicv = {
68     src = fetchFromGitHub {
69       owner  = "opencv";
70       repo   = "opencv_3rdparty";
71       rev    = "32e315a5b106a7b89dbed51c28f8120a48b368b4";
72       sha256 = "19w9f0r16072s59diqxsr5q6nmwyz9gnxjs49nglzhd66p3ddbkp";
73     } + "/ippicv";
74     files = let name = platform : "ippicv_2019_${platform}_general_20180723.tgz"; in
75       if stdenv.hostPlatform.system == "x86_64-linux" then
76       { ${name "lnx_intel64"} = "c0bd78adb4156bbf552c1dfe90599607"; }
77       else if stdenv.hostPlatform.system == "i686-linux" then
78       { ${name "lnx_ia32"}    = "4f38432c30bfd6423164b7a24bbc98a0"; }
79       else if stdenv.hostPlatform.system == "x86_64-darwin" then
80       { ${name "mac_intel64"} = "fe6b2bb75ae0e3f19ad3ae1a31dfa4a2"; }
81       else
82       throw "ICV is not available for this platform (or not yet supported by this package)";
83     dst = ".cache/ippicv";
84   };
86   # See opencv_contrib/modules/xfeatures2d/cmake/download_vgg.cmake
87   vgg = {
88     src = fetchFromGitHub {
89       owner  = "opencv";
90       repo   = "opencv_3rdparty";
91       rev    = "fccf7cd6a4b12079f73bbfb21745f9babcd4eb1d";
92       sha256 = "0r9fam8dplyqqsd3qgpnnfgf9l7lj44di19rxwbm8mxiw0rlcdvy";
93     };
94     files = {
95       "vgg_generated_48.i"  = "e8d0dcd54d1bcfdc29203d011a797179";
96       "vgg_generated_64.i"  = "7126a5d9a8884ebca5aea5d63d677225";
97       "vgg_generated_80.i"  = "7cd47228edec52b6d82f46511af325c5";
98       "vgg_generated_120.i" = "151805e03568c9f490a5e3a872777b75";
99     };
100     dst = ".cache/xfeatures2d/vgg";
101   };
103   # See opencv_contrib/modules/xfeatures2d/cmake/download_boostdesc.cmake
104   boostdesc = {
105     src = fetchFromGitHub {
106       owner  = "opencv";
107       repo   = "opencv_3rdparty";
108       rev    = "34e4206aef44d50e6bbcd0ab06354b52e7466d26";
109       sha256 = "13yig1xhvgghvxspxmdidss5lqiikpjr0ddm83jsi0k85j92sn62";
110     };
111     files = {
112       "boostdesc_bgm.i"          = "0ea90e7a8f3f7876d450e4149c97c74f";
113       "boostdesc_bgm_bi.i"       = "232c966b13651bd0e46a1497b0852191";
114       "boostdesc_bgm_hd.i"       = "324426a24fa56ad9c5b8e3e0b3e5303e";
115       "boostdesc_binboost_064.i" = "202e1b3e9fec871b04da31f7f016679f";
116       "boostdesc_binboost_128.i" = "98ea99d399965c03d555cef3ea502a0b";
117       "boostdesc_binboost_256.i" = "e6dcfa9f647779eb1ce446a8d759b6ea";
118       "boostdesc_lbgm.i"         = "0ae0675534aa318d9668f2a179c2a052";
119     };
120     dst = ".cache/xfeatures2d/boostdesc";
121   };
123   # See opencv_contrib/modules/face/CMakeLists.txt
124   face = {
125     src = fetchFromGitHub {
126       owner  = "opencv";
127       repo   = "opencv_3rdparty";
128       rev    = "8afa57abc8229d611c4937165d20e2a2d9fc5a12";
129       sha256 = "061lsvqdidq9xa2hwrcvwi9ixflr2c2lfpc8drr159g68zi8bp4v";
130     };
131     files = {
132       "face_landmark_model.dat" = "7505c44ca4eb54b4ab1e4777cb96ac05";
133     };
134     dst = ".cache/data";
135   };
137   # See opencv/cmake/OpenCVDownload.cmake
138   installExtraFiles = extra : with lib; ''
139     mkdir -p "${extra.dst}"
140   '' + concatStrings (mapAttrsToList (name : md5 : ''
141     ln -s "${extra.src}/${name}" "${extra.dst}/${md5}-${name}"
142   '') extra.files);
144   opencvFlag = name: enabled: "-DWITH_${name}=${printEnabled enabled}";
146   printEnabled = enabled : if enabled then "ON" else "OFF";
149 stdenv.mkDerivation {
150   pname = "opencv";
151   inherit version src;
153   postUnpack = lib.optionalString buildContrib ''
154     cp --no-preserve=mode -r "${contribSrc}/modules" "$NIX_BUILD_TOP/opencv_contrib"
155   '';
157   # Ensures that we use the system OpenEXR rather than the vendored copy of the source included with OpenCV.
158   patches = [
159     ./cmake-don-t-use-OpenCVFindOpenEXR.patch
160   ];
162   # This prevents cmake from using libraries in impure paths (which
163   # causes build failure on non NixOS)
164   # Also, work around https://github.com/NixOS/nixpkgs/issues/26304 with
165   # what appears to be some stray headers in dnn/misc/tensorflow
166   # in contrib when generating the Python bindings:
167   postPatch = ''
168     sed -i '/Add these standard paths to the search paths for FIND_LIBRARY/,/^\s*$/{d}' CMakeLists.txt
169     sed -i -e 's|if len(decls) == 0:|if len(decls) == 0 or "opencv2/" not in hdr:|' ./modules/python/src2/gen2.py
170   '';
172   preConfigure =
173     lib.optionalString enableIpp (installExtraFiles ippicv) + (
174     lib.optionalString buildContrib ''
175       cmakeFlagsArray+=("-DOPENCV_EXTRA_MODULES_PATH=$NIX_BUILD_TOP/opencv_contrib")
177       ${installExtraFiles vgg}
178       ${installExtraFiles boostdesc}
179       ${installExtraFiles face}
180     '');
182   postConfigure = ''
183     [ -e modules/core/version_string.inc ]
184     echo '"(build info elided)"' > modules/core/version_string.inc
185   '';
187   buildInputs =
188        [ zlib pcre hdf5 glog boost gflags ]
189     ++ lib.optional useSystemProtobuf protobuf_21
190     ++ lib.optional enablePython pythonPackages.python
191     ++ lib.optional enableGtk2 gtk2
192     ++ lib.optional enableGtk3 gtk3
193     ++ lib.optional enableJPEG libjpeg
194     ++ lib.optional enablePNG libpng
195     ++ lib.optional enableTIFF libtiff
196     ++ lib.optional enableWebP libwebp
197     ++ lib.optionals enableEXR [ openexr ilmbase ]
198     ++ lib.optional enableFfmpeg ffmpeg
199     ++ lib.optionals (enableFfmpeg && stdenv.isDarwin)
200                      [ VideoDecodeAcceleration bzip2 ]
201     ++ lib.optionals enableGStreamer (with gst_all_1; [ gstreamer gst-plugins-base ])
202     ++ lib.optional enableOvis ogre
203     ++ lib.optional enableGPhoto2 libgphoto2
204     ++ lib.optional enableDC1394 libdc1394
205     ++ lib.optional enableEigen eigen
206     ++ lib.optional enableOpenblas openblas
207     # There is seemingly no compile-time flag for Tesseract.  It's
208     # simply enabled automatically if contrib is built, and it detects
209     # tesseract & leptonica.
210     ++ lib.optionals enableTesseract [ tesseract leptonica ]
211     ++ lib.optional enableTbb tbb
212     ++ lib.optionals stdenv.isDarwin [
213       bzip2 AVFoundation Cocoa VideoDecodeAcceleration CoreMedia MediaToolbox Accelerate
214     ]
215     ++ lib.optionals enableDocs [ doxygen graphviz-nox ];
217   propagatedBuildInputs = lib.optional enablePython pythonPackages.numpy
218     ++ lib.optional enableCuda cudatoolkit;
220   nativeBuildInputs = [ cmake pkg-config unzip ];
222   env.NIX_CFLAGS_COMPILE = lib.optionalString enableEXR "-I${ilmbase.dev}/include/OpenEXR";
224   # Configure can't find the library without this.
225   OpenBLAS_HOME = lib.optionalString enableOpenblas openblas;
227   cmakeFlags = [
228     "-DWITH_OPENMP=ON"
229     "-DBUILD_PROTOBUF=${printEnabled (!useSystemProtobuf)}"
230     "-DPROTOBUF_UPDATE_FILES=${printEnabled useSystemProtobuf}"
231     "-DOPENCV_ENABLE_NONFREE=${printEnabled enableUnfree}"
232     "-DBUILD_TESTS=OFF"
233     "-DBUILD_PERF_TESTS=OFF"
234     "-DBUILD_DOCS=${printEnabled enableDocs}"
235     (opencvFlag "IPP" enableIpp)
236     (opencvFlag "TIFF" enableTIFF)
237     (opencvFlag "WEBP" enableWebP)
238     (opencvFlag "JPEG" enableJPEG)
239     (opencvFlag "PNG" enablePNG)
240     (opencvFlag "OPENEXR" enableEXR)
241     (opencvFlag "CUDA" enableCuda)
242     (opencvFlag "CUBLAS" enableCuda)
243     (opencvFlag "TBB" enableTbb)
244   ] ++ lib.optionals enableCuda [
245     "-DCUDA_FAST_MATH=ON"
246     "-DCUDA_HOST_COMPILER=${cudatoolkit.cc}/bin/cc"
247     "-DCUDA_NVCC_FLAGS=--expt-relaxed-constexpr"
248     "-DCUDA_ARCH_BIN=${lib.concatStringsSep ";" cudaCapabilities}"
249     "-DCUDA_ARCH_PTX=${lib.last cudaCapabilities}"
250   ] ++ lib.optionals stdenv.isDarwin [
251     "-DWITH_OPENCL=OFF"
252     "-DWITH_LAPACK=OFF"
254     # Disable unnecessary vendoring that's enabled by default only for Darwin.
255     # Note that the opencvFlag feature flags listed above still take
256     # precedence, so we can safely list everything here.
257     "-DBUILD_ZLIB=OFF"
258     "-DBUILD_TIFF=OFF"
259     "-DBUILD_JASPER=OFF"
260     "-DBUILD_JPEG=OFF"
261     "-DBUILD_PNG=OFF"
262     "-DBUILD_WEBP=OFF"
263   ] ++ lib.optionals enablePython [
264     "-DOPENCV_SKIP_PYTHON_LOADER=ON"
265   ] ++ lib.optionals enableEigen [
266     # Autodetection broken by https://github.com/opencv/opencv/pull/13337
267     "-DEIGEN_INCLUDE_PATH=${eigen}/include/eigen3"
268   ];
270   postBuild = lib.optionalString enableDocs ''
271     make doxygen
272   '';
274   # By default $out/lib/pkgconfig/opencv.pc looks something like this:
275   #
276   #   prefix=/nix/store/10pzq1a8fkh8q4sysj8n6mv0w0nl0miq-opencv-3.4.1
277   #   exec_prefix=${prefix}
278   #   libdir=${exec_prefix}//nix/store/10pzq1a8fkh8q4sysj8n6mv0w0nl0miq-opencv-3.4.1/lib
279   #   ...
280   #   Libs: -L${exec_prefix}//nix/store/10pzq1a8fkh8q4sysj8n6mv0w0nl0miq-opencv-3.4.1/lib ...
281   #
282   # Note that ${exec_prefix} is set to $out but that $out is also appended to
283   # ${exec_prefix}. This causes linker errors in downstream packages so we strip
284   # of $out after the ${exec_prefix} prefix:
285   postInstall = ''
286     sed -i "s|{exec_prefix}/$out|{exec_prefix}|" \
287       "$out/lib/pkgconfig/opencv.pc"
288   '';
290   hardeningDisable = [ "bindnow" "relro" ];
292   passthru = lib.optionalAttrs enablePython { pythonPath = []; } // {
293     tests = lib.optionalAttrs enableCuda {
294       no-libstdcxx-errors = callPackage ./libstdcxx-test.nix { attrName = "opencv3"; };
295     };
296   };
298   meta = with lib; {
299     description = "Open Computer Vision Library with more than 500 algorithms";
300     homepage = "https://opencv.org/";
301     license = with licenses; if enableUnfree then unfree else bsd3;
302     maintainers = with maintainers; [mdaiter basvandijk];
303     platforms = with platforms; linux ++ darwin;
304   };