2011-08-01 14 views
11

这个问题之前已经被问到,但是挖掘到各种开发工具的文档,看起来像这样可能,只是不明显。如何在没有公开所有符号的情况下为iOS创建静态库

动机: 其他iOS开发制作中使用的静态库。如果导出库中的某些符号会导致问题,所以我希望将它们作为内部符号。随着一个动态库,这是很容易,只需使用-exported_symbols_listlibtoolld)参数,并列出要公开的人。 libtool文档不会允许这种说法的静态库。

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

尝试了libtool -exported_symbols_list publicsymbols.explibtool的论点不支持-static静态库。

不能使符号与私有属性(如果那会甚至工作),因为它们是由该组中的其他.m文件需要。

看起来像ld可能需要几个.o文件,并将它们连接成一个新的.o文件(通过-r参数),它并没有为-exported_symbols_list参数“动态只有”声明(这可能仅仅是不清楚的文件...)。

只是作为一个测试,我建我的Xcode项目,所以我都.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 

其中{}路径类型的东西有很长的路径到那里的适当的地方。

,但我得到类似下面的错误:

在/ usr/bin中/ ld_classic:/Users/Dad/ABCsdk/iphone-ABClib/build/ABCLib.build/Distribution-iphoneos/ABCLib-device。建立/对象 - 正常/的ARMv6/ABCmain.o不相容,文件包含不支持的类型在负荷命令0第3(_ TEXT, _picsymbolstub4)的(必须指定 “-dynamic” 被使用)

所以有些事情似乎不对劲的地方......

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

+0

你需要隐藏什么样的符号? – Macmade

+0

符号如果他们有相同的子库已经链接到他们的应用程序可能会冲突(JSONkit说)。显然,我可以包含JSONKit文件,并说如果它们还不在您的项目中,也可以包含它们,但我希望将一个.h文件和.a文件添加到项目中以实现更清洁的集成。 – Dad

回答

14

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

假设你有四个文件,

  • common.c中定义common,这是 “私人”
  • fn1.c定义fn1,这就要求common
  • fn2。c定义了fn2,其调用common
  • other.c定义为other

在一个动态库,链接捆绑一切成的代码一个大截。该库出口other,fn1fn2。您必须加载整个库或不加载它,但是两个程序都可以加载它,而不会将多个副本放入内存中。 common的入口点在符号表中完全没有 - 您不能从库之外调用它,因为链接程序找不到它。

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

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

假设您的应用程序调用fn1。链接器看到一个未解决的调用fn1,然后查看库。它在fn1.o中找到了fn1的定义。然后链接程序发现一个未解决的电话号码为common,所以它会共同查看它。该程序不会从fn2.c或other.c中获取代码,因为它不使用这些文件中的定义。

静态库是非常古老的,他们没有任何动态库的功能。您可以将静态库视为基本上是一个包含已编译源代码的zip文件,而不像一个链接在一起的动态库。没有人曾打算扩展存档格式以添加符号可见性。当您与静态库链接时,您会得到与将库的源代码添加到程序中相同的结果。

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

如果我们知道您为什么试图这样做,或许我们可以给您一个建议。 (是否为安全?名称冲突?所有这些问题都有解决方案。)

+0

我不想写一个新的答案,因为你已经在这里写了一个很好的解释,但是看起来解决方案就是将所有源文件合并为一个文件,并将其编译为一个单元。 (自动,而不是手动。)SQLite项目做这样的事情。 – benzado

+0

@benzado:对于Objective C类不起作用。 –

+0

不够公平,所以即使他可以隐藏其他符号(函数,常量),类名仍然会被暴露,所以没有意义。 – benzado

0

XCode BuildSetting可以做到这一点! 1.设置Perform Single-Object PrelinkYES 2.设置Exported Symbols Filepath_for_symbols_file

也许你应该删除-static-exported_symbols_list不能工作静态库,但可以采取目标文件的影响。

相关问题