From 54c1d5602d9dd4110c9731104ff387256d735560 Mon Sep 17 00:00:00 2001 From: Ted Strzalkowski Date: Sun, 2 Aug 2020 11:22:06 -0700 Subject: [PATCH] Disable Java wrapper build by default. - Java wrapper build isn't necessary for all Python builds. - Java wrapper build can now be enabled with ``ENABLE_JAVA`` environment variable. --- README.md | 1 + setup.py | 857 +++++++++++++++++++++++++++--------------------------- 2 files changed, 431 insertions(+), 427 deletions(-) diff --git a/README.md b/README.md index ddb0104c..13462507 100644 --- a/README.md +++ b/README.md @@ -113,6 +113,7 @@ The build can be customized with environment variables. In addition to any varia - ``CI_BUILD``. Set to ``1`` to emulate the CI environment build behaviour. Used only in CI builds to force certain build flags on in ``setup.py``. Do not use this unless you know what you are doing. - ``ENABLE_CONTRIB`` and ``ENABLE_HEADLESS``. Set to ``1`` to build the contrib and/or headless version +- ``ENABLE_JAVA``, Set to ``1`` to enable the Java client build. This is disabled by default. - ``CMAKE_ARGS``. Additional arguments for OpenCV's CMake invocation. You can use this to make a custom build. See the next section for more info about manual builds outside the CI environment. diff --git a/setup.py b/setup.py index 64162d68..76cd77c1 100644 --- a/setup.py +++ b/setup.py @@ -1,427 +1,430 @@ -import io -import os -import os.path -import sys -import runpy -import subprocess -import re -import sysconfig -import skbuild -from skbuild import cmaker - - -def main(): - os.chdir(os.path.dirname(os.path.abspath(__file__))) - - CI_BUILD = os.environ.get("CI_BUILD", "False") - is_CI_build = True if CI_BUILD == "1" else False - cmake_source_dir = "opencv" - minimum_supported_numpy = "1.13.1" - build_contrib = get_build_env_var_by_name("contrib") - build_headless = get_build_env_var_by_name("headless") - - if sys.version_info[:2] >= (3, 6): - minimum_supported_numpy = "1.13.3" - if sys.version_info[:2] >= (3, 7): - minimum_supported_numpy = "1.14.5" - if sys.version_info[:2] >= (3, 8): - minimum_supported_numpy = "1.17.3" - - numpy_version = "numpy>=%s" % minimum_supported_numpy - - python_version = cmaker.CMaker.get_python_version() - python_lib_path = cmaker.CMaker.get_python_library(python_version).replace( - "\\", "/" - ) - python_include_dir = cmaker.CMaker.get_python_include_dir(python_version).replace( - "\\", "/" - ) - - if os.path.exists(".git"): - import pip._internal.vcs.git as git - - g = git.Git() # NOTE: pip API's are internal, this has to be refactored - - g.run_command(["submodule", "sync"]) - g.run_command( - ["submodule", "update", "--init", "--recursive", cmake_source_dir] - ) - - if build_contrib: - g.run_command( - ["submodule", "update", "--init", "--recursive", "opencv_contrib"] - ) - - package_version, build_contrib, build_headless = get_and_set_info( - build_contrib, build_headless, is_CI_build - ) - - # https://stackoverflow.com/questions/1405913/python-32bit-or-64bit-mode - x64 = sys.maxsize > 2 ** 32 - - package_name = "opencv-python" - - if build_contrib and not build_headless: - package_name = "opencv-contrib-python" - - if build_contrib and build_headless: - package_name = "opencv-contrib-python-headless" - - if build_headless and not build_contrib: - package_name = "opencv-python-headless" - - long_description = io.open("README.md", encoding="utf-8").read() - - packages = ["cv2", "cv2.data"] - - package_data = { - "cv2": ["*%s" % sysconfig.get_config_vars().get("SO"), "version.py"] - + (["*.dll"] if os.name == "nt" else []) - + ["LICENSE.txt", "LICENSE-3RD-PARTY.txt"], - "cv2.data": ["*.xml"], - } - - # Files from CMake output to copy to package. - # Path regexes with forward slashes relative to CMake install dir. - rearrange_cmake_output_data = { - "cv2": ( - [r"bin/opencv_videoio_ffmpeg\d{3}%s\.dll" % ("_64" if x64 else "")] - if os.name == "nt" - else [] - ) - + - # In Windows, in python/X.Y//; in Linux, in just python/X.Y/. - # Naming conventions vary so widely between versions and OSes - # had to give up on checking them. - [ - "python/cv2[^/]*%(ext)s" - % {"ext": re.escape(sysconfig.get_config_var("EXT_SUFFIX"))} - ], - "cv2.data": [ # OPENCV_OTHER_INSTALL_PATH - ("etc" if os.name == "nt" else "share/opencv4") + r"/haarcascades/.*\.xml" - ], - } - - # Files in sourcetree outside package dir that should be copied to package. - # Raw paths relative to sourcetree root. - files_outside_package_dir = {"cv2": ["LICENSE.txt", "LICENSE-3RD-PARTY.txt"]} - - ci_cmake_generator = ( - ["-G", "Visual Studio 14" + (" Win64" if x64 else "")] - if os.name == "nt" - else ["-G", "Unix Makefiles"] - ) - - cmake_args = ( - (ci_cmake_generator if is_CI_build else []) - + [ - # skbuild inserts PYTHON_* vars. That doesn't satisfy opencv build scripts in case of Py3 - "-DPYTHON3_EXECUTABLE=%s" % sys.executable, - "-DPYTHON3_INCLUDE_DIR=%s" % python_include_dir, - "-DPYTHON3_LIBRARY=%s" % python_lib_path, - "-DBUILD_opencv_python3=ON", - "-DBUILD_opencv_python2=OFF", - # When off, adds __init__.py and a few more helper .py's. We use our own helper files with a different structure. - "-DOPENCV_SKIP_PYTHON_LOADER=ON", - # Relative dir to install the built module to in the build tree. - # The default is generated from sysconfig, we'd rather have a constant for simplicity - "-DOPENCV_PYTHON3_INSTALL_PATH=python", - # Otherwise, opencv scripts would want to install `.pyd' right into site-packages, - # and skbuild bails out on seeing that - "-DINSTALL_CREATE_DISTRIB=ON", - # See opencv/CMakeLists.txt for options and defaults - "-DBUILD_opencv_apps=OFF", - "-DBUILD_SHARED_LIBS=OFF", - "-DBUILD_TESTS=OFF", - "-DBUILD_PERF_TESTS=OFF", - "-DBUILD_DOCS=OFF", - ] - + ( - ["-DOPENCV_EXTRA_MODULES_PATH=" + os.path.abspath("opencv_contrib/modules")] - if build_contrib - else [] - ) - ) - - if build_headless: - # it seems that cocoa cannot be disabled so on macOS the package is not truly headless - cmake_args.append("-DWITH_WIN32UI=OFF") - cmake_args.append("-DWITH_QT=OFF") - cmake_args.append("-DWITH_GTK=OFF") - if is_CI_build: - cmake_args.append( - "-DWITH_MSMF=OFF" - ) # see: https://github.com/skvark/opencv-python/issues/263 - - if sys.platform.startswith("linux") and not x64 and "bdist_wheel" in sys.argv: - subprocess.check_call("patch -p0 < patches/patchOpenEXR", shell=True) - - # OS-specific components during CI builds - if is_CI_build: - if sys.platform.startswith("linux") and not build_headless: - cmake_args.append("-DWITH_QT=4") - - if sys.platform == "darwin" and not build_headless: - if "bdist_wheel" in sys.argv: - cmake_args.append("-DWITH_QT=5") - rearrange_cmake_output_data["cv2.qt.plugins.platforms"] = [ - (r"lib/qt/plugins/platforms/libqcocoa\.dylib") - ] - subprocess.check_call("patch -p1 < patches/patchQtPlugins", shell=True) - - if sys.platform.startswith("linux"): - cmake_args.append("-DWITH_V4L=ON") - cmake_args.append("-DWITH_LAPACK=ON") - cmake_args.append("-DENABLE_PRECOMPILED_HEADERS=OFF") - - # https://github.com/scikit-build/scikit-build/issues/479 - if "CMAKE_ARGS" in os.environ: - import shlex - - cmake_args.extend(shlex.split(os.environ["CMAKE_ARGS"])) - del shlex - - # works via side effect - RearrangeCMakeOutput( - rearrange_cmake_output_data, files_outside_package_dir, package_data.keys() - ) - - skbuild.setup( - name=package_name, - version=package_version, - url="https://github.com/skvark/opencv-python", - license="MIT", - description="Wrapper package for OpenCV python bindings.", - long_description=long_description, - long_description_content_type="text/markdown", - packages=packages, - package_data=package_data, - maintainer="Olli-Pekka Heinisuo", - ext_modules=EmptyListWithLength(), - install_requires=numpy_version, - classifiers=[ - "Development Status :: 5 - Production/Stable", - "Environment :: Console", - "Intended Audience :: Developers", - "Intended Audience :: Education", - "Intended Audience :: Information Technology", - "Intended Audience :: Science/Research", - "License :: OSI Approved :: MIT License", - "Operating System :: MacOS", - "Operating System :: Microsoft :: Windows", - "Operating System :: POSIX", - "Operating System :: Unix", - "Programming Language :: Python", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.5", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: C++", - "Programming Language :: Python :: Implementation :: CPython", - "Topic :: Scientific/Engineering", - "Topic :: Scientific/Engineering :: Image Recognition", - "Topic :: Software Development", - ], - cmake_args=cmake_args, - cmake_source_dir=cmake_source_dir, - ) - - -class RearrangeCMakeOutput(object): - """ - Patch SKBuild logic to only take files related to the Python package - and construct a file hierarchy that SKBuild expects (see below) - """ - - _setuptools_wrap = None - - # Have to wrap a function reference, or it's converted - # into an instance method on attr assignment - import argparse - - wraps = argparse.Namespace(_classify_installed_files=None) - del argparse - - package_paths_re = None - packages = None - files_outside_package = None - - def __init__(self, package_paths_re, files_outside_package, packages): - cls = self.__class__ - assert not cls.wraps._classify_installed_files, "Singleton object" - import skbuild.setuptools_wrap - - cls._setuptools_wrap = skbuild.setuptools_wrap - cls.wraps._classify_installed_files = ( - cls._setuptools_wrap._classify_installed_files - ) - cls._setuptools_wrap._classify_installed_files = ( - self._classify_installed_files_override - ) - - cls.package_paths_re = package_paths_re - cls.files_outside_package = files_outside_package - cls.packages = packages - - def __del__(self): - cls = self.__class__ - cls._setuptools_wrap._classify_installed_files = ( - cls.wraps._classify_installed_files - ) - cls.wraps._classify_installed_files = None - cls._setuptools_wrap = None - - def _classify_installed_files_override( - self, - install_paths, - package_data, - package_prefixes, - py_modules, - new_py_modules, - scripts, - new_scripts, - data_files, - cmake_source_dir, - cmake_install_reldir, - ): - """ - From all CMake output, we're only interested in a few files - and must place them into CMake install dir according - to Python conventions for SKBuild to find them: - package\ - file - subpackage\ - etc. - """ - - cls = self.__class__ - - # 'relpath'/'reldir' = relative to CMAKE_INSTALL_DIR/cmake_install_dir - # 'path'/'dir' = relative to sourcetree root - cmake_install_dir = os.path.join( - cls._setuptools_wrap.CMAKE_INSTALL_DIR(), cmake_install_reldir - ) - install_relpaths = [ - os.path.relpath(p, cmake_install_dir) for p in install_paths - ] - fslash_install_relpaths = [ - p.replace(os.path.sep, "/") for p in install_relpaths - ] - relpaths_zip = list(zip(fslash_install_relpaths, install_relpaths)) - del install_relpaths, fslash_install_relpaths - - final_install_relpaths = [] - - print("Copying files from CMake output") - - for package_name, relpaths_re in cls.package_paths_re.items(): - package_dest_reldir = package_name.replace(".", os.path.sep) - for relpath_re in relpaths_re: - found = False - r = re.compile(relpath_re + "$") - for fslash_relpath, relpath in relpaths_zip: - m = r.match(fslash_relpath) - if not m: - continue - found = True - new_install_relpath = os.path.join( - package_dest_reldir, os.path.basename(relpath) - ) - cls._setuptools_wrap._copy_file( - os.path.join(cmake_install_dir, relpath), - os.path.join(cmake_install_dir, new_install_relpath), - hide_listing=False, - ) - final_install_relpaths.append(new_install_relpath) - del m, fslash_relpath, new_install_relpath - else: - if not found: - raise Exception("Not found: '%s'" % relpath_re) - del r, found - - del relpaths_zip - - print("Copying files from non-default sourcetree locations") - - for package_name, paths in cls.files_outside_package.items(): - package_dest_reldir = package_name.replace(".", os.path.sep) - for path in paths: - new_install_relpath = os.path.join( - package_dest_reldir, - # Don't yet have a need to copy - # to subdirectories of package dir - os.path.basename(path), - ) - cls._setuptools_wrap._copy_file( - path, - os.path.join(cmake_install_dir, new_install_relpath), - hide_listing=False, - ) - final_install_relpaths.append(new_install_relpath) - - final_install_paths = [ - os.path.join(cmake_install_dir, p) for p in final_install_relpaths - ] - - return (cls.wraps._classify_installed_files)( - final_install_paths, - package_data, - package_prefixes, - py_modules, - new_py_modules, - scripts, - new_scripts, - data_files, - # To get around a check that prepends source dir to paths and breaks package detection code. - cmake_source_dir="", - cmake_install_dir=cmake_install_reldir, - ) - - -def get_and_set_info(contrib, headless, ci_build): - # cv2/version.py should be generated by running find_version.py - version = {} - here = os.path.abspath(os.path.dirname(__file__)) - version_file = os.path.join(here, "cv2", "version.py") - - # generate a fresh version.py always when Git repository exists - # (in sdists the version.py file already exists) - if os.path.exists(".git"): - old_args = sys.argv.copy() - sys.argv = ["", str(contrib), str(headless), str(ci_build)] - runpy.run_path("find_version.py", run_name="__main__") - sys.argv = old_args - - with open(version_file) as fp: - exec(fp.read(), version) - - return version["opencv_version"], version["contrib"], version["headless"] - - -def get_build_env_var_by_name(flag_name): - flag_set = False - - try: - flag_set = bool(int(os.getenv("ENABLE_" + flag_name.upper(), None))) - except Exception: - pass - - if not flag_set: - try: - flag_set = bool(int(open(flag_name + ".enabled").read(1))) - except Exception: - pass - - return flag_set - - -# This creates a list which is empty but returns a length of 1. -# Should make the wheel a binary distribution and platlib compliant. -class EmptyListWithLength(list): - def __len__(self): - return 1 - - -if __name__ == "__main__": - main() +import io +import os +import os.path +import sys +import runpy +import subprocess +import re +import sysconfig +import skbuild +from skbuild import cmaker + + +def main(): + os.chdir(os.path.dirname(os.path.abspath(__file__))) + + CI_BUILD = os.environ.get("CI_BUILD", "False") + is_CI_build = True if CI_BUILD == "1" else False + cmake_source_dir = "opencv" + minimum_supported_numpy = "1.13.1" + build_contrib = get_build_env_var_by_name("contrib") + build_headless = get_build_env_var_by_name("headless") + build_java = 'ON' if get_build_env_var_by_name("java") else 'OFF' + + if sys.version_info[:2] >= (3, 6): + minimum_supported_numpy = "1.13.3" + if sys.version_info[:2] >= (3, 7): + minimum_supported_numpy = "1.14.5" + if sys.version_info[:2] >= (3, 8): + minimum_supported_numpy = "1.17.3" + + numpy_version = "numpy>=%s" % minimum_supported_numpy + + python_version = cmaker.CMaker.get_python_version() + python_lib_path = cmaker.CMaker.get_python_library(python_version).replace( + "\\", "/" + ) + python_include_dir = cmaker.CMaker.get_python_include_dir(python_version).replace( + "\\", "/" + ) + + if os.path.exists(".git"): + import pip._internal.vcs.git as git + + g = git.Git() # NOTE: pip API's are internal, this has to be refactored + + g.run_command(["submodule", "sync"]) + g.run_command( + ["submodule", "update", "--init", "--recursive", cmake_source_dir] + ) + + if build_contrib: + g.run_command( + ["submodule", "update", "--init", "--recursive", "opencv_contrib"] + ) + + package_version, build_contrib, build_headless = get_and_set_info( + build_contrib, build_headless, is_CI_build + ) + + # https://stackoverflow.com/questions/1405913/python-32bit-or-64bit-mode + x64 = sys.maxsize > 2 ** 32 + + package_name = "opencv-python" + + if build_contrib and not build_headless: + package_name = "opencv-contrib-python" + + if build_contrib and build_headless: + package_name = "opencv-contrib-python-headless" + + if build_headless and not build_contrib: + package_name = "opencv-python-headless" + + long_description = io.open("README.md", encoding="utf-8").read() + + packages = ["cv2", "cv2.data"] + + package_data = { + "cv2": ["*%s" % sysconfig.get_config_vars().get("SO"), "version.py"] + + (["*.dll"] if os.name == "nt" else []) + + ["LICENSE.txt", "LICENSE-3RD-PARTY.txt"], + "cv2.data": ["*.xml"], + } + + # Files from CMake output to copy to package. + # Path regexes with forward slashes relative to CMake install dir. + rearrange_cmake_output_data = { + "cv2": ( + [r"bin/opencv_videoio_ffmpeg\d{3}%s\.dll" % ("_64" if x64 else "")] + if os.name == "nt" + else [] + ) + + + # In Windows, in python/X.Y//; in Linux, in just python/X.Y/. + # Naming conventions vary so widely between versions and OSes + # had to give up on checking them. + [ + "python/cv2[^/]*%(ext)s" + % {"ext": re.escape(sysconfig.get_config_var("EXT_SUFFIX"))} + ], + "cv2.data": [ # OPENCV_OTHER_INSTALL_PATH + ("etc" if os.name == "nt" else "share/opencv4") + r"/haarcascades/.*\.xml" + ], + } + + # Files in sourcetree outside package dir that should be copied to package. + # Raw paths relative to sourcetree root. + files_outside_package_dir = {"cv2": ["LICENSE.txt", "LICENSE-3RD-PARTY.txt"]} + + ci_cmake_generator = ( + ["-G", "Visual Studio 14" + (" Win64" if x64 else "")] + if os.name == "nt" + else ["-G", "Unix Makefiles"] + ) + + cmake_args = ( + (ci_cmake_generator if is_CI_build else []) + + [ + # skbuild inserts PYTHON_* vars. That doesn't satisfy opencv build scripts in case of Py3 + "-DPYTHON3_EXECUTABLE=%s" % sys.executable, + "-DPYTHON3_INCLUDE_DIR=%s" % python_include_dir, + "-DPYTHON3_LIBRARY=%s" % python_lib_path, + "-DBUILD_opencv_python3=ON", + "-DBUILD_opencv_python2=OFF", + # Disable the Java build by default as it is not needed + "-DBUILD_opencv_java=%s" % build_java, + # When off, adds __init__.py and a few more helper .py's. We use our own helper files with a different structure. + "-DOPENCV_SKIP_PYTHON_LOADER=ON", + # Relative dir to install the built module to in the build tree. + # The default is generated from sysconfig, we'd rather have a constant for simplicity + "-DOPENCV_PYTHON3_INSTALL_PATH=python", + # Otherwise, opencv scripts would want to install `.pyd' right into site-packages, + # and skbuild bails out on seeing that + "-DINSTALL_CREATE_DISTRIB=ON", + # See opencv/CMakeLists.txt for options and defaults + "-DBUILD_opencv_apps=OFF", + "-DBUILD_SHARED_LIBS=OFF", + "-DBUILD_TESTS=OFF", + "-DBUILD_PERF_TESTS=OFF", + "-DBUILD_DOCS=OFF", + ] + + ( + ["-DOPENCV_EXTRA_MODULES_PATH=" + os.path.abspath("opencv_contrib/modules")] + if build_contrib + else [] + ) + ) + + if build_headless: + # it seems that cocoa cannot be disabled so on macOS the package is not truly headless + cmake_args.append("-DWITH_WIN32UI=OFF") + cmake_args.append("-DWITH_QT=OFF") + cmake_args.append("-DWITH_GTK=OFF") + if is_CI_build: + cmake_args.append( + "-DWITH_MSMF=OFF" + ) # see: https://github.com/skvark/opencv-python/issues/263 + + if sys.platform.startswith("linux") and not x64 and "bdist_wheel" in sys.argv: + subprocess.check_call("patch -p0 < patches/patchOpenEXR", shell=True) + + # OS-specific components during CI builds + if is_CI_build: + if sys.platform.startswith("linux") and not build_headless: + cmake_args.append("-DWITH_QT=4") + + if sys.platform == "darwin" and not build_headless: + if "bdist_wheel" in sys.argv: + cmake_args.append("-DWITH_QT=5") + rearrange_cmake_output_data["cv2.qt.plugins.platforms"] = [ + (r"lib/qt/plugins/platforms/libqcocoa\.dylib") + ] + subprocess.check_call("patch -p1 < patches/patchQtPlugins", shell=True) + + if sys.platform.startswith("linux"): + cmake_args.append("-DWITH_V4L=ON") + cmake_args.append("-DWITH_LAPACK=ON") + cmake_args.append("-DENABLE_PRECOMPILED_HEADERS=OFF") + + # https://github.com/scikit-build/scikit-build/issues/479 + if "CMAKE_ARGS" in os.environ: + import shlex + + cmake_args.extend(shlex.split(os.environ["CMAKE_ARGS"])) + del shlex + + # works via side effect + RearrangeCMakeOutput( + rearrange_cmake_output_data, files_outside_package_dir, package_data.keys() + ) + + skbuild.setup( + name=package_name, + version=package_version, + url="https://github.com/skvark/opencv-python", + license="MIT", + description="Wrapper package for OpenCV python bindings.", + long_description=long_description, + long_description_content_type="text/markdown", + packages=packages, + package_data=package_data, + maintainer="Olli-Pekka Heinisuo", + ext_modules=EmptyListWithLength(), + install_requires=numpy_version, + classifiers=[ + "Development Status :: 5 - Production/Stable", + "Environment :: Console", + "Intended Audience :: Developers", + "Intended Audience :: Education", + "Intended Audience :: Information Technology", + "Intended Audience :: Science/Research", + "License :: OSI Approved :: MIT License", + "Operating System :: MacOS", + "Operating System :: Microsoft :: Windows", + "Operating System :: POSIX", + "Operating System :: Unix", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.5", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: C++", + "Programming Language :: Python :: Implementation :: CPython", + "Topic :: Scientific/Engineering", + "Topic :: Scientific/Engineering :: Image Recognition", + "Topic :: Software Development", + ], + cmake_args=cmake_args, + cmake_source_dir=cmake_source_dir, + ) + + +class RearrangeCMakeOutput(object): + """ + Patch SKBuild logic to only take files related to the Python package + and construct a file hierarchy that SKBuild expects (see below) + """ + + _setuptools_wrap = None + + # Have to wrap a function reference, or it's converted + # into an instance method on attr assignment + import argparse + + wraps = argparse.Namespace(_classify_installed_files=None) + del argparse + + package_paths_re = None + packages = None + files_outside_package = None + + def __init__(self, package_paths_re, files_outside_package, packages): + cls = self.__class__ + assert not cls.wraps._classify_installed_files, "Singleton object" + import skbuild.setuptools_wrap + + cls._setuptools_wrap = skbuild.setuptools_wrap + cls.wraps._classify_installed_files = ( + cls._setuptools_wrap._classify_installed_files + ) + cls._setuptools_wrap._classify_installed_files = ( + self._classify_installed_files_override + ) + + cls.package_paths_re = package_paths_re + cls.files_outside_package = files_outside_package + cls.packages = packages + + def __del__(self): + cls = self.__class__ + cls._setuptools_wrap._classify_installed_files = ( + cls.wraps._classify_installed_files + ) + cls.wraps._classify_installed_files = None + cls._setuptools_wrap = None + + def _classify_installed_files_override( + self, + install_paths, + package_data, + package_prefixes, + py_modules, + new_py_modules, + scripts, + new_scripts, + data_files, + cmake_source_dir, + cmake_install_reldir, + ): + """ + From all CMake output, we're only interested in a few files + and must place them into CMake install dir according + to Python conventions for SKBuild to find them: + package\ + file + subpackage\ + etc. + """ + + cls = self.__class__ + + # 'relpath'/'reldir' = relative to CMAKE_INSTALL_DIR/cmake_install_dir + # 'path'/'dir' = relative to sourcetree root + cmake_install_dir = os.path.join( + cls._setuptools_wrap.CMAKE_INSTALL_DIR(), cmake_install_reldir + ) + install_relpaths = [ + os.path.relpath(p, cmake_install_dir) for p in install_paths + ] + fslash_install_relpaths = [ + p.replace(os.path.sep, "/") for p in install_relpaths + ] + relpaths_zip = list(zip(fslash_install_relpaths, install_relpaths)) + del install_relpaths, fslash_install_relpaths + + final_install_relpaths = [] + + print("Copying files from CMake output") + + for package_name, relpaths_re in cls.package_paths_re.items(): + package_dest_reldir = package_name.replace(".", os.path.sep) + for relpath_re in relpaths_re: + found = False + r = re.compile(relpath_re + "$") + for fslash_relpath, relpath in relpaths_zip: + m = r.match(fslash_relpath) + if not m: + continue + found = True + new_install_relpath = os.path.join( + package_dest_reldir, os.path.basename(relpath) + ) + cls._setuptools_wrap._copy_file( + os.path.join(cmake_install_dir, relpath), + os.path.join(cmake_install_dir, new_install_relpath), + hide_listing=False, + ) + final_install_relpaths.append(new_install_relpath) + del m, fslash_relpath, new_install_relpath + else: + if not found: + raise Exception("Not found: '%s'" % relpath_re) + del r, found + + del relpaths_zip + + print("Copying files from non-default sourcetree locations") + + for package_name, paths in cls.files_outside_package.items(): + package_dest_reldir = package_name.replace(".", os.path.sep) + for path in paths: + new_install_relpath = os.path.join( + package_dest_reldir, + # Don't yet have a need to copy + # to subdirectories of package dir + os.path.basename(path), + ) + cls._setuptools_wrap._copy_file( + path, + os.path.join(cmake_install_dir, new_install_relpath), + hide_listing=False, + ) + final_install_relpaths.append(new_install_relpath) + + final_install_paths = [ + os.path.join(cmake_install_dir, p) for p in final_install_relpaths + ] + + return (cls.wraps._classify_installed_files)( + final_install_paths, + package_data, + package_prefixes, + py_modules, + new_py_modules, + scripts, + new_scripts, + data_files, + # To get around a check that prepends source dir to paths and breaks package detection code. + cmake_source_dir="", + cmake_install_dir=cmake_install_reldir, + ) + + +def get_and_set_info(contrib, headless, ci_build): + # cv2/version.py should be generated by running find_version.py + version = {} + here = os.path.abspath(os.path.dirname(__file__)) + version_file = os.path.join(here, "cv2", "version.py") + + # generate a fresh version.py always when Git repository exists + # (in sdists the version.py file already exists) + if os.path.exists(".git"): + old_args = sys.argv.copy() + sys.argv = ["", str(contrib), str(headless), str(ci_build)] + runpy.run_path("find_version.py", run_name="__main__") + sys.argv = old_args + + with open(version_file) as fp: + exec(fp.read(), version) + + return version["opencv_version"], version["contrib"], version["headless"] + + +def get_build_env_var_by_name(flag_name): + flag_set = False + + try: + flag_set = bool(int(os.getenv("ENABLE_" + flag_name.upper(), None))) + except Exception: + pass + + if not flag_set: + try: + flag_set = bool(int(open(flag_name + ".enabled").read(1))) + except Exception: + pass + + return flag_set + + +# This creates a list which is empty but returns a length of 1. +# Should make the wheel a binary distribution and platlib compliant. +class EmptyListWithLength(list): + def __len__(self): + return 1 + + +if __name__ == "__main__": + main()