From 0c173d89e6fc1fe5431d555642fcd155d5659b99 Mon Sep 17 00:00:00 2001 From: zacharyburnett Date: Sun, 26 Jan 2025 15:28:54 -0500 Subject: [PATCH 1/2] build and test CMake project in CI --- .github/workflows/build.yml | 41 ++++++++++++++++++++++++++++ .github/workflows/test.yml | 53 +++++++++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+) create mode 100644 .github/workflows/build.yml create mode 100644 .github/workflows/test.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 00000000..356609c8 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,41 @@ +name: build + +on: + pull_request: + push: + branches: + - master + release: + types: + - released + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.ref }} + cancel-in-progress: true + +permissions: read-all + +jobs: + cmake: + strategy: + matrix: + runs-on: + - ubuntu-latest + # macos-13 is an intel runner, macos-14 is apple silicon + - macos-13 + - macos-latest + fail-fast: false + runs-on: ${{ matrix.runs-on }} + timeout-minutes: 30 + steps: + - uses: zacharyburnett/setup-abseil-cpp@de39f445295c887839e30c864ffbbb1c0231bc83 # 1.0.5 + with: + cmake-build-args: "-DCMAKE_CXX_STANDARD=17 -DABSL_PROPAGATE_CXX_STD=ON -DABSL_ENABLE_INSTALL=ON -DBUILD_TESTING=off -DCMAKE_POSITION_INDEPENDENT_CODE=ON" + abseil-version: "20240722.0" + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - run: mkdir build + - run: cmake -DCMAKE_CXX_STANDARD=17 -DCMAKE_PREFIX_PATH=/usr/local/ -DBUILD_TESTS=OFF .. + working-directory: build/ + - run: sudo cmake --build . --parallel --target=install + working-directory: build/ diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 00000000..cdeb1af0 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,53 @@ +name: test + +on: + pull_request: + push: + branches: + - master + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.ref }} + cancel-in-progress: true + +permissions: read-all + +env: + GOOGLETEST_VERSION: "1.15.2" + +jobs: + ctest: + strategy: + matrix: + runs-on: + - ubuntu-latest + # macos-13 is an intel runner, macos-14 is apple silicon + - macos-13 + - macos-latest + fail-fast: false + runs-on: ${{ matrix.runs-on }} + timeout-minutes: 30 + env: + CTEST_OUTPUT_ON_FAILURE: ON + steps: + - uses: zacharyburnett/setup-abseil-cpp@de39f445295c887839e30c864ffbbb1c0231bc83 # 1.0.5 + with: + cmake-build-args: "-DCMAKE_CXX_STANDARD=17 -DABSL_PROPAGATE_CXX_STD=ON -DABSL_ENABLE_INSTALL=ON -DBUILD_TESTING=off -DCMAKE_POSITION_INDEPENDENT_CODE=ON" + abseil-version: "20240722.0" + - name: retrieve googletest v${{ env.GOOGLETEST_VERSION }} + run: | + wget https://github.com/google/googletest/releases/download/v${{ env.GOOGLETEST_VERSION }}/googletest-${{ env.GOOGLETEST_VERSION }}.tar.gz + tar -xzvf googletest-${{ env.GOOGLETEST_VERSION }}.tar.gz + echo GOOGLETEST_ROOT=${{ runner.temp }}/googletest-${{ env.GOOGLETEST_VERSION }} >> $GITHUB_ENV + working-directory: ${{ runner.temp }} + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - run: mkdir build + - run: cmake -DCMAKE_CXX_STANDARD=17 -DCMAKE_PREFIX_PATH=/usr/local/ -DGOOGLETEST_ROOT=${{ env.GOOGLETEST_ROOT }} -DGOOGLETEST_VERSION=${{ env.GOOGLETEST_VERSION }} .. + working-directory: build/ + - run: cmake --build . ${{ runner.os == 'macOS' && '--parallel' || '' }} + # building tests with `--parallel` is disabled on Linux because GitHub seems to automatically cancel the job due to resource limits(?) + working-directory: build/ + - if: always() + run: cmake --build . --parallel --target=test + working-directory: build/ From 06d742f381d599a16b1ca3b2aa749d28994d752e Mon Sep 17 00:00:00 2001 From: zacharyburnett Date: Sun, 26 Jan 2025 15:54:09 -0500 Subject: [PATCH 2/2] attempt to use cibuildwheel to build library port --- .github/workflows/build.yml | 16 +++++++ pyproject.toml | 89 ++++++++++++++++++++++++++----------- setup.py | 33 ++++++++------ 3 files changed, 99 insertions(+), 39 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 356609c8..5b9fdc9a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -39,3 +39,19 @@ jobs: working-directory: build/ - run: sudo cmake --build . --parallel --target=install working-directory: build/ + cibuildwheel: + strategy: + matrix: + # macos-13 is an intel runner, macos-14 is apple silicon + os: + - ubuntu-latest + - macos-13 + - macos-latest + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: pypa/cibuildwheel@ee63bf16da6cddfb925f542f2c7b59ad50e93969 # v2.22.0 + - uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 + with: + name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }} + path: ./wheelhouse/*.whl diff --git a/pyproject.toml b/pyproject.toml index 6a55b8c3..5fe12a17 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,25 +2,23 @@ name = "s2geometry" description = "Computational geometry and spatial indexing on the sphere" authors = [ - { name = "Dan Larkin-York", email = "dan@arangodb.com" }, - { name = "Eric Veach", email = "ericv@google.com" }, - { name = "Jesse Rosenstock", email = "jmr@google.com" }, - { name = "Julien Basch", email = "julienbasch@google.com" }, - { name = "Mike Playle", email = "mike@mythik.co.uk" }, - { name = "Phil Elson", email = "pelson.pub@gmail.com" }, - { name = "Robert Coup", email = "robert.coup@koordinates.com" }, - { name = "Tiago Brito", email = "tiago.brito@90poe.io" }, - { name = "Zachary Burnett", email = "zachary.r.burnett@gmail.com" }, + { name = "Dan Larkin-York", email = "dan@arangodb.com" }, + { name = "Eric Veach", email = "ericv@google.com" }, + { name = "Jesse Rosenstock", email = "jmr@google.com" }, + { name = "Julien Basch", email = "julienbasch@google.com" }, + { name = "Mike Playle", email = "mike@mythik.co.uk" }, + { name = "Phil Elson", email = "pelson.pub@gmail.com" }, + { name = "Robert Coup", email = "robert.coup@koordinates.com" }, + { name = "Tiago Brito", email = "tiago.brito@90poe.io" }, + { name = "Zachary Burnett", email = "zachary.r.burnett@gmail.com" }, ] requires-python = ">=3.7" classifiers = [ - "Programming Language :: Python :: 3", - "Operating System :: POSIX", - "License :: OSI Approved :: Apache Software License", -] -dynamic = [ - "version", + "Programming Language :: Python :: 3", + "Operating System :: POSIX", + "License :: OSI Approved :: Apache Software License", ] +dynamic = ["version"] [project.license] file = "LICENSE" @@ -30,16 +28,15 @@ content-type = "text/plain" Source = "https://github.com/google/s2geometry" [project.optional-dependencies] -test = [ - "pytest", -] +test = ["pytest"] [build-system] requires = [ - "wheel", - "setuptools", - "setuptools_scm[toml]", - "cmake_build_extension", + "wheel", + "setuptools", + "setuptools_scm[toml]", + "cmake_build_extension", + "swig", ] build-backend = "setuptools.build_meta" @@ -48,11 +45,53 @@ zip-safe = false include-package-data = false [tool.setuptools.packages.find] -where = [ - "src", -] +where = ["src"] namespaces = false [tool.setuptools.package-dir] "" = "src" +[tool.cibuildwheel] +# manylinux-x86_64-image = "quay.io/pypa/manylinux2014_x86_64" +build-frontend = "build[uv]" +build = "cp3*-manylinux_x86_64 cp3*-macosx_x86_64 cp3*-macosx_arm64" +# test-requires = "pytest" +# test-command = "pytest {project}/src/python/" + +[tool.cibuildwheel.environment] +MACOSX_DEPLOYMENT_TARGET = 14.0 + +[tool.cibuildwheel.linux] +# repair-wheel-command = "" +# the EPEL9 package `abseil-cpp` is out of date, so we have to build `abseil-cpp` from source +before-all = """ +yum install -y gflags-devel glog-devel gtest-devel openssl-devel +git clone https://github.com/abseil/abseil-cpp.git && cd ./abseil-cpp +git checkout 20240116.2 +mkdir ./build && cd ./build +cmake -DCMAKE_CXX_STANDARD=17 -DABSL_PROPAGATE_CXX_STD=ON -DABSL_ENABLE_INSTALL=ON -DBUILD_TESTING=off .. +cmake --build . --parallel --target=install +""" + +[tool.cibuildwheel.macos] +before-all = """ +git clone https://github.com/gflags/gflags.git && cd ./gflags +mkdir ./build && cd ./build +cmake .. -DBUILD_SHARED_LIBS=OFF -DBUILD_TESTING=OFF +cmake --build . --parallel --target install +cd ../../ +git clone https://github.com/google/glog.git && cd ./glog +cmake -S . -B ./build && cd ./build +cmake --build . --parallel --target install +cd ../../ +git clone https://github.com/openssl/openssl.git && cd ./openssl +mkdir ./build && cd ./build +../Configure install +cmake --build . --parallel --target install +cd ../../ +git clone https://github.com/abseil/abseil-cpp.git && cd ./abseil-cpp +git checkout 20240116.2 +mkdir ./build && cd ./build +cmake -DCMAKE_CXX_STANDARD=17 -DABSL_PROPAGATE_CXX_STD=ON -DABSL_ENABLE_INSTALL=ON -DBUILD_TESTING=off .. +cmake --build . --parallel --target=install +""" diff --git a/setup.py b/setup.py index 242882ab..388ad49e 100644 --- a/setup.py +++ b/setup.py @@ -1,33 +1,38 @@ +import os import sys from pathlib import Path import cmake_build_extension import setuptools +# Extra options passed to the CI/CD pipeline that uses cibuildwheel +CIBW_CMAKE_OPTIONS = [] +if "CIBUILDWHEEL" in os.environ and os.environ["CIBUILDWHEEL"] == "1": + # The manylinux variant runs in Debian Stretch and it uses lib64 folder + if sys.platform == "linux": + CIBW_CMAKE_OPTIONS += ["-DCMAKE_INSTALL_LIBDIR=lib"] setuptools.setup( ext_modules=[ cmake_build_extension.CMakeExtension( - # This could be anything you like, it is used to create build folders - name="SwigBindings", - # Name of the resulting package name (import s2geometry) + name="s2geometry", install_prefix="s2geometry", - # Selects the folder where the main CMakeLists.txt is stored - # (it could be a subfolder) source_dir=str(Path(__file__).parent.absolute()), cmake_configure_options=[ - # This option points CMake to the right Python interpreter, and helps - # the logic of FindPython3.cmake to find the active version - f"-DPython3_ROOT_DIR={Path(sys.prefix)}", - '-DCALL_FROM_SETUP_PY:BOOL=ON', - '-DBUILD_SHARED_LIBS:BOOL=OFF', - '-DCMAKE_POSITION_INDEPENDENT_CODE=ON', - '-DWITH_PYTHON=ON' - ] + # This option points CMake to the right Python interpreter, and helps + # the logic of FindPython3.cmake to find the active version + # f"-DPython3_ROOT_DIR={Path(sys.prefix)}", + "-DCALL_FROM_SETUP_PY:BOOL=ON", + "-DBUILD_SHARED_LIBS:BOOL=OFF", + "-DCMAKE_POSITION_INDEPENDENT_CODE:BOOL=ON", + "-DWITH_PYTHON:BOOL=ON", + "-DBUILD_TESTS:BOOL=OFF", + ] + + CIBW_CMAKE_OPTIONS, ) ], cmdclass=dict( - # Enable the CMakeExtension entries defined above build_ext=cmake_build_extension.BuildExtension, + sdist=cmake_build_extension.GitSdistFolder, ), )