Skip to content

Commit

Permalink
MAINT: Switch to abi3 mode and unify before_all (openmeeg#708)
Browse files Browse the repository at this point in the history
  • Loading branch information
larsoner authored Dec 13, 2024
1 parent 4cf760b commit 60f5981
Show file tree
Hide file tree
Showing 14 changed files with 252 additions and 235 deletions.
53 changes: 36 additions & 17 deletions .github/workflows/build_and_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ env:

defaults:
run:
shell: bash -el {0}
shell: bash -o pipefail -el {0}

jobs:

Expand Down Expand Up @@ -61,6 +61,11 @@ jobs:
python: cmake
windows_compiler: msvc
slow: false
- os: macos-15
blas: OpenBLAS
blas_linking: dynamic
python: cmake
slow: false
- os: macos-13
blas: OpenBLAS
blas_linking: dynamic
Expand Down Expand Up @@ -93,9 +98,6 @@ jobs:
blas_linking: static
- os: ubuntu-20.04
blas: mkl-findblas
- os: macos-13
blas: mkl-findblas # only available on Intel
blas_linking: static
# One without Python but with VTK (once we fix it!)
- os: ubuntu-22.04
python: no-python
Expand Down Expand Up @@ -265,7 +267,7 @@ jobs:
pip install --upgrade --pre --only-binary ":all:" "numpy>=2.0.0rc1,<3"
fi
fi
pip install --upgrade --progress-bar off --only-binary="numpy" -q setuptools setuptools_scm wheel twine threadpoolctl $EXTRA_PIP
pip install --upgrade --progress-bar off --only-binary="numpy" -q setuptools setuptools_scm wheel twine threadpoolctl "swig>=4.2" $EXTRA_PIP
- name: MKL setup - mkl via conda
Expand Down Expand Up @@ -344,12 +346,14 @@ jobs:
if: startswith(steps.env-vars.outputs.os,'macos')
run: |
echo "Installing dependencies with brew"
brew update > /dev/null
echo "::group::brew update"
brew update
echo "::endgroup::"
if [[ "${{steps.env-vars.outputs.blas}}" == "OpenBLAS" ]]; then
BREW_EXTRA=openblas
fi
echo "Installing dependencies with brew"
HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 HOMEBREW_NO_AUTO_UPDATE=1 brew install hdf5 libmatio libomp swig $BREW_EXTRA
HOMEBREW_NO_AUTO_UPDATE=1 brew install hdf5 libmatio libomp swig zlib $BREW_EXTRA
echo "brew install complete"
if [[ "${{steps.env-vars.outputs.blas}}" == "OpenBLAS" ]]; then
if [[ "$(arch)" == "arm64" ]]; then
Expand Down Expand Up @@ -564,26 +568,40 @@ jobs:
python setup.py bdist_wheel sdist
echo "Wheels:"
ls -alR dist/*.whl
unzip dist/*.whl -d check
FNAME=$(ls dist/*.whl)
echo "Processing $FNAME"
test -n "$FNAME"
test -f "$FNAME"
unzip "$FNAME" -d check
echo "Contents before:"
ls -alR check/*
if [[ ${{steps.env-vars.outputs.os}} == 'windows'* ]]; then
PATH="$(cygpath -w $PWD/openmeeg);$PATH" delvewheel show dist/*.whl
PATH="$(cygpath -w $PWD/openmeeg);$PATH" delvewheel repair $DELVEWHEEL_ADD_DLL -w dist dist/*.whl
PATH="$(cygpath -w $PWD/openmeeg);$PATH" delvewheel show "$FNAME"
PATH="$(cygpath -w $PWD/openmeeg);$PATH" delvewheel repair $DELVEWHEEL_ADD_DLL -w dist "$FNAME"
elif [[ ${{steps.env-vars.outputs.os}} == 'macos'* ]]; then
delocate-wheel -v dist/*.whl
delocate-listdeps --all dist/*.whl
length=${#FNAME}
ORIG_FNAME="${FNAME::length-4}.orig"
cp -a "$FNAME" "$ORIG_FNAME"
# TODO: This is broken for our abi3 wheel
# delocate-wheel -v "$FNAME"
# This can change thename of the wheel so we need to re-find it
FNAME=$(ls dist/*.whl)
test -f "$FNAME"
mv "$ORIG_FNAME" "${ORIG_FNAME}.whl"
delocate-listdeps --all "$FNAME"
# This build uses a toolchain that is too new, so skip this on Linux
# else
# auditwheel show dist/*.whl
# auditwheel repair dist/*.whl
# auditwheel show "$FNAME"
# auditwheel repair "$FNAME"
# FNAME=$(ls dist/*.whl)
# test -f "$FNAME"
fi
rm -Rf check
unzip dist/*.whl -d check
unzip "$FNAME" -d check
echo "Contents after:"
ls -alR check/*
twine check dist/*
pip install dist/*.whl --force-reinstall
pip install "$FNAME" --force-reinstall
if [[ "${{ steps.env-vars.outputs.numpy_version }}" == "oldest" ]]; then
pip install --only-binary "numpy" "numpy<2"
fi
Expand All @@ -597,7 +615,7 @@ jobs:
fi
- name: Upload wrapped Python lib
if: startswith(steps.env-vars.outputs.python, 'python')
if: startswith(steps.env-vars.outputs.python, 'python') && (success() || failure())
uses: actions/upload-artifact@v4
with:
name: wrapping_${{ steps.env-vars.outputs.os }}_${{ steps.env-vars.outputs.python_type }}_${{ steps.env-vars.outputs.blas }}_${{ steps.env-vars.outputs.blas_linking }}_${{ steps.env-vars.outputs.windows_compiler }}_${{ steps.env-vars.outputs.python_version }}_${{ steps.env-vars.outputs.numpy_version }}
Expand All @@ -621,3 +639,4 @@ jobs:
if: startsWith(steps.env-vars.outputs.os,'ubuntu')
with:
files: coverage.info
token: ${{ secrets.CODECOV_TOKEN }}
6 changes: 3 additions & 3 deletions .github/workflows/cibuildwheel_apps.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,11 @@ jobs:
output-dir: installers
env:
CIBW_ENVIRONMENT_LINUX: ""
CIBW_ENVIRONMENT_MACOS: "OPENMEEG_MACOS_WHEEL_PURE=false"
CIBW_ENVIRONMENT_MACOS: ""
CIBW_ENVIRONMENT_WINDOWS: ""
CIBW_BUILD: "cp310-*"
CIBW_BUILD: "cp310-*" # same as default, but just in case we add PyPy in the future
CIBW_BUILD_FRONTEND: "pip"
CIBW_BEFORE_ALL: "bash {project}/build_tools/cibw_before_all_apps.sh {project}"
CIBW_BEFORE_ALL: "bash {project}/build_tools/cibw_before_all.sh {project} app"
CIBW_BEFORE_BUILD_WINDOWS: ""
CIBW_REPAIR_WHEEL_COMMAND_LINUX: ""
CIBW_REPAIR_WHEEL_COMMAND_MACOS: ""
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ jobs:
gcc --version
- name: Install NumPy
run: |
pip install --upgrade --user --pre "numpy>=2.0.0b1,<3" setuptools setuptools_scm
pip install --upgrade --user --pre "numpy>=2.0.0b1,<3" setuptools setuptools_scm "swig>=4.2"
- name: Configure
run: |
export DISABLE_CCACHE=1
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,5 @@ coverage.info
.vscode/
Testing/
.ccache/
installers/
wheelhouse/
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
cmake_minimum_required (VERSION 3.14)
project (OpenMEEG VERSION 2.5.12 LANGUAGES C CXX)
project (OpenMEEG VERSION 2.5.13 LANGUAGES C CXX)

set(CMAKE_CXX_STANDARD 17) # use c++17

Expand Down
166 changes: 136 additions & 30 deletions build_tools/cibw_before_all.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,22 @@ if [[ "$1" == "" ]]; then
echo "Usage: $0 <PROJECT_PATH>"
exit 1
fi
KIND=$2
if [[ "$KIND" == "" ]]; then
KIND=wheel
fi
if [[ "$KIND" != "wheel" ]] && [[ "$KIND" != "app" ]]; then
echo "Usage $0 <PROJECT_PATH> <KIND>"
echo "Got KIND=\"$KIND\", should be \"wheel\" or \"app\""
exit 1
fi
cd $1
ROOT=$(pwd)
echo "Using project root \"${ROOT}\" on RUNNER_OS=\"${RUNNER_OS}\""
if [ -z "$RUNNER_OS" ]; then
echo "RUNNER_OS is empty, it must be present in the environment"
exit 1
fi
echo "Using project root \"${ROOT}\" on RUNNER_OS=\"${RUNNER_OS}\" to set up KIND=\"$KIND\""

# Let's have NumPy help us out
if [[ "$RUNNER_OS" == "macOS" ]] && [[ $(uname -m) == 'arm64' ]]; then
Expand All @@ -29,8 +42,11 @@ rm -Rf numpy numpy-1.23.1 tools
echo "Using NumPy PLATFORM=\"${PLATFORM}\""
git config --global --add safe.directory "$ROOT"
git checkout LICENSE.txt # This file is modified by NumPy
if [[ "$KIND" == "app" ]]; then
rm -Rf .ccache gfortran.dmg gfortran-darwin-arm64.tar.gz openblas-v*.zip
fi
git status --porcelain --untracked-files=no
test -z "$(git status --porcelain --untracked-files=no)"
test -z "$(git status --porcelain --untracked-files=no)" || test "$CHECK_PORCELAIN" == "false"

# PLATFORM can be:
# linux-x86_64
Expand All @@ -40,15 +56,31 @@ test -z "$(git status --porcelain --untracked-files=no)"
# win-amd64

if [[ "$PLATFORM" == 'linux-'* ]]; then
echo "::group::yum"
rpm --import https://repo.almalinux.org/almalinux/RPM-GPG-KEY-AlmaLinux
yum -y install epel-release
yum -y install hdf5-devel matio-devel
export OPENBLAS_INCLUDE=/usr/local/include
export OPENBLAS_LIB=/usr/local/lib
yum -y install hdf5-devel matio-devel curl zip unzip tar ninja-build
echo "::endgroup::"
BLAS_DIR=/usr/local
export OPENBLAS_INCLUDE=$BLAS_DIR/include
export OPENBLAS_LIB=$BLAS_DIR/lib
export CMAKE_CXX_FLAGS="-I$OPENBLAS_INCLUDE"
export LINKER_OPT="-lgfortran -lpthread"
export DISABLE_CCACHE=1
SHARED_OPT="-DBUILD_SHARED_LIBS=OFF"
if [[ "$KIND" == "app" ]]; then
if [[ "$PLATFORM" == "linux-x86_64" ]]; then
export VCPKG_DEFAULT_TRIPLET="x64-linux"
elif [[ "$PLATFORM" == "linux-aarch64" ]]; then
export VCPKG_DEFAULT_TRIPLET="arm64-linux"
else
echo "Unknown PLATFORM=\"$PLATFORM\""
exit 1
fi
source ./build_tools/setup_vcpkg_compilation.sh
LAPACK_LIBRARIES_OPT="-DLAPACK_LIBRARIES=/usr/local/lib/libopenblas.a"
LIBDIR_OPT="-DCMAKE_INSTALL_LIBDIR=lib"
fi
elif [[ "$PLATFORM" == 'macosx-'* ]]; then
BLAS_DIR=/usr/local
OPENBLAS_INCLUDE=$BLAS_DIR/include
Expand All @@ -57,60 +89,134 @@ elif [[ "$PLATFORM" == 'macosx-'* ]]; then
export CMAKE_PREFIX_PATH="$BLAS_DIR"
export LINKER_OPT="-L$OPENBLAS_LIB"
if [[ "$PLATFORM" == "macosx-x86_64" ]]; then
export VCPKG_DEFAULT_TRIPLET="x64-osx-release-10.15"
export SYSTEM_VERSION_OPT="-DCMAKE_OSX_DEPLOYMENT_TARGET=10.15"
VC_NAME="x64"
MIN_VER="10.15"
LIBGFORTRAN="/usr/local/gfortran/lib/libgfortran.3.dylib"
elif [[ "$PLATFORM" == "macosx-arm64" ]]; then
export VCPKG_DEFAULT_TRIPLET="arm64-osx-release-11.0"
export SYSTEM_VERSION_OPT="-DCMAKE_OSX_DEPLOYMENT_TARGET=11.0"
VC_NAME="arm64"
MIN_VER="11.0"
LIBGFORTRAN="$(find /opt/gfortran-darwin-arm64/lib -name libgfortran.dylib)"
else
echo "Unknown PLATFORM=\"$PLATFORM\""
exit 1
fi
export VCPKG_DEFAULT_TRIPLET="${VC_NAME}-osx-release-${MIN_VER}"
export SYSTEM_VERSION_OPT="-DCMAKE_OSX_DEPLOYMENT_TARGET=${MIN_VER}"
source ./build_tools/setup_vcpkg_compilation.sh
# libomp can cause segfaults on macos... maybe from version conflicts with OpenBLAS, or from being too recent?
export OPENMP_OPT="-DUSE_OPENMP=OFF"
# need SWIG for Python bindings
brew install swig
if [[ "$KIND" == "app" ]]; then
GFORTRAN_LIB=$(dirname $LIBGFORTRAN)
GFORTRAN_NAME=$(basename $LIBGFORTRAN)
sudo chmod -R a+w $GFORTRAN_LIB
otool -L $LIBGFORTRAN
install_name_tool -id "@rpath/${GFORTRAN_NAME}" $LIBGFORTRAN
LIBRARIES_INSTALL_OPT="-DEXTRA_INSTALL_LIBRARIES=$LIBGFORTRAN"
if [[ "$PLATFORM" == "macosx-x86_64" ]]; then
PACKAGE_ARCH_SUFFIX="_Intel"
install_name_tool -change "${GFORTRAN_LIB}/libgcc_s.1.dylib" "@rpath/libgcc_s.1.dylib" ${LIBGFORTRAN}
install_name_tool -change "${GFORTRAN_LIB}/libquadmath.0.dylib" "@rpath/libquadmath.0.dylib" ${LIBGFORTRAN}
LIBRARIES_INSTALL_OPT="$LIBRARIES_INSTALL_OPT;$GFORTRAN_LIB/libgcc_s.1.dylib;$GFORTRAN_LIB/libquadmath.0.dylib"
else
PACKAGE_ARCH_SUFFIX="_M1"
install_name_tool -change "${GFORTRAN_LIB}/libgcc_s.2.dylib" "@rpath/libgcc_s.2.dylib" ${LIBGFORTRAN}
LIBRARIES_INSTALL_OPT="$LIBRARIES_INSTALL_OPT;$GFORTRAN_LIB/libgcc_s.2.dylib"
# Doesn't seem like this should be necessary but it is for the arm64 build
codesign --force -s - $GFORTRAN_LIB/libgcc_s.2.dylib
fi
# Need to fix the now-broken signature via ad-hoc signing (at least on arm)
# https://github.com/matthew-brett/delocate/blob/de38e09acd86b27c795c3d342d132031c45b1aff/delocate/tools.py#L660
codesign --force -s - $LIBGFORTRAN
# Set LINKER_OPT after vckpg_compilation.sh because it also sets LINKER_OPT
export LINKER_OPT="$LINKER_OPT -lgfortran -L$GFORTRAN_LIB"
PACKAGE_ARCH_OPT="-DPACKAGE_ARCH_SUFFIX=$PACKAGE_ARCH_SUFFIX"
fi
elif [[ "$PLATFORM" == "win-amd64" ]]; then
export VCPKG_DEFAULT_TRIPLET="x64-windows-release-static"
export CMAKE_GENERATOR="Visual Studio 17 2022"
source ./build_tools/setup_vcpkg_compilation.sh
source ./build_tools/download_openblas.sh windows # NumPy doesn't install the headers for Windows
pip install delvewheel "pefile!=2024.8.26"
export SYSTEM_VERSION_OPT="-DCMAKE_SYSTEM_VERSION=7"
if [[ "$KIND" == "app" ]]; then
OPENBLAS_DLL=$(ls $OPENBLAS_LIB/libopenblas*.dll)
echo "OPENBLAS_DLL=\"${OPENBLAS_DLL}\""
test -f $OPENBLAS_DLL
LIBRARIES_INSTALL_OPT="-DEXTRA_INSTALL_LIBRARIES=$(cygpath -m ${OPENBLAS_DLL})"
fi
else
echo "Unknown platform: ${PLATFORM}"
exit 1
fi
export PYTHON_OPT="-DENABLE_PYTHON=OFF"
export BLA_IMPLEMENTATION="OpenBLAS"
export WERROR_OPT="-DENABLE_WERROR=ON"
pip install cmake
./build_tools/cmake_configure.sh -DCMAKE_VERBOSE_MAKEFILE=ON -DCMAKE_INSTALL_PREFIX=${ROOT}/install ${CMAKE_PREFIX_PATH_OPT} -DENABLE_APPS=OFF ${SHARED_OPT} -DCMAKE_INSTALL_UCRT_LIBRARIES=TRUE ${BLAS_LIBRARIES_OPT} ${LAPACK_LIBRARIES_OPT}
cmake --build build --target install --target package --config release
echo "::group::pip"
pip install --upgrade cmake "swig>=4.2"
echo "::endgroup::"
if [[ "${KIND}" == "wheel" ]]; then
./build_tools/cmake_configure.sh -DCMAKE_VERBOSE_MAKEFILE=ON -DCMAKE_INSTALL_PREFIX=${ROOT}/install ${CMAKE_PREFIX_PATH_OPT} -DENABLE_APPS=OFF ${SHARED_OPT} -DCMAKE_INSTALL_UCRT_LIBRARIES=TRUE ${BLAS_LIBRARIES_OPT} ${LAPACK_LIBRARIES_OPT}
echo "::group::cmake --build"
cmake --build build --target install --target package --config release
echo "::endgroup::"
else
export BLA_STATIC_OPT="-DBLA_STATIC=ON"
./build_tools/cmake_configure.sh -DCMAKE_WARN_DEPRECATED=FALSE -DCMAKE_VERBOSE_MAKEFILE=ON -DCMAKE_INSTALL_PREFIX=${ROOT}/install ${LIBDIR_OPT} ${LIBRARIES_INSTALL_OPT} ${PACKAGE_ARCH_OPT} ${CMAKE_PREFIX_PATH_OPT} -DENABLE_APPS=ON ${SHARED_OPT} -DCMAKE_INSTALL_UCRT_LIBRARIES=TRUE ${BLAS_LIBRARIES_OPT} ${LAPACK_LIBRARIES_OPT}
echo "::group::cmake --build"
cmake --build build --config release
if [[ "${PLATFORM}" == 'macosx-'* ]]; then
for name in OpenMEEG OpenMEEGMaths; do
install_name_tool -change "${LIBGFORTRAN}" "@rpath/${GFORTRAN_NAME}" ./build/${name}/lib${name}.1.1.0.dylib
done
fi
echo "::endgroup::"
echo "::group::cmake --target package"
cmake --build build --target package --target install --config release
mkdir -p installers
cp -av build/OpenMEEG-*-*.* installers/
echo "::endgroup::"
fi

# Put DLLs where they can be found
if [[ "$PLATFORM" == 'linux'* ]]; then
ls -al install/lib64/*.so*
cp -av install/lib64/*.so* /usr/local/lib/
elif [[ "$PLATFORM" == 'macosx-arm64' ]]; then
# https://matthew-brett.github.io/docosx/mac_runtime_link.html
#cp -av $ROOT/vcpkg_installed/arm64-osx-release-11.0/lib/libomp* $ROOT/install/lib/
otool -L $ROOT/install/lib/libOpenMEEG.1.1.0.dylib
# install_name_tool -change "@@HOMEBREW_PREFIX@@/opt/libomp/lib/libomp.dylib" "@loader_path/libomp.dylib" $ROOT/install/lib/libOpenMEEG.1.1.0.dylib
# otool -L $ROOT/install/lib/libOpenMEEG.1.1.0.dylib
mkdir -p /output
if [[ "$KIND" == "wheel" ]]; then
ls -al install/lib64/*.so*
cp -av install/lib64/*.so* /usr/local/lib/
else
cp -av build/OpenMEEG-*-*.* /output/
fi
elif [[ "$PLATFORM" == 'macosx-'* ]]; then
if [[ "$KIND" == "app" ]]; then
otool -L $ROOT/build/OpenMEEG/libOpenMEEG.1.1.0.dylib
otool -L $ROOT/install/lib/libgfortran*.dylib
else
if [[ "$PLATFORM" == 'macosx-arm64' ]]; then
# https://matthew-brett.github.io/docosx/mac_runtime_link.html
#cp -av $ROOT/vcpkg_installed/arm64-osx-release-11.0/lib/libomp* $ROOT/install/lib/
otool -L $ROOT/install/lib/libOpenMEEG.1.1.0.dylib
# install_name_tool -change "@@HOMEBREW_PREFIX@@/opt/libomp/lib/libomp.dylib" "@loader_path/libomp.dylib" $ROOT/install/lib/libOpenMEEG.1.1.0.dylib
# otool -L $ROOT/install/lib/libOpenMEEG.1.1.0.dylib
fi
fi
elif [[ "$PLATFORM" == 'win'* ]]; then
cp -av $OPENBLAS_LIB/libopenblas_v0.3.20-140-gbfd9c1b5-gcc_8_1_0.dll install/bin/
if [[ "$KIND" == "wheel" ]]; then
cp -av $OPENBLAS_LIB/libopenblas_v0.3.20-140-gbfd9c1b5-gcc_8_1_0.dll install/bin/
else
./build_tools/install_dependency_walker.sh
fi
fi

# TODO: This is only necessary because SWIG does not work outside cmake yet,
# and we want this on windows
if [[ "$PLATFORM" == 'win'* ]]; then
mv build build_nopython
if [[ "$KIND" == "wheel" ]]; then
# TODO: This is only necessary because SWIG does not work outside cmake yet,
# and we want this on windows
if [[ "$PLATFORM" == 'win'* ]]; then
mv build build_nopython
fi
echo "ls -al $PWD:"
ls -al
fi
echo "ls -al $PWD:"
ls -al

echo "git status:"
git status --porcelain --untracked-files=no
test -z "$(git status --porcelain --untracked-files=no)"
test -z "$(git status --porcelain --untracked-files=no)" || test "$CHECK_PORCELAIN" == "false"
Loading

0 comments on commit 60f5981

Please sign in to comment.