Линукс линкер / порядок поиска загрузчика - PullRequest
2 голосов
/ 27 сентября 2011

Этот вопрос относится к способу поиска библиотек во время компиляции и динамического связывания.

Рассмотрим этот небольшой проект:

  • project
    • liba
      • a.hpp
      • a.cpp
    • libb
      • b.hpp
      • b.cpp
    • main.cpp

a.hpp:

int AAA();

a.cpp:

#include <b.hpp>

int AAA()
{
    return BBB();
}

b.hpp:

int BBB();

b.cpp:

int BBB()
{
    return 3;
}

main.cpp:

#include "liba/a.hpp"
#include "libb/b.hpp"

int main()
{
    AAA();
    BBB();
}

libb компилируется с:

cd libb;g ++ -shared -o libb.so b.cpp

liba скомпилирована с:

cd liba;g ++ -I ../ libb / -L ../ libb / -lb -shared -o liba.so -Wl, -rpath / full / path / to / project / libb / a.cpp

и main компилируется с:

g ++ -Lliba -la -Wl, -rpath / full / path / to / project / liba / main.cpp

Компиляция завершается без ошибок, но при выполнении a.out файл libb.so не может быть найден.

ldd:

ldd ./a.out 
    linux-gate.so.1 =>  (0xffffe000)
    liba.so => /full/path/to/project/liba/liba.so (0xb780a000)
    libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0xb76ba000)
    libm.so.6 => /lib/libm.so.6 (0xb7692000)
    libgcc_s.so.1 => /lib/libgcc_s.so.1 (0xb7672000)
    libc.so.6 => /lib/libc.so.6 (0xb750f000)
    libb.so => not found
    libb.so => /full/path/to/project/libb/libb.so (0xb750c000)
    /lib/ld-linux.so.2 (0xb780e000)

Обратите внимание, что libb.so встречается дважды.Один раз динамический компоновщик не может найти библиотеку, и один раз это так.Я предполагаю, что во втором случае он использует rpath, встроенный в liba.so.

Конечно, есть несколько способов исправить эту проблему (например, LD_LIBRARY_PATH, вставлять правильный rpath при компиляции main.cpp ..., но меня больше интересует, почему компиляция main.cpp работает, а динамическая компоновка - нет.

До сих пор я предполагал, что та же самая процедура использовалась для поиска необходимых библиотек.Есть ли что-то, что я пропускаю, или какая-то скрытая магия, о которой я не знаю?:)

(протестировано на коробке SLED11 с gcc 4.3.4.)

1 Ответ

0 голосов
/ 27 сентября 2011

В этом нет скрытой магии, но вы в основном пообещали компилятору, что вы будете сообщать загрузчику во время выполнения, где найти функции, но вы этого не сделали. BBB, вызванный из AAA, знает, как туда попасть, но BBB, вызванный из main, не знает.

...