Xcode 动态库的设置

最近项目开发新的功能,要在主应用中嵌入一个子程序:
(本文暂不涉及如何嵌入子程序)
在这里插入图片描述
主程序和子程序引用同一个framework,出现了重复,这会导致程序比较大。
为了解决此问题,学习了解了下xcode动态库设置
重复

1. 首先我在子程序中移除嵌入的framework

2. 因为公用framework,所以我觉得将该framework嵌入大SharedFrameworks路径下比较合适
注: 路径是可以自定义的,我在该Demo中将其放在~/**MainApp.app/Contents/SharedFrameworks

3. build主工程后在主工程的.app文件中双击打开子程序
发现无法打开子应用,在Console中看到crash日志:

Dyld Error Message:
  dyld: Using shared cache: 467A83CB-BA86-3F07-B652-B9256C74080A
Library not loaded: @rpath/**IPCComm.framework/Versions/A/**IPCComm
  Referenced from: /Users/USER/Library/Developer/Xcode/DerivedData/ZWIPCDemo-gkbfqxfobhhkajaylzhevlbfjqaq/Build/Products/Debug/**MainApp.app/Contents/Applications/**Indexer.app/Contents/MacOS/**Indexer
  Reason: image not found

Library not loaded: @rpath/**IPCComm.framework/Versions/A/**IPCComm

4. 解决:

  1. 配置子程序Runpath Search Paths 路径:
    这个路径要根据子工程嵌入的位置来设置
    我的子应用相对主应用的路径:
    ~/**MainApp.app/Contents/Applications/**Indexer.app
    我嵌入的共享Framework路径:
    ~/**MainApp.app/Contents/SharedFrameworks/**IPCComm.framework

所以我配置的是@executable_path/…/…/…/…/SharedFrameworks

2. 配置住程序Runpath Search Paths 路径:
我配置的为;@executable_path/…/SharedFrameworks


在解决该问题的过程中遇到几个变量:

@rpath, @loader_path, @executable_path

官方文档:Dynamic Library Programming Topics

参考1
参考2

这里copy下参考2,以作记录(暂未验证,因为我的案例和这个介绍不同)

1. @executable_path
这个变量表示可执行程序所在的目录. 比如 /path/QQ.app/Contents/MacOS/

2. @loader_path
这个变量表示每一个被加载的 binary (包括App, dylib, framework,plugin等) 所在的目录.

在一个程序中, 对于每一个模块, @loader_path 会解析成不用的路径, 而 @executable_path 总是被解析为同一个路径(可执行程序所在目录).

比如一个会被多个程序调用的 plugin, 位于 /path/Flash Player.plugin/Contents/MacOS/Flash Player, 依赖 /path/Flash Player.plugin/Contents/Frameworks/XPSSO.dylib.
那么 XPSSO.dylib 的 INSTALL_PATH 可以设置为 @loader_path/…/Frameworks, 这样设置的话, 不论 Flash Player.plugin 目录放到什么位置, XPSSO.dylib 都能正确的被加载.

2. @rpath
和前面两个不同, 它只是一个保存着一个或多个路径的变量.
比如 XPSSO.dylib 被两个 .app 使用, 且被包含的路径不同。
比如:

  • softA.app/Contents/MacOS/dylib/XPSSO.dylib
  • softB.app/Contents/MacOS/Frameworks/XPSSO.dylib

将 XPSSO.dylib 的 INSTALL_PATH 设置成 @loader_path/…/dylib 或 @loader_path/…/Frameworks 都只能满足其中一个 .app 的需求.

要解决这个问题, 就可以用 @rpath.
将 XPSSO.dylib 的 INSTALL_PATH 设置成 @rpath, 然后在编译 softA.app, softB.app 时分别指定 @rpath 为 @loader_path/…/dylib, @loader_path/…/Frameworks, 问题得到了解决.
@rpath 的另一个优点是可以设置多个路径. 如果 softA.app 还需要使用另一个 .plugin (假设它的 INSTALL_PATH 也设置成了 @rpath), 位于 @loader_path/…/plugin, 把这个路径加到 @rpath 即可.

XPSSO.dylib的Build Settings中设置Installation Directory:

在 softA.app或softB.app 中设置 Runpath Search Paths(对应了@rpath):

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值