如何在没有公开所有符号的情况下为iOS创build静态库

这个问题之前已经被问过了,但是深入挖掘各种开发工具的文档,看起来这可能的,只是不明显。

动机:制作一个供其他iOS开发人员使用的静态库。 库中的一些符号会导致出现问题,所以我希望使它们成为内部符号。 使用dynamic库这很容易,只需使用-exported_symbols_list libtoolld )参数,并列出你想要公开的参数。 libtool文档不会允许静态库的这个参数。

库有几个使用相互代码的ObjectiveC .m文件。 只有组中的一个类需要向最终的.a静态库文件的用户公开。

试过libtool -exported_symbols_list publicsymbols.explibtool参数不支持静态库的静态。

不能使这些符号具有私有属性(如果甚至可以),因为组中的其他.m文件需要它们。

看起来像ld可以采取几个.o文件,并将它们链接到一个新的.o文件(通过-r参数),它没有“dynamic唯一”的免责声明-exported_symbols_list参数(这可能只是不清楚的文档…)。

就像testing我用Xcode构build项目一样,我将所有的.o文件制作完成,然后尝试在命令行上调用ld ,如下所示:

 ld -r -x -all_load -static -arch armv6 -syslibroot {path} -filelist /Users/Dad/ABCsdk/iphone-ABClib/build/ABCLib.build/Distribution-iphoneos/ABCLib-device.build/Objects-normal/armv6/ABCsdk.LinkFileList -exported_symbols_list {exp file path} -o outputfile.o 

{path}types的东西有很长的path,在那里适当的地方。

但我得到如下错误:

/ usr / bin / ld_classic:/Users/Dad/ABCsdk/iphone-ABClib/build/ABCLib.build/Distribution-iphoneos/ABCLib-device.build/Objects-normal/armv6/ABCmain.o不兼容,文件包含不受支持的types加载命令0中的第3节(_ TEXT, _picsymbolstub4)(必须指定“-dynamic”来使用)

所以有些东西似乎错了

任何人都知道一个聪明的方法来做这个工作? 谢谢。

这真的不可能,我很抱歉地说。 它与静态库的工作方式有关。 静态库只不过是捆绑在一起的一堆对象*.o文件,而dynamic库就像可执行文件一样是一个可加载的二进制映像。

假设你有四个文件,

  • common.c定义了common ,即“private”
  • fn1.c定义fn1 ,它调用common
  • fn2.c定义fn2 ,它调用common
  • other.c定义other

在dynamic库中,链接器将所有东西都捆绑成一大块代码。 该库导出other fn1fn2 。 您必须加载整个库,否则都不会加载,但是两个程序都可以加载它,而不会将多个副本放在内存中。 common的入口点从符号表中简单地丢失 – 不能从库之外调用它,因为链接器找不到它。

请注意,应用程序和共享库具有基本相同的格式:应用程序基本上是共享库,只导出一个符号main 。 (这不完全正确,但接近。)

在静态库中,链接器从不运行。 这些文件全部被编译成* .o文件并放入一个* .a库文件。 内部参考将被解决。

假设你的应用程序调用fn1 。 链接器看到一个未parsing的fn1调用,然后查看库。 它在fn1.o中findfn1的定义。 然后链接器注意到一个common的未解决的调用,所以它通常查找它。 这个程序不会从fn2.c或other.c中获取代码,因为它不使用这些文件中的定义。

静态库是非常古老的,他们没有任何dynamic库的function。 您可以将静态库视为基本上是一个完整的编译源代码的zip文件,而不像一个链接在一起的dynamic库。 从来没有人打算扩展存档格式来添加符号可见性。 当你与一个静态库链接时,你会得到和把程序库的源代码添加到程序中一样的结果。

短版本:一个dynamic库有一个所有导出符号的符号表,但没有一个私有符号。 同样,一个目标文件有一个所有extern符号的列表,但没有一个是static的。 但是一个静态库没有符号表,它只是一个存档。 所以没有任何机制可以将代码隐藏到静态库(除了定义static对象,但对于Objective-C类不起作用)。

如果我们知道你为什么要这样做,也许我们可以给你一个build议。 (这是为了安全吗?名字冲突?所有这些问题都有解决办法。)

XCode BuildSetting可以做到这一点! 1.将Perform Single-Object Prelink设置为YES 2.将Exported Symbols File设置为path_for_symbols_file

也许你应该删除-static-exported_symbols_list不能工作静态库,但可以对目标文件生效。