二进制文件上的 ldd 未显示我的共享库
ldd on the binary not showing my shared library
我在构建可执行文件时在命令行上 link 一个共享库。该可执行文件上的 运行 ldd
未显示 linked 共享库。
查看 linker 的一些输出后,我什至尝试添加 -Wl,--no-as-needed
选项,但也没有帮助。
foo.c:
#include <stdio.h>
void foo () {
printf ("Hello world\n");
}
main.c:
#include <stdio.h>
int main () {
printf ("In main \n");
foo ();
}
这是我用来编译的命令 link:
$ gcc -Wl,--no-as-needed main.c -o main -L./ -lfoo
/bin/ld: cannot find -lfoo
collect2: error: ld returned 1 exit status
$ gcc -c foo.c -shared -Wl,-soname,libfoo.so -o libfoo.so
$ ls -l libfoo.so
-rw-r--r-- 1 apple eng 1488 Jun 4 04:44 libfoo.so
$ gcc -Wl,--no-as-needed main.c -o main -L./ -lfoo
$ ldd main
linux-vdso.so.1 => (0x00007fffbdd6c000)
libc.so.6 => /lib64/libc.so.6 (0x00007f6367e23000)
/lib64/ld-linux-x86-64.so.2 (0x00005556e268a000)
libfoo.so
上面没有出现。
$ objdump -x main | grep NEEDED
NEEDED libc.so.6
为什么 libfoo.so
没有显示为 NEEDED
?
此命令不会生成共享库:
gcc -c foo.c -shared -Wl,-soname,libfoo.so -o libfoo.so
它会生成一个目标文件 libfoo.so
,稍后会 静态 链接到您的代码。证明:去掉lib
文件,程序还是运行.
解法:
单独编译目标文件,然后将其转换为共享库。您必须通过设置 LD_LIBRARY_PATH
:
告诉加载程序在哪里搜索共享库
gcc -c foo.c
gcc foo.o -shared -o libfoo.so
gcc main.c -o main -L./ -lfoo
export LD_LIBRARY_PATH=`pwd`
ldd ./main
# linux-vdso.so.1 (0x00007ffe0f7cb000)
# libfoo.so => /home/---/tmp/libfoo.so (0x00007f9bab6ec000)
# libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f9bab2fb000)
# /lib64/ld-linux-x86-64.so.2 (0x00007f9babaf0000)
通过使用 gcc 选项 -c
你告诉它只从 foo.c
创建对象,所以你从这个 gcc 命令得到的唯一产品是 目标文件。它的后缀是 .so
的事实只是因为你使用 -o
选项强制它。如果你 运行 这个命令没有 -o
你会看到输出只是 foo.o
- 一个目标文件。
如果您从 gcc 命令中省略 -c
,您将获得所需的共享对象。
输出文件上的 运行 file
显示了差异(请注意,我没有使用 -o
设置输出名称并让 gcc 使用其默认名称):
与-c
:
> gcc -c foo.c -shared
> file foo.o
foo.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped
没有-c
:
> gcc foo.c -shared
> file a.out
a.out: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=a63581bfc45f845c501ffb6635, not stripped
^^^
|||
我在构建可执行文件时在命令行上 link 一个共享库。该可执行文件上的 运行 ldd
未显示 linked 共享库。
查看 linker 的一些输出后,我什至尝试添加 -Wl,--no-as-needed
选项,但也没有帮助。
foo.c:
#include <stdio.h>
void foo () {
printf ("Hello world\n");
}
main.c:
#include <stdio.h>
int main () {
printf ("In main \n");
foo ();
}
这是我用来编译的命令 link:
$ gcc -Wl,--no-as-needed main.c -o main -L./ -lfoo
/bin/ld: cannot find -lfoo
collect2: error: ld returned 1 exit status
$ gcc -c foo.c -shared -Wl,-soname,libfoo.so -o libfoo.so
$ ls -l libfoo.so
-rw-r--r-- 1 apple eng 1488 Jun 4 04:44 libfoo.so
$ gcc -Wl,--no-as-needed main.c -o main -L./ -lfoo
$ ldd main
linux-vdso.so.1 => (0x00007fffbdd6c000)
libc.so.6 => /lib64/libc.so.6 (0x00007f6367e23000)
/lib64/ld-linux-x86-64.so.2 (0x00005556e268a000)
libfoo.so
上面没有出现。
$ objdump -x main | grep NEEDED
NEEDED libc.so.6
为什么 libfoo.so
没有显示为 NEEDED
?
此命令不会生成共享库:
gcc -c foo.c -shared -Wl,-soname,libfoo.so -o libfoo.so
它会生成一个目标文件 libfoo.so
,稍后会 静态 链接到您的代码。证明:去掉lib
文件,程序还是运行.
解法:
单独编译目标文件,然后将其转换为共享库。您必须通过设置 LD_LIBRARY_PATH
:
gcc -c foo.c
gcc foo.o -shared -o libfoo.so
gcc main.c -o main -L./ -lfoo
export LD_LIBRARY_PATH=`pwd`
ldd ./main
# linux-vdso.so.1 (0x00007ffe0f7cb000)
# libfoo.so => /home/---/tmp/libfoo.so (0x00007f9bab6ec000)
# libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f9bab2fb000)
# /lib64/ld-linux-x86-64.so.2 (0x00007f9babaf0000)
通过使用 gcc 选项 -c
你告诉它只从 foo.c
创建对象,所以你从这个 gcc 命令得到的唯一产品是 目标文件。它的后缀是 .so
的事实只是因为你使用 -o
选项强制它。如果你 运行 这个命令没有 -o
你会看到输出只是 foo.o
- 一个目标文件。
如果您从 gcc 命令中省略 -c
,您将获得所需的共享对象。
运行 file
显示了差异(请注意,我没有使用 -o
设置输出名称并让 gcc 使用其默认名称):
与-c
:
> gcc -c foo.c -shared
> file foo.o
foo.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped
没有-c
:
> gcc foo.c -shared
> file a.out
a.out: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=a63581bfc45f845c501ffb6635, not stripped
^^^
|||