我有一个依赖于库Y的库X.我有一个从X调用函数的App A.
假设库Y仅作为静态库提供。如果X和Y都静态链接到App A,一切正常。但是,我希望X成为一个动态(共享)库。
目前,静态链接Y不起作用,因为动态X无法看到Y中的内容。
有没有办法让Y作为动态库而不必静态地将X链接到Y?我们不能将Y包装起来,以便我们有一个动态版本的Y.一般来说,是否有可用的链接器选项以某种方式将Y(静态链接到A)暴露给X(动态库)?
我要问的原因是我还有库Z也依赖于Y.我不想将Y静态地链接到X和Z,因此X和Z可以是动态的。
希望这不会太混乱。我感谢任何帮助。
答案 0 :(得分:3)
你想要编译静态链接Y的X的动态版本。然后应用程序只链接X,并且不知道Y的使用。你是否可以做到这一点因平台而异我认为 - 我知道GCC并且GNU链接器将允许它。问题是编译用作静态库的代码和编译用作动态库的代码不相同;生成动态库,以便它们可以在任何内存区域中重新定位(这使它们可共享)。在Linux和Solaris上,这意味着使用“-fpic”指令编译共享库。如果在创建共享库时混合使用PIC'd代码和非PIC代码(这是将Y静态链接到X时会发生的情况),您将收到有关未解析的文本重定位的错误 - 这是链接器抱怨的部分你的图书馆是不可分割的。您可以通过传递-mimpure-text来禁用警告。但是,要意识到内存中包含未使用“-fpic”编译的代码的任何页面(因此任何包含对Y的调用的页面)将不会在应用程序之间共享。因此,如果多个应用程序正在使用您的库,它们将无法通过使用共享库获得通常所带来的全部内存节省。如果那是你的平台,Windows上可能存在等效的MSVC标志。
编辑:在我的第一次阅读时没有发现你的Z问题。尝试使用“-z undefs”编译X和Z,这样GCC将忽略未定义的符号,然后当你链接你的应用程序时确保Y在链接上X和Z之后的行(后面的库填写了早期库中的参考文献)。
答案 1 :(得分:1)
嗯,将静态库转换为.so:
相当简单gcc -shared library.a -oliblibrary.so
这解决了吗?
答案 2 :(得分:0)
正如你所指出的那样 - 如果你包裹Y或有动态Y你的问题就会解决。
为什么不能包装Y以使其动态化?
为什么你不能获得动态Y?
鉴于你不妥协的限制,你可能需要为Z和X链接Y.你基本上是删除所有选项......