macOS: Portable builds with dynamic libraries.

For Blender.app: dropping libomp.dylib next to Blender executable is
enough for it getting picked up since `@executable_path` is an rpath.

For non-distributed binaries datatoc, makesdna, tests etc, code for
copying libomp.dylib to build folder is removed and replaced by
CMake's rpath option for *build* tree.

For bpy.so, the post build rpath change has also been replaced by CMake
rpath option for *install* tree.

Since -id has been changed in D11748, remove the
`install_name_tool -change ...` command.

Any dylib can just be dropped at `MAC_BLENDER_TARGET_DYLIBS_DIR`
hereafter. Appending dylib path to `CMAKE_BUILD_RPATH` will be needed
for datatoc etc if linked against one (instead of copying the
dylibs around).

Reviewed By: #platform_macos, brecht
Differential Revision: https://developer.blender.org/D11997
This commit is contained in:
Ankit Meel 2021-08-03 20:49:40 +05:30
parent a25a1f39aa
commit 652fbc2005
3 changed files with 37 additions and 35 deletions

@ -110,6 +110,10 @@ if(POLICY CMP0074)
cmake_policy(SET CMP0074 NEW)
endif()
# Install CODE|SCRIPT allow the use of generator expressions.
if(POLICY CMP0087)
cmake_policy(SET CMP0087 NEW)
endif()
#-----------------------------------------------------------------------------
# Load some macros.
include(build_files/cmake/macros.cmake)

@ -411,25 +411,9 @@ if(WITH_OPENMP)
set(OPENMP_FOUND ON)
set(OpenMP_C_FLAGS "-Xclang -fopenmp -I'${LIBDIR}/openmp/include'")
set(OpenMP_CXX_FLAGS "-Xclang -fopenmp -I'${LIBDIR}/openmp/include'")
set(OpenMP_LINKER_FLAGS "-L'${LIBDIR}/openmp/lib' -lomp")
# Copy libomp.dylib to allow executables like datatoc and tests to work.
# `@executable_path/../Resources/lib/` `LC_ID_DYLIB` is added by the deps builder.
# For single config generator datatoc, tests etc.
execute_process(
COMMAND mkdir -p ${CMAKE_BINARY_DIR}/Resources/lib
COMMAND cp -p ${LIBDIR}/openmp/lib/libomp.dylib ${CMAKE_BINARY_DIR}/Resources/lib/libomp.dylib
)
# For multi-config generator datatoc, etc.
execute_process(
COMMAND mkdir -p ${CMAKE_BINARY_DIR}/bin/Resources/lib
COMMAND cp -p ${LIBDIR}/openmp/lib/libomp.dylib ${CMAKE_BINARY_DIR}/bin/Resources/lib/libomp.dylib
)
# For multi-config generator tests.
execute_process(
COMMAND mkdir -p ${CMAKE_BINARY_DIR}/bin/tests/Resources/lib
COMMAND cp -p ${LIBDIR}/openmp/lib/libomp.dylib ${CMAKE_BINARY_DIR}/bin/tests/Resources/lib/libomp.dylib
)
set(OpenMP_LIBRARY_DIR "${LIBDIR}/openmp/lib/")
set(OpenMP_LINKER_FLAGS "-L'${OpenMP_LIBRARY_DIR}' -lomp")
set(OpenMP_LIBRARY "${OpenMP_LIBRARY_DIR}/libomp.dylib")
endif()
endif()
@ -511,3 +495,19 @@ if(WITH_COMPILER_CCACHE)
endif()
endif()
endif()
# For binaries that are built but not installed (also not distributed) (datatoc,
# makesdna, tests, etc.), we add an rpath to the OpenMP library dir through
# CMAKE_BUILD_RPATH. This avoids having to make many copies of the dylib next to each binary.
#
# For the installed Blender executable, CMAKE_INSTALL_RPATH will be used, but
# needs no changes since it already looks for dylibs next to the executable by
# default (@executable_path).
#
# For the installed Python module, CMAKE_INSTALL_RPATH is modified to find the
# dylib in an adjacent folder.
set(CMAKE_SKIP_BUILD_RPATH FALSE)
list(APPEND CMAKE_BUILD_RPATH "${OpenMP_LIBRARY_DIR}")
if(WITH_PYTHON_MODULE)
list(APPEND CMAKE_INSTALL_RPATH "@loader_path/../Resources/${BLENDER_VERSION}/lib")
endif()

@ -345,8 +345,13 @@ elseif(APPLE)
set(TARGETDIR_VER "${PYTHON_LIBPATH}/Resources/${BLENDER_VERSION}")
set(INSTALL_BPY_TO_SITE_PACKAGES ON)
endif()
# Dylibs folder for bpy.so.
set(MAC_BLENDER_TARGET_DYLIBS_DIR "${TARGETDIR_VER}/lib")
else()
set(TARGETDIR_VER Blender.app/Contents/Resources/${BLENDER_VERSION})
# Dylibs folder for Blender executable. @executable_path is a default
# rpath, so dropping libraries next to Blender is enough.
set(MAC_BLENDER_TARGET_DYLIBS_DIR "$<TARGET_FILE_DIR:blender>")
endif()
# Skip relinking on cpack / install
set_target_properties(blender PROPERTIES BUILD_WITH_INSTALL_RPATH true)
@ -1041,23 +1046,16 @@ elseif(APPLE)
if(WITH_OPENMP AND OPENMP_CUSTOM)
install(
FILES ${LIBDIR}/openmp/lib/libomp.dylib
DESTINATION Blender.app/Contents/Resources/lib
)
if(WITH_PYTHON_MODULE)
# Move the dylib in a Blender version folder to keep the corresponding OpenMP version.
install(
DIRECTORY ${CMAKE_BINARY_DIR}/Resources/lib
DESTINATION ${TARGETDIR_VER}
)
add_custom_command(TARGET blender POST_BUILD
# The old `LC_LOAD_DYLIB` is the `LC_ID_DYLIB` of the LIBDIR OpenMP dylib.
# Change it to support multiple rpaths.
COMMAND xcrun install_name_tool -change "@executable_path/../Resources/lib/libomp.dylib" "@rpath/libomp.dylib" "$<TARGET_FILE:blender>"
# For installation into site-packages.
COMMAND xcrun install_name_tool -add_rpath "@loader_path/../Resources/${BLENDER_VERSION}/lib" "$<TARGET_FILE:blender>"
FILES "${OpenMP_LIBRARY}"
DESTINATION "${MAC_BLENDER_TARGET_DYLIBS_DIR}"
)
endif()
if(WITH_COMPILER_ASAN)
install(
FILES "${COMPILER_ASAN_LIBRARY}"
DESTINATION "${MAC_BLENDER_TARGET_DYLIBS_DIR}"
)
endif()
# python