Skip to content

Commit

Permalink
[ci] [python-package] add arm64 macOS wheels (#6391)
Browse files Browse the repository at this point in the history
  • Loading branch information
jameslamb authored Jun 14, 2024
1 parent 4e74403 commit ad1237d
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 8 deletions.
8 changes: 3 additions & 5 deletions .ci/lint-python.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,9 @@

set -e -E -u -o pipefail

# this can be re-enabled when this is fixed:
# https://github.com/tox-dev/filelock/issues/337
# echo "running pre-commit checks"
# pre-commit run --all-files || exit 1
# echo "done running pre-commit checks"
echo "running pre-commit checks"
pre-commit run --all-files || exit 1
echo "done running pre-commit checks"

echo "running mypy"
mypy \
Expand Down
3 changes: 1 addition & 2 deletions .ci/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -174,8 +174,7 @@ elif [[ $TASK == "bdist" ]]; then
if [[ $ARCH == "x86_64" ]]; then
PLATFORM="macosx_10_15_x86_64.macosx_11_6_x86_64.macosx_12_5_x86_64"
else
echo "ERROR: macos wheels not supported yet on architecture '${ARCH}'"
exit 1
PLATFORM="macosx_14_0_arm64"
fi
mv \
./dist/tmp.whl \
Expand Down
16 changes: 15 additions & 1 deletion .github/workflows/python_package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ jobs:
python_version: '3.8'
- os: macos-13
task: if-else
python_version: '3.9'
- os: macos-14
task: bdist
method: wheel
python_version: '3.10'
# We're currently skipping MPI jobs on macOS, see https://github.com/microsoft/LightGBM/pull/6425
# for further details.
Expand Down Expand Up @@ -63,7 +67,11 @@ jobs:
export TASK="${{ matrix.task }}"
export METHOD="${{ matrix.method }}"
export PYTHON_VERSION="${{ matrix.python_version }}"
if [[ "${{ matrix.os }}" == "macos-13" ]]; then
if [[ "${{ matrix.os }}" == "macos-14" ]]; then
# use clang when creating macOS release artifacts
export COMPILER="clang"
export OS_NAME="macos"
elif [[ "${{ matrix.os }}" == "macos-13" ]]; then
export COMPILER="gcc"
export OS_NAME="macos"
elif [[ "${{ matrix.os }}" == "ubuntu-latest" ]]; then
Expand All @@ -75,6 +83,12 @@ jobs:
export PATH=${CONDA}/bin:${PATH}
$GITHUB_WORKSPACE/.ci/setup.sh || exit 1
$GITHUB_WORKSPACE/.ci/test.sh || exit 1
- name: upload wheels
if: ${{ matrix.method == 'wheel' && matrix.os == 'macos-14' }}
uses: actions/upload-artifact@v4
with:
name: macosx-arm64-wheel
path: dist/*.whl
test-latest-versions:
name: Python - latest versions (ubuntu-latest)
runs-on: ubuntu-latest
Expand Down
77 changes: 77 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -707,6 +707,83 @@ if(__BUILD_FOR_PYTHON)
set(CMAKE_INSTALL_PREFIX "lightgbm")
endif()

# The macOS linker puts an absolute path to linked libraries in lib_lightgb.dylib.
# This block overrides that information for LightGBM's OpenMP dependency, to allow
# finding that library in more places.
#
# This reduces the risk of runtime issues resulting from multiple libomp.dylib being loaded.
#
if(APPLE AND USE_OPENMP)
# store path to libomp found at build time in a variable
get_target_property(
OpenMP_LIBRARY_LOCATION
OpenMP::OpenMP_CXX
INTERFACE_LINK_LIBRARIES
)
# get just the filename of that path
# (to deal with the possibility that it might be 'libomp.dylib' or 'libgomp.dylib' or 'libiomp.dylib')
get_filename_component(
OpenMP_LIBRARY_NAME
${OpenMP_LIBRARY_LOCATION}
NAME
)
# get directory of that path
get_filename_component(
OpenMP_LIBRARY_DIR
${OpenMP_LIBRARY_LOCATION}
DIRECTORY
)
# get exact name of the library in a variable
get_target_property(
__LIB_LIGHTGBM_OUTPUT_NAME
_lightgbm
OUTPUT_NAME
)
if(NOT __LIB_LIGHTGBM_OUTPUT_NAME)
set(__LIB_LIGHTGBM_OUTPUT_NAME "lib_lightgbm")
endif()

if(CMAKE_SHARED_LIBRARY_SUFFIX_CXX)
set(
__LIB_LIGHTGBM_FILENAME "${__LIB_LIGHTGBM_OUTPUT_NAME}${CMAKE_SHARED_LIBRARY_SUFFIX_CXX}"
CACHE INTERNAL "lightgbm shared library filename"
)
else()
set(
__LIB_LIGHTGBM_FILENAME "${__LIB_LIGHTGBM_OUTPUT_NAME}.dylib"
CACHE INTERNAL "lightgbm shared library filename"
)
endif()

# Override the absolute path to OpenMP with a relative one using @rpath.
#
# This also ensures that if a libomp.dylib has already been loaded, it'll just use that.
add_custom_command(
TARGET _lightgbm
POST_BUILD
COMMAND
install_name_tool
-change
${OpenMP_LIBRARY_LOCATION}
"@rpath/${OpenMP_LIBRARY_NAME}"
"${__LIB_LIGHTGBM_FILENAME}"
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMENT "Replacing hard-coded OpenMP install_name with '@rpath/${OpenMP_LIBRARY_NAME}'..."
)
# add RPATH entries to ensure the loader looks in the following, in the following order:
#
# - /opt/homebrew/opt/libomp/lib (where 'brew install' / 'brew link' puts libomp.dylib)
# - ${OpenMP_LIBRARY_DIR} (wherever find_package(OpenMP) found OpenMP at build time)
#
set_target_properties(
_lightgbm
PROPERTIES
BUILD_WITH_INSTALL_RPATH TRUE
INSTALL_RPATH "/opt/homebrew/opt/libomp/lib;${OpenMP_LIBRARY_DIR}"
INSTALL_RPATH_USE_LINK_PATH FALSE
)
endif()

install(
TARGETS _lightgbm
RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin
Expand Down

0 comments on commit ad1237d

Please sign in to comment.