From 6ee82a398e1f4b02d86b8966c49f9278c348eaf8 Mon Sep 17 00:00:00 2001 From: Olli-Pekka Heinisuo Date: Sun, 11 Oct 2020 17:13:29 +0300 Subject: [PATCH] fix line endings --- appveyor.yml | 382 ++++++++++---------- cv2/__init__.py | 66 ++-- find_version.py | 136 ++++---- setup.py | 900 ++++++++++++++++++++++++------------------------ tests/test.py | 34 +- 5 files changed, 759 insertions(+), 759 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index d203b1c..b658399 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,191 +1,191 @@ -environment: - USER: - secure: fXgF9uyy6sT0JoVOR7BoqA== - - PASS: - secure: 0bXSOVjf9x8L7nErTivu92TF1FwNosTjFJQPmxp8Dys= - - matrix: - - PYTHON: "C:/Python36" - ENABLE_CONTRIB: 0 - ENABLE_HEADLESS: 0 - - - PYTHON: "C:/Python36-x64" - ENABLE_CONTRIB: 0 - ENABLE_HEADLESS: 0 - - - PYTHON: "C:/Python37" - ENABLE_CONTRIB: 0 - ENABLE_HEADLESS: 0 - - - PYTHON: "C:/Python37-x64" - ENABLE_CONTRIB: 0 - ENABLE_HEADLESS: 0 - - - PYTHON: "C:/Python38" - ENABLE_CONTRIB: 0 - ENABLE_HEADLESS: 0 - - - PYTHON: "C:/Python38-x64" - ENABLE_CONTRIB: 0 - ENABLE_HEADLESS: 0 - - - PYTHON: "C:/Python39" - ENABLE_CONTRIB: 0 - ENABLE_HEADLESS: 0 - - - PYTHON: "C:/Python39-x64" - ENABLE_CONTRIB: 0 - ENABLE_HEADLESS: 0 - - - PYTHON: "C:/Python36" - ENABLE_CONTRIB: 1 - ENABLE_HEADLESS: 0 - - - PYTHON: "C:/Python36-x64" - ENABLE_CONTRIB: 1 - ENABLE_HEADLESS: 0 - - - PYTHON: "C:/Python37" - ENABLE_CONTRIB: 1 - ENABLE_HEADLESS: 0 - - - PYTHON: "C:/Python37-x64" - ENABLE_CONTRIB: 1 - ENABLE_HEADLESS: 0 - - - PYTHON: "C:/Python38" - ENABLE_CONTRIB: 1 - ENABLE_HEADLESS: 0 - - - PYTHON: "C:/Python38-x64" - ENABLE_CONTRIB: 1 - ENABLE_HEADLESS: 0 - - - PYTHON: "C:/Python39" - ENABLE_CONTRIB: 1 - ENABLE_HEADLESS: 0 - - - PYTHON: "C:/Python39-x64" - ENABLE_CONTRIB: 1 - ENABLE_HEADLESS: 0 - - - PYTHON: "C:/Python36" - ENABLE_CONTRIB: 0 - ENABLE_HEADLESS: 1 - - - PYTHON: "C:/Python36-x64" - ENABLE_CONTRIB: 0 - ENABLE_HEADLESS: 1 - - - PYTHON: "C:/Python37" - ENABLE_CONTRIB: 0 - ENABLE_HEADLESS: 1 - - - PYTHON: "C:/Python37-x64" - ENABLE_CONTRIB: 0 - ENABLE_HEADLESS: 1 - - - PYTHON: "C:/Python38" - ENABLE_CONTRIB: 0 - ENABLE_HEADLESS: 1 - - - PYTHON: "C:/Python38-x64" - ENABLE_CONTRIB: 0 - ENABLE_HEADLESS: 1 - - - PYTHON: "C:/Python39" - ENABLE_CONTRIB: 0 - ENABLE_HEADLESS: 1 - - - PYTHON: "C:/Python39-x64" - ENABLE_CONTRIB: 0 - ENABLE_HEADLESS: 1 - - - PYTHON: "C:/Python36" - ENABLE_CONTRIB: 1 - ENABLE_HEADLESS: 1 - - - PYTHON: "C:/Python36-x64" - ENABLE_CONTRIB: 1 - ENABLE_HEADLESS: 1 - - - PYTHON: "C:/Python37" - ENABLE_CONTRIB: 1 - ENABLE_HEADLESS: 1 - - - PYTHON: "C:/Python37-x64" - ENABLE_CONTRIB: 1 - ENABLE_HEADLESS: 1 - - - PYTHON: "C:/Python38" - ENABLE_CONTRIB: 1 - ENABLE_HEADLESS: 1 - - - PYTHON: "C:/Python38-x64" - ENABLE_CONTRIB: 1 - ENABLE_HEADLESS: 1 - - - PYTHON: "C:/Python39" - ENABLE_CONTRIB: 1 - ENABLE_HEADLESS: 1 - - - PYTHON: "C:/Python39-x64" - ENABLE_CONTRIB: 1 - ENABLE_HEADLESS: 1 - -matrix: - fast_finish: true - -build_script: -- cmd: | - "%PYTHON%/python.exe" -m pip install --upgrade pip - "%PYTHON%/python.exe" -m pip install --upgrade setuptools - set "CI_BUILD=1" && "%PYTHON%/python.exe" -m pip wheel --wheel-dir=%cd%\dist . --verbose - -before_test: -- ps: | - - cd ${Env:APPVEYOR_BUILD_FOLDER}\tests - $env:PYTHONWARNINGS = "ignore:::pip._internal.cli.base_command" - &"${Env:PYTHON}/python.exe" -m pip install --user --no-warn-script-location (ls "../dist/opencv_*.whl") - if ($LastExitCode -ne 0) {throw $LastExitCode} - -test_script: -- cmd: | - - cd %APPVEYOR_BUILD_FOLDER%\tests - "%PYTHON%/python.exe" -m unittest test - -artifacts: -- path: dist\opencv*.whl - name: wheels - -deploy_script: -- ps: | - - if (${Env:APPVEYOR_REPO_TAG} -eq "true") { - cd ${Env:APPVEYOR_BUILD_FOLDER} - if (${Env:ENABLE_CONTRIB} -eq 0) { - if (${Env:ENABLE_HEADLESS} -eq 0) { - echo "This is a default build. Deployment will be done to PyPI entry opencv-python." - } - else { - echo "This is a headless build. Deployment will be done to PyPI entry opencv-python-headless." - } - } - else { - if (${Env:ENABLE_HEADLESS} -eq 0) { - echo "This is a contrib build. Deployment will be done to PyPI entry opencv-contrib-python." - } - else { - echo "This is a headless contrib build. Deployment will be done to PyPI entry opencv-contrib-python-headless." - } - } - - &"${Env:PYTHON}/python.exe" -m pip install twine - &"${Env:PYTHON}/python.exe" -m twine upload -u ${Env:USER} -p ${Env:PASS} --skip-existing dist/opencv* - } - else { - echo "Tag not set, deployment skipped." - } +environment: + USER: + secure: fXgF9uyy6sT0JoVOR7BoqA== + + PASS: + secure: 0bXSOVjf9x8L7nErTivu92TF1FwNosTjFJQPmxp8Dys= + + matrix: + - PYTHON: "C:/Python36" + ENABLE_CONTRIB: 0 + ENABLE_HEADLESS: 0 + + - PYTHON: "C:/Python36-x64" + ENABLE_CONTRIB: 0 + ENABLE_HEADLESS: 0 + + - PYTHON: "C:/Python37" + ENABLE_CONTRIB: 0 + ENABLE_HEADLESS: 0 + + - PYTHON: "C:/Python37-x64" + ENABLE_CONTRIB: 0 + ENABLE_HEADLESS: 0 + + - PYTHON: "C:/Python38" + ENABLE_CONTRIB: 0 + ENABLE_HEADLESS: 0 + + - PYTHON: "C:/Python38-x64" + ENABLE_CONTRIB: 0 + ENABLE_HEADLESS: 0 + + - PYTHON: "C:/Python39" + ENABLE_CONTRIB: 0 + ENABLE_HEADLESS: 0 + + - PYTHON: "C:/Python39-x64" + ENABLE_CONTRIB: 0 + ENABLE_HEADLESS: 0 + + - PYTHON: "C:/Python36" + ENABLE_CONTRIB: 1 + ENABLE_HEADLESS: 0 + + - PYTHON: "C:/Python36-x64" + ENABLE_CONTRIB: 1 + ENABLE_HEADLESS: 0 + + - PYTHON: "C:/Python37" + ENABLE_CONTRIB: 1 + ENABLE_HEADLESS: 0 + + - PYTHON: "C:/Python37-x64" + ENABLE_CONTRIB: 1 + ENABLE_HEADLESS: 0 + + - PYTHON: "C:/Python38" + ENABLE_CONTRIB: 1 + ENABLE_HEADLESS: 0 + + - PYTHON: "C:/Python38-x64" + ENABLE_CONTRIB: 1 + ENABLE_HEADLESS: 0 + + - PYTHON: "C:/Python39" + ENABLE_CONTRIB: 1 + ENABLE_HEADLESS: 0 + + - PYTHON: "C:/Python39-x64" + ENABLE_CONTRIB: 1 + ENABLE_HEADLESS: 0 + + - PYTHON: "C:/Python36" + ENABLE_CONTRIB: 0 + ENABLE_HEADLESS: 1 + + - PYTHON: "C:/Python36-x64" + ENABLE_CONTRIB: 0 + ENABLE_HEADLESS: 1 + + - PYTHON: "C:/Python37" + ENABLE_CONTRIB: 0 + ENABLE_HEADLESS: 1 + + - PYTHON: "C:/Python37-x64" + ENABLE_CONTRIB: 0 + ENABLE_HEADLESS: 1 + + - PYTHON: "C:/Python38" + ENABLE_CONTRIB: 0 + ENABLE_HEADLESS: 1 + + - PYTHON: "C:/Python38-x64" + ENABLE_CONTRIB: 0 + ENABLE_HEADLESS: 1 + + - PYTHON: "C:/Python39" + ENABLE_CONTRIB: 0 + ENABLE_HEADLESS: 1 + + - PYTHON: "C:/Python39-x64" + ENABLE_CONTRIB: 0 + ENABLE_HEADLESS: 1 + + - PYTHON: "C:/Python36" + ENABLE_CONTRIB: 1 + ENABLE_HEADLESS: 1 + + - PYTHON: "C:/Python36-x64" + ENABLE_CONTRIB: 1 + ENABLE_HEADLESS: 1 + + - PYTHON: "C:/Python37" + ENABLE_CONTRIB: 1 + ENABLE_HEADLESS: 1 + + - PYTHON: "C:/Python37-x64" + ENABLE_CONTRIB: 1 + ENABLE_HEADLESS: 1 + + - PYTHON: "C:/Python38" + ENABLE_CONTRIB: 1 + ENABLE_HEADLESS: 1 + + - PYTHON: "C:/Python38-x64" + ENABLE_CONTRIB: 1 + ENABLE_HEADLESS: 1 + + - PYTHON: "C:/Python39" + ENABLE_CONTRIB: 1 + ENABLE_HEADLESS: 1 + + - PYTHON: "C:/Python39-x64" + ENABLE_CONTRIB: 1 + ENABLE_HEADLESS: 1 + +matrix: + fast_finish: true + +build_script: +- cmd: | + "%PYTHON%/python.exe" -m pip install --upgrade pip + "%PYTHON%/python.exe" -m pip install --upgrade setuptools + set "CI_BUILD=1" && "%PYTHON%/python.exe" -m pip wheel --wheel-dir=%cd%\dist . --verbose + +before_test: +- ps: | + + cd ${Env:APPVEYOR_BUILD_FOLDER}\tests + $env:PYTHONWARNINGS = "ignore:::pip._internal.cli.base_command" + &"${Env:PYTHON}/python.exe" -m pip install --user --no-warn-script-location (ls "../dist/opencv_*.whl") + if ($LastExitCode -ne 0) {throw $LastExitCode} + +test_script: +- cmd: | + + cd %APPVEYOR_BUILD_FOLDER%\tests + "%PYTHON%/python.exe" -m unittest test + +artifacts: +- path: dist\opencv*.whl + name: wheels + +deploy_script: +- ps: | + + if (${Env:APPVEYOR_REPO_TAG} -eq "true") { + cd ${Env:APPVEYOR_BUILD_FOLDER} + if (${Env:ENABLE_CONTRIB} -eq 0) { + if (${Env:ENABLE_HEADLESS} -eq 0) { + echo "This is a default build. Deployment will be done to PyPI entry opencv-python." + } + else { + echo "This is a headless build. Deployment will be done to PyPI entry opencv-python-headless." + } + } + else { + if (${Env:ENABLE_HEADLESS} -eq 0) { + echo "This is a contrib build. Deployment will be done to PyPI entry opencv-contrib-python." + } + else { + echo "This is a headless contrib build. Deployment will be done to PyPI entry opencv-contrib-python-headless." + } + } + + &"${Env:PYTHON}/python.exe" -m pip install twine + &"${Env:PYTHON}/python.exe" -m twine upload -u ${Env:USER} -p ${Env:PASS} --skip-existing dist/opencv* + } + else { + echo "Tag not set, deployment skipped." + } diff --git a/cv2/__init__.py b/cv2/__init__.py index 7f7c126..d665b75 100644 --- a/cv2/__init__.py +++ b/cv2/__init__.py @@ -1,33 +1,33 @@ -import importlib -import os -import sys - -from .cv2 import * -from .data import * - -# wildcard import above does not import "private" variables like __version__ -# this makes them available -globals().update(importlib.import_module("cv2.cv2").__dict__) - -ci_and_not_headless = False - -try: - from .version import ci_build, headless - - ci_and_not_headless = ci_build and not headless -except: - pass - -# the Qt plugin is included currently only in the pre-built wheels -if ( - sys.platform == "darwin" or sys.platform.startswith("linux") -) and ci_and_not_headless: - os.environ["QT_QPA_PLATFORM_PLUGIN_PATH"] = os.path.join( - os.path.dirname(os.path.abspath(__file__)), "qt", "plugins" - ) - -# Qt will throw warning on Linux if fonts are not found -if sys.platform.startswith("linux") and ci_and_not_headless: - os.environ["QT_QPA_FONTDIR"] = os.path.join( - os.path.dirname(os.path.abspath(__file__)), "qt", "fonts" - ) +import importlib +import os +import sys + +from .cv2 import * +from .data import * + +# wildcard import above does not import "private" variables like __version__ +# this makes them available +globals().update(importlib.import_module("cv2.cv2").__dict__) + +ci_and_not_headless = False + +try: + from .version import ci_build, headless + + ci_and_not_headless = ci_build and not headless +except: + pass + +# the Qt plugin is included currently only in the pre-built wheels +if ( + sys.platform == "darwin" or sys.platform.startswith("linux") +) and ci_and_not_headless: + os.environ["QT_QPA_PLATFORM_PLUGIN_PATH"] = os.path.join( + os.path.dirname(os.path.abspath(__file__)), "qt", "plugins" + ) + +# Qt will throw warning on Linux if fonts are not found +if sys.platform.startswith("linux") and ci_and_not_headless: + os.environ["QT_QPA_FONTDIR"] = os.path.join( + os.path.dirname(os.path.abspath(__file__)), "qt", "fonts" + ) diff --git a/find_version.py b/find_version.py index 80ae522..6c676b2 100644 --- a/find_version.py +++ b/find_version.py @@ -1,68 +1,68 @@ -import sys -import os -import subprocess - -if __name__ == "__main__": - contrib = sys.argv[1] - headless = sys.argv[2] - ci_build = sys.argv[3] - - opencv_version = "" - # dig out the version from OpenCV sources - version_file_path = "opencv/modules/core/include/opencv2/core/version.hpp" - - with open(version_file_path, "r") as f: - for line in f: - words = line.split() - - if "CV_VERSION_MAJOR" in words: - opencv_version += words[2] - opencv_version += "." - - if "CV_VERSION_MINOR" in words: - opencv_version += words[2] - opencv_version += "." - - if "CV_VERSION_REVISION" in words: - opencv_version += words[2] - break - - # used in local dev releases - git_hash = ( - subprocess.check_output(["git", "rev-parse", "--short", "HEAD"]) - .splitlines()[0] - .decode() - ) - # this outputs the annotated tag if we are exactly on a tag, otherwise --g - try: - tag = ( - subprocess.check_output( - ["git", "describe", "--tags"], stderr=subprocess.STDOUT - ) - .splitlines()[0] - .decode() - .split("-") - ) - except subprocess.CalledProcessError as e: - # no tags reachable (e.g. on a topic branch in a fork), see - # https://stackoverflow.com/questions/4916492/git-describe-fails-with-fatal-no-names-found-cannot-describe-anything - if e.output.rstrip() == b"fatal: No names found, cannot describe anything.": - tag = [] - else: - print(e.output) - raise - - if len(tag) == 1: - # tag identifies the build and should be a sequential revision number - version = tag[0] - opencv_version += ".{}".format(version) - else: - # local version identifier, not to be published on PyPI - version = git_hash - opencv_version += "+{}".format(version) - - with open("cv2/version.py", "w") as f: - f.write('opencv_version = "{}"\n'.format(opencv_version)) - f.write("contrib = {}\n".format(contrib)) - f.write("headless = {}\n".format(headless)) - f.write("ci_build = {}".format(ci_build)) +import sys +import os +import subprocess + +if __name__ == "__main__": + contrib = sys.argv[1] + headless = sys.argv[2] + ci_build = sys.argv[3] + + opencv_version = "" + # dig out the version from OpenCV sources + version_file_path = "opencv/modules/core/include/opencv2/core/version.hpp" + + with open(version_file_path, "r") as f: + for line in f: + words = line.split() + + if "CV_VERSION_MAJOR" in words: + opencv_version += words[2] + opencv_version += "." + + if "CV_VERSION_MINOR" in words: + opencv_version += words[2] + opencv_version += "." + + if "CV_VERSION_REVISION" in words: + opencv_version += words[2] + break + + # used in local dev releases + git_hash = ( + subprocess.check_output(["git", "rev-parse", "--short", "HEAD"]) + .splitlines()[0] + .decode() + ) + # this outputs the annotated tag if we are exactly on a tag, otherwise --g + try: + tag = ( + subprocess.check_output( + ["git", "describe", "--tags"], stderr=subprocess.STDOUT + ) + .splitlines()[0] + .decode() + .split("-") + ) + except subprocess.CalledProcessError as e: + # no tags reachable (e.g. on a topic branch in a fork), see + # https://stackoverflow.com/questions/4916492/git-describe-fails-with-fatal-no-names-found-cannot-describe-anything + if e.output.rstrip() == b"fatal: No names found, cannot describe anything.": + tag = [] + else: + print(e.output) + raise + + if len(tag) == 1: + # tag identifies the build and should be a sequential revision number + version = tag[0] + opencv_version += ".{}".format(version) + else: + # local version identifier, not to be published on PyPI + version = git_hash + opencv_version += "+{}".format(version) + + with open("cv2/version.py", "w") as f: + f.write('opencv_version = "{}"\n'.format(opencv_version)) + f.write("contrib = {}\n".format(contrib)) + f.write("headless = {}\n".format(headless)) + f.write("ci_build = {}".format(ci_build)) diff --git a/setup.py b/setup.py index 7f52501..3ba7244 100644 --- a/setup.py +++ b/setup.py @@ -1,450 +1,450 @@ -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 ( - not build_headless - and "bdist_wheel" in sys.argv - and (sys.platform == "darwin" or sys.platform.startswith("linux")) - ): - cmake_args.append("-DWITH_QT=5") - subprocess.check_call("patch -p1 < patches/patchQtPlugins", shell=True) - - if sys.platform.startswith("linux"): - rearrange_cmake_output_data["cv2.qt.plugins.platforms"] = [ - (r"lib/qt/plugins/platforms/libqxcb\.so") - ] - - # add fonts for Qt5 - fonts = [] - for file in os.listdir("/usr/share/fonts/dejavu"): - if file.endswith(".ttf"): - fonts.append( - (r"lib/qt/fonts/dejavu/%s\.ttf" % file.split(".")[0]) - ) - - rearrange_cmake_output_data["cv2.qt.fonts"] = fonts - - if sys.platform == "darwin": - rearrange_cmake_output_data["cv2.qt.plugins.platforms"] = [ - (r"lib/qt/plugins/platforms/libqcocoa\.dylib") - ] - - 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, - python_requires=">=3.6", - 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 :: Only", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "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 ( + not build_headless + and "bdist_wheel" in sys.argv + and (sys.platform == "darwin" or sys.platform.startswith("linux")) + ): + cmake_args.append("-DWITH_QT=5") + subprocess.check_call("patch -p1 < patches/patchQtPlugins", shell=True) + + if sys.platform.startswith("linux"): + rearrange_cmake_output_data["cv2.qt.plugins.platforms"] = [ + (r"lib/qt/plugins/platforms/libqxcb\.so") + ] + + # add fonts for Qt5 + fonts = [] + for file in os.listdir("/usr/share/fonts/dejavu"): + if file.endswith(".ttf"): + fonts.append( + (r"lib/qt/fonts/dejavu/%s\.ttf" % file.split(".")[0]) + ) + + rearrange_cmake_output_data["cv2.qt.fonts"] = fonts + + if sys.platform == "darwin": + rearrange_cmake_output_data["cv2.qt.plugins.platforms"] = [ + (r"lib/qt/plugins/platforms/libqcocoa\.dylib") + ] + + 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, + python_requires=">=3.6", + 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 :: Only", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "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() diff --git a/tests/test.py b/tests/test.py index 54ee19d..6411ff3 100644 --- a/tests/test.py +++ b/tests/test.py @@ -1,17 +1,17 @@ -import unittest -import sys - - -class OpenCVTest(unittest.TestCase): - """ Simple functionality tests. """ - - def test_import(self): - """ Test that the cv2 module can be imported. """ - import cv2 - - def test_video_capture(self): - - import cv2 - - cap = cv2.VideoCapture("SampleVideo_1280x720_1mb.mp4") - self.assertTrue(cap.isOpened()) +import unittest +import sys + + +class OpenCVTest(unittest.TestCase): + """ Simple functionality tests. """ + + def test_import(self): + """ Test that the cv2 module can be imported. """ + import cv2 + + def test_video_capture(self): + + import cv2 + + cap = cv2.VideoCapture("SampleVideo_1280x720_1mb.mp4") + self.assertTrue(cap.isOpened()) -- GitLab