我正在调查
sudo
的问题,在某些时候我注意到 gcc
添加了 libintl
作为 sudo
依赖项:
$ ldd src/sudo
/lib/ld-musl-x86_64.so.1 (0x77e7c812f000)
libintl.so.8 => /usr/lib/libintl.so.8 (0x77e7c7d0d000)
libc.musl-x86_64.so.1 => /lib/ld-musl-x86_64.so.1 (0x77e7c812f000)
据说是没有原因的。
我的猜测是,如果
sudo
依赖于libintl
,那么后者的符号之一应该位于sudo
成分之一的符号表中。
sudo
是这样构建的:
$ gcc -o sudo conversation.o error.o exec.o \
exec_pty.o get_pty.o net_ifs.o load_plugins.o \
parse_args.o sudo.o sudo_edit.o tgetpass.o \
ttysize.o utmp.o ../common/libcommon.la \
../compat/libreplace.la ...
还有这个:
$ { readelf -s src/conversation.o;
readelf -s src/error.o; readelf -s src/exec.o;
readelf -s src/exec_pty.o; readelf -s src/get_pty.o;
readelf -s src/net_ifs.o; readelf -s src/load_plugins.o;
readelf -s src/parse_args.o; readelf -s src/sudo.o;
readelf -s src/sudo_edit.o; readelf -s src/tgetpass.o;
readelf -s src/ttysize.o; readelf -s src/utmp.o;
readelf -s common/.libs/libcommon.a;
readelf -s compat/.libs/libreplace.a; } \
| grep -E "intl|gettext"
什么也没提供。
我错过了什么?我怎样才能进一步澄清这个问题?
readelf -s /usr/lib/libintl.so.8.1.4
输出在gist中。
UPD
$ ldd /lib/ld-musl-x86_64.so.1
ldd (0x787ce30fe000)
默认情况下,链接器将通过
-l
传递的每个库添加为依赖项。
通常链接器会为命令行中提到的每个动态库添加 DT_NEEDED 标记,无论该库是否实际需要。
据说
--as-needed
开关是在2.15.90中添加的。
因此,在 Alpine Linux 3.4 (
gcc-5.3.0
) 中,它表现正常:它获得 -lintl
,并添加 libintl
作为依赖项。
在 Alpine Linux >= 3.5 (
gcc-6
) 中,它的行为就好像 --as-needed
已被传递:它获得 -lintl
,但它不会将库添加为依赖项,因为它没有被使用(引用)。
最后一个难题是 Alpine Linux 提交,它使
gcc
将 --as-needed
传递给链接器。
实际上它可以被复制更容易(感谢yvs2014)。