遇到的问题
-
git报错:
dyld[86362]: Symbol not found: _iconv Referenced from: <0B17F88E-81CD-3265-A735-F54385122F74> /opt/homebrew/Cellar/git/2.46.0/bin/git Expected in: <5E3C6B42-48F0-3444-ABA3-D9F7C90E124C> /opt/homebrew/Cellar/libiconv/1.18/lib/libiconv.2.dylib zsh: abort git remote -v
需要的文件明明是存在的,然后尝试修复:
brew update brew upgrade brew reinstall git brew reinstall libiconv
仍然错误,继续排查
echo $DYLD_LIBRARY_PATH
发现之前有过设置,于是执行
unset $DYLD_LIBRARY_PATH
之后就好了(unset仅对当前终端有效,永久修复需要删除~/.zshrc中的配置)
原因:
DYLD_LIBRARY_PATH
设置后,macOS 会优先加载路径中的libiconv
版本,而不是 Git 编译时预期的 Homebrewlibiconv
版本 -
但是unset了之后,操作psql又报错了(之前临时设置的
DYLD_LIBRARY_PATH
就是为了解决这个问题的):dyld[6824]: Library not loaded: @rpath/libpq.5.dylib Referenced from: <29FDBA1B-B4AA-3198-B7F6-CD3558E65EE1> ~/.cargo/bin/cli Reason: no LC_RPATH's found
解释:
- 可执行文件里写的是
@rpath/libpq.5.dylib
- 但是这个可执行文件 并没有 在它的 Mach-O 头部声明任何 RPATH 路径
- 之前用
DYLD_LIBRARY_PATH
来告诉系统临时去找这些库,一旦 unset 后,就失去了线索
类比:写了
@/pages/index.tsx
但是没有配置'@': path.resolve(__dirname, 'src')
解决:
install_name_tool -add_rpath /opt/homebrew/opt/libpq/lib ~/.cargo/bin/cli install_name_tool -add_rpath /opt/homebrew/opt/libiconv/lib ~/.cargo/bin/cli
解释:将需要的目录添加进可执行文件的LC_RPATH中
- 可执行文件里写的是
进行一些学习
-
MacOS上的动态库文件.dylib属于Mach-O格式(具体为MH_DYLIB),Mach-O是Mach object的缩写,是iOS、macOS上用于存储程序、库的标准格式,比如任何应用程序.app/Content/MacOS中的可执行文件就属于这个格式(使用命令file file_name查看,举例输出:Mach-O 64-bit executable arm64)
-
一个Mach-O文件包含三个主要区域:
- Header:包含文件类型、目标架构类型等
- Load commands:描述文件在虚拟内存中的逻辑结构、布局,指定segment的虚拟内存地址,以及其它权限等
- Raw segment data:在load commands中定义的segment的原始数据,每个segment包含一个或多个section。不同类型code、data,存储到不同section
-
LC_RPATH
是什么:在 macOS 的 Mach-O 二进制格式中,
LC
代表Load Command,R
代表Run-time,整体表示的是一个 "运行时搜索路径",是Mach-O Load Command 部分的一种 -
otool
工具用来查看Mach-O特定部分和段的内容,比如-h
输出mach头部信息,-L
输出该文件使用的共享库 -
install_name_tool
是 macOS 系统下专门用于编辑Mach-O 格式可执行文件和动态库 的命令行工具
tips:MacOS系统(xcode)本身会有一些库,HomwBrew又会自己管理一些库,所以建议不要手动控制的DYLD_LIBRARY_PATH
之类的东西,避免混乱