diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index bafa91a39..4736acc68 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -27,7 +27,7 @@ env: jobs: lint: name: Lint - runs-on: ubuntu-22.04 + runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 @@ -44,43 +44,43 @@ jobs: fail-fast: false matrix: include: - - os: ubuntu-22.04 + - os: ubuntu-latest arch: "x86_64" build: "manylinux_" use_qemu: false - - os: ubuntu-22.04 + - os: ubuntu-latest arch: "x86_64" build: "musllinux_" use_qemu: false - - os: ubuntu-22.04 + - os: ubuntu-latest arch: "i686" build: "manylinux_" use_qemu: false - - os: ubuntu-22.04 + - os: ubuntu-latest arch: "i686" build: "musllinux_" use_qemu: false - - os: ubuntu-22.04 + - os: ubuntu-latest arch: "aarch64" build: "manylinux_" use_qemu: true - - os: ubuntu-22.04 + - os: ubuntu-latest arch: "aarch64" build: "musllinux_" use_qemu: true - - os: ubuntu-22.04 + - os: ubuntu-latest arch: "ppc64le" build: "manylinux_" use_qemu: true - - os: ubuntu-22.04 + - os: ubuntu-latest arch: "ppc64le" build: "musllinux_" use_qemu: true - - os: ubuntu-22.04 + - os: ubuntu-latest arch: "s390x" build: "manylinux_" use_qemu: true - - os: ubuntu-22.04 + - os: ubuntu-latest arch: "s390x" build: "musllinux_" use_qemu: true @@ -96,8 +96,8 @@ jobs: arch: "x86" build: "" use_qemu: false - - os: macos-11 - arch: "x86_64" + - os: macos-14 + arch: "universal2" build: "" use_qemu: false @@ -121,13 +121,13 @@ jobs: - uses: actions/upload-artifact@v4 if: (!matrix.use_qemu) || fromJSON(env.USE_QEMU) with: - name: Wheel-${{ matrix.os }}-${{ matrix.build }}${{ matrix.arch }} + name: Wheel-${{ runner.os }}-${{ matrix.build }}${{ matrix.arch }} path: ./wheelhouse/*.whl build_manylinux2010_wheels: name: Build ${{ matrix.arch }} manylinux2010 wheels needs: [lint] - runs-on: ubuntu-22.04 + runs-on: ubuntu-latest strategy: fail-fast: false matrix: @@ -153,10 +153,53 @@ jobs: name: Wheel-manylinux2010-${{ matrix.arch }} path: ./wheelhouse/*.whl + test_old_pythons: + name: Test wheel with python ${{ matrix.python }} + needs: [build_wheels] + runs-on: windows-latest + strategy: + fail-fast: false + matrix: + python: ["2.7", "3.5"] + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + if: matrix.python != '2.7' + name: Install Python ${{ matrix.python }} + with: + python-version: ${{ matrix.python }} + + - name: Install Python ${{ matrix.python }} + if: matrix.python == '2.7' + shell: bash + run: | + nuget install python2 -Version 2.7.18 -OutputDirectory '${{ runner.temp }}' + echo '${{ runner.temp }}\python2.2.7.18\tools' >> $GITHUB_PATH + + - name: Install dependencies + shell: bash + run: | + python -m pip install -U pip + python -m pip install pytest pytest-cov + + - uses: actions/download-artifact@v4 + with: + name: Wheel-Windows-AMD64 + path: wheelhouse + + - name: Install wheel + shell: bash + run: | + python -m pip -V + python -m pip install "$(find wheelhouse -name '*.whl')[test]" + + - name: Test installed SDist + run: python -m pytest ./tests + build_sdist: name: Build source distribution needs: [lint] - runs-on: ubuntu-22.04 + runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: @@ -173,36 +216,24 @@ jobs: test_sdist: name: Test SDist with python ${{ matrix.python }} needs: [build_sdist] - # 22.04 doesn't have 2.7 or 3.6 - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest strategy: fail-fast: false matrix: - python: ["2.7", "3.6", "3.12"] + python: ["3.7", "3.12"] steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 - if: matrix.python != '2.7' name: Install Python ${{ matrix.python }} with: python-version: ${{ matrix.python }} - - name: Install Ubuntu Python 2.7 - if: matrix.python == '2.7' - run: | - sudo apt-get update - sudo apt-get install -y --no-install-recommends python2 python3-virtualenv - virtualenv -p python2 ${HOME}/cp27 - ${HOME}/cp27/bin/python -m pip install -U pip - ${HOME}/cp27/bin/python -m pip install -U setuptools wheel - echo "${HOME}/cp27/bin" >> $GITHUB_PATH - - name: Install dependencies run: | sudo apt-get update sudo apt-get install -y --no-install-recommends libssl-dev - pip install -r requirements-test.txt + pip install pytest pytest-cov - uses: actions/download-artifact@v4 with: @@ -211,8 +242,9 @@ jobs: - name: Install SDist env: - SKBUILD_CONFIGURE_OPTIONS: "-DBUILD_CMAKE_FROM_SOURCE:BOOL=OFF" + CMAKE_ARGS: "-DBUILD_CMAKE_FROM_SOURCE:BOOL=OFF" run: | + pip -V pip install dist/*.tar.gz rm -rf dist @@ -221,8 +253,8 @@ jobs: check_dist: name: Check dist - needs: [build_wheels, build_manylinux2010_wheels, build_sdist, test_sdist] - runs-on: ubuntu-22.04 + needs: [build_wheels, build_manylinux2010_wheels, test_old_pythons, build_sdist, test_sdist] + runs-on: ubuntu-latest steps: - uses: actions/download-artifact@v4 with: diff --git a/.gitignore b/.gitignore index 561347a16..552de032a 100644 --- a/.gitignore +++ b/.gitignore @@ -30,6 +30,7 @@ develop-eggs .installed.cfg lib lib64 +wheelhouse # Installer logs pip-log.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index 1201904a2..0c0673469 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -109,6 +109,20 @@ if(CMakePythonDistributions_SUPERBUILD) ) endfunction() + # Add an external project step named `forceconfigure` to `project_name` ensuring + # the project will always be reconfigured. + # + # Copied from ExternalProjectDependency.cmake (commontk/Artichoke@613e3739a) + function(cpd_ExternalProject_AlwaysConfigure proj) + _ep_get_step_stampfile(${proj} "configure" stampfile) + ExternalProject_Add_Step(${proj} forceconfigure + COMMAND ${CMAKE_COMMAND} -E remove ${stampfile} + COMMENT "Forcing configure step for '${proj}'" + DEPENDEES build + ALWAYS 1 + ) + endfunction() + # Note: To minimize confusion between variables defined by CMake and # variables used in this project. The following convention applies: # CMakeProject_xxx : Variables defined in this project @@ -128,6 +142,12 @@ if(CMakePythonDistributions_SUPERBUILD) ) endif() + set(ep_download_extract_timestamp_arg) + if(CMAKE_VERSION VERSION_EQUAL "3.24" OR CMAKE_VERSION VERSION_GREATER "3.24") + # See https://cmake.org/cmake/help/latest/policy/CMP0135.html + set(ep_download_extract_timestamp_arg DOWNLOAD_EXTRACT_TIMESTAMP 1) + endif() + # # CMakeProject_SOURCE_DIR: Always expect the sources (needed for `sdist`) # @@ -145,6 +165,7 @@ if(CMakePythonDistributions_SUPERBUILD) BUILD_COMMAND "" BUILD_IN_SOURCE 1 INSTALL_COMMAND "" + ${ep_download_extract_timestamp_arg} ${ep_download_no_progress_args} ) message(STATUS "SuperBuild - CMakeProject-src-download") @@ -338,6 +359,7 @@ set(CMAKE_EXE_LINKER_FLAGS \"-lstdc++ -lgcc -lrt\" CACHE STRING \"Initial cache\ BUILD_COMMAND "" BUILD_IN_SOURCE 1 INSTALL_COMMAND "" + ${ep_download_extract_timestamp_arg} ${ep_download_no_progress_args} ) message(STATUS "SuperBuild - CMakeProject-binary-download") @@ -368,6 +390,8 @@ set(CMAKE_EXE_LINKER_FLAGS \"-lstdc++ -lgcc -lrt\" CACHE STRING \"Initial cache\ ) message(STATUS "SuperBuild - ${PROJECT_NAME}") + cpd_ExternalProject_AlwaysConfigure(${PROJECT_NAME}) + # This adds an "install" target in the top-level directory. The # target will simply include the install rules associated with the # inner build @@ -436,5 +460,4 @@ include\(\"${CMakeProject_BINARY_DIR}/cmake_install.cmake\") install(${type} ${file} DESTINATION "${relative_directory}" ${_permissions}) endforeach() endif() - endif() diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index e060c63b0..000000000 --- a/MANIFEST.in +++ /dev/null @@ -1,15 +0,0 @@ -include CMakeLists.txt -include CMakeUrls.cmake -include requirements-test.txt -include HISTORY.rst -include README.rst -include LICENSE_Apache_20 -include LICENSE_BSD_3 - -recursive-exclude _skbuild * -recursive-exclude CMake-src * - -include src/cmake/_version.py -include src/cmake/_version.pyi -include src/cmake/__init__.pyi -include src/cmake/py.typed diff --git a/constraints-ci.txt b/constraints-ci.txt deleted file mode 100644 index d7fc56496..000000000 --- a/constraints-ci.txt +++ /dev/null @@ -1,2 +0,0 @@ -cmake==3.28.3 -ninja==1.11.1.1 diff --git a/pyproject.toml b/pyproject.toml index dd2b71824..d2e45baed 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,54 +1,95 @@ [build-system] -requires = [ - "scikit-build>=0.12", - "setuptools>=42", - "setuptools-scm[toml]", +requires = ["scikit-build-core"] +build-backend = "scikit_build_core.build" + +[project] +name = "cmake" +description = "CMake is an open-source, cross-platform family of tools designed to build, test and package software" +keywords = ["CMake", "build", "c++", "fortran", "cross-platform", "cross-compilation"] +readme = "README.rst" +license = {text = "Apache 2.0"} +authors = [ + {name = "Jean-Christophe Fillion-Robin", email = "jchris.fillionr@kitware.com"}, +] +classifiers = [ + "License :: OSI Approved :: Apache Software License", + "License :: OSI Approved :: BSD License", + "Programming Language :: C", + "Programming Language :: C++", + "Programming Language :: Fortran", + "Programming Language :: Python", + "Operating System :: OS Independent", + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "Topic :: Software Development :: Build Tools", + "Typing :: Typed" +] +dynamic = ["version"] +# requires-python = ">=3.7" this is only required to build the wheel. We're still compatible with python 2.7 + +[project.urls] +Homepage = "https://cmake.org" +Documentation = "https://cmake-python-distributions.readthedocs.io" +Source = "ttps://github.com/scikit-build/cmake-python-distributions" +"Mailing list" = "https://groups.google.com/forum/#!forum/scikit-build" +"Bug Tracker" = "https://github.com/scikit-build/cmake-python-distributions/issues" + +[project.optional-dependencies] +test = [ + "coverage>=4.2", + "importlib_metadata>=2.0; python_version<'3.10'", + "pytest>=3.0.3", + "pytest-cov>=2.4.0", ] -build-backend = "setuptools.build_meta" + +[project.scripts] +cmake = "cmake:cmake" +cpack = "cmake:cpack" +ctest = "cmake:ctest" + +[tool.scikit-build] +minimum-version = "0.8" +build-dir = "build/{wheel_tag}" +metadata.version.provider = "scikit_build_core.metadata.setuptools_scm" +ninja.make-fallback = false +sdist.include = ["src/cmake/_version.py"] +wheel.py-api = "py2.py3" +wheel.expand-macos-universal-tags = true +wheel.install-dir = "cmake/data" [tool.setuptools_scm] write_to = "src/cmake/_version.py" +# Setuptools-scm includes type annotations in the default template +write_to_template = "version = '{version}'" [tool.cibuildwheel] build = "cp39-*" -before-all = [ - 'pipx install -f --pip-args="-c {project}/constraints-ci.txt" cmake', - 'cmake --version', - 'pipx install -f --pip-args="-c {project}/constraints-ci.txt" ninja', - 'ninja --version', -] -before-build = "pip install -r requirements-repair.txt" -repair-wheel-command = "python scripts/repair_wheel.py -w {dest_dir} {wheel}" test-extras = "test" test-command = "pytest {project}/tests" build-verbosity = 1 [tool.cibuildwheel.linux] before-all = [ - 'pipx install -f --pip-args="-c {project}/constraints-ci.txt" cmake', - 'cmake --version', - 'pipx install -f --pip-args="-c {project}/constraints-ci.txt" ninja', - 'ninja --version', './scripts/manylinux-build-and-install-openssl.sh', ] -environment = { SKBUILD_CONFIGURE_OPTIONS = "-DOPENSSL_ROOT_DIR:PATH=/usr/local/ssl -DCMAKE_JOB_POOL_COMPILE:STRING=compile -DCMAKE_JOB_POOL_LINK:STRING=link -DCMAKE_JOB_POOLS:STRING=compile=4;link=1 -DCMAKE_CXX_STANDARD:STRING=11" } +environment = { CMAKE_ARGS = "-DOPENSSL_ROOT_DIR:PATH=/usr/local/ssl -DCMAKE_JOB_POOL_COMPILE:STRING=compile -DCMAKE_JOB_POOL_LINK:STRING=link -DCMAKE_JOB_POOLS:STRING=compile=4;link=1 -DCMAKE_CXX_STANDARD:STRING=11" } [[tool.cibuildwheel.overrides]] select = ["*-manylinux_aarch64", "*-manylinux_ppc64le", "*-manylinux_s390x"] # disable tests on those platforms, QEMU is taking to long for jobs to pass on GHA -environment = { SKBUILD_CONFIGURE_OPTIONS = "-DOPENSSL_ROOT_DIR:PATH=/usr/local/ssl -DCMAKE_JOB_POOL_COMPILE:STRING=compile -DCMAKE_JOB_POOL_LINK:STRING=link -DCMAKE_JOB_POOLS:STRING=compile=4;link=1 -DCMAKE_CXX_STANDARD:STRING=11 -DRUN_CMAKE_TEST:BOOL=OFF" } +environment = { CMAKE_ARGS = "-DOPENSSL_ROOT_DIR:PATH=/usr/local/ssl -DCMAKE_JOB_POOL_COMPILE:STRING=compile -DCMAKE_JOB_POOL_LINK:STRING=link -DCMAKE_JOB_POOLS:STRING=compile=4;link=1 -DCMAKE_CXX_STANDARD:STRING=11 -DRUN_CMAKE_TEST:BOOL=OFF" } [[tool.cibuildwheel.overrides]] select = ["*-musllinux_x86_64", "*-musllinux_i686"] # disable some tests # - BootstrapTest fails with custom OpenSSL and probably does not make much sense for this project # - ExportImport|RunCMake.install|RunCMake.file-GET_RUNTIME_DEPENDENCIES: c.f. https://discourse.cmake.org/t/cmake-test-suite-failing-on-alpine-linux/5064 -environment = { SKBUILD_CONFIGURE_OPTIONS = "-DOPENSSL_ROOT_DIR:PATH=/usr/local/ssl -DCMAKE_JOB_POOL_COMPILE:STRING=compile -DCMAKE_JOB_POOL_LINK:STRING=link -DCMAKE_JOB_POOLS:STRING=compile=4;link=1 -DRUN_CMAKE_TEST_EXCLUDE:STRING='BootstrapTest|ExportImport|RunCMake.install|RunCMake.file-GET_RUNTIME_DEPENDENCIES'" } +environment = { CMAKE_ARGS = "-DOPENSSL_ROOT_DIR:PATH=/usr/local/ssl -DCMAKE_JOB_POOL_COMPILE:STRING=compile -DCMAKE_JOB_POOL_LINK:STRING=link -DCMAKE_JOB_POOLS:STRING=compile=4;link=1 -DRUN_CMAKE_TEST_EXCLUDE:STRING='BootstrapTest|ExportImport|RunCMake.install|RunCMake.file-GET_RUNTIME_DEPENDENCIES'" } [[tool.cibuildwheel.overrides]] select = ["*-musllinux_aarch64", "*-musllinux_ppc64le", "*-musllinux_s390x"] # disable tests on those platforms, QEMU is taking to long for jobs to pass on GHA -environment = { SKBUILD_CONFIGURE_OPTIONS = "-DOPENSSL_ROOT_DIR:PATH=/usr/local/ssl -DCMAKE_JOB_POOL_COMPILE:STRING=compile -DCMAKE_JOB_POOL_LINK:STRING=link -DCMAKE_JOB_POOLS:STRING=compile=4;link=1 -DRUN_CMAKE_TEST:BOOL=OFF" } +environment = { CMAKE_ARGS = "-DOPENSSL_ROOT_DIR:PATH=/usr/local/ssl -DCMAKE_JOB_POOL_COMPILE:STRING=compile -DCMAKE_JOB_POOL_LINK:STRING=link -DCMAKE_JOB_POOLS:STRING=compile=4;link=1 -DRUN_CMAKE_TEST:BOOL=OFF" } [tool.cibuildwheel.macos.environment] MACOSX_DEPLOYMENT_TARGET = "10.10" diff --git a/requirements-dev.txt b/requirements-dev.txt deleted file mode 100644 index a44bbeeeb..000000000 --- a/requirements-dev.txt +++ /dev/null @@ -1,2 +0,0 @@ --r requirements-test.txt --r requirements-repair.txt diff --git a/requirements-repair.txt b/requirements-repair.txt deleted file mode 100644 index de121f347..000000000 --- a/requirements-repair.txt +++ /dev/null @@ -1 +0,0 @@ -wheel>=0.40.0 diff --git a/requirements-test.txt b/requirements-test.txt deleted file mode 100644 index 45923ba3f..000000000 --- a/requirements-test.txt +++ /dev/null @@ -1,4 +0,0 @@ -coverage>=4.2 -importlib_metadata>=2.0 -pytest>=3.0.3 -pytest-cov>=2.4.0 diff --git a/scripts/repair_wheel.py b/scripts/repair_wheel.py deleted file mode 100755 index f53a5e7f2..000000000 --- a/scripts/repair_wheel.py +++ /dev/null @@ -1,95 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -import argparse -import re -import shutil -import subprocess -import sys -import tempfile -from pathlib import Path - - -def main(): - if sys.platform.startswith("linux"): - os_ = "linux" - elif sys.platform.startswith("darwin"): - os_ = "macos" - elif sys.platform.startswith("win32"): - os_ = "windows" - else: - raise NotImplementedError("sys.platform '{}' is not supported yet.".format(sys.platform)) - - p = argparse.ArgumentParser(description="Convert wheel to be independent of python implementation and ABI") - p.set_defaults(prog=Path(sys.argv[0]).name) - p.add_argument("WHEEL_FILE", help="Path to wheel file.") - p.add_argument( - "-w", - "--wheel-dir", - dest="WHEEL_DIR", - help=('Directory to store delocated wheels (default: "wheelhouse/")'), - default="wheelhouse/", - ) - - args = p.parse_args() - - file = Path(args.WHEEL_FILE).resolve(strict=True) - wheelhouse = Path(args.WHEEL_DIR).resolve() - wheelhouse.mkdir(parents=True, exist_ok=True) - - with tempfile.TemporaryDirectory() as tmpdir_: - tmpdir = Path(tmpdir_) - # use the platform specific repair tool first - if os_ == "linux": - subprocess.run(["auditwheel", "repair", "-w", str(tmpdir), str(file)], check=True, stdout=subprocess.PIPE) - elif os_ == "macos": - subprocess.run( - ["delocate-wheel", "--require-archs", "arm64,x86_64", "-w", str(tmpdir), str(file)], - check=True, - stdout=subprocess.PIPE, - ) - elif os_ == "windows": - # no specific tool, just copy - shutil.copyfile(file, tmpdir / file.name) - (file,) = tmpdir.glob("*.whl") - - # we need to handle macOS universal2 & arm64 here for now, let's use platform_tag_args for this. - platform_tag_args = [] - if os_ == "macos": - additional_platforms = [] - - # first, get the target macOS deployment target from the wheel - match = re.match(r"^.*-macosx_(\d+)_(\d+)_x86_64\.whl$", file.name) - assert match is not None - target = tuple(map(int, match.groups())) - - # let's add universal2 platform for this wheel. - additional_platforms = ["macosx_{}_{}_universal2".format(*target)] - - # given pip support for universal2 was added after arm64 introduction - # let's also add arm64 platform. - arm64_target = target - if arm64_target < (11, 0): - arm64_target = (11, 0) - additional_platforms.append("macosx_{}_{}_arm64".format(*arm64_target)) - - if target < (11, 0): - # They're were also issues with pip not picking up some universal2 wheels, tag twice - additional_platforms.append("macosx_11_0_universal2") - - platform_tag_args = [f"--platform-tag=+{'.'.join(additional_platforms)}"] - - # make this a py2.py3 wheel - subprocess.run( - ["wheel", "tags", "--python-tag", "py2.py3", "--abi-tag", "none", *platform_tag_args, "--remove", str(file)], - check=True, - stdout=subprocess.PIPE, - ) - files = list(tmpdir.glob("*.whl")) - assert len(files) == 1, files - file = files[0] - file.rename(wheelhouse / file.name) - - -if __name__ == "__main__": - main() diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 0cd99068b..000000000 --- a/setup.cfg +++ /dev/null @@ -1,3 +0,0 @@ -[tool:pytest] -testpaths = tests -addopts = -v --cov --cov-report xml diff --git a/setup.py b/setup.py deleted file mode 100755 index 490ee7611..000000000 --- a/setup.py +++ /dev/null @@ -1,163 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -import os -import sys -from distutils.text_file import TextFile - -from skbuild import setup - -with open('README.rst', 'r') as fp: - readme = fp.read() - -with open('HISTORY.rst', 'r') as fp: - history = fp.read().replace('.. :changelog:', '') - - -def parse_requirements(filename): - with open(filename, 'r') as file: - return TextFile(filename, file).readlines() - - -test_requirements = parse_requirements('requirements-test.txt') - -try: - setup( - name='cmake', - - author='Jean-Christophe Fillion-Robin', - author_email='jchris.fillionr@kitware.com', - - package_dir={'': 'src'}, - packages=['cmake'], - package_data={"cmake": ["py.typed"]}, - - cmake_install_dir='src/cmake/data', - - entry_points={ - 'console_scripts': [ - 'cmake=cmake:cmake', 'cpack=cmake:cpack', 'ctest=cmake:ctest' - ] - }, - - url='https://cmake.org/', - download_url='https://cmake.org/download', - project_urls={ - "Documentation": "https://cmake-python-distributions.readthedocs.io/", - "Source Code": "https://github.com/scikit-build/cmake-python-distributions", - "Mailing list": "https://groups.google.com/forum/#!forum/scikit-build", - "Bug Tracker": "https://github.com/scikit-build/cmake-python-distributions/issues", - }, - - - description='CMake is an open-source, cross-platform family of ' - 'tools designed to build, test and package software', - - long_description=readme + '\n\n' + history, - long_description_content_type='text/x-rst', - - classifiers=[ - 'License :: OSI Approved :: Apache Software License', - 'License :: OSI Approved :: BSD License', - 'Programming Language :: C', - 'Programming Language :: C++', - 'Programming Language :: Fortran', - 'Programming Language :: Python', - 'Operating System :: OS Independent', - 'Development Status :: 5 - Production/Stable', - 'Intended Audience :: Developers', - 'Topic :: Software Development :: Build Tools', - 'Typing :: Typed', - ], - - license='Apache 2.0', - - keywords='CMake build c++ fortran cross-platform cross-compilation', - - extras_require={"test": test_requirements}, - ) -except BaseException: - # Note: This is a bare exception that re-raises so that we don't interfere - # with anything the installation machinery might want to do. Because we - # print this for any exception this msg can appear (e.g. in verbose logs) - # even if there's no failure. For example, SetupRequirementsError is raised - # during PEP517 building and prints this text. setuptools raises SystemExit - # when compilation fails right now, but it's possible this isn't stable - # or a public API commitment so we'll remain ultra conservative. - import platform - import subprocess - try: - import pkg_resources - except ImportError: - pass - - print( - """ - =============================DEBUG ASSISTANCE============================= - If you are seeing a compilation error please try the following steps to - successfully install cmake: - 1) Upgrade to the latest pip and try again. This will fix errors for most - users. See: https://pip.pypa.io/en/stable/installing/#upgrading-pip - 2) If running on Raspberry Pi OS, you can set PIP_ONLY_BINARY=cmake in - order to retrieve the latest wheels built by piwheels. - c.f. https://github.com/scikit-build/cmake-python-distributions/issues/392#issuecomment-1676284749 - 3) If on Linux, with glibc < 2.12, you can set PIP_ONLY_BINARY=cmake in - order to retrieve the last manylinux1 compatible wheel. - 4) If on Linux, with glibc < 2.12, you can cap "cmake<3.23" in your - requirements in order to retrieve the last manylinux1 compatible wheel. - 5) Open an issue with the debug information that follows at - https://github.com/scikit-build/cmake-python-distributions/issues - """ - ) - print(" Python: %s" % '.'.join(str(v) for v in sys.version_info[:3])) - print(" platform: %s" % platform.platform()) - if sys.platform.startswith("linux"): - try: - print(" glibc: %s" % os.confstr("CS_GNU_LIBC_VERSION")) - except BaseException: - try: - import ctypes - process_namespace = ctypes.CDLL(None) - gnu_get_libc_version = process_namespace.gnu_get_libc_version - gnu_get_libc_version.restype = ctypes.c_char_p - glibc_version = gnu_get_libc_version() - if not isinstance(glibc_version, str): - glibc_version = glibc_version.decode("ascii") - print(" glibc: %s" % glibc_version) - except BaseException: - pass - if sys.platform.startswith("darwin"): - try: - macos_ver = subprocess.check_output( - [ - sys.executable, - "-sS", - "-c", - "import platform; print(platform.mac_ver()[0])", - ], - universal_newlines=True, - env={"SYSTEM_VERSION_COMPAT": "0"}, - ).strip() - print(" macos: %s" % macos_ver) - except BaseException: - try: - print(" macos: %s" % platform.mac_ver()[0]) - except BaseException: - pass - print(" machine: %s" % platform.machine()) - print(" bits: %d" % (64 if sys.maxsize > 2**32 else 32)) - for dist in ["pip", "setuptools", "scikit-build"]: - try: - version = pkg_resources.get_distribution(dist).version - except BaseException: - version = "n/a" - print(" {}: {}".format(dist, version)) - for key in ["PEP517_BUILD_BACKEND"]: - if key in os.environ: - print(" {}={}".format(key, os.environ[key])) - print( - """\ - =============================DEBUG ASSISTANCE============================= - """ - ) - raise diff --git a/src/cmake/__init__.py b/src/cmake/__init__.py index c0bff820b..35bc96994 100644 --- a/src/cmake/__init__.py +++ b/src/cmake/__init__.py @@ -3,6 +3,12 @@ import subprocess import sys +if sys.version_info >= (3, 4): + if sys.version_info < (3, 10): + from importlib_metadata import distribution + else: + from importlib.metadata import distribution + from ._version import version as __version__ __all__ = ["__version__", "CMAKE_DATA", "CMAKE_BIN_DIR", "CMAKE_DOC_DIR", "CMAKE_SHARE_DIR", "cmake", "cpack", "ctest"] @@ -12,27 +18,23 @@ def __dir__(): return __all__ -CMAKE_DATA = os.path.join(os.path.dirname(__file__), 'data') - - -# Support running tests from the source tree -if not os.path.exists(CMAKE_DATA): - from skbuild.constants import CMAKE_INSTALL_DIR as SKBUILD_CMAKE_INSTALL_DIR - from skbuild.constants import set_skbuild_plat_name - - if sys.platform.startswith("darwin"): - # Since building the project specifying --plat-name or CMAKE_OSX_* variables - # leads to different SKBUILD_DIR, the code below attempt to guess the most - # likely plat-name. - _skbuild_dirs = os.listdir(os.path.join(os.path.dirname(__file__), '..', '..', '_skbuild')) - if _skbuild_dirs: - _likely_plat_name = '-'.join(_skbuild_dirs[0].split('-')[:3]) - set_skbuild_plat_name(_likely_plat_name) - - _cmake_data = os.path.abspath(os.path.join( - os.path.dirname(__file__), '..', '..', SKBUILD_CMAKE_INSTALL_DIR(), 'src/cmake/data')) - if os.path.exists(_cmake_data): - CMAKE_DATA = _cmake_data +if sys.version_info >= (3, 4): + cmake_executable_path = None + for script in distribution("cmake").files: + if str(script).startswith("cmake/data/bin/cmake"): + if sys.version_info < (3, 6): + # pre-3.6 behavior is strict + resolved_script = script.locate().resolve() + else: + resolved_script = script.locate().resolve(strict=True) + cmake_executable_path = resolved_script.parents[1] + break + CMAKE_DATA = str(cmake_executable_path) if cmake_executable_path else None +else: + CMAKE_DATA = os.path.join(os.path.dirname(__file__), "data") + +assert CMAKE_DATA is not None +assert os.path.exists(CMAKE_DATA) CMAKE_BIN_DIR = os.path.join(CMAKE_DATA, 'bin') CMAKE_DOC_DIR = os.path.join(CMAKE_DATA, 'doc') diff --git a/src/cmake/__init__.pyi b/src/cmake/__init__.pyi index 7bb53539f..ffa3ffe93 100644 --- a/src/cmake/__init__.pyi +++ b/src/cmake/__init__.pyi @@ -1,6 +1,6 @@ from typing import Iterator, NoReturn -__version__: tuple[int, int, int] | tuple[int, int, int, str, str] +__version__: str CMAKE_DATA: str diff --git a/src/cmake/_version.pyi b/src/cmake/_version.pyi index 91744f983..c2ee2cab4 100644 --- a/src/cmake/_version.pyi +++ b/src/cmake/_version.pyi @@ -1,4 +1 @@ -from __future__ import annotations - version: str -version_tuple: tuple[int, int, int] | tuple[int, int, int, str, str] diff --git a/tests/test_cmake.py b/tests/test_cmake.py index 3781e286c..596d50aab 100644 --- a/tests/test_cmake.py +++ b/tests/test_cmake.py @@ -1,11 +1,16 @@ # -*- coding: utf-8 -*- import os import subprocess +import sys import sysconfig import textwrap import pytest -from importlib_metadata import distribution + +if sys.version_info < (3, 10): + from importlib_metadata import distribution +else: + from importlib.metadata import distribution import cmake @@ -56,7 +61,11 @@ def _get_scripts(): scripts = [] for file in dist.files: if os.path.abspath(str(file.locate().parent)) in scripts_paths: - scripts.append(file.locate().resolve(strict=True)) + if sys.version_info < (3, 6): + # pre-3.6 behavior is strict + scripts.append(file.locate().resolve()) + else: + scripts.append(file.locate().resolve(strict=True)) return scripts