Nano Hash - криптовалюты, майнинг, программирование

компоновщик gcc разрешает символы

Я немного пытался понять, как работает компоновщик gcc и чем отличаются вещи при связывании общей библиотеки с другой общей библиотекой и при связывании двоичного файла с общей библиотекой. Я использую Ubuntu 16.04.1 LTS, gcc 5.4.0 и ld 2.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)

Последовательность 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

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

28.01.2017

Ответы:


1

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

14.12.2017
Новые материалы

Кластеризация: более глубокий взгляд
Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

Как написать эффективное резюме
Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

Частный метод Python: улучшение инкапсуляции и безопасности
Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

Как я автоматизирую тестирование с помощью Jest
Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..