ldd в двоичном файле не показывает мою общую библиотеку - PullRequest
1 голос
/ 04 июня 2019

Я связываю общую библиотеку в командной строке при создании исполняемого файла. Запуск ldd на этом исполняемом файле не показывает связанную совместно используемую библиотеку.

Посмотрев на некоторые результаты компоновщика, я даже попытался добавить опцию -Wl,--no-as-needed, и это тоже не помогло.

foo.c:

#include <stdio.h>
void foo () {
    printf ("Hello world\n");
}

main.c:

#include <stdio.h>

int main () {
    printf ("In main \n");
    foo ();
}

Вот команда, которую я использовал для компиляции и ссылки:

$ gcc -Wl,--no-as-needed main.c -o main -L./ -lfoo
/bin/ld: cannot find -lfoo
collect2: error: ld returned 1 exit status

$ gcc -c foo.c -shared -Wl,-soname,libfoo.so -o libfoo.so

$ ls -l libfoo.so
-rw-r--r-- 1 apple eng 1488 Jun  4 04:44 libfoo.so

$ gcc -Wl,--no-as-needed main.c -o main -L./ -lfoo

$ ldd main
    linux-vdso.so.1 =>  (0x00007fffbdd6c000)
    libc.so.6 => /lib64/libc.so.6 (0x00007f6367e23000)
    /lib64/ld-linux-x86-64.so.2 (0x00005556e268a000)

libfoo.so не отображается выше.

$ objdump -x main | grep NEEDED
  NEEDED               libc.so.6

Почему libfoo.so не отображается как NEEDED?

Ответы [ 2 ]

1 голос
/ 04 июня 2019

Используя опцию gcc -c, вы указываете ему создавать только объект из foo.c, поэтому единственный продукт, который вы получаете с помощью этой команды gcc, - это объектный файл .Тот факт, что его суффикс .so, объясняется только тем, что вы принудительно использовали опцию -o.Если вы запустите эту команду без -o, вы увидите, что на выходе будет просто foo.o - объектный файл.

Если вы опустите -c в команде gcc, вы получите общий объектВы хотели.

Запуск file в выходном файле показывает разницу (обратите внимание, что я не устанавливаю имя вывода с помощью -o и разрешаю gcc использовать его имена по умолчанию):

С -c:

> gcc -c foo.c -shared
> file foo.o
foo.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped

Без -c:

> gcc foo.c -shared
> file a.out
a.out: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=a63581bfc45f845c501ffb6635, not stripped
                                                                  ^^^
                                                                  |||
1 голос
/ 04 июня 2019

Эта команда не создает общую библиотеку:

gcc -c foo.c -shared -Wl,-soname,libfoo.so -o libfoo.so

Она создает объектный файл libfoo.so, который позже статически связан с вашим кодом.Доказательство: удалите файл lib, программа все равно будет работать.

Решение:

Скомпилируйте объектный файл отдельно, а затем преобразуйте его в общую библиотеку.Вам нужно будет указать загрузчику, где искать общие библиотеки, установив LD_LIBRARY_PATH:

gcc -c foo.c 
gcc foo.o -shared -o libfoo.so
gcc main.c -o main -L./ -lfoo
export LD_LIBRARY_PATH=`pwd`
ldd ./main 
#   linux-vdso.so.1 (0x00007ffe0f7cb000)
#   libfoo.so => /home/---/tmp/libfoo.so (0x00007f9bab6ec000)
#   libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f9bab2fb000)
#   /lib64/ld-linux-x86-64.so.2 (0x00007f9babaf0000)
...