#!/usr/bin/env python
# -*- coding: utf-8 -*-
from conans import ConanFile, CMake, tools
from conans.model.version import Version
from conans.errors import ConanInvalidConfiguration
import os
class OpenCVConan(ConanFile):
name = "opencv"
version = "4.0.1"
license = "BSD-3-Clause"
homepage = "https://github.com/opencv/opencv"
url = "https://github.com/conan-community/conan-opencv"
author = "Conan Community"
topics = ("conan", "opencv", "computer-vision",
"image-processing", "deep-learning")
settings = "os", "compiler", "build_type", "arch"
options = {"shared": [True, False],
"fPIC": [True, False],
"contrib": [True, False],
"jpeg": [True, False],
"jpegturbo": [True, False],
"tiff": [True, False],
"webp": [True, False],
"png": [True, False],
"jasper": [True, False],
"openexr": [True, False],
"gtk": [None, 2, 3],
"nonfree": [True, False],
"dc1394": [True, False],
"carotene": [True, False],
"cuda": [True, False],
"protobuf": [True, False],
"freetype": [True, False],
"harfbuzz": [True, False]}
default_options = {"shared": False,
"fPIC": True,
"contrib": False,
"jpeg": True,
"jpegturbo": False,
"tiff": True,
"webp": True,
"png": True,
"jasper": True,
"openexr": True,
"gtk": 3,
"nonfree": False,
"dc1394": True,
"carotene": False,
"cuda": False,
"protobuf": True,
"freetype": True,
"harfbuzz": True}
exports_sources = ["CMakeLists.txt", "patches/*.patch"]
exports = "LICENSE"
generators = "cmake"
description = "OpenCV is an open source computer vision and machine learning software library."
short_paths = True
_source_subfolder = "source_subfolder"
_build_subfolder = "build_subfolder"
def configure(self):
compiler_version = Version(self.settings.compiler.version.value)
if self.settings.compiler == "Visual Studio" and compiler_version < "14":
raise ConanInvalidConfiguration(
"OpenCV 4.x requires Visual Studio 2015 and higher")
if self.options.cuda and not self.options.contrib:
raise ConanInvalidConfiguration(
"opencv:cuda requires opencv:contrib")
def source(self):
sha256 = "7b86a0ee804244e0c407321f895b15e4a7162e9c5c0d2efc85f1cadec4011af4"
tools.get("{}/archive/{}.tar.gz".format(self.homepage,
self.version))
os.rename('opencv-%s' % self.version, self._source_subfolder)
sha256 = "0d8acbad4b7074cfaafd906a7419c23629179d5e98894714402090b192ef8237"
tools.get(
"https://github.com/opencv/opencv_contrib/archive/{}.tar.gz".format(self.version))
os.rename('opencv_contrib-%s' % self.version, 'contrib')
if self.settings.os != 'Android' and not self.options.carotene:
tools.rmdir(os.path.join(self._source_subfolder, '3rdparty'))
def config_options(self):
if self.settings.os == 'Windows':
del self.options.fPIC
if self.settings.os != 'Linux':
del self.options.gtk
def system_requirements(self):
if self.settings.os == 'Linux' and tools.os_info.is_linux:
if tools.os_info.with_apt:
installer = tools.SystemPackageTool()
arch_suffix = ''
if self.settings.arch == 'x86':
arch_suffix = ':i386'
elif self.settings.arch == 'x86_64':
arch_suffix = ':amd64'
packages = []
if self.options.gtk == 2:
packages.append('libgtk2.0-dev%s' % arch_suffix)
elif self.options.gtk == 3:
packages.append('libgtk-3-dev%s' % arch_suffix)
for package in packages:
installer.install(package)
elif tools.os_info.with_yum:
installer = tools.SystemPackageTool()
arch_suffix = ''
if self.settings.arch == 'x86':
arch_suffix = '.i686'
elif self.settings.arch == 'x86_64':
arch_suffix = '.x86_64'
packages = []
if self.options.gtk == 2:
packages.append('gtk2-devel%s' % arch_suffix)
elif self.options.gtk == 3:
packages.append('gtk3-devel%s' % arch_suffix)
for package in packages:
installer.install(package)
def requirements(self):
self.requires.add('zlib/1.2.11@conan/stable')
if self.options.jpeg:
# NOTE : use the same libjpeg implementation as jasper uses
# otherwise, jpeg_create_decompress will fail on version check
if self.options.jpegturbo:
self.requires.add('libjpeg-turbo/1.5.2@bincrafters/stable')
else:
self.requires.add('libjpeg/9c@bincrafters/stable')
if self.options.tiff:
self.requires.add('libtiff/4.0.9@bincrafters/stable')
if self.options.webp:
self.requires.add('libwebp/1.0.0@bincrafters/stable')
if self.options.png:
self.requires.add('libpng/1.6.34@bincrafters/stable')
if self.options.jasper:
self.requires.add('jasper/2.0.14@conan/stable')
if self.options.openexr:
self.requires.add('openexr/2.3.0@conan/stable')
if self.options.protobuf:
# NOTE : version should be the same as used in OpenCV release,
# otherwise, PROTOBUF_UPDATE_FILES should be set to re-generate files
self.requires.add('protobuf/3.5.2@bincrafters/stable')
if self.options.freetype:
self.requires.add('freetype/2.9.1@bincrafters/stable')
if self.options.harfbuzz:
self.requires.add('harfbuzz/2.4.0@bincrafters/stable')
def _configure_cmake(self):
cmake = CMake(self)
cmake.definitions['BUILD_EXAMPLES'] = False
cmake.definitions['BUILD_DOCS'] = False
cmake.definitions['BUILD_TESTS'] = False
cmake.definitions['BUILD_PERF_TEST'] = False
cmake.definitions['WITH_IPP'] = False
cmake.definitions['BUILD_IPP_IW'] = False
cmake.definitions['BUILD_opencv_apps'] = False
cmake.definitions['BUILD_opencv_java'] = False
cmake.definitions['BUILD_opencv_python'] = False
cmake.definitions['BUILD_opencv_python2'] = False
cmake.definitions['BUILD_opencv_python3'] = False
cmake.definitions['INSTALL_C_EXAMPLES'] = False
cmake.definitions['INSTALL_PYTHON_EXAMPLES'] = False
cmake.definitions['BUILD_opencv_python_bindings_generator'] = False
cmake.definitions['BUILD_opencv_js'] = False
cmake.definitions['BUILD_opencv_java_bindings_generator'] = False
if self.settings.compiler == 'Visual Studio':
cmake.definitions['BUILD_WITH_STATIC_CRT'] = 'MT' in str(
self.settings.compiler.runtime)
if self.settings.os != 'Windows':
cmake.definitions['ENABLE_PIC'] = self.options.fPIC
# 3rd-party
# disable builds for all 3rd-party components, use libraries from conan only
cmake.definitions['BUILD_ZLIB'] = False
cmake.definitions['BUILD_TIFF'] = False
cmake.definitions['BUILD_JASPER'] = False
cmake.definitions['BUILD_JPEG'] = False
cmake.definitions['BUILD_PNG'] = False
cmake.definitions['BUILD_OPENEXR'] = False
cmake.definitions['BUILD_WEBP'] = False
cmake.definitions['BUILD_TBB'] = False
cmake.definitions['BUILD_IPP_IW'] = False
cmake.definitions['BUILD_ITT'] = False
cmake.definitions['BUILD_JPEG_TURBO_DISABLE'] = True
cmake.definitions['BUILD_PROTOBUF'] = False
cmake.definitions['PROTOBUF_UPDATE_FILES'] = False
cmake.definitions['WITH_JPEG'] = self.options.jpeg
cmake.definitions['WITH_TIFF'] = self.options.tiff
cmake.definitions['WITH_WEBP'] = self.options.webp
cmake.definitions['WITH_PNG'] = self.options.png
cmake.definitions['WITH_JASPER'] = self.options.jasper
cmake.definitions['WITH_OPENEXR'] = self.options.openexr
cmake.definitions["WITH_1394"] = self.options.dc1394
cmake.definitions['WITH_PROTOBUF'] = self.options.protobuf
cmake.definitions['WITH_FFMPEG'] = False
cmake.definitions['WITH_QUIRC'] = False
cmake.definitions['WITH_CAROTENE'] = self.options.carotene
cmake.definitions['WITH_CUDA'] = self.options.cuda
# This allows compilation on older GCC/NVCC, otherwise build errors.
cmake.definitions['CUDA_NVCC_FLAGS'] = '--expt-relaxed-constexpr'
# MinGW doesn't build wih Media Foundation
cmake.definitions['WITH_MSMF'] = self.settings.compiler == 'Visual Studio'
# OpenCV doesn't use find_package for freetype & harfbuzz, so let's specify them
if self.options.freetype:
cmake.definitions['FREETYPE_FOUND'] = True
cmake.definitions['FREETYPE_LIBRARIES'] = ';'.join(self.deps_cpp_info['freetype'].libs)
cmake.definitions['FREETYPE_INCLUDE_DIRS'] = ';'.join(self.deps_cpp_info['freetype'].includedirs)
if self.options.harfbuzz:
cmake.definitions['HARFBUZZ_FOUND'] = True
cmake.definitions['HARFBUZZ_LIBRARIES'] = ';'.join(self.deps_cpp_info['harfbuzz'].libs)
cmake.definitions['HARFBUZZ_INCLUDE_DIRS'] = ';'.join(self.deps_cpp_info['harfbuzz'].includedirs)
if self.options.openexr:
cmake.definitions['OPENEXR_ROOT'] = self.deps_cpp_info['openexr'].rootpath
# system libraries
if self.settings.os == 'Linux':
cmake.definitions['WITH_GTK'] = self.options.gtk is not None
cmake.definitions['WITH_GTK_2_X'] = self.options.gtk == 2
if self.options.contrib:
cmake.definitions['OPENCV_EXTRA_MODULES_PATH'] = os.path.join(
self.build_folder, 'contrib', 'modules')
if self.options.nonfree:
cmake.definitions['OPENCV_ENABLE_NONFREE'] = True
if self.settings.os == 'Android':
cmake.definitions['ANDROID_STL'] = self.settings.compiler.libcxx
cmake.definitions['ANDROID_NATIVE_API_LEVEL'] = self.settings.os.api_level
cmake.definitions['BUILD_PERF_TESTS'] = False
cmake.definitions['BUILD_ANDROID_EXAMPLES'] = False
arch = str(self.settings.arch)
if arch.startswith(('armv7', 'armv8')):
cmake.definitions['ANDROID_ABI'] = 'NEON'
else:
cmake.definitions['ANDROID_ABI'] = {'armv5': 'armeabi',
'armv6': 'armeabi-v6',
'armv7': 'armeabi-v7a',
'armv7hf': 'armeabi-v7a',
'armv8': 'arm64-v8a'}.get(arch, arch)
if 'ANDROID_NDK_HOME' in os.environ:
cmake.definitions['ANDROID_NDK'] = os.environ.get(
'ANDROID_NDK_HOME')
cmake.configure(build_folder=self._build_subfolder)
return cmake
def build(self):
# https://github.com/opencv/opencv/issues/8010
if str(self.settings.compiler) == 'clang' and str(self.settings.compiler.version) == '3.9':
tools.replace_in_file(os.path.join(self._source_subfolder, 'modules', 'imgproc', 'CMakeLists.txt'),
'ocv_define_module(imgproc opencv_core WRAP java python js)',
'ocv_define_module(imgproc opencv_core WRAP java python js)\n'
'set_source_files_properties(${CMAKE_CURRENT_LIST_DIR}/src/'
'imgwarp.cpp PROPERTIES COMPILE_FLAGS "-O0")')
tools.patch(base_path=self._source_subfolder,
patch_file=os.path.join("patches", "0001-fix-FindOpenEXR-for-conan.patch"))
cmake = self._configure_cmake()
cmake.build()
def package(self):
self.copy("LICENSE", dst="licenses", src=self._source_subfolder)
cmake = self._configure_cmake()
cmake.install()
cmake.patch_config_paths()
def add_libraries_from_pc(self, library):
pkg_config = tools.PkgConfig(library)
libs = [lib[2:] for lib in pkg_config.libs_only_l] # cut -l prefix
lib_paths = [lib[2:]
for lib in pkg_config.libs_only_L] # cut -L prefix
self.cpp_info.libs.extend(libs)
self.cpp_info.libdirs.extend(lib_paths)
self.cpp_info.sharedlinkflags.extend(pkg_config.libs_only_other)
self.cpp_info.exelinkflags.extend(pkg_config.libs_only_other)
def package_info(self):
opencv_libs = ["stitching",
"photo",
"video",
"ml",
"calib3d",
"features2d",
"highgui",
"videoio",
"flann",
"imgcodecs",
"objdetect",
"imgproc",
"core"]
if self.settings.os != 'Android':
# gapi depends on ade but ade disabled for Android
# https://github.com/opencv/opencv/blob/4.0.1/modules/gapi/cmake/DownloadADE.cmake#L2
opencv_libs.append("gapi")
if self.options.contrib:
opencv_libs = [
"aruco",
"bgsegm",
"bioinspired",
"ccalib",
"datasets",
"dpm",
"face",
"freetype",
"fuzzy",
"hfs",
"img_hash",
"line_descriptor",
"optflow",
"phase_unwrapping",
"plot",
"reg",
"rgbd",
"saliency",
"shape",
"stereo",
"structured_light",
"superres",
"surface_matching",
"tracking",
"videostab",
"xfeatures2d",
"ximgproc",
"xobjdetect",
"xphoto"] + opencv_libs
if not self.options.freetype or not self.options.harfbuzz:
opencv_libs.remove("freetype")
if self.options.cuda:
opencv_libs = ["cudaarithm",
"cudabgsegm",
"cudacodec",
"cudafeatures2d",
"cudafilters",
"cudaimgproc",
"cudalegacy",
"cudaobjdetect",
"cudaoptflow",
"cudastereo",
"cudawarping",
"cudev"
] + opencv_libs
suffix = 'd' if self.settings.build_type == 'Debug' and self.settings.compiler == 'Visual Studio' else ''
version = self.version.replace(
".", "") if self.settings.os == "Windows" else ""
for lib in opencv_libs:
self.cpp_info.libs.append("opencv_%s%s%s" % (lib, version, suffix))
opencv_lib = 'lib' if self.options.shared else 'staticlib'
opencv_arch = {'x86': 'x86',
'x86_64': 'x64',
'armv7': 'ARM',
'armv8': 'ARM'}.get(str(self.settings.arch), None)
opencv_runtime = None
if self.settings.compiler == 'Visual Studio':
opencv_runtime = 'vc%s' % str(self.settings.compiler.version)
if self.options.cuda:
cuda_platform = {'x86': 'Win32',
'x86_64': 'x64'}.get(str(self.settings.arch))
cuda_path = os.environ.get('CUDA_PATH')
self.cpp_info.libdirs.append(os.path.join(cuda_path, "lib", cuda_platform))
if self.settings.os == "Windows" and self.settings.compiler == "gcc":
opencv_runtime = 'mingw'
if opencv_runtime:
bindir = os.path.join(self.package_folder, opencv_arch, opencv_runtime, 'bin')
libdir = os.path.join(self.package_folder, opencv_arch, opencv_runtime, opencv_lib)
self.cpp_info.bindirs.append(bindir)
self.cpp_info.libdirs.append(libdir)
if self.options.cuda:
self.cpp_info.libs.extend(["nvrtc", "cudart", "cuda"])
if self.settings.os == "Linux":
self.cpp_info.libs.extend([
"pthread",
"m",
"dl"])
if self.options.gtk == 2:
self.add_libraries_from_pc('gtk+-2.0')
elif self.options.gtk == 3:
self.add_libraries_from_pc('gtk+-3.0')
elif self.settings.os == 'Macos':
for framework in ['OpenCL',
'Accelerate',
'CoreMedia',
'CoreVideo',
'CoreGraphics',
'AVFoundation',
'QuartzCore',
'Cocoa']:
self.cpp_info.exelinkflags.append('-framework %s' % framework)
self.cpp_info.sharedlinkflags = self.cpp_info.exelinkflags
elif self.settings.os == 'Windows':
self.cpp_info.libs.append('Vfw32')
if self.settings.os == 'Android' and not self.options.shared:
self.cpp_info.includedirs.append(
os.path.join('sdk', 'native', 'jni', 'include'))
self.cpp_info.libdirs.append(
os.path.join('sdk', 'native', 'staticlibs'))
else:
self.cpp_info.includedirs.append(
os.path.join('include', 'opencv4'))
self.cpp_info.libdirs.append(
os.path.join('lib', 'opencv4', '3rdparty'))
if not self.options.shared:
self.cpp_info.libs.append('ade')