libtool 更改了 autotools 中链接器标志的顺序?
libtool changes the order of my linker flags in autotools?
我正在尝试使用 musl(对于 x86)作为我的编译器和 lighttpd 的 autotools 构建系统来静态构建 web 服务器 lighttpd(版本 1.4.49)。我的配置脚本如下:
CC=/home/musl-1.1.23/install/bin/musl-gcc CFLAGS="-g --static" LDFLAGS="-L/home/lighttpd -lwrappers -static-libgcc -Wl,--wrap=socket -Wl,--wrap=bind -Wl,--wrap=listen -Wl,--wrap=accept4 -Wl,--wrap=send -Wl,--wrap=recv -Wl,--wrap=shutdown LIGHTTPD_STATIC=yes ./configure --prefix=/home/lighttpd/install --enable-static --disable-shared --without-zlib --disable-ipv6 --without-bzip2 --without-pcre
我在其中创建了自己的静态库“包装器”,其中包含在我的配置的 LDFLAGS 参数中指定的函数的包装定义。一切设置的方式我需要我的包装库成为第一个链接的库(甚至在 musl 的标准 c 库之前),但是 libtool 正在将我的 LDFLAGS 参数的顺序从上面更改为以下:
libtool: link: /home/musl-1.1.23/install/bin/musl-gcc -g --static -Wall -W -Wshadow -pedantic -static-libgcc -Wl,--wrap=socket -Wl,--wrap=bind -Wl,--wrap=listen -Wl,--wrap=accept4 -Wl,--wrap=send -Wl,--wrap=recv -Wl,--wrap=shutdown -o proc_open proc_open-proc_open.o proc_open-buffer.o -L/home/lighttpd-1.4.49 -lwrappers
而不是:
libtool: link: /home/musl-1.1.23/install/bin/musl-gcc -g --static -Wall -W -Wshadow -pedantic -L/home/lighttpd-1.4.49 -lwrappers -static-libgcc -Wl,--wrap=socket -Wl,--wrap=bind -Wl,--wrap=listen -Wl,--wrap=accept4 -Wl,--wrap=send -Wl,--wrap=recv -Wl,--wrap=shutdown -o proc_open proc_open-proc_open.o proc_open-buffer.o
导致以下错误(我只包括了前几个,其他的都差不多):
/usr/local/bin/ld: /home/musl-1.1.23/install/lib/libc.a(syslog.o): in function `__openlog':
/home/musl-1.1.23/src/misc/syslog.c:51: undefined reference to `__wrap_socket'
/usr/local/bin/ld: /home/musl-1.1.23/install/lib/libc.a(syslog.o): in function `_vsyslog':
/usr/local/bin/ld: /home/musl-1.1.23/src/misc/syslog.c:111: undefined reference to `__wrap_send'
/usr/local/bin/ld: /home/musl-1.1.23/src/misc/syslog.c:113: undefined reference to `__wrap_send'
我很奇怪为什么会这样,因为 LDFLAGS 在其他任何地方都以正确的顺序出现:
/bin/bash ../libtool --tag=CC --mode=link /home/musl-1.1.23/install/bin/musl-gcc -g --static -Wall -W -Wshadow -pedantic -module -export-dynamic -avoid-version -L/home/lighttpd -lwrappers -static-libgcc -Wl,--wrap=socket -Wl,--wrap=bind -Wl,--wrap=listen -Wl,--wrap=accept4 -Wl,--wrap=send -Wl,--wrap=recv -Wl,--wrap=shutdown -o mod_setenv.la -rpath /home/lighttpd/install/lib mod_setenv.lo
libtool: link: ranlib .libs/mod_scgi.a
如有任何帮助,我们将不胜感激!提前谢谢你。
LDFLAGS
不是为了库添加到 link。 libtool
尽管如此,LDFLAGS
在 link 命令中展开得太早了,这不是 autotools 特有的。
在您的情况下,libtool
似乎正在识别该错误,并且在重要的情况下,将 -L
和 -l
选项移动到需要的位置,在 对象被 link 编辑之后。 (或者至少 -l
选项需要存在,特别是对于静态 link,如果 libtool
将移动这些选项,那么移动 [=15] 是有实际原因的=] 选项。)
不幸的是,也没有其他适合您所述目的的面向用户的 Autotools 变量。将额外的库注入 link 不是 Autotools 旨在支持的用例,并且将它们注入 在 link 的开头 不太可能可行无需破解自动工具。
另一方面,您似乎误解了问题。你声称
I need my wrapped library to be the first library linked (even before musl's standard c library)
但是这...
/usr/local/bin/ld: /home/musl-1.1.23/install/lib/libc.a(syslog.o): in function `_vsyslog':
/usr/local/bin/ld: /home/musl-1.1.23/src/misc/syslog.c:111: undefined reference to `__wrap_send'
...告诉我恰恰相反:即使是来自 libc 中标准库函数内部的调用也被包装,因此包装器需要出现 last,甚至 在 标准库(通常是最后一个,而不是第一个)之后。* 并且由于 libwrap
可能调用标准库函数本身,您可能需要 link libc 两次。当然,这假设你真的想以这种方式搞乱标准库,这对我来说似乎不可取。
如果您正在执行动态 link 那么这将不是问题:首先不可能包装 C 库的内部调用。这向我表明,linker 的 --wrap
选项可能在设计时并未考虑到标准库的静态 linking。
我不想建立一个测试平台来验证以下内容,但如果你真的想包装 libc
自己的内部函数调用,那么这可能会起作用:... LDFLAGS="-static-libgcc -Wl,--wrap=socket -Wl,--wrap=bind -Wl,--wrap=listen -Wl,--wrap=accept4 -Wl,--wrap=send -Wl,--wrap=recv -Wl,--wrap=shutdown" LIBS="-L/home/lighttpd -lc -lwrappers -lc" ./configure ...
LIBS
并不是真正打算成为用户变量,这是该计划的潜在弱点。但它是 Autoconf 的标准输出变量之一,它的内容应该出现在 link 行的末尾。 configure
可以将其他库添加到 LIBS
之前,但不应添加任何内容。风险是 configure
可能会清除任何初始内容。
出现在-lwrappers
之前的-lc
是秘诀。通常,您不需要明确指定 -lc
,但在这种情况下您需要指定,因为您需要针对 libwrappers 解析其中的一些符号,否则会过早地 linked。您还(可能)需要 link libwrappers 中的一些符号来对抗 libc。这可能是多余的,但在 libwrappers 之后再次显式 linking libc 可能是必要的,以克服 linker 不需要的聪明才智。
如果你想避免包装内部 libc 自我调用,那么你可以尝试 ... LDFLAGS="-static-libgcc -Wl,--wrap=socket -Wl,--wrap=bind -Wl,--wrap=listen -Wl,--wrap=accept4 -Wl,--wrap=send -Wl,--wrap=recv -Wl,--wrap=shutdown" LIBS="-L/home/lighttpd -lwrappers -Wl,--no-wrap=socket -Wl,--no-wrap=bind -Wl,--no-wrap=listen -Wl,--no-wrap=accept4 -Wl,--no-wrap=send -Wl,--no-wrap=recv -Wl,--no-wrap=shutdown" ./configure ...
。那里的想法是关闭 libc 的包装(仅),但它是相当推测的,因为虽然用 no-
否定长选项是标准的 GNU 形式,但特别是 --no-wrap
选项没有记录。
*所以 libtool 的重新排序不会导致您出现的问题。事实上,如果 libtool 没有执行重新排序,那么您会遇到更多 link 错误。
我正在尝试使用 musl(对于 x86)作为我的编译器和 lighttpd 的 autotools 构建系统来静态构建 web 服务器 lighttpd(版本 1.4.49)。我的配置脚本如下:
CC=/home/musl-1.1.23/install/bin/musl-gcc CFLAGS="-g --static" LDFLAGS="-L/home/lighttpd -lwrappers -static-libgcc -Wl,--wrap=socket -Wl,--wrap=bind -Wl,--wrap=listen -Wl,--wrap=accept4 -Wl,--wrap=send -Wl,--wrap=recv -Wl,--wrap=shutdown LIGHTTPD_STATIC=yes ./configure --prefix=/home/lighttpd/install --enable-static --disable-shared --without-zlib --disable-ipv6 --without-bzip2 --without-pcre
我在其中创建了自己的静态库“包装器”,其中包含在我的配置的 LDFLAGS 参数中指定的函数的包装定义。一切设置的方式我需要我的包装库成为第一个链接的库(甚至在 musl 的标准 c 库之前),但是 libtool 正在将我的 LDFLAGS 参数的顺序从上面更改为以下:
libtool: link: /home/musl-1.1.23/install/bin/musl-gcc -g --static -Wall -W -Wshadow -pedantic -static-libgcc -Wl,--wrap=socket -Wl,--wrap=bind -Wl,--wrap=listen -Wl,--wrap=accept4 -Wl,--wrap=send -Wl,--wrap=recv -Wl,--wrap=shutdown -o proc_open proc_open-proc_open.o proc_open-buffer.o -L/home/lighttpd-1.4.49 -lwrappers
而不是:
libtool: link: /home/musl-1.1.23/install/bin/musl-gcc -g --static -Wall -W -Wshadow -pedantic -L/home/lighttpd-1.4.49 -lwrappers -static-libgcc -Wl,--wrap=socket -Wl,--wrap=bind -Wl,--wrap=listen -Wl,--wrap=accept4 -Wl,--wrap=send -Wl,--wrap=recv -Wl,--wrap=shutdown -o proc_open proc_open-proc_open.o proc_open-buffer.o
导致以下错误(我只包括了前几个,其他的都差不多):
/usr/local/bin/ld: /home/musl-1.1.23/install/lib/libc.a(syslog.o): in function `__openlog':
/home/musl-1.1.23/src/misc/syslog.c:51: undefined reference to `__wrap_socket'
/usr/local/bin/ld: /home/musl-1.1.23/install/lib/libc.a(syslog.o): in function `_vsyslog':
/usr/local/bin/ld: /home/musl-1.1.23/src/misc/syslog.c:111: undefined reference to `__wrap_send'
/usr/local/bin/ld: /home/musl-1.1.23/src/misc/syslog.c:113: undefined reference to `__wrap_send'
我很奇怪为什么会这样,因为 LDFLAGS 在其他任何地方都以正确的顺序出现:
/bin/bash ../libtool --tag=CC --mode=link /home/musl-1.1.23/install/bin/musl-gcc -g --static -Wall -W -Wshadow -pedantic -module -export-dynamic -avoid-version -L/home/lighttpd -lwrappers -static-libgcc -Wl,--wrap=socket -Wl,--wrap=bind -Wl,--wrap=listen -Wl,--wrap=accept4 -Wl,--wrap=send -Wl,--wrap=recv -Wl,--wrap=shutdown -o mod_setenv.la -rpath /home/lighttpd/install/lib mod_setenv.lo
libtool: link: ranlib .libs/mod_scgi.a
如有任何帮助,我们将不胜感激!提前谢谢你。
LDFLAGS
不是为了库添加到 link。 libtool
尽管如此,LDFLAGS
在 link 命令中展开得太早了,这不是 autotools 特有的。
在您的情况下,libtool
似乎正在识别该错误,并且在重要的情况下,将 -L
和 -l
选项移动到需要的位置,在 对象被 link 编辑之后。 (或者至少 -l
选项需要存在,特别是对于静态 link,如果 libtool
将移动这些选项,那么移动 [=15] 是有实际原因的=] 选项。)
不幸的是,也没有其他适合您所述目的的面向用户的 Autotools 变量。将额外的库注入 link 不是 Autotools 旨在支持的用例,并且将它们注入 在 link 的开头 不太可能可行无需破解自动工具。
另一方面,您似乎误解了问题。你声称
I need my wrapped library to be the first library linked (even before musl's standard c library)
但是这...
/usr/local/bin/ld: /home/musl-1.1.23/install/lib/libc.a(syslog.o): in function `_vsyslog': /usr/local/bin/ld: /home/musl-1.1.23/src/misc/syslog.c:111: undefined reference to `__wrap_send'
...告诉我恰恰相反:即使是来自 libc 中标准库函数内部的调用也被包装,因此包装器需要出现 last,甚至 在 标准库(通常是最后一个,而不是第一个)之后。* 并且由于 libwrap
可能调用标准库函数本身,您可能需要 link libc 两次。当然,这假设你真的想以这种方式搞乱标准库,这对我来说似乎不可取。
如果您正在执行动态 link 那么这将不是问题:首先不可能包装 C 库的内部调用。这向我表明,linker 的 --wrap
选项可能在设计时并未考虑到标准库的静态 linking。
我不想建立一个测试平台来验证以下内容,但如果你真的想包装 libc
自己的内部函数调用,那么这可能会起作用:... LDFLAGS="-static-libgcc -Wl,--wrap=socket -Wl,--wrap=bind -Wl,--wrap=listen -Wl,--wrap=accept4 -Wl,--wrap=send -Wl,--wrap=recv -Wl,--wrap=shutdown" LIBS="-L/home/lighttpd -lc -lwrappers -lc" ./configure ...
LIBS
并不是真正打算成为用户变量,这是该计划的潜在弱点。但它是 Autoconf 的标准输出变量之一,它的内容应该出现在 link 行的末尾。 configure
可以将其他库添加到 LIBS
之前,但不应添加任何内容。风险是 configure
可能会清除任何初始内容。
出现在-lwrappers
之前的-lc
是秘诀。通常,您不需要明确指定 -lc
,但在这种情况下您需要指定,因为您需要针对 libwrappers 解析其中的一些符号,否则会过早地 linked。您还(可能)需要 link libwrappers 中的一些符号来对抗 libc。这可能是多余的,但在 libwrappers 之后再次显式 linking libc 可能是必要的,以克服 linker 不需要的聪明才智。
如果你想避免包装内部 libc 自我调用,那么你可以尝试 ... LDFLAGS="-static-libgcc -Wl,--wrap=socket -Wl,--wrap=bind -Wl,--wrap=listen -Wl,--wrap=accept4 -Wl,--wrap=send -Wl,--wrap=recv -Wl,--wrap=shutdown" LIBS="-L/home/lighttpd -lwrappers -Wl,--no-wrap=socket -Wl,--no-wrap=bind -Wl,--no-wrap=listen -Wl,--no-wrap=accept4 -Wl,--no-wrap=send -Wl,--no-wrap=recv -Wl,--no-wrap=shutdown" ./configure ...
。那里的想法是关闭 libc 的包装(仅),但它是相当推测的,因为虽然用 no-
否定长选项是标准的 GNU 形式,但特别是 --no-wrap
选项没有记录。
*所以 libtool 的重新排序不会导致您出现的问题。事实上,如果 libtool 没有执行重新排序,那么您会遇到更多 link 错误。