【发布时间】:2012-04-13 14:32:23
【问题描述】:
这是一个 iOS 问题。
我构建了一个静态库(iOS 中的框架),然后将其包含在应用程序中。结果二进制文件的大小(500kb)小于静态库的大小(6mb)。这是如何运作的?我对静态库的理解是静态库包含在最终的二进制文件中
【问题讨论】:
标签: objective-c c ios build static-libraries
这是一个 iOS 问题。
我构建了一个静态库(iOS 中的框架),然后将其包含在应用程序中。结果二进制文件的大小(500kb)小于静态库的大小(6mb)。这是如何运作的?我对静态库的理解是静态库包含在最终的二进制文件中
【问题讨论】:
标签: objective-c c ios build static-libraries
因为您没有使用库的所有功能。归档类型为.a 的静态库是.o 目标文件的集合,并且在链接时仅包含程序中需要的目标文件。
【讨论】:
.o 文件中。在这种用法中,.o 文件头的开销很容易达到每个.o 文件大小的 25%,在最坏的情况下,开销可能是代码大小的几十或几百倍。也就是说,一个精心设计的.a 文件通常可能有50% 的代码和50% 的.o 文件头。当然,这与 ouah 的回答一起使用:库的结构越好,链接器就越有机会忽略不需要的目标文件。
-ffunction-sections(有效地将每个函数放在.o 文件中)等),所以也许在源代码级别这样做并不重要曾经是。
-ffunction-sections 和相关选项可用,但我认为它们没有被广泛使用,而且我不清楚是否默认启用了必要的链接器选项.还有一些情况,比如包含函数指针的静态结构,-ffunction-sections 可能(同样,我不确定)不足以消除不需要的函数。
-Objc 链接器标志时会发生什么情况,该标志会强制包含所有函数,无论是否使用它们?
当你静态链接一个可执行文件时,链接器可以继续并解析所有符号名称(即将它们映射到一个地址),因为 所有 它现在知道的关于你的符号已经提供给链接器(以.o 文件和.a 库的形式,它们实际上只是.o 文件的集合)。如果名称不存在,您将收到链接错误(这与动态链接不同,您可以在运行时加载另一个库)。在您的情况下,您有可执行文件未引用的额外符号。由于链接器知道这些符号是未使用的,因此它们只是从可执行输出中删除。因此,在这种情况下,您的可执行文件将小于输入库。
【讨论】:
-Objc 或-all_load 标志后会发生什么?
-Objcdescribed here 的效果表示它将“加载实现任何 Objective-C 类或类别的静态库的所有成员。”,并且作为警告说“但它可以使生成的可执行文件更大,并且可能会拾取不必要的对象。”。因此,这将使可执行文件大于常规链接(如果您有这些对象)。 -all_load 听起来更加激进,包括根据this description 的目标代码,包括更多的目标代码。
-Objc 和-all_load 影响的对象需要在对象代码中。如果这些对象(例如额外的 Objective-C 类或类别)不在库或 .o 文件的集合中,则它们不会链接到可执行文件。