手头上有一个 iOS 动态库项目,因为想要自动编译生成 XCFramework ,在网上找了一个脚本生成 XCFramework ,结果发现生成的 XCFramework 库(arm64+armv7 架构)比平常生成的 framework 大多了,前者是 23.1M, 后者是 4.7M
上面用的生成 XCFramework 脚本是 How to make XCFramework / Fat Framework in Xcode 里的第 1 个脚本
研究了一下,发现这个脚本里是用 Archive 生成目标 framework 的,而我们平常都是直接用 Run+Release 模式编译的。查问题手动进行 Archive 编译时,发现生成的 Products 目录还是空的。搜了一下在 Build Setting 中设置 SKIP_INSTALL
为 NO ,就能成功 Archive 出 framework 了,大小跟前面脚本生成的一致了,是 23.1M 。
另外发现把 BitCode 改为 NO 后,手动 Archive 生成的 framework 大小变为 6.3 MB 了。
这个 Framework 项目里用到了 OpenSSL 的 libssl.a 和 libcrypto.a 库,可能是这个原因,前者是 21.4M ,后者是 4.3M ,可能是这两个库的原因导致 Archive 生成的库比较大?感觉不太像。
同样都是 BitCode 为 YES 的情况下,为什么用 Run+Release 模式生成的 framework 就小很多呢,有人知道原因吗?
1
Tangdixi 2022-02-18 13:00:11 +08:00
Run+Release 模式下,应该会命中符号优化吧,比如 -Oz 之类的
|
2
xuzhongzhou 2022-02-18 13:18:46 +08:00 via iPhone 2
run 和 release 没有特别配置的情况下,bitcode 并没有真的加进去。
在 Build Options 中启用 BitCode ,且使用 Build 而非 Archive 编译时,Xcode 会自动添加编译选项-fembed-bitcode-marker ,这个选项的意思大概就是说:如果 BitCode 开启的话,这里本来应当是放 bitcode 的,实际上没放。 |
3
pheyer OP @xuzhongzhou 还真是的,原来直接用 Run+Release 模式得到的 Framework 是假 Bitcode ,估计是为了方便真机测试吧。archive 模式就是用 -fembed-bitcode 参数的
搜了一下,发现有办法判断生成的 framework 是用 -fembed-bitcode-marker 还是用 -fembed-bitcode 参数编译生成的。可以参考 https://www.jianshu.com/p/9a081d681967 这篇文章。 |
4
icyalala 2022-02-18 14:22:33 +08:00
遇到这种 macho 问题,可以用 MachOExplorer 或者 XMachOViewer 打开看看,
对比能看到那个大的里面多了个 __LLVM 段,里面就是 bitcode ,没有就说明 bitcode 没打包进去。 |
5
pheyer OP @xuzhongzhou
@icyalala 估计是因为第三方也没用 BitCode ,所以没发现我们提供的库有 BitCode 问题的。这么一看,要用 BitCode 的话,还非得用 Archive 编译 Framework 不可。 我还想知道的是,除了这个 BitCode 差异,以及 dSym 差异,Run+Release 模式编译和 Archive 编译生成的 Framework 还有没有其它的类似差异,你们知道吗 |
6
magic3584 2022-02-18 14:49:05 +08:00
收藏了,我一直用的 build+release 去生成 framework 的,而且一直以为 bitcode 开启后 framework 会小。。。
准备查查资料学习下,感谢~ |
7
CaffreySun 2022-02-18 15:32:34 +08:00
自己写了打包 XCFramework 的脚本,用 xcodebuild archive 命令生成 xcarchive ,然后再用 xcarchive 合并成 XCFramework
|
8
CaffreySun 2022-02-18 15:40:34 +08:00
我看你提到的脚本中合成 XCFramework 是这样 `xcodebuild -create-xcframework -framework xxxx.xcarchive/Products/Library/Frameworks/xxxx.framework`
其实可以不用这样拼接路径 /Products/Library/Frameworks/xxxx.framework 优雅一点的做法 `xcodebuild -create-xcframework -archive xxx.xcarchive -framework xxxx.framework` 如果哪天 xcarchive 里的目录有调整,拼接路径的方法就无法运行了。 |
9
pheyer OP @CaffreySun 感谢提醒
|
10
icyalala 2022-02-18 16:34:59 +08:00
@pheyer macho 文件多了个 LC_SEGMENNT(__LLVM) 和 LC_ENCRYPTION_INFO 这两个 LOAD command 。
其他直接拿 diff 工具比如 Kaleidoscope 看一下就有了。 |
11
xuzhongzhou 2022-02-18 23:30:50 +08:00
验证可以用 @icyalala 说的工具,更简单的方法可以直接用这个命令:
`otool -l yourBinaryLib | grep __LLVM` 有 __LLVM 段就是有 bitcode 。-configuration Run+Release 和 Archive 在输出库上的差异可能要跑下自己对比下完整的编译命令的差异了。实际上 Archive 用的也是 Release 的 config ,应该就是 bitcode 的差别。 |
12
magic3584 2022-02-24 15:28:56 +08:00
@pheyer
请教大佬,为什么 SKIP_INSTALL 为 NO 还是无法 archive 生成 framework 呢? |
13
pheyer OP @magic3584 这个就不知道了,你用上面链接中的第 1 个脚本能生成 xcframework 吗,它里面也是用 archive 的?
|
14
magic3584 2022-02-25 10:11:18 +08:00
@pheyer #13
脚本没有尝试,archive 后导出后能找到 framework 了,但是 Xcode 中的 Products 下面还是没有。 而且我测试了一下,Bitcode 为 NO 时,archive 比 build 要小,但是 Bitcode 为 YES 时,archive 比 build 要大。 请问楼主知道为什么了吗?求分享资料 |
15
pheyer OP @magic3584 archive 后 Xcode 中的 Products 下面就是没有的,Archive 完自动显示的列表中选择刚的包右键选择 show in finder ,里面的 Products 就是你要找的 framework
开启 Bitcode 包会变大,这与 BitCode 的原理相关,网上很多的,你搜一下就行 |
16
magic3584 2022-02-25 10:45:18 +08:00
@pheyer #15
Bitcode 为 YES 时候包大我了解了,但是不清楚为什么 archive 和 build 相比一会大一会小 |
17
pheyer OP @magic3584 archive 和 build 相比一会大一会小这个问题上面都说到了啊,可以理解为设置了 BitCode 后,Archive 模式是真 Bitcode ,Build 模式是假 Bitcode
|
18
magic3584 2022-02-25 11:31:12 +08:00
@pheyer #17
大佬您的意思是 archive 理应比 build 小吗?在 Bitcode 为 YES 时 archive 反而大是因为加入了 bitcode ? |
19
pheyer OP @magic3584 在 Bitcode 为 YES 时 archive 反而大是因为加入了 bitcode——这个是这样的,而且是大很多。BitCode 为 No 时看你的 Build 是 Debug 模式还是 Release 模式吧,另外还要看 Build Setting 中的优化选项,这种情况下与 Archive 后的包比较大小没有绝对答案,纠结这个没意义
|