Skip to content
ShenYj edited this page Feb 11, 2022 · 3 revisions

@rpath

简介

  • Runpath search Paths: dyld 搜索路径

    运行时 @rpath 指示 dylb 按顺序搜索路径列表, 以找到动态库。

    @path 保存一个或多个路径的变量

    谁链接当前的动态库,谁来提供 @rpath, 相当于环境变量,由链接的对象来提供

install_name_tool设置rpath

install_name_tool -id @rpath/动态库从属资源的路径 动态库文件路径

链接framework动态库 为例

在其制定一个绝对路径成功运行基础上,没有重新进行过编译,在原有生成动态库、可执行文件基础上使用 install_name_tool 设置 rpath

test.m 编译成 test.o文件后来链接动态库 TestExample

  • 目录结构

    .
    ├── Frameworks
    │   └── TextExample.framework
    │       ├── Headers
    │       │   └── TestExample.h
    │       ├── TestExample
    │       ├── TestExample.m
    │       └── build.sh
    ├── build.sh
    └── test.m
  • 动态库的 rpath

    • 那么设置动态库路径的完整命令应该是

      install_name_tool -id @rpath/Frameworks/TextExample.framework/TestExample/Users/shenyj/framework动态库/Frameworks/TestExample.framework/TestExample
    • 这样就与实际开发中用到的动态库路径一致了

      ❯ otool -l TestExample | grep 'ID' -B 5 -A 5
      maxprot 0x00000001
      initprot 0x00000001
      nsects 0
          flags 0x0
      Load command 4
              cmd LC_ID_DYLIB
          cmdsize 80
              name @rpath/Frameworks/TextExample.framework/TestExample (offset 24)
      time stamp 1 Thu Jan  1 08:00:01 1970
          current version 0.0.0
      compatibility version 0.0.0
      --
          extreloff 0
              nextrel 0
          locreloff 0
              nlocrel 0
      Load command 9
          cmd LC_UUID
      cmdsize 24
          uuid 751402DD-EBFE-36BD-9D78-C918909190BD
      Load command 10
          cmd LC_BUILD_VERSION
      cmdsize 32
      
    • 再来对比一下 RxSwift动态库 name 的信息

      TestExample (自己的包装的动态库) RxSwift (真实项目中生成的)
      name @rpath/Frameworks/TextExample.framework/TestExample (offset 24) @rpath/RxSwift.framework/RxSwift (offset 24)
  • test 执行文件的 rpath

    install_name_tool -add_rpath /Users/shenyj/framework动态库 test

    前面绝对路径成功运行的前提是动态库和执行文件中的 rpath一一对应了, 既然这里又重新修改了动态库的路径,现在再去给先前链接后的可执行文件添加一个 rpath

    动态库的 rpathFrameworks文件夹开始,可执行文件为动态库补全 rpath 的路径

    • 查看 test 可执行文件的 LC_RPATH (即当前可执行文件下配置过的rpath

      ❯ otool -l test | grep 'RPATH' -A 5
              cmd LC_RPATH
          cmdsize 144
              path /Users/shenyj/framework动态库 (offset 12)

      在添加之前,输出为空
      这样可执行文件的 rpath + 动态库的 rpath 就是一个完整的路径了

  • 无需重新编译链接,在 lldb环境下直接运行

    ❯ lldb -file test
    (lldb) target create "test"
    Current executable set to '/Users/shenyj/framework动态库/test' (x86_64).
    (lldb) r
    Process 91954 launched: '/Users/shenyj/framework动态库/test' (x86_64)
    2022-02-11 22:49:37.169603+0800 test[91954:3729185] TestExample----
    2022-02-11 22:49:37.169938+0800 test[91954:3729185] testApp----
    Process 91954 exited with status = 0 (0x00000000)

在给 test 可执行文件添加 rpath时,前面仍然是个绝对路径,除此方式外, 系统还提供了两个路径

链接时设置rpath

资料

Getting Started

Social

Clone this wiki locally