遇到的问题

  1. 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 编译时预期的 Homebrew libiconv 版本

  2. 但是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
    

    解释:

    1. 可执行文件里写的是 @rpath/libpq.5.dylib
    2. 但是这个可执行文件 并没有 在它的 Mach-O 头部声明任何 RPATH 路径
    3. 之前用 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

进行一些学习

  1. MacOS上的动态库文件.dylib属于Mach-O格式(具体为MH_DYLIB),Mach-O是Mach object的缩写,是iOS、macOS上用于存储程序、库的标准格式,比如任何应用程序.app/Content/MacOS中的可执行文件就属于这个格式(使用命令file file_name查看,举例输出:Mach-O 64-bit executable arm64)
  2. 一个Mach-O文件包含三个主要区域:
  3. LC_RPATH 是什么:
    1. 在 macOS 的 Mach-O 二进制格式中,LC代表Load Command,R代表Run-time,整体表示的是一个 "运行时搜索路径",是Mach-O Load Command 部分的一种
  4. otool工具用来查看Mach-O特定部分和段的内容,比如-h输出mach头部信息,-L输出该文件使用的共享库
  5. install_name_tool 是 macOS 系统下专门用于编辑Mach-O 格式可执行文件和动态库 的命令行工具

tips:MacOS系统(xcode)本身会有一些库,HomwBrew又会自己管理一些库,所以建议不要手动控制的DYLD_LIBRARY_PATH之类的东西,避免混乱