报错dyld: Library not loaded原因:链接时和运行时都需要指定动态库路径(利用@rpath指定运行时动态库路径)

最近在mac上写了一个动态库,然后又写了一个可执行文件来链接它并使用该动态库。链接时一切正常,但是在执行生成的可执行文件时出现了下面的链接报错:

dyld: Library not loaded: ./obj/libtest.dylib

Referenced from: /Users/zeng/Workspace/practice_make/generate_lib/./test

Reason: image not found

可以看到,链接器没有正常载入应该的动态库。

我用mac下的otool工具查看了一些可执行文件test的链接情况,如下:

otool -L test

test:

./obj/libtest.dylib (compatibility version 0.0.0, current version 0.0.0)

/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.250.1)

第一条结果显示,我想链接的动态库的地址是./obj/...,这下我知道问题出在哪了。

我的动态库文件分明是在路径./source/obj/下,我链接时指定的-L中也是这么指定的。可在可执行文件test中,却显示动态库路径是./obj下,分明就不对嘛,难怪运行时无法载入呢。

我搜了些资料,理解如下(不一定正确哈仅供参考):

其实这涉及到所谓的动态库的install-name的问题。在生成动态库.so时它默认会有一个install-name(这个名称也可以人为指定),这个install-name往往是不具备完备的路径的。当编译可执行文件时,我们虽然不需要链接到动态库(直到运行时才动态链接),但还是需要用-L和-l指定用到的动态库,这个过程的效果之一是把这个install-name写到可执行文件中去(就是上面的./obj/libtest.dylib这个东西),那么运行时就可以默认到这个名字对应的路径下去找动态库。

但由于默认的install-name的路径是不完备的(就可执行文件所在的位置而言),或者说动态库文件与当前的可执行文件不在同一路径下,所以运行可执行文件时只根据install-name找不到动态库。此时就需要人为的指定一下动态库路径了,一般来说有三种方法。

第一种,就是在命令行中执行:export DYLD_LIBRARY_PATH=./obj告诉链接器去这里找。

第二种,就是修改可执行程序中的install-name,使其指向动态库文件所在的位置。具体做法见下面第一个链接。

第三种,就是在生成动态库的时候指定其install-name为@rpath/libxx.so,这样,之后在生成可执行文件指定-L,-l,-Wl,-rpath时写入可执行文件的install-name就是带全路径的动态库名。我理解为这里动态库的install-name中的@rpath就是个占位符,表示之后在使用动态库的时候,指定动态库路径就能自动替换掉这个占位符,使可执行文件能正常地动态链接。

 

所以,链接时查找的位置和运行时查找的位置是两码事:

-L指定编译链接时的搜索目录;

-Wl,-rpath指定程序运行时加载的共享库搜索目录

 

更详细的解释(说得非常清楚),见:

https://www.cnblogs.com/liubaocheng999/p/4285256.html

 

更官方和准确的文档见:

stack overflow上有个相关问题:

https://stackoverflow.com/questions/29809069/dyld-library-not-loaded-on-os-x

讲动态库的:

https://developer.apple.com/library/archive/documentation/DeveloperTools/Conceptual/DynamicLibraries/100-Articles/OverviewOfDynamicLibraries.html#//apple_ref/doc/uid/TP40001873-SW3

讲Run-Path Dependent Libraries的:

https://developer.apple.com/library/archive/documentation/DeveloperTools/Conceptual/DynamicLibraries/100-Articles/RunpathDependentLibraries.html#//apple_ref/doc/uid/TP40008306-SW1

### 解决 macOS 下 `Library not loaded: @rpath/libomp.dylib` 错误 在 macOS 上遇到 `Library not loaded: @rpath/libomp.dylib` 的错误通常是由于动态链接库未正确加载引起的。以下是针对该问题的具体解决方法: #### 方法一:通过 Homebrew 安装并配置 libomp 如果尚未安装 `libomp`,可以通过 Homebrew 来安装它: ```bash brew install libomp ``` 安装完成后,确认其路径是否存在对应的 `.dylib` 文件。通常情况下,Homebrew 会将其安装至 `/usr/local/opt/libomp/lib/` 或 `/opt/homebrew/opt/libomp/lib/`(对于 Apple Silicon)。接着,创建软链接指向所需的动态库位置: ```bash sudo ln -sf /usr/local/opt/libomp/lib/libomp.dylib /usr/local/lib/libomp.dylib ``` 或者如果是 M1/M2 芯片设备,则可能是: ```bash sudo ln -sf /opt/homebrew/opt/libomp/lib/libomp.dylib /usr/local/lib/libomp.dylib ``` 此操作确保程序能够找到正确的动态链接库[^2]。 #### 方法二:修改可执行文件的 RPATH 设置 另一种方式是调整目标二进制文件或共享对象中的运行搜索路径 (RPATH),使其能定位到实际存在的 `libomp.dylib` 库。具体步骤如下: 1. 使用工具查看当前依赖关系: ```bash otool -L your_executable_or_shared_object_file ``` 2. 如果发现缺少 `@rpath/libomp.dylib`,则可通过 `install_name_tool` 修改其引用地址为绝对路径形式。例如: ```bash install_name_tool -change @rpath/libomp.dylib /usr/local/opt/libomp/lib/libomp.dylib your_executable_or_shared_object_file ``` 替换其中的路径部分以匹配本地实际情况。 3. 验证更改是否成功应用: ```bash otool -L your_executable_or_shared_object_file | grep libomp.dylib ``` 上述过程直接改变了应用程序内部关于外部资源的位置定义,从而绕过了原有无法解析相对路径的问题[^5]。 #### 方法三:临指定 DYLD_LIBRARY_PATH 环境变量 作为快速测试手段,在终端启动前设置环境变量也可以解决问题: ```bash export DYLD_LIBRARY_PATH=/usr/local/opt/libomp/lib:$DYLD_LIBRARY_PATH ./your_program ``` 这种方法仅适用于单次运行场景,并不推荐长期采用因为每次都需要重复设定且容易遗忘[^3]。 --- ### 总结 以上三种方案分别从不同角度处理了因缺失 `libomp.dylib` 导致的应用崩溃现象。优先考虑利用包管理器完成基础支持软件部署后再做进一步优化;而对于某些特殊需求场合,则可以灵活运用命令行工具来达成目的。 ```python import ctypes ctypes.CDLL("/usr/local/opt/libomp/lib/libomp.dylib") # 测试加载情况 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值