【问题标题】:When using LIBADD in automake, libtool links incorrectly在 automake 中使用 LIBADD 时,libtool 链接不正确
【发布时间】:2022-01-04 19:35:39
【问题描述】:

我正在使用 automake 来构建我的项目。我的项目中有一些第三方(开源)库作为 git 子模块,我想单独构建和链接。这是我的 Makefile.am 的编辑(名称已更改)版本:

lib_LTLIBRARIES = libfoo.la libbar.la
libbar_la_SOURCES = ../submodules/bar/bar.c

libfoo_la_LIBADD = libbar.la
libfoo_la_SOURCES = \
    some_source.c \
    some_other_source.c

libfoo_la_CFLAGS = $(CFLAGS)
libfoo_la_LDFLAGS = $(LIBS)

if OS_LINUX
libfoo_la_SOURCES += \
    linux/some_source.c \
    linux/some_other_source.c

libfoo_la_CFLAGS += $(PTHREAD_CFLAGS)
libfoo_la_LDFLAGS += $(PTHREAD_LIBS)
endif

if OS_WINDOWS_MSYS
libfoo_la_SOURCES += \
    nt/some_source.c \
    nt/some_other_source.c

libfoo_la_LDFLAGS += -no-undefined
endif

bin_PROGRAMS = main
main_SOURCES = main.c
main_LDADD = libfoo.la

autoreconfconfiguremake 运行正常,但 make install 失败

/usr/bin/ld: cannot find -lbar
collect2: error: ld returned 1 exit status

似乎 autoconf 正在尝试将libbar 用作全局安装库而不是本地库? main 目标上的 LDADD 工作正常。

autoreconf -V 输出

autoreconf (GNU Autoconf) 2.71
Copyright (C) 2021 Free Software Foundation, Inc.
License GPLv3+/Autoconf: GNU GPL version 3 or later
<https://gnu.org/licenses/gpl.html>, <https://gnu.org/licenses/exceptions.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by David J. MacKenzie and Akim Demaille.

编辑:我在 Linux 上。不要介意窗户部件。

【问题讨论】:

  • 您是否忘记将libbar_la_LDFLAGS += -no-undefined 行复制到上面的示例中,或者您的实际代码中也缺少该行?
  • @ndim 我忘了说,这个问题在 Linux 上,我什至没有在 Windows 上尝试过。 Linux 不需要 -no-undefined。
  • 什么 Linux 发行版、autoconf、automake、libtool 版本?什么实际的链接器命令,什么实际的输出? github.com/ndim/stackoverflow-q70584133 对你有用还是失败了?

标签: c autoconf automake libtool


【解决方案1】:

我试图通过基本上复制您提供的Makefile.am 并添加一些非常基本的源文件来在https://github.com/ndim/stackoverflow-q70584133 上重现此内容。

我发现在 Linux for Linux(Fedora 35、autoconf 2.69-37、automake 1.16.2-5、libtool 2.4.6-42)上构建运行良好。同时运行make installed 结果:

[user@host stackoverflow-q70584133]$ mkdir _b-host && cd _b-host
[user@host _b-host]$ ../configure --prefix=$PWD/_i
[user@host _b-host]$ make && make install && ./_i/bin/main
[...]
main: x86_64-pc-linux-gnu
foo_func
bar_func
foo_host_func: Linux 331524 = 0x50f04 = 5.15.4 (5.15.4)
[user@host _b-host]$ _

因此,如果您在为 Linux 构建和构建时遇到问题,则必须关闭其他东西。

我假设您已运行 make distclean,然后重新运行 autoreconfconfigure 以确保您的构建系统和源代码树以及构建树处于明确定义的状态。

但是,在构建 libbar.la 没有 -no-undefined 时,我在 Windows 的 Fedora 35(32 位和 64 位)上构建失败:

/bin/sh ../libtool  --tag=CC   --mode=link i686-w64-mingw32-gcc  -g -O2   -o libbar.la -rpath /home/user/stackoverflow-q70584133/_b-w32/_i/lib ../bar/libbar_la-bar.lo  
libtool: warning: undefined symbols not allowed in i686-w64-mingw32 shared libraries; building static only
libtool: link: i686-w64-mingw32-ar cru .libs/libbar.a  ../bar/libbar_la-bar.o
libtool: link: i686-w64-mingw32-ranlib .libs/libbar.a
libtool: link: ( cd ".libs" && rm -f "libbar.la" && ln -s "../libbar.la" "libbar.la" )
/bin/sh ../libtool  --tag=CC   --mode=link i686-w64-mingw32-gcc  -g -O2 -no-undefined  -o libfoo.la -rpath /home/user/stackoverflow-q70584133/_b-w32/_i/lib foo/libfoo_la-foo.lo  foo/libfoo_la-foo-nt.lo libbar.la  

*** Warning: This system cannot link to static lib archive libbar.la.
*** I have the capability to make that library automatically link in when
*** you link to this library.  But I can only do this if you have a
*** shared version of the library, which you do not appear to have.
libtool: link: i686-w64-mingw32-gcc -shared  foo/.libs/libfoo_la-foo.o foo/.libs/libfoo_la-foo-nt.o    -g -O2   -o .libs/libfoo-0.dll -Wl,--enable-auto-image-base -Xlinker --out-implib -Xlinker .libs/libfoo.dll.a
/usr/lib/gcc/i686-w64-mingw32/11.2.1/../../../../i686-w64-mingw32/bin/ld: foo/.libs/libfoo_la-foo.o: in function `foo_func':
/home/user/stackoverflow-q70584133/_b-w32/src/../../src/foo/foo.c:10: undefined reference to `bar_func'
collect2: error: ld returned 1 exit status
make[1]: *** [Makefile:521: libfoo.la] Error 1

Makefile.am加一行点赞

libbar_la_LDFLAGS += -no-undefined

修复了 Windows 的链接问题,并构建并运行了整个东西(在 Linux 上构建,在 Linux 上使用 wine 运行):

[user@host stackoverflow-q70584133]$ mkdir _b-w64 && cd _b-w64
[user@host _b-w64]$ ../configure --host=x86_64-w64-mingw32 --prefix=$PWD/_i
[user@host _b-w64]$ make && make install && ./_i/bin/main.exe
[...]
main: x86_64-w64-mingw32
foo_func
bar_func
foo_host_func: Windows 0x0a00 = 10.0
[user@host _b-w64]$ _

(顺便说一句,LIBS_LIBS 类型变量可能应该添加到 _LIBADD_LDADD 变量中,而不是添加到 _LDFLAGS 变量中。)

更新

基于 Debian 10(autoconf 2.69-11、automake 1:1.16.1-4、libtool 2.4.6-9),当 main_LDADD 缺失 libbar.lasrc/main.c 调用bar_func() 来自 libbar 的函数(取消注释 src/main.c 中的 #define 以重现):

[user@host _b-host]$ make
[...]
/bin/bash ../libtool  --tag=CC   --mode=link gcc  -g -O2   -o main main-main.o libfoo.la 
libtool: link: gcc -g -O2 -o .libs/main main-main.o  ./.libs/libfoo.so -pthread -Wl,-rpath -Wl,/home/user/stackoverflow-q70584133/_b-host/_i/lib
/usr/bin/ld: main-main.o: undefined reference to symbol 'bar_func'
/usr/bin/ld: //home/user/stackoverflow-q70584133/_b-host/src/.libs/libbar.so.0: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
make[1]: *** [Makefile:525: main] Error 1
make[1]: Leaving directory '/home/user/stackoverflow-q70584133/_b-host/src'
make: *** [Makefile:390: all-recursive] Error 1
[user@host _b-host]$ _

但是,在从src/main.c 中删除对libbarbar_func() 的直接调用后,make 命令将再次起作用,make install 也是如此:

[user@host _b-host]$ make install && ./_i/bin/main
main: x86_64-pc-linux-gnu
foo_func
bar_func
foo_host_func: Linux 267216 = 0x413d0 = 4.19.208
[user@host _b-host]$ _

这表明从链接单元调用 libbar 的函数而不显式将该单元与 libbar 链接是错误的,这确实是有道理的。

所以我仍然无法重现 OP 关于 make 工作但 make install 失败的报告。 OP 使用比我 (2.69) 更新的 autoconf (2.71)。也许 OP 正在使用不同的 automake/libtool 版本以及不同的错误集(dpkg -l autoconf automake libtoolrpm -q autoconf automake libtool 等)?

【讨论】:

  • 很好的调查。我一直对 autotools 有爱/恨的关系,当它工作时我喜欢它,当它不起作用时我讨厌它。在过去的 Pentium 时代(包括 koffice 的 7 小时构建),它从头到尾完美地构建了 KDE3。但我也遇到了一些问题。和其他任何东西一样,如果你经常使用它,你必须付出代价才能与它交朋友。
猜你喜欢
  • 1970-01-01
  • 2013-08-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-24
  • 1970-01-01
相关资源
最近更新 更多