除了更长的编译时间,与未使用的库连接是否有任何缺点?
例如,编译为两种方式之一的程序的可执行文件有任何差异:
g++ -o main main.cpp g++ -o main main.cpp -llib1 -llib2 -llib3 -lmore
我相信它没有什么不同,因为文件大小是一样的,但我要求确认.
解决方法
这取决于.
>如果liblib1.a,liblib2.a和liblib3.a是静态库,并且没有使用任何符号,那就没有区别.
>如果liblib1.so,liblib2.so或liblib3.so是共享库,那么它们将在运行时被加载,无论它们是否被使用.您可以使用链接器标志 – 需要更改此行为,建议使用此标志.
要检查二进制文件在运行时直接加载的共享库,可以在ELF系统上使用readelf.
$cat main.c int main() { return 0; } $gcc main.c $readelf -d a.out | grep NEEDED 0x0000000000000001 (NEEDED) Shared library: [libc.so.6] $gcc -lpng main.c $readelf -d a.out | grep NEEDED 0x0000000000000001 (NEEDED) Shared library: [libpng12.so.0] 0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
您可以看到,在我的系统上,-lpng与libpng12.so.0的链接,无论是否实际使用符号. – 需要的链接器标志修复这个:
$gcc -Wl,--as-needed -lpng main.c $readelf -d a.out | grep NEEDED 0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
笔记
>必须在库之前指定–as-needed标志.它只影响后面出现的库.所以gcc -lpng -Wl,根据需要不起作用.> ldd命令不仅列出了您的二进制文件直接链接的库,还列出了所有的间接依赖关系.这可以根据这些库的编译方式而改变.只有readelf会显示你的直接依赖,只有ldd会显示你的间接依赖.