Привязка общей библиотеки к абсолютному или относительному пути - PullRequest
0 голосов
/ 28 мая 2018

Я пытался связать разделяемую библиотеку с моей программой, и я хочу, чтобы ее путь был относительно моего RPATH.

Однако, когда я запустил ldd, я заметил, что абсолютный путь разделяемойбиблиотека была связана.Есть идеи почему?

Редактировать:

/home/projects/my_files/winter_fresh.so
libgcc_s.so.1 => /home/tomo/anaconda3/lib/libgcc_s.so.1 (0x00007f0a3bf64000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f0a3bd47000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f0a3b97d000)
/lib64/ld-linux-x86-64.so.2 (0x00007f0a3e369000)
libstdc++.so.6 => /home/tomo/anaconda3/lib/libstdc++.so.6 (0x00007f0a3b643000)

Проблема в первом файле.Я не хочу, чтобы библиотека winter_fresh представляла собой абсолютный путь, так как у меня есть RPATH, который ее содержит.

Ответы [ 2 ]

0 голосов
/ 28 мая 2018

Проблема в первом файле.Я не хочу, чтобы библиотека winter_fresh представляла собой абсолютный путь

Чаще всего это происходит, когда вы ссылаетесь на свою библиотеку, например:

gcc ... /home/projects/my_files/winter_fresh.so ...

, а ваша библиотека этого не делаетиметь SONAME (вы не использовали опцию компоновщика -soname при его создании).

Чтобы это исправить, либо добавьте SONAME к winter_fresh.so (хорошая практика в целом), либо добавьте ссылку наэто выглядит так:

gcc ... -L /home/projects/my_files -l:winter_fresh.so

Еще более удачный подход - переименовать winter_fresh.so в libwinter_fresh.so, а затем связать его с ним следующим образом:

gcc ... -L /home/projects/my_files -lwinter_fresh
0 голосов
/ 28 мая 2018

Полагаю, вы скомпилировали свою программу, используя winter_fresh.so в качестве исходного файла, а не ссылаясь на него.
Если вы закодировали путь к разделяемой библиотеке / исполняемому файлу как /home/projects/my_files/winter_fresh.so, вы можете поместить свою разделяемую библиотеку внутрьКаталог RPATH, например:

 $ mkdir some_dir
 $ mkdir -p some_dir/home/projects/my_files
 $ cp /home/projects/my_files/winter_fresh.so some_dir/home/projects/my_files
 $ RPATH=$(pwd)/some_dir ./executable

Компоновщик ищет библиотеку с именем /home/projects/my_files/winter_fresh.so в RPATH.

Теперь простой тест:

// main.c
int main() {
  int external_function(void);
  return external_function();
}

// exlib.c
#include <stdio.h>
int external_function(void) {
  return printf("%s\n", __func__);
}

Теперь давайте создадим bad.out скомпилированную с exlib.so общей библиотекой, используемой в качестве источника:

$ gcc -shared -fPIC -o exlib.so exlib.c
$ gcc /tmp/exlib.so main.c -o bad.out
$ ldd bad.out
linux-vdso.so.1 (0x00007ffd921db000)
/tmp/exlib.so (0x00007fe4470f7000)
libc.so.6 => /usr/lib/libc.so.6 (0x00007fe446d3b000)
/lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007fe4474fb000)

Как видитестрока /tmp/exlib.so указывает на общую библиотеку.Я могу запустить программу, используя RPATH, чтобы указать компоновщику местоположение exlib.so.Мне нужно создать поддерево /tmp/exlib.so внутри RPATH, например:

$ mkdir -p lib/tmp
$ mv exlib.so lib/tmp
$ RPATH=$(pwd)/lib ./bad.out
external_function

При запуске bad.out компоновщик ищет файл с именем /tmp/exlib.so внутри RPATH.
Linux использует соглашениедля именования общих библиотек .Теперь давайте свяжемся с good.out:

$ gcc -shared -fPIC -o libexlib.so exlib.c
$ gcc -I /tmp -lexlib main.c -o good.out
$ ldd good.out 
linux-vdso.so.1 (0x00007ffcb01bf000)
libexlib.so => not found
libc.so.6 => /usr/lib/libc.so.6 (0x00007fc1230ef000)
/lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007fc1236ad000)

Теперь вы видите, что good.out связан с libexlib.so.gcc искал в каталоге / tmp папку с именем lib exlib .so в каталоге / tmp.Я могу запустить good.out, указав LD_LIBRARY_PATH путь к файлу libexlib.so:

 $ LD_LIBRARY_PATH=/tmp ldd ./good.out
 external_function
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...