2017-01-28 4 views
1

Я немного пытался понять, как работает gcc-компоновщик, и как все обстоит иначе при связывании разделяемой библиотеки с другой разделяемой библиотекой и при связывании двоичного файла с общей библиотекой. Я использую Ubuntu 16.04.1 LTS, gcc 5.4.0 и ld 2.26.1.gSC linker resolving symbols

Ниже приведены два набора последовательности команд, выполняемых в некоторых исходных файлах C.

Последовательность 1: -

[email protected]:~/linktest6$ cat a.c 
#include <stdio.h> 

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

    return 0; 
} 

[email protected]:~/linktest6$ cat b.c 
#include <stdio.h> 

int a_func(); 

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

    return 0; 
} 

[email protected]:~/linktest6$ cat d.c 
#include <stdio.h> 

int b_func(); 

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

    return 0; 
} 

[email protected]:~/linktest6$ cat myprog.c 
#include <stdio.h> 

int d_func(); 

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

    return 0; 
} 

[email protected]:~/linktest6$ gcc -shared -fPIC -o liba.so a.c 

[email protected]:~/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) 

[email protected]:~/linktest6$ gcc -shared -fPIC -o libb.so b.c 

[email protected]:~/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) 

[email protected]:~/linktest6$ gcc -shared -fPIC -o libd.so d.c 

[email protected]:~/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) 

[email protected]:~/linktest6$ gcc -fPIC -o myprog myprog.c -L. -ld -lb -la 

[email protected]:~/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) 

Последовательность 2: -

[email protected]:~/linktest6$ cat a.c 
#include <stdio.h> 

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

    return 0; 
} 

[email protected]:~/linktest6$ cat b.c 
#include <stdio.h> 

int a_func(); 

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

    return 0; 
} 

[email protected]:~/linktest6$ cat d.c 
#include <stdio.h> 

int b_func(); 

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

    return 0; 
} 

[email protected]:~/linktest6$ cat myprog.c 
#include <stdio.h> 

int d_func(); 

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

    return 0; 
} 

[email protected]:~/linktest6$ gcc -shared -fPIC -o liba.so a.c 

[email protected]:~/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) 

[email protected]:~/linktest6$ gcc -shared -fPIC -o libb.so b.c 

[email protected]:~/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) 

[email protected]:~/linktest6$ gcc -shared -fPIC -o libd.so d.c -L. -lb -Wl,-rpath=/home/ammal/linktest6 

[email protected]:~/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) 

[email protected]:~/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 

Мой вопрос, почему я в состоянии успешно скомпилировать двоичный файл в первом случае, а не второй.

ответ

0

В Sequence 2 libd.so связан с общим объектом (а именно с libb.so). gcc требует пути для его решения. Попробуйте следующее. $ gcc -fPIC -o myprog myprog.c -L. -ld -lb -la -Wl, -rpath =/home/ammal/linktest6