From 545b817f427db3d1b096faa676c4ac0af9be8c0b Mon Sep 17 00:00:00 2001 From: Keisuke Ishihara Date: Sat, 21 Feb 2026 23:26:19 -0500 Subject: [PATCH 1/3] Fix macOS arm64 installation - setup.py: pass -DCMAKE_POLICY_VERSION_MINIMUM=3.5 to cmake so the bundled pybind11 v2.9.2 (cmake_minimum_required VERSION 3.4) works with CMake 4.x, which dropped compatibility below 3.5 - CMakeLists.txt: detect Homebrew's libomp early (before any add_subdirectory) and set OpenMP hint variables as CACHE entries; this lets both LibAPR and the pyapr wrapper find OpenMP on macOS where Apple Clang does not bundle it - build-deploy.yml: add macos-14 (arm64) runner alongside macos-13 (Intel); replace hardcoded /usr/local/opt/llvm paths with $(brew --prefix llvm) so CI works on both architectures; extend CIBW_BUILD to cp39-cp313 (drop EOL 3.8); bump actions/cache, upload-artifact, download-artifact to v4 and setup-python to v5 - setup.cfg: add Python 3.12 and 3.13 classifiers, remove 3.8 Co-Authored-By: Claude Sonnet 4.6 --- .github/workflows/build-deploy.yml | 45 +++++++++++++++++++----------- CMakeLists.txt | 25 +++++++++++++++++ setup.cfg | 3 +- setup.py | 3 ++ 4 files changed, 58 insertions(+), 18 deletions(-) diff --git a/.github/workflows/build-deploy.yml b/.github/workflows/build-deploy.yml index c13decad..3a29ed74 100644 --- a/.github/workflows/build-deploy.yml +++ b/.github/workflows/build-deploy.yml @@ -28,7 +28,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-latest, windows-latest] + os: [ubuntu-latest, macos-13, macos-14, windows-latest] include: - os: windows-latest triplet: x64-windows @@ -36,18 +36,22 @@ jobs: - os: ubuntu-latest triplet: x64-linux builddir: wheelhouse - - os: macos-latest + - os: macos-13 triplet: x64-osx builddir: wheelhouse + cibw_archs: x86_64 + - os: macos-14 + triplet: arm64-osx + builddir: wheelhouse + cibw_archs: arm64 env: # Indicates the CMake build directory where project files and binaries are being produced. CMAKE_BUILD_DIR: ${{ github.workspace }}/builddir/ # Indicates the location of the vcpkg as a Git submodule of the project repository. VCPKG_ROOT: ${{ github.workspace }}/external/LibAPR/vcpkg CIBW_ENVIRONMENT_WINDOWS: EXTRA_CMAKE_ARGS="-DCMAKE_TOOLCHAIN_FILE=D:\\a\\pyapr\\pyapr\\external\\LibAPR\\vcpkg\\scripts\\buildsystems\\vcpkg.cmake -DVCPKG_MANIFEST_DIR=D:\\a\\pyapr\\pyapr\\external\\LibAPR\\" - CIBW_BUILD: "cp38-* cp39-* cp310-* cp311-*" + CIBW_BUILD: "cp39-* cp310-* cp311-* cp312-* cp313-*" CIBW_SKIP: "*musllinux*" - CIBW_ARCHS: "auto64" CIBW_BUILD_VERBOSITY: 1 CIBW_REPAIR_WHEEL_COMMAND_MACOS: "pip install -U delocate && delocate-listdeps {wheel} && delocate-wheel -w {dest_dir} -v {wheel}" CIBW_REPAIR_WHEEL_COMMAND_WINDOWS: "pip install -U wheel delvewheel && python fix_windows_wheel.py {wheel} {dest_dir}" @@ -55,7 +59,12 @@ jobs: CIBW_TEST_COMMAND: "python3 -m pytest -vv {project}/pyapr/tests" CIBW_TEST_SKIP: "*-win_amd64" # windows tests are run separately CIBW_BEFORE_BUILD_LINUX: "yum makecache && yum install -y libtiff-devel hdf5-devel" - CIBW_ENVIRONMENT_MACOS: CPPFLAGS="-I/usr/local/opt/llvm/include" LDFLAGS="-L/usr/local/opt/llvm/lib -Wl,-rpath,/usr/local/opt/llvm/lib" CXX="/usr/local/opt/llvm/bin/clang++" CC="/usr/local/opt/llvm/bin/clang" + # Use $(brew --prefix llvm) so the path works on both Intel (macos-13) and arm64 (macos-14) runners. + CIBW_ENVIRONMENT_MACOS: > + CPPFLAGS="-I$(brew --prefix llvm)/include" + LDFLAGS="-L$(brew --prefix llvm)/lib -Wl,-rpath,$(brew --prefix llvm)/lib" + CXX="$(brew --prefix llvm)/bin/clang++" + CC="$(brew --prefix llvm)/bin/clang" steps: - uses: actions/checkout@v4 @@ -67,12 +76,12 @@ jobs: run: | git submodule update --init --recursive git status - + # Setup the build machine with the most recent versions of CMake and Ninja. Both are cached if not already: on subsequent runs both will be quickly restored from GitHub cache service. - uses: lukka/get-cmake@latest # Restore both vcpkg and its artifacts from the GitHub cache service. - name: Restore vcpkg and its artifacts. - uses: actions/cache@v3 + uses: actions/cache@v4 with: # The first path is where vcpkg generates artifacts while consuming the vcpkg.json manifest file. # The second path is the location of vcpkg (it contains the vcpkg executable and data files). @@ -101,16 +110,16 @@ jobs: # On Windows runners, let's ensure to have the Developer Command Prompt environment setup correctly. As used here the Developer Command Prompt created is targeting x64 and using the default the Windows SDK. - uses: ilammy/msvc-dev-cmd@v1 - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 name: Install Python with: - python-version: '3.9' + python-version: '3.12' - name: Install cibuildwheel run: | python3 -m pip install cibuildwheel - - name: Install OpenMP dependencies with brew for OSX + - name: Install OpenMP dependencies with brew for macOS if: contains(matrix.os,'macos') run: | brew install llvm @@ -119,12 +128,14 @@ jobs: brew install hdf5 - name: Run cibuildwheel + env: + CIBW_ARCHS: ${{ matrix.cibw_archs || 'auto64' }} run: | git status python3 -m cibuildwheel --output-dir ${{matrix.builddir}} - name: Upload wheels as artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: ${{ matrix.os }}-wheels path: ${{matrix.builddir}}/ @@ -138,7 +149,7 @@ jobs: fail-fast: false matrix: os: [ windows-latest ] - python-version: ['3.8', '3.9', '3.10', '3.11'] + python-version: ['3.9', '3.10', '3.11', '3.12', '3.13'] steps: - name: Checkout @@ -147,12 +158,12 @@ jobs: submodules: false - name: Set up Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - name: Download wheels from artifacts - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: ${{ matrix.os }}-wheels path: wheelhouse @@ -182,14 +193,14 @@ jobs: if: contains(github.ref, 'tags') steps: - name: Download wheels from artifacts - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: path: wheelhouse - name: Set up Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: - python-version: '3.9' + python-version: '3.12' - name: Install dependencies run: | diff --git a/CMakeLists.txt b/CMakeLists.txt index d73f9e2a..7c5fd974 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,6 +9,31 @@ option(PYAPR_USE_OPENMP "Use OpenMP for PyAPR functionality" ON) option(PYAPR_USE_CUDA "Use CUDA for PyAPR functionality" OFF) option(PYAPR_PREFER_EXTERNAL_LIBAPR "Use installed LibAPR rather than building from submodules" OFF) +############################################################################### +# macOS: hint OpenMP to Homebrew's libomp BEFORE any subdirectories so that +# both LibAPR and the pyapr wrapper can find it. Apple Clang does not bundle +# OpenMP; Homebrew's libomp provides it on both Intel and arm64 Macs. +############################################################################### +if(APPLE AND PYAPR_USE_OPENMP) + find_program(BREW_EXECUTABLE brew) + if(BREW_EXECUTABLE) + execute_process( + COMMAND ${BREW_EXECUTABLE} --prefix libomp + OUTPUT_VARIABLE LIBOMP_PREFIX + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_QUIET + ) + if(LIBOMP_PREFIX AND EXISTS "${LIBOMP_PREFIX}") + message(STATUS "PyAPR: Found Homebrew libomp at ${LIBOMP_PREFIX}") + set(OpenMP_C_FLAGS "-Xpreprocessor -fopenmp -I${LIBOMP_PREFIX}/include" CACHE STRING "" FORCE) + set(OpenMP_CXX_FLAGS "-Xpreprocessor -fopenmp -I${LIBOMP_PREFIX}/include" CACHE STRING "" FORCE) + set(OpenMP_C_LIB_NAMES "omp" CACHE STRING "" FORCE) + set(OpenMP_CXX_LIB_NAMES "omp" CACHE STRING "" FORCE) + set(OpenMP_omp_LIBRARY "${LIBOMP_PREFIX}/lib/libomp.dylib" CACHE FILEPATH "" FORCE) + endif() + endif() +endif() + ##------------- Required libraries -------------## find_package(HDF5 REQUIRED) find_package(ZLIB REQUIRED) diff --git a/setup.cfg b/setup.cfg index 7a287fb8..493d7fc5 100644 --- a/setup.cfg +++ b/setup.cfg @@ -12,10 +12,11 @@ classifiers = Intended Audience :: Developers License :: OSI Approved :: Apache Software License Programming Language :: Python :: 3 - Programming Language :: Python :: 3.8 Programming Language :: Python :: 3.9 Programming Language :: Python :: 3.10 Programming Language :: Python :: 3.11 + Programming Language :: Python :: 3.12 + Programming Language :: Python :: 3.13 Topic :: Scientific/Engineering Topic :: Scientific/Engineering :: Image Processing diff --git a/setup.py b/setup.py index 12c4a9a7..2f41f157 100644 --- a/setup.py +++ b/setup.py @@ -48,6 +48,9 @@ def build_extension(self, ext): "-DCMAKE_LIBRARY_OUTPUT_DIRECTORY={}".format(extdir), "-DPython_EXECUTABLE={}".format(sys.executable), "-DCMAKE_BUILD_TYPE={}".format(build_type), # not used on MSVC, but no harm + # Allow old pybind11 submodule (cmake_minimum_required VERSION 3.4) + # to work with CMake 4.x which dropped <3.5 compat. + "-DCMAKE_POLICY_VERSION_MINIMUM=3.5", ] # Pass CMake arguments via the environment variable 'EXTRA_CMAKE_ARGS' From d7912a897885b2b982d50fdb7850f7801953edf6 Mon Sep 17 00:00:00 2001 From: Keisuke Ishihara Date: Sun, 22 Feb 2026 10:33:12 -0500 Subject: [PATCH 2/3] Pin cmake to 3.x in quick-test.yml to fix vcpkg build failure CMake 4.x (now delivered by lukka/get-cmake@latest) is incompatible with the old vcpkg submodule in external/LibAPR/vcpkg, causing lz4 (a blosc dependency) to fail during package installation. Co-Authored-By: Claude Sonnet 4.6 --- .github/workflows/quick-test.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/quick-test.yml b/.github/workflows/quick-test.yml index 602dc2d4..1da20d45 100644 --- a/.github/workflows/quick-test.yml +++ b/.github/workflows/quick-test.yml @@ -46,7 +46,10 @@ jobs: run: git submodule update --init --recursive # Setup the build machine with the most recent versions of CMake and Ninja. Both are cached if not already: on subsequent runs both will be quickly restored from GitHub cache service. + # Pin to CMake 3.x: the vcpkg submodule in LibAPR is too old to work with CMake 4.x - uses: lukka/get-cmake@latest + with: + cmakeVersion: "~3.31.0" # Restore both vcpkg and its artifacts from the GitHub cache service. - name: Restore vcpkg and its artifacts. uses: actions/cache@v3 From b2355edae602c7cbec71650fbcbce8764c26e2d0 Mon Sep 17 00:00:00 2001 From: Keisuke Ishihara Date: Mon, 23 Feb 2026 10:52:22 -0500 Subject: [PATCH 3/3] Restore Python 3.8 support Re-add cp38 to CIBW_BUILD, add 3.8 back to the Windows test matrix, and restore the 3.8 classifier in setup.cfg. Co-Authored-By: Claude Sonnet 4.6 --- .github/workflows/build-deploy.yml | 4 ++-- setup.cfg | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-deploy.yml b/.github/workflows/build-deploy.yml index 3a29ed74..62ce5327 100644 --- a/.github/workflows/build-deploy.yml +++ b/.github/workflows/build-deploy.yml @@ -50,7 +50,7 @@ jobs: # Indicates the location of the vcpkg as a Git submodule of the project repository. VCPKG_ROOT: ${{ github.workspace }}/external/LibAPR/vcpkg CIBW_ENVIRONMENT_WINDOWS: EXTRA_CMAKE_ARGS="-DCMAKE_TOOLCHAIN_FILE=D:\\a\\pyapr\\pyapr\\external\\LibAPR\\vcpkg\\scripts\\buildsystems\\vcpkg.cmake -DVCPKG_MANIFEST_DIR=D:\\a\\pyapr\\pyapr\\external\\LibAPR\\" - CIBW_BUILD: "cp39-* cp310-* cp311-* cp312-* cp313-*" + CIBW_BUILD: "cp38-* cp39-* cp310-* cp311-* cp312-* cp313-*" CIBW_SKIP: "*musllinux*" CIBW_BUILD_VERBOSITY: 1 CIBW_REPAIR_WHEEL_COMMAND_MACOS: "pip install -U delocate && delocate-listdeps {wheel} && delocate-wheel -w {dest_dir} -v {wheel}" @@ -149,7 +149,7 @@ jobs: fail-fast: false matrix: os: [ windows-latest ] - python-version: ['3.9', '3.10', '3.11', '3.12', '3.13'] + python-version: ['3.8', '3.9', '3.10', '3.11', '3.12', '3.13'] steps: - name: Checkout diff --git a/setup.cfg b/setup.cfg index 493d7fc5..ebd28284 100644 --- a/setup.cfg +++ b/setup.cfg @@ -12,6 +12,7 @@ classifiers = Intended Audience :: Developers License :: OSI Approved :: Apache Software License Programming Language :: Python :: 3 + Programming Language :: Python :: 3.8 Programming Language :: Python :: 3.9 Programming Language :: Python :: 3.10 Programming Language :: Python :: 3.11