gcc链接器解析符号

gcc链接器解析符号,gcc,ld,ldd,.so,Gcc,Ld,Ldd,.so,我一直在努力理解gcc链接器是如何工作的,以及在将一个共享库链接到另一个共享库和将二进制文件链接到一个共享库时,事情是如何不同的。我使用的是Ubuntu 16.04.1 LTS、gcc 5.4.0和LD2.26.1 下面是在一些C源文件上执行的两组命令序列 顺序1:- ammal@ubuntu:~/linktest6$ cat a.c #include <stdio.h> int a_func() { printf("Running a_func()\n");

我一直在努力理解gcc链接器是如何工作的,以及在将一个共享库链接到另一个共享库和将二进制文件链接到一个共享库时,事情是如何不同的。我使用的是Ubuntu 16.04.1 LTS、gcc 5.4.0和LD2.26.1

下面是在一些C源文件上执行的两组命令序列

顺序1:-

ammal@ubuntu:~/linktest6$ cat a.c 
#include <stdio.h>

int a_func() {
    printf("Running a_func()\n");

    return 0;
}

ammal@ubuntu:~/linktest6$ cat b.c 
#include <stdio.h>

int a_func();

int b_func() {
    printf("Running b_func()\n");
    a_func();

    return 0;
}

ammal@ubuntu:~/linktest6$ cat d.c 
#include <stdio.h>

int b_func();

int d_func() {
    printf("Running d_func()\n");
    b_func();

    return 0;
}

ammal@ubuntu:~/linktest6$ cat myprog.c 
#include <stdio.h>

int d_func();

int main() {
    printf("Running myprog_func()\n");
    d_func();

    return 0;
}

ammal@ubuntu:~/linktest6$ gcc -shared -fPIC -o liba.so a.c 

ammal@ubuntu:~/linktest6$ ldd -r liba.so 
    linux-vdso.so.1 =>  (0x00007ffc6fded000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f1898da3000)
    /lib64/ld-linux-x86-64.so.2 (0x0000555e2853c000)

ammal@ubuntu:~/linktest6$ gcc -shared -fPIC -o libb.so b.c 

ammal@ubuntu:~/linktest6$ ldd -r libb.so 
    linux-vdso.so.1 =>  (0x00007ffd82127000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f0cc6253000)
    /lib64/ld-linux-x86-64.so.2 (0x00005586e6a36000)
undefined symbol: a_func    (./libb.so)

ammal@ubuntu:~/linktest6$ gcc -shared -fPIC -o libd.so d.c 

ammal@ubuntu:~/linktest6$ ldd -r libd.so 
    linux-vdso.so.1 =>  (0x00007ffc3addb000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f408db59000)
    /lib64/ld-linux-x86-64.so.2 (0x0000558720efc000)
undefined symbol: b_func    (./libd.so)

ammal@ubuntu:~/linktest6$ gcc -fPIC -o myprog myprog.c -L. -ld -lb -la

ammal@ubuntu:~/linktest6$ ldd -r myprog
    linux-vdso.so.1 =>  (0x00007ffe807aa000)
    libd.so => not found
    libb.so => not found
    liba.so => not found
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f344acce000)
    /lib64/ld-linux-x86-64.so.2 (0x0000563a89eb4000)
undefined symbol: d_func    (./myprog)
ammal@ubuntu:~/linktest6$cat a.c
#包括
int a_func(){
printf(“运行函数()\n”);
返回0;
}
ammal@ubuntu:~/linktest6$cat b.c
#包括
int a_func();
int b_func(){
printf(“运行b_func()\n”);
a_func();
返回0;
}
ammal@ubuntu:~/linktest6$cat d.c
#包括
int b_func();
int d_func(){
printf(“运行d_func()\n”);
b_func();
返回0;
}
ammal@ubuntu:~/linktest6$cat myprog.c
#包括
int d_func();
int main(){
printf(“运行myprog_func()\n”);
d_func();
返回0;
}
ammal@ubuntu:~/linktest6$gcc-shared-fPIC-o liba.so a.c
ammal@ubuntu:~/linktest6$ldd-r liba.so
linux vdso.so.1=>(0x00007ffc6fded000)
libc.so.6=>/lib/x86_64-linux-gnu/libc.so.6(0x00007f1898da3000)
/lib64/ld-linux-x86-64.so.2(0x00005555E2853C000)
ammal@ubuntu:~/linktest6$gcc-shared-fPIC-o libb.so b.c
ammal@ubuntu:~/linktest6$ldd-r libb.so
linux vdso.so.1=>(0x00007ffd82127000)
libc.so.6=>/lib/x86_64-linux-gnu/libc.so.6(0x00007f0cc6253000)
/lib64/ld-linux-x86-64.so.2(0x00005586e6a36000)
未定义符号:a_func(./libb.so)
ammal@ubuntu:~/linktest6$gcc-shared-fPIC-o libd.so d.c
ammal@ubuntu:~/linktest6$ldd-r libd.so
linux vdso.so.1=>(0x00007ffc3addb000)
libc.so.6=>/lib/x86_64-linux-gnu/libc.so.6(0x00007f408db59000)
/lib64/ld-linux-x86-64.so.2(0x0000558720efc000)
未定义符号:b_func(./libd.so)
ammal@ubuntu:~/linktest6$gcc-fPIC-o myprog-myprog.c-L-ld-lb-la
ammal@ubuntu:~/linktest6$ldd-r myprog
linux vdso.so.1=>(0x00007ffe807aa000)
libd.so=>未找到
libb.so=>未找到
liba.so=>未找到
libc.so.6=>/lib/x86_64-linux-gnu/libc.so.6(0x00007f344acce000)
/lib64/ld-linux-x86-64.so.2(0x0000563a89eb4000)
未定义符号:d_func(./myprog)
顺序2:-

ammal@ubuntu:~/linktest6$ cat a.c 
#include <stdio.h>

int a_func() {
    printf("Running a_func()\n");

    return 0;
}

ammal@ubuntu:~/linktest6$ cat b.c 
#include <stdio.h>

int a_func();

int b_func() {
    printf("Running b_func()\n");
    a_func();

    return 0;
}

ammal@ubuntu:~/linktest6$ cat d.c 
#include <stdio.h>

int b_func();

int d_func() {
    printf("Running d_func()\n");
    b_func();

    return 0;
}

ammal@ubuntu:~/linktest6$ cat myprog.c 
#include <stdio.h>

int d_func();

int main() {
    printf("Running myprog_func()\n");
    d_func();

    return 0;
}

ammal@ubuntu:~/linktest6$ gcc -shared -fPIC -o liba.so a.c 

ammal@ubuntu:~/linktest6$ ldd -r liba.so 
    linux-vdso.so.1 =>  (0x00007ffe8c9ee000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f88b91c2000)
    /lib64/ld-linux-x86-64.so.2 (0x0000555cf72ef000)

ammal@ubuntu:~/linktest6$ gcc -shared -fPIC -o libb.so b.c 

ammal@ubuntu:~/linktest6$ ldd -r libb.so 
    linux-vdso.so.1 =>  (0x00007fffbffc4000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f69ea310000)
    /lib64/ld-linux-x86-64.so.2 (0x000055996b3e5000)
undefined symbol: a_func    (./libb.so)

ammal@ubuntu:~/linktest6$ gcc -shared -fPIC -o libd.so d.c -L. -lb -Wl,-rpath=/home/ammal/linktest6

ammal@ubuntu:~/linktest6$ ldd -r libd.so 
    linux-vdso.so.1 =>  (0x00007ffe21bb6000)
    libb.so => /home/ammal/linktest6/libb.so (0x00007fca1cdb6000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fca1c9d5000)
    /lib64/ld-linux-x86-64.so.2 (0x000055f517b11000)
undefined symbol: a_func    (/home/ammal/linktest6/libb.so)

ammal@ubuntu:~/linktest6$ gcc -fPIC -o myprog myprog.c -L. -ld -lb -la
./libb.so: undefined reference to `a_func'
collect2: error: ld returned 1 exit status
ammal@ubuntu:~/linktest6$cat a.c
#包括
int a_func(){
printf(“运行函数()\n”);
返回0;
}
ammal@ubuntu:~/linktest6$cat b.c
#包括
int a_func();
int b_func(){
printf(“运行b_func()\n”);
a_func();
返回0;
}
ammal@ubuntu:~/linktest6$cat d.c
#包括
int b_func();
int d_func(){
printf(“运行d_func()\n”);
b_func();
返回0;
}
ammal@ubuntu:~/linktest6$cat myprog.c
#包括
int d_func();
int main(){
printf(“运行myprog_func()\n”);
d_func();
返回0;
}
ammal@ubuntu:~/linktest6$gcc-shared-fPIC-o liba.so a.c
ammal@ubuntu:~/linktest6$ldd-r liba.so
linux vdso.so.1=>(0x00007ffe8c9ee000)
libc.so.6=>/lib/x86_64-linux-gnu/libc.so.6(0x00007f88b91c2000)
/lib64/ld-linux-x86-64.so.2(0x000055CF72EF000)
ammal@ubuntu:~/linktest6$gcc-shared-fPIC-o libb.so b.c
ammal@ubuntu:~/linktest6$ldd-r libb.so
linux vdso.so.1=>(0x00007fffbffc4000)
libc.so.6=>/lib/x86_64-linux-gnu/libc.so.6(0x00007f69ea310000)
/lib64/ld-linux-x86-64.so.2(0x000055996b3e5000)
未定义符号:a_func(./libb.so)
ammal@ubuntu:~/linktest6$gcc-shared-fPIC-o libd.so d.c-L-lb-Wl,-rpath=/home/ammal/linktest6
ammal@ubuntu:~/linktest6$ldd-r libd.so
linux vdso.so.1=>(0x00007ffe21bb6000)
libb.so=>/home/ammal/linktest6/libb.so(0x00007fca1cdb6000)
libc.so.6=>/lib/x86_64-linux-gnu/libc.so.6(0x00007fca1c9d5000)
/lib64/ld-linux-x86-64.so.2(0x000055f517b11000)
未定义的符号:a_func(/home/ammal/linktest6/libb.so)
ammal@ubuntu:~/linktest6$gcc-fPIC-o myprog-myprog.c-L-ld-lb-la
./libb.so:a_func的未定义引用
collect2:错误:ld返回了1个退出状态

我的问题是,为什么我能够在第一种情况下而不是第二种情况下成功编译二进制文件。

在序列2中,libd.so链接到一个共享对象(即libb.so)。gcc需要一条路径来解决它。尝试以下方法。
$gcc-fPIC-o myprog myprog.c-L-ld-lb-la-Wl,-rpath=/home/ammal/linktest6

在序列2中,libd.so链接到一个共享对象(即libb.so)。gcc需要一条路径来解决它。尝试以下方法。 $gcc-fPIC-o myprog-myprog.c-L-ld-lb-la-Wl,-rpath=/home/ammal/linktest6