我正在尝试使用 CMake 在 MacOS 上编译 dylib。我的库动态链接到其他一些库,我想将它们与我的库一起提供。为此,我需要确保在加载库时,从同一文件夹加载依赖库,无论其位置。我相信它与rpath有关,但我不是这里的专家。您能否建议一种使用 CMake 实现此目的的方法?(我想需要通过 -Wl,-rpath 或类似的方式提供一些链接器选项
提前致谢!
Linux ${ORIGIN} 技巧将不起作用。在 macOS 上,库依赖项默认指定为绝对路径 ( otool -L mylib.dylib
)。
install_name_tool -change ...
要拥有相对路径(例如,相同的文件夹),我认为正确的方法是将主库(with )中依赖库的安装名称更改为@rpath/other.dylib 之类的名称,并在可执行文件(dylib)中使用正确的 rpath或者在你的情况下只是@executable_path/other.dylib。
关于 CMake,我已成功使用 CMake BundleUtilities模块自动修复此问题,可能值得一试。
以下是我在 CMake 脚本中所做的,以便从与我的二进制文件(可执行文件和其他库)相同的目录中加载共享库:
SET(CMAKE_BUILD_WITH_INSTALL_RPATH true)
SET(CMAKE_INSTALL_RPATH "$ORIGIN/")
(使用 CMake 3.0+ 测试)
它是如何工作的(我的理解):第二行告诉 CMake 将 $ORIGIN 特殊字符串添加到二进制文件搜索文件夹(这个特殊的 $ORIGIN 字符串在执行时由操作系统“替换”,文件夹包含正在执行的二进制文件. 因此,将正确找到包含此字符串的二进制文件旁边的所需库)。
但是,在 CMake 中设置此变量只会影响安装时二进制文件(例如,使用make install部署的二进制文件):CMake 不会更改在构建阶段创建的二进制文件中的搜索路径,但只会在安装它们时更改。
由于我没有使用 CMake 安装功能,并且我只想在可自由重定位的文件夹中提供我的应用程序,因此我使用了第一个调用,它告诉 CMake 在构建时也使用安装时搜索路径。
因此,通过这两个调用,在 CMake 生成的 makefile 上调用make(或使用 XCode 构建,我猜)将创建搜索文件夹正确设置为 $ORIGIN 的二进制文件。
请在定义任何其他目标之前执行此操作。您还可以通过使用带有 BUILD_WITH_INSTALL_RPATH 和 INSTALL_RPATH 属性的 set_target_property 为各个目标自定义这些设置。
我只在 Linux 下对此进行了测试,但如果 MacOS X 的行为方式相同,则应该没问题。
希望这可以帮助
本杰明