-
-
Notifications
You must be signed in to change notification settings - Fork 8.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
) * [CI] Stop vendoring libomp.dylib in MacOS Python wheels (#10440) * [CI] [jvm-packages] Build libxgboost4j.dylib on M1 MacOS with OpenMP support (#10449)
- Loading branch information
Showing
6 changed files
with
153 additions
and
43 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
# Find OpenMP library on MacOS | ||
# Automatically handle locating libomp from the Homebrew package manager | ||
|
||
# lint_cmake: -package/consistency | ||
|
||
macro(find_openmp_macos) | ||
if(NOT APPLE) | ||
message(FATAL_ERROR "${CMAKE_CURRENT_FUNCTION}() must only be used on MacOS") | ||
endif() | ||
find_package(OpenMP) | ||
if(NOT OpenMP_FOUND) | ||
# Try again with extra path info. This step is required for libomp 15+ from Homebrew, | ||
# as libomp 15.0+ from brew is keg-only | ||
# See https://github.com/Homebrew/homebrew-core/issues/112107#issuecomment-1278042927. | ||
execute_process(COMMAND brew --prefix libomp | ||
OUTPUT_VARIABLE HOMEBREW_LIBOMP_PREFIX | ||
OUTPUT_STRIP_TRAILING_WHITESPACE) | ||
set(OpenMP_C_FLAGS | ||
"-Xpreprocessor -fopenmp -I${HOMEBREW_LIBOMP_PREFIX}/include") | ||
set(OpenMP_CXX_FLAGS | ||
"-Xpreprocessor -fopenmp -I${HOMEBREW_LIBOMP_PREFIX}/include") | ||
set(OpenMP_C_LIB_NAMES omp) | ||
set(OpenMP_CXX_LIB_NAMES omp) | ||
set(OpenMP_omp_LIBRARY ${HOMEBREW_LIBOMP_PREFIX}/lib/libomp.dylib) | ||
find_package(OpenMP REQUIRED) | ||
endif() | ||
endmacro() | ||
|
||
# Patch libxgboost.dylib so that it depends on @rpath/libomp.dylib instead of | ||
# /opt/homebrew/opt/libomp/lib/libomp.dylib or other hard-coded paths. | ||
# Doing so enables XGBoost to interoperate with multiple kinds of OpenMP | ||
# libraries. See https://github.com/microsoft/LightGBM/pull/6391 for detailed | ||
# explanation. Adapted from https://github.com/microsoft/LightGBM/pull/6391 | ||
# by James Lamb. | ||
# MacOS only. | ||
function(patch_openmp_path_macos target target_default_output_name) | ||
if(NOT APPLE) | ||
message(FATAL_ERROR "${CMAKE_CURRENT_FUNCTION}() must only be used on MacOS") | ||
endif() | ||
# Get path to libomp found at build time | ||
get_target_property( | ||
__OpenMP_LIBRARY_LOCATION | ||
OpenMP::OpenMP_CXX | ||
INTERFACE_LINK_LIBRARIES | ||
) | ||
# Get the base name of the OpenMP lib | ||
# Usually: libomp.dylib, libgomp.dylib, or libiomp.dylib | ||
get_filename_component( | ||
__OpenMP_LIBRARY_NAME | ||
${__OpenMP_LIBRARY_LOCATION} | ||
NAME | ||
) | ||
# Get the directory containing the OpenMP lib | ||
get_filename_component( | ||
__OpenMP_LIBRARY_DIR | ||
${__OpenMP_LIBRARY_LOCATION} | ||
DIRECTORY | ||
) | ||
# Get the name of the XGBoost lib, e.g. libxgboost | ||
get_target_property( | ||
__LIBXGBOOST_OUTPUT_NAME | ||
${target} | ||
OUTPUT_NAME | ||
) | ||
if(NOT __LIBXGBOOST_OUTPUT_NAME) | ||
set(__LIBXGBOOST_OUTPUT_NAME "${target_default_output_name}") | ||
endif() | ||
|
||
# Get the file name of the XGBoost lib, e.g. libxgboost.dylib | ||
if(CMAKE_SHARED_LIBRARY_SUFFIX_CXX) | ||
set( | ||
__LIBXGBOOST_FILENAME_${target} "${__LIBXGBOOST_OUTPUT_NAME}${CMAKE_SHARED_LIBRARY_SUFFIX_CXX}" | ||
CACHE INTERNAL "Shared library filename ${target}" | ||
) | ||
else() | ||
set( | ||
__LIBXGBOOST_FILENAME_${target} "${__LIBXGBOOST_OUTPUT_NAME}.dylib" | ||
CACHE INTERNAL "Shared library filename ${target}" | ||
) | ||
endif() | ||
|
||
message(STATUS "Creating shared lib for target ${target}: ${__LIBXGBOOST_FILENAME_${target}}") | ||
|
||
# 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. | ||
if(KEEP_BUILD_ARTIFACTS_IN_BINARY_DIR) | ||
set(__LIB_DIR ${xgboost_BINARY_DIR}/lib) | ||
else() | ||
set(__LIB_DIR ${xgboost_SOURCE_DIR}/lib) | ||
endif() | ||
add_custom_command( | ||
TARGET ${target} | ||
POST_BUILD | ||
COMMAND | ||
install_name_tool | ||
-change | ||
${__OpenMP_LIBRARY_LOCATION} | ||
"@rpath/${__OpenMP_LIBRARY_NAME}" | ||
"${__LIBXGBOOST_FILENAME_${target}}" | ||
WORKING_DIRECTORY ${__LIB_DIR} | ||
) | ||
message(STATUS | ||
"${__LIBXGBOOST_FILENAME_${target}}: " | ||
"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) | ||
# | ||
# Note: This list will only be used if libomp.dylib isn't already loaded into memory. | ||
# So Conda users will likely use ${CONDA_PREFIX}/libomp.dylib | ||
execute_process(COMMAND brew --prefix libomp | ||
OUTPUT_VARIABLE HOMEBREW_LIBOMP_PREFIX | ||
OUTPUT_STRIP_TRAILING_WHITESPACE) | ||
set_target_properties( | ||
${target} | ||
PROPERTIES | ||
BUILD_WITH_INSTALL_RPATH TRUE | ||
INSTALL_RPATH "${HOMEBREW_LIBOMP_PREFIX}/lib;${__OpenMP_LIBRARY_DIR}" | ||
INSTALL_RPATH_USE_LINK_PATH FALSE | ||
) | ||
endfunction() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters