diff --git a/.github/workflows/build-deploy.yml b/.github/workflows/build-deploy.yml index c13deca..62ce532 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: "cp38-* 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.8', '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/.github/workflows/quick-test.yml b/.github/workflows/quick-test.yml index 602dc2d..1da20d4 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 diff --git a/CMakeLists.txt b/CMakeLists.txt index d73f9e2..7c5fd97 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 7a287fb..ebd2828 100644 --- a/setup.cfg +++ b/setup.cfg @@ -16,6 +16,8 @@ classifiers = 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 12c4a9a..2f41f15 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'