Skip to content

Commit e9946ad

Browse files
cbjeukendrupkryksyh
authored andcommitted
Fix missing transitive rpath for fetched dependencies on macOS
_bd_relocatable_macos never received depends_prefixes, unlike its Linux counterpart _bd_relocatable_elf, so a fetched dependency's own dylib never got an rpath entry for its own dependencies' lib directories. Any binary linking only the top-level dependency (not its transitive shared-lib dependencies) would then fail to load at runtime with a dyld "Library not loaded" error, since neither the binary nor the dependency's dylib recorded where to find it. Mirror the existing patchelf-based Linux logic: add install_name_tool -add_rpath calls using @loader_path-relative paths to each dependency prefix's lib directory.
1 parent f348375 commit e9946ad

1 file changed

Lines changed: 28 additions & 4 deletions

File tree

buildtools/build_dependency.cmake

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -264,8 +264,9 @@ function(_bd_relocatable_elf os name install_dir depends_prefixes)
264264
endforeach()
265265
endfunction()
266266

267-
# macOS: make installed dylibs relocatable.
268-
function(_bd_relocatable_macos os install_dir)
267+
# macOS: make installed dylibs relocatable, and point them at sibling deps'
268+
# lib directories so transitive runtime dependencies can be found.
269+
function(_bd_relocatable_macos os install_dir depends_prefixes)
269270
if(NOT os STREQUAL "macos")
270271
return()
271272
endif()
@@ -274,7 +275,25 @@ function(_bd_relocatable_macos os install_dir)
274275
if(NOT INSTALL_NAME_TOOL OR NOT OTOOL)
275276
return()
276277
endif()
278+
277279
file(GLOB _dylibs "${install_dir}/lib/*.dylib")
280+
if(NOT _dylibs)
281+
return()
282+
endif()
283+
284+
get_filename_component(_install_lib "${install_dir}/lib" ABSOLUTE)
285+
set(_rpath_entries "")
286+
foreach(_prefix ${depends_prefixes})
287+
if(EXISTS "${_prefix}/lib")
288+
get_filename_component(_dep_lib "${_prefix}/lib" ABSOLUTE)
289+
file(RELATIVE_PATH _rel "${_install_lib}" "${_dep_lib}")
290+
list(APPEND _rpath_entries "@loader_path/${_rel}")
291+
endif()
292+
endforeach()
293+
if(_rpath_entries)
294+
list(REMOVE_DUPLICATES _rpath_entries)
295+
endif()
296+
278297
foreach(_dylib ${_dylibs})
279298
if(IS_SYMLINK "${_dylib}")
280299
continue()
@@ -285,6 +304,11 @@ function(_bd_relocatable_macos os install_dir)
285304
execute_process(COMMAND ${INSTALL_NAME_TOOL} -id "@rpath/${_name}" "${_dylib}" ERROR_QUIET)
286305
message(STATUS "[${BD_NAME}] install_name -> @rpath/${_name}")
287306
endif()
307+
308+
foreach(_entry ${_rpath_entries})
309+
# -add_rpath fails (non-fatally, ERROR_QUIET'd) if the entry is already present
310+
execute_process(COMMAND ${INSTALL_NAME_TOOL} -add_rpath "${_entry}" "${_dylib}" ERROR_QUIET)
311+
endforeach()
288312
endforeach()
289313
endfunction()
290314

@@ -347,7 +371,7 @@ function(build_dep)
347371
message(STATUS "[${BD_NAME}] up-to-date (recipe unchanged), skipping build")
348372
_bd_ensure_sonames("${BD_OS}" "${BD_NAME}" "${BD_INSTALL_DIR}")
349373
_bd_relocatable_elf("${BD_OS}" "${BD_NAME}" "${BD_INSTALL_DIR}" "${BD_DEPENDS_PREFIXES}")
350-
_bd_relocatable_macos("${BD_OS}" "${BD_INSTALL_DIR}")
374+
_bd_relocatable_macos("${BD_OS}" "${BD_INSTALL_DIR}" "${BD_DEPENDS_PREFIXES}")
351375
return()
352376
endif()
353377
endif()
@@ -446,7 +470,7 @@ function(build_dep)
446470
# Fix-up installed libraries
447471
_bd_ensure_sonames("${BD_OS}" "${BD_NAME}" "${INSTALL}")
448472
_bd_relocatable_elf("${BD_OS}" "${BD_NAME}" "${INSTALL}" "${BD_DEPENDS_PREFIXES}")
449-
_bd_relocatable_macos("${BD_OS}" "${INSTALL}")
473+
_bd_relocatable_macos("${BD_OS}" "${INSTALL}" "${BD_DEPENDS_PREFIXES}")
450474

451475
# Record the build signature
452476
file(WRITE "${_build_stamp}" "${_build_sig}")

0 commit comments

Comments
 (0)