在macOS上使用CMake为可执行文件设置@rpath的问题
macOS下预编译libIrrlicht.dylib无法加载的解决方法
我在构建依赖多个dylib的可执行文件时,遇到libIrrlicht无法加载的问题。用otool -L查看可执行文件的依赖,结果如下:
@rpath/libtuio.dylib (compatibility version 0.0.0, current version 0.0.0) @rpath/liburg_library.dylib (compatibility version 0.0.0, current version 0.0.0) /libIrrlicht.dylib (compatibility version 1.0.0, current version 1.0.0)
可以看到,自行编译的libtuio和liburg_library都带有@rpath/前缀,而预编译的libIrrlicht却是绝对路径/libIrrlicht.dylib,导致程序无法找到复制到可执行文件同目录的库文件。
CMake生成的链接命令片段:
/usr/bin/clang++ -g -arch arm64 [...] -Wl,-rpath,@loader_path/ [...] bin/libtuio.dylib bin/liburg_library.dylib [...] external/lib_mac_arm/libIrrlicht.dylib
CMakeLists.txt相关代码:
target_link_libraries(myBinary [...] ${TUIO_LIB_TARGET} ${URG_LIB_TARGET} ${OSC_LIB_TARGET}) if (MACOSX) target_link_libraries(myBinary [...] ${IRR_LIB_DIR}/libIrrlicht.dylib opencv_core opencv_video ${OPENSSL_CRYPTO_LIBRARIES} ${SDL2_LIBRARIES}) set_target_properties(myBinary PROPERTIES BUILD_WITH_INSTALL_RPATH TRUE) set_property( TARGET myBinary PROPERTY INSTALL_RPATH "@loader_path/" )
解决方法
方法一:创建CMake导入目标(推荐)
通过为预编译库创建CMake导入目标,让CMake自动处理rpath路径:
修改MACOSX分支下的代码:
if (MACOSX) # 为预编译的libIrrlicht创建导入目标 add_library(Irrlicht SHARED IMPORTED) set_target_properties(Irrlicht PROPERTIES IMPORTED_LOCATION "${IRR_LIB_DIR}/libIrrlicht.dylib" IMPORTED_SONAME "@rpath/libIrrlicht.dylib" ) # 链接时使用导入目标而非直接路径 target_link_libraries(myBinary [...] Irrlicht opencv_core opencv_video ${OPENSSL_CRYPTO_LIBRARIES} ${SDL2_LIBRARIES}) set_target_properties(myBinary PROPERTIES BUILD_WITH_INSTALL_RPATH TRUE) set_property( TARGET myBinary PROPERTY INSTALL_RPATH "@loader_path/" ) endif()
方法二:手动修改链接选项
在链接时添加参数,强制替换libIrrlicht的依赖路径:
if (MACOSX) target_link_libraries(myBinary [...] ${IRR_LIB_DIR}/libIrrlicht.dylib opencv_core opencv_video ${OPENSSL_CRYPTO_LIBRARIES} ${SDL2_LIBRARIES}) set_target_properties(myBinary PROPERTIES BUILD_WITH_INSTALL_RPATH TRUE # 替换可执行文件中libIrrlicht的依赖路径 LINK_OPTIONS "-Wl,-change_install_name,/libIrrlicht.dylib,@rpath/libIrrlicht.dylib" ) set_property( TARGET myBinary PROPERTY INSTALL_RPATH "@loader_path/" ) endif()
方法三:修改预编译库本身的install name
直接用install_name_tool修改libIrrlicht的内部install name:
install_name_tool -id "@rpath/libIrrlicht.dylib" external/lib_mac_arm/libIrrlicht.dylib
修改后再用CMake重新链接,可执行文件会自动使用@rpath/libIrrlicht.dylib作为依赖路径。
内容的提问来源于stack exchange,提问作者pholz
相关产品推荐
相关产品推荐

