gpt4 book ai didi

c - 在 automake 中使用 LIBADD 时,libtool 链接不正确

转载 作者:行者123 更新时间:2023-12-05 04:38:32 24 4
gpt4 key购买 nike

我正在使用 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 上。不要介意 window 部件。

最佳答案

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

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

[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 上和为 Linux 构建时遇到问题,则必须关闭其他东西。

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

但是,在构建 libbar.la 没有 -no-undefined 时,我在 Fedora 35 for Windows(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.clibbar 调用 bar_func() 函数(取消注释 #define 在 src/main.c 中重现):

[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 等)?

关于c - 在 automake 中使用 LIBADD 时,libtool 链接不正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70584133/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com