【问题标题】:binding .a file with the .so shared library file in linux在linux中将.a文件与.so共享库文件绑定
【发布时间】:2018-07-11 10:01:07
【问题描述】:

我有一个 .a 文件(ar 命令),我想在 GCC 编译期间将它与我的 .so 文件绑定。

我该怎么做。

如果我运行这个命令:

gcc /usr/local/apr/lib/libapr-1.a ../../ndagentlibc/obj/*.o tideways_xhprof.o tracing.o -shared -o libhello.so


nm libhello.so | grep apr_term

output:  U    apr_terminate

apr_terminate 没有得到它的定义

【问题讨论】:

  • 例如:gcc ../libnd.a trendways_xhprof.o tracking.o -shared -o libhello.so .. 好吗?
  • 不,请看我的回答。

标签: c linux gcc libtool


【解决方案1】:

如果您的.so 文件需要.a 文件,请将您的.so.a 文件链接,.a 存档中的所有所需代码都将在.so 文件中提供。

【讨论】:

  • 请查看链接器文档...参数顺序对于选择归档文件中的目标模块至关重要。只有在已经检测到可以解决的未解决的引用(包括存档中的模块)时才会选择它们...否则该模块将不会包含在最终的可执行文件中。
  • @LuisColorado 当然,我的印象是你的 SO 是需要 A 的组件。如果不是这样,你不能将它捆绑在 SO 文件中,它不像可以嵌入任何类型资源的 macOS 框架。
  • 不,您正在进行混合链接,.so 文件在运行时动态加载,.o 静态对象在链接时绑定。通常将它们存档在 .a 存档中,因为链接器仅使用所需的。但是要选择一个文件,您需要先触发未解决的问题。将.so 或更高版本链接到最终可执行文件时,您可以将.o 添加到.so,始终,当链接.so 时,这两种策略都是可能的。
  • 顺便说一句,.a 不是资源......它只是一个档案......它没有什么特别的,但链接器进入它,并从那里得到当时需要的东西.它仅简化了与大量静态对象的库的链接...
  • @LuisColorado 我认为我们彼此误解了
【解决方案2】:

重新排序您的命令并将.a 库放在末尾...

gcc ../../ndagentlibc/obj/*.o tideways_xhprof.o tracing.o -shared -o libhello.so /usr/local/apr/lib/libapr-1.a

因为ld(1) 链接器仅选择包含在库存档中的对象模块 (*.o),它知道在阅读它时 有未解决的引用(正如您将其放在首位在您的命令行中,到那时没有出现未解决的引用,因此在库处理时没有选择并包含库 .o 组件)

在目标模块存档的情况下,链接器会尽力做到最好,只选择那些看起来是必要的,并且首先放置存档会使链接器不从中选择要链接的文件。

注意

顺便说一句,-shared 选项用于创建可能不是您想要的共享对象(.so 模块)。如果要创建最终的可执行程序,请不要使用-shared。我指出这一点,因为我第一次不得不与之抗争,我假设链接的类型(共享或静态)是用某个选项指定的(我认为常见错误)但实际上给出了链接的类型,对象为对象,根据您提供给链接器的文件类型,而不是使用命令行选项。除了其他事情之外,它使链接器在程序中缺少某些引用时不遵守(它假设这些将在以后的链接中解决)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-09-27
    • 1970-01-01
    • 2017-06-12
    • 2012-11-16
    • 2019-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多