如何链接到 libabc.a 而不是 libabc.so?

Posted

技术标签:

【中文标题】如何链接到 libabc.a 而不是 libabc.so?【英文标题】:How to link to the libabc.a instead of libabc.so? 【发布时间】:2011-11-08 03:46:24 【问题描述】:

在书Autotools: A Practioner's Guide to GNU Autoconf, Automake, and Libtool,第6章(使用libtool构建库)中,给出了链接库的example。

在示例中,库 libjupiter.so 链接到另一个库 libjupcommon.a。第一次尝试失败,因为 libjupiter.so 需要 PIC,但 libjupcommon.a 不需要。作者添加libjupcommon_a_CFLAGS = -fPIC修复。它变得更好了,但出现了“将共享库 libjupiter.la 与静态库 ../common/libjupcommon.a 链接起来不可移植!”的警告。

因此作者再次修改了Makefile.am,使用libtool构建libjupcommon.lalibjupiter 链接到 libjupcommon.la。 像这样:

noinst_LTLIBRARIES = libjupcommon.la

libjupcommon_la_SOURCES = jupcommon.h print.c

...

libjupiter_la_LIBADD = ../common/libjupcommon.la

这次一切正常。


现在,我的问题:

我有一个库需要另一个库,就像libjupiter 需要libjupcommon。不同之处在于我的libjupcommon 来自另一个项目并安装到系统中。它不是noinst_LTLIBRARIES.so.a 版本都存在。当我尝试像示例所示链接libjupcommon.la 时,选择了.so,但我不想要动态链接关系。我想链接到.a,就像书中的例子一样。

显式链接到.a(通过使用 _LIBADD=.a 文件)提供了一个可用的库,但给出了“...不可移植”的警告。

在这种情况下,实现链接到.a 的正确方法是什么?

PS:从book's official site 下载示例。在autotools/book/jupiter-libtool-ch6/common 中,将Makefile.am 的noinst_LTLIBRARIES 修改为lib_LTLIBRARIES 应该很接近我的问题。

【问题讨论】:

你想建什么库?共享库还是静态库?如果您正在构建共享库,那么与已安装的 .a 库链接是没有意义的,因此会出现 libtool 警告。如果您正在构建静态库,则应明确说明(请参阅 ldav1s 的回答)。 我想建立一个共享库。即使安装的.a 是PIC 也没有意义?为什么会这样? 但在那种情况下,.a 不是由 Libtool 生成的。据我所知,Libtool安装的.a文件不是PIC。 【参考方案1】:

您可以尝试几件事。您可以尝试使用--disable-shared 选项运行configure 以关闭共享库的编译(并再次将静态库添加到libfoo_LIBADD)。您可以尝试将-static 添加到libfoo_LDFLAGS 以让libtool 静态构建它(同样将静态库添加到libfoo_LIBADD)。

编辑:由于需要静态库和共享库,因此上述方法不起作用。

尝试添加:

AC_CHECK_LIB([abc],[some_function_in_libabc])

配置.ac。

【讨论】:

你的意思是只编译静态的?我认为它会起作用。但我需要静态和动态libjupcommon;并让libjupiter.so 链接静态链接。 noinst_LTLIBRARIES 是便利库,旨在在构建期间与某些可执行文件或其他库重新链接。 在阅读了libtool的代码之后,我确信构建一个纯静态库是我应该做的。像 libfoo.so、libfoo.a libfoo_static.a。谢谢 ldav1s。【参考方案2】:

您可以使用此构造强制静态链接到 一个 库(同时保持所有其他链接共享):

-Wl,-Bstatic -Wl,-whole-archive -Xlinker -l$1 -Wl,-no-whole-archive -Wl,-Bdynamic

将上面的 $1 替换为您的库名称。

解释:上面的大部分怪事都是为了绕过 libtool 将重新排列命令行参数这一事实,这非常有帮助。使用 -Xlinker 将强制 libtool 忽略 -l$1 并且不重新排列它。 -Wl,-Bstatic 告诉链接器将所有以下库链接为静态。 -Wl,-Bdynamic 切换回动态链接以获取更多库。

【讨论】:

以上是关于如何链接到 libabc.a 而不是 libabc.so?的主要内容,如果未能解决你的问题,请参考以下文章

如何强制 CMake 链接到系统库而不是同名目标

Highcharts:如何将图例链接到类别而不是条形系列?

如何根据链接到用户的模型(而不是基于用户组)设置 Django 权限?

如何调整我的模型以将上传的图像存储到我的数据库作为图像的链接而不是显示为 blob?

如何隐藏滚动间谍中的其他内容而不是滚动到特定位置

如何制作一个只是链接而不是 iFrame 的 Facebook“Like”按钮?