如何在没有公开所有符号的情况下为iOS创build静态库
这个问题之前已经被问过了,但是深入挖掘各种开发工具的文档,看起来这是可能的,只是不明显。
动机:制作一个供其他iOS开发人员使用的静态库。 库中的一些符号会导致出现问题,所以我希望使它们成为内部符号。 使用dynamic库这很容易,只需使用-exported_symbols_list
libtool
( ld
)参数,并列出你想要公开的参数。 libtool
文档不会允许静态库的这个参数。
库有几个使用相互代码的ObjectiveC .m文件。 只有组中的一个类需要向最终的.a静态库文件的用户公开。
试过libtool -exported_symbols_list publicsymbols.exp
但libtool
参数不支持静态库的静态。
不能使这些符号具有私有属性(如果甚至可以),因为组中的其他.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
fn1
和fn2
。 您必须加载整个库,否则都不会加载,但是两个程序都可以加载它,而不会将多个副本放在内存中。 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
不能工作静态库,但可以对目标文件生效。