查找iOS上每个外部库贡献的大小

查找iOS上每个外部库贡献的大小,ios,xcode,linker,uikit,Ios,Xcode,Linker,Uikit,我正在尝试减少我的应用商店二进制大小,我们有很多外部lib,这可能会影响最终ipa的大小。有没有办法找出每个外部静态库在最终二进制文件中所占的比例(除了删除每个静态库?)我认为您应该能够从中提取所需的信息: 符号-w-此处没有您的文件来源 参考: IIRC,它不会为您提供每个库的明确摘要信息,但您会发现每个库中的函数都应该聚集在一起,因此只需稍加努力,您就可以计算每个库的大致贡献:还要确保在构建设置中将“生成调试符号”设置为“否”。这可以将静态库的大小减少约30% 如果这是您担心的一部分,静态库

我正在尝试减少我的应用商店二进制大小,我们有很多外部lib,这可能会影响最终ipa的大小。有没有办法找出每个外部静态库在最终二进制文件中所占的比例(除了删除每个静态库?)

我认为您应该能够从中提取所需的信息:

符号-w-此处没有您的文件来源

参考:


IIRC,它不会为您提供每个库的明确摘要信息,但您会发现每个库中的函数都应该聚集在一起,因此只需稍加努力,您就可以计算每个库的大致贡献:

还要确保在构建设置中将“生成调试符号”设置为“否”。这可以将静态库的大小减少约30%

如果这是您担心的一部分,静态库就是将相关的.o文件一起归档,再加上一些簿记。因此,一个1.7mb静态库——即使其中的代码是整个1.7mb——通常不会向您的产品中添加1.7mb。关于死代码剥离的常规规则将适用

除此之外,您还可以减少代码的构建大小。下面可能不是一个全面的列表

在目标的构建设置中,查找“优化级别”。通过将其切换为“最快、最小的操作系统”,您将允许编译器为大小牺牲一些速度

确保您正在为thumb构建更紧凑的ARM代码。假设您使用的是LLVM,这意味着确保您的项目设置中没有-mno thumb


还考虑要构建哪些架构。苹果不允许提交同时支持ARMv6和iPhone 5屏幕的应用程序,并且已经完全从最新的Xcode中删除了对ARMv6的支持。因此,在这一点上,可能没有必要包含这些信息。

如果你有耐心筛选的话,所有这些信息都包含在链接图中(对于大型应用程序,它可能会非常大)。链接图列出了所有库、它们的对象文件以及打包到应用程序中的所有符号,所有这些都是人类可读的文本。通常情况下,默认情况下不会将项目配置为生成它们,因此您必须快速更改项目文件

从Xcode中:

  • 在目标的“构建设置”下,搜索“地图”
  • 在下面的结果中,在“链接”部分下,将“写入链接映射文件”设置为“是”
  • 确保记下“链接映射文件的路径”下列出的完整路径和文件名
  • 下次你构建应用程序时,你会得到一个链接映射转储到该文件路径。请注意,路径是相对于您的应用程序在DerivedData文件夹中的位置(通常为
    ~/Library/Developer/Xcode/DerivedData/-/Build/Intermediates/..
    ,但不包括YMMV)。因为它只是一个文本文件,所以您可以使用任何文本编辑器读取它

    链接地图的内容分为3个部分,其中2个与您要查找的内容相关:

  • 对象文件:此部分包含最终应用程序中包含的所有对象文件的列表,包括您自己的代码和您包含的任何第三方库的代码。重要的是,每个对象文件还列出了它来自的库
  • 部分:本部分和您的问题无关,包含处理器段及其部分的列表
  • 符号:本节包含您感兴趣的原始数据:所有符号/方法的列表及其绝对位置(即处理器内存映射中的地址)、大小,最重要的是,对其包含对象模块的交叉引用(在“文件”列下)
  • 根据这些原始数据,您拥有进行所需尺寸计算所需的一切。从#1可以看出,对于每个库,都有N个可能的组成对象模块;从#2中,您可以看到,对于每个对象模块,有M个可能的符号,每个符号占用大小S。对于任何给定的库,您的大致大小顺序将类似于O(N*M*S)。这只是给你一个指示,说明你实际计算中会用到的成分,这不是什么有用的公式。为了执行计算本身,我很抱歉地说,我不知道有任何现有的工具可以为您执行必要的处理,但是考虑到链接映射只是一个文本文件,通过一点脚本魔法和创造力,您可以构建一个脚本来完成繁重的工作

    例如,我有一个链接到以下库的小示例项目:(示例项目本身来自关于ReactiveCocoa的一个很好的教程,这里:),我想知道它占用了多少空间。我已经生成了一个链接映射TwitterInstant-LinkMap-normal-x86_64.txt(它在模拟器中运行)。为了查找库中包含的所有对象模块,我执行以下操作:

    $ grep -i "libLinqToObjectiveC.a" TwitterInstant-LinkMap-normal-x86_64.txt
    
    这就给了我:

    [  8] /Users/Smyrl/Library/Developer/Xcode/DerivedData/TwitterInstant-ecppmzhbawtxkwctokwryodvgkur/Build/Products/Debug-iphonesimulator/libLinqToObjectiveC.a(LinqToObjectiveC-dummy.o)
    [  9] /Users/Smyrl/Library/Developer/Xcode/DerivedData/TwitterInstant-ecppmzhbawtxkwctokwryodvgkur/Build/Products/Debug-iphonesimulator/libLinqToObjectiveC.a(NSArray+LinqExtensions.o)
    [ 10] /Users/Smyrl/Library/Developer/Xcode/DerivedData/TwitterInstant-ecppmzhbawtxkwctokwryodvgkur/Build/Products/Debug-iphonesimulator/libLinqToObjectiveC.a(NSDictionary+LinqExtensions.o)
    
    第一列包含我需要的符号表的交叉引用,因此我可以搜索这些:

    $ cat TwitterInstant-LinkMap-normal-x86_64.txt | grep -e "\[  8\]"
    
    这给了我:

    0x100087161 0x0000001B  [  8] literal string: PodsDummy_LinqToObjectiveC
    0x1000920B8 0x00000008  [  8] anon
    0x100093658 0x00000048  [  8] l_OBJC_METACLASS_RO_$_PodsDummy_LinqToObjectiveC
    0x1000936A0 0x00000048  [  8] l_OBJC_CLASS_RO_$_PodsDummy_LinqToObjectiveC
    0x10009F0A8 0x00000028  [  8] _OBJC_METACLASS_$_PodsDummy_LinqToObjectiveC
    0x10009F0D0 0x00000028  [  8] _OBJC_CLASS_$_PodsDummy_LinqToObjectiveC
    
    第二列包含所讨论的符号的大小(十六进制),因此如果我将它们全部相加,将得到0x103或259字节

    更棒的是,我可以做一些流黑客,将其缩减到基本元素,并为我添加:

    $ cat TwitterInstant-LinkMap-normal-x86_64.txt | grep -e "\[  8\]" | grep -e "0x" | awk '{print $2}' | xargs printf "%d\n" | paste -sd+ - | bc
    
    这给了我一个直截了当的数字:

    259
    
    “\[9\]”
    (13016字节)和
    “\[10\]”
    (5503字节)执行相同的操作,并将它们添加到前面的259字节中,得到18778字节


    你当然可以改进我在这里所做的流攻击,使其更加健壮(在这个实现中,你必须确保获得正确的空格数并引用括号),但至少你知道了这个想法。

    为你的应用程序创建一个.ipa文件并将其保存在你的系统中

    然后打开终端并执行以下命令:

    解压缩-lv/path/t