From 781a4a6b42ca71643a286234f81283d6609ffe8b Mon Sep 17 00:00:00 2001 From: Oscar Mojica Date: Tue, 27 Sep 2022 16:47:01 -0500 Subject: [PATCH] Build macos wheels (#6) * take into account the extension of the shared lib for macos * build macos wheels for PYPI * add CMake variables related to RPATH for macos * Update config.cmake * Update config.cmake * Update python.yml * set the rpath properly for macOS * upload coverage data only for ubuntu tests * Update setup.py * set INSTALL_NAME_DIR * upload coverage with verbose=true --- .github/workflows/build_wheels.yml | 4 +++- .github/workflows/python.yml | 14 ++++++++++++-- config.cmake | 29 ++++++++++++++++++++++------ sotb_wrapper/interface.py | 31 ++++++++++++++++++++++-------- 4 files changed, 61 insertions(+), 17 deletions(-) diff --git a/.github/workflows/build_wheels.yml b/.github/workflows/build_wheels.yml index d9fd97d..5e6688c 100644 --- a/.github/workflows/build_wheels.yml +++ b/.github/workflows/build_wheels.yml @@ -15,7 +15,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: [ubuntu-latest] + os: [macos-latest, ubuntu-latest] steps: - uses: actions/checkout@v3 - run: | @@ -27,6 +27,8 @@ jobs: uses: pypa/cibuildwheel@v2.3.1 env: CIBW_BUILD_VERBOSITY: 1 + CIBW_ARCHS_MACOS: x86_64 + CIBW_ENVIRONMENT_MACOS: CC=clang CXX=clang FC=gfortran-11 CIBW_ARCHS: auto64 CIBW_SKIP: skip = pp* *-musllinux* diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index 2a466ac..77a975b 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -14,14 +14,22 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu] + os: [ubuntu, macos] python_version: ["3.8", "3.9", "3.10"] include: - os: ubuntu cc: gcc-10 cxx: g++-10 fc: gfortran-10 - + - os: macos + cc: gcc-11 + cxx: g++-11 + fc: gfortran-11 + exclude: + - os: macos + python_version: "3.8" + - os: macos + python_version: "3.9" steps: - uses: actions/checkout@v3 - name: Install Python ${{ matrix.python_version }} @@ -39,6 +47,7 @@ jobs: CXX: ${{ matrix.cxx }} FC: ${{ matrix.fc }} - name: Upload coverage data + if: contains(matrix.os, 'ubuntu') uses: "actions/upload-artifact@v3" with: name: coverage-data @@ -71,4 +80,5 @@ jobs: uses: codecov/codecov-action@v3 with: files: ./coverage.xml + verbose: true diff --git a/config.cmake b/config.cmake index ceea263..0c37ad5 100644 --- a/config.cmake +++ b/config.cmake @@ -10,13 +10,30 @@ option(BUILD_SHARED_LIBS "Whether the libraries built should be shared" TRUE) if (${BUILD_SHARED_LIBS}) - file(RELATIVE_PATH relativeRpath - ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR} - ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR} - ) - set(CMAKE_INSTALL_RPATH $ORIGIN $ORIGIN/${relativeRpath}) + if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + message(STATUS "Darwin specific RPATH configuration") + if(SKBUILD) + set(CMAKE_MACOSX_RPATH FALSE) + set(CMAKE_INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/sotb_wrapper") + else() + set(CMAKE_MACOSX_RPATH TRUE) + set(CMAKE_SKIP_BUILD_RPATH FALSE) +# when building, don't use the install RPATH already +# (but later on when installing) + set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) + set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib") +# add the automatically determined parts of the RPATH +# which point to directories outside the build tree to the install RPATH + set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) + endif() + else() + file(RELATIVE_PATH relativeRpath + ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR} + ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR} + ) + set(CMAKE_INSTALL_RPATH $ORIGIN $ORIGIN/${relativeRpath}) + endif() endif() - # # Fortran compiler dependent config options # diff --git a/sotb_wrapper/interface.py b/sotb_wrapper/interface.py index 49f3912..436940c 100644 --- a/sotb_wrapper/interface.py +++ b/sotb_wrapper/interface.py @@ -4,6 +4,7 @@ import ctypes from ctypes import byref, c_float, c_int, POINTER from pathlib import Path +import sys from typing import Optional import numpy as np @@ -113,7 +114,12 @@ def __repr__(self) -> str: # Load shared library path = Path(__file__).parent name = "libsotb" -name = f"{name}.so" +if sys.platform.startswith("linux"): + name = f"{name}.so" +elif sys.platform == "darwin": + name = f"{name}.dylib" +else: + raise ImportError(f"Your OS is not supported: {sys.platform}") # This is how a dll/so library is loaded try: @@ -129,21 +135,30 @@ def __repr__(self) -> str: github_url = "https://github.com/ofmla/seiscope_opt_toolbox_w_ctypes#compiling" print() print( - "Failed to load the required SEISCOPE OPTIMIZATION TOOLBOX (sotb) " + "Failed to load the required SEISCOPE OPTIMIZATION TOOLBOX (sotb) shared" + + " library." + "\n" - + "shared library. You can likely resolve this error by building " + + "You are likely to see this message as consequence of the attempt to " + + "run the tests " + "\n" - + "the required sotb shared library on your linux system. " + + "from the local project directory (the one obtained with the clone command). " + "\n" + "\n" - + "Visit" + + "If your objective is to contribute to sotb-wrapper and you got a development " + "\n" + + "copy via `git clone` command, you must have the nox package to be able to run" + "\n" - + " " - + github_url + + "the tests from the local repository. So an immediate step after cloning the " + + "repo" + "\n" + + "is to install nox in your python environment" + "\n" - + "for instructions to build the sotb library on your linux system. " + + "\n" + + "python3 -m pip install nox" + + "\n" + + "\n" + + "You can then make changes and use the command `nox -s tests` to execute the " + + "tests session. " + "\n" ) print()