自动工具用户如何指定静态和动态链接的组合?

14
我正在使用autoconf,automake和libtool构建程序。我的工作要求我静态链接(大部分)库。过去这不是问题因为我可以使用-all-static来链接所有的库。现在有一个问题,因为我必须使用一个只有动态库的库;它是由第三方给我们的,我们没有源代码。
当然,-all-static现在导致构建失败。有没有可能告诉libtool静态链接除了这个库之外的所有东西?是不是静态和动态链接的任意组合都可能由libtool完成,或者只能是全静态或全动态?
到目前为止,我尝试使用LDFLAGS = -static创建一个便捷库,该库依赖于我想要静态链接的库。但是libtool不会连接静态库,就像我希望的那样。依赖于便利库的程序仍然动态链接所有内容。
我还尝试了--disable-shared,但这对构建没有影响。
这些问题类似,但并没有真正回答我的问题:
- Force linking a static library into a shared one with Libtool - Is it possible to link some — but not all — libraries statically with libtool? (我不想从系统中删除共享库,指定所有内容的完整路径几乎和手动链接一样糟糕,但也许这是唯一的方法。)
2个回答

13
您没有指定操作系统,但我们假设它是相对较新的Unix/Linux/OSX。如果不是,请忽略以下警告。
在回答之前,您应该知道,在大多数基于ELF的系统(Unix/Linux)上混合静态和共享代码是有问题的。其中一个原因是,如果您忘记重新链接已更新的依赖项,它可能会导致代码不同步。另一个原因是由于静态代码与PIC的性质不同。这就是为什么libtool试图阻止它的原因。
话虽如此,在Makefile.am中(假设您的最终程序是foo,共享库是:):
    .
    .
    .
    foo_SOURCES = foo.c abc.c def.c hij.c
    foo_LDFLAGS = -all-static -Wl,-Bdynamic,-L/path/to,-lshared,-Bstatic
    foo_LDADD = -L../path/to -lbar -lbaz

重要的是,libtool允许您通过直接传递-Wl,参数给链接器(GNU ld)来绕过检查和GNU gcc的-static标志(由libtool使用)。使用逗号,分隔符在参数之间添加空格。 -Bstatic-Bdynamic都在GNU ld的info pages以及帮助屏幕中有记录。再次强调,由于您没有提到所使用的操作系统或编译器包,我假设是Linux上的GNU gcc和GNU ld。您可以使用ld --help进行验证。如果出于某种原因它不是GNU ld,则需要找到等效的-Bstatic-Bdynamic标志,并在适当的位置进行替换。

1
这个可以工作,但会失去一些灵活性。我不需要动态构建,但如果我需要的话,我需要编辑一些 Makefile.am,对吧?这也会导致像 AC_CHECK_LIB 这样的宏出现问题(它只是将 -l 添加到 LIBS 中),但我想这是可以预料的。 - tprk77
2
我提供了最简单的方法。但是,如果你想要更高级的东西,你可以将标志拉入你的 configure.ac 中。一旦在那里,你可以添加 DYNLIBS="-Wl,-Bdynamic,-L/path/to,-lshared,-Bstatic" 并调用 AC_SUBST([DYNLIBS])。然后你只需要在你的 Makefile.am 中调用 $(DYNLIBS)。这会给你更多的控制权,但请记住,AC_CHECK_LIBS 不检查静态库和动态库。这是你想要的吗?还是有其他什么东西可以使它更灵活? - NickW
我正在尝试做相反的事情:动态链接所有库,除了给定的一个(以Makefile.am中的cjpeg目标为例)。我已经更改了cjpeg_LDADD = -ljpeg并添加了cjpeg_LDFLAGS = -Wl,-Bstatic,-ljpeg,-Bdynamic,但仍然将libjpeg.so添加到参数并动态链接。如果我说cjpeg_LDADD =,它会抱怨缺少符号。如果我说cjpeg_LDFLAGS = -Wl,-static,它会失败并显示“尝试静态链接动态对象”。该库本身是构建过程的一部分-也许这就是问题所在? - dma_k
刚从这个回答中发现,可以通过 ./configure --disable-shared 来实现这一点(不需要使用 Makefile.am 进行其他技巧)。看起来这是目前唯一的解决方法。 - dma_k

0
在我的情况下,我想要静态链接labA,但是动态链接pthread。如果我将libA添加到Makefile.am
my_proc_LDADD = -Wl,-Bstatic -lA -Wl,-Bdynamic

如果 ldd 无法链接 libA。 应该在 LDADD 中指定 libA,但是 Autotools 不允许这样做。

如果我将 LDADD 添加到 Makefile.am 中作为注释

#my_proc_LDADD = -Wl,-Bstatic -lA -Wl,-Bdynamic

那么它也会作为注释添加到生成的Makefile中,因此我只需在configure脚本之后取消注释这个字符串:

./configure
sed -i -e 's/#my_proc_LDADD/my_proc_LDADD/g' ./src/Makefile
make

因此,静态链接的libA被追加到LDADD


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接