Я создаю исполняемый файл app
, использующий liba
. liba
, в свою очередь, требует libb
. libb
, в свою очередь, требуется libc
. Зависимость выглядит так: app
- ›liba
-› libb
- ›libc
. app
и liba
созданы мной, а libb
и libc
являются сторонними разработчиками. Я не знаю, как они были скомпилированы, но я знаю, что они оба находятся в одной папке, и у меня есть конфигурация CMake, чтобы найти libb
.
Установка, которая не работает.
В CMake
я нахожу пакет для libb
, публично связываю библиотеку с liba
и, наконец, связываю liba
с app
. app
компилируется нормально, но при запуске я получаю: error while loading shared libraries: libc: cannot open shared object file: No such file or directory
. Т.е. последняя библиотека, символы которой я даже не использую напрямую, не может быть найдена.
Я проверяю свою библиотеку liba
с помощью readelf -d liba | grep PATH
:
...
0x000000000000001d (RUNPATH) Library runpath: [/path/to/dir/with/both/libb/and/libc:]
...
Итак, путь находится внутри моего liba
, он правильный и указывает как на libb
, так и на libc
.
Затем я проверяю пути поиска загрузки с помощью LD_DEBUG=libs ./app
:
...
27012: find library=libb [0]; searching
27012: search path=/*a lot of paths INCLUDING the needed path*/ (RUNPATH from file ./app)
...
27012: find library=libc [0]; searching
27012: search cache=/etc/ld.so.cache
27012: search path=/*a lot of system paths, but the needed path is MISSING*/ (system search path)
27012: trying file=/lib/x86_64/libc
many other tries
...
Как такое может быть, что libb
находится в RUNPATH
, а libc
нет ???! Почему libc
использует system search path
вместо RUNPATH
??
Настройка, которая работает
Затем я пытаюсь использовать RPATH
при сборке моей библиотеки liba
, устанавливая флаг -Wl,--disable-new-dtags
. Теперь readelf -d liba | grep PATH
выводит мне тот же путь, что и раньше, но сокращенно RPATH
вместо RUNPATH
и LD_DEBUG=libs ./app
печатает:
...
27012: find library=libb [0]; searching
27012: search path=/*a lot of paths INCLUDING the needed path*/ (RUNPATH from file ./app)
...
27012: find library=libc [0]; searching
27012: search path=/*a lot of paths INCLUDING the needed path*/ (RUNPATH from file ./app)
...
Сейчас обе библиотеки используют RUNPATH
, но я не могу понять почему. Какого черта они используют RUNPATH
, хотя библиотека была скомпилирована с явным RPATH
?? Откуда это взялось?
Обновлять:
Под [libc]
я имею в виду мою стороннюю библиотеку (a, b, c
), а не системную.
readelf -d libb | grep NEEDED
0x0000000000000001 (NEEDED) Shared library: [libboost_thread.so.1.65.1]
0x0000000000000001 (NEEDED) Shared library: [libboost_system.so.1.65.1]
0x0000000000000001 (NEEDED) Shared library: [libc]
0x0000000000000001 (NEEDED) Shared library: [libpthread.so.0]
0x0000000000000001 (NEEDED) Shared library: [libstdc++.so.6]
0x0000000000000001 (NEEDED) Shared library: [libm.so.6]
0x0000000000000001 (NEEDED) Shared library: [libgcc_s.so.1]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x0000000000000001 (NEEDED) Shared library: [ld-linux-x86-64.so.2]
Обновление 2:
Прочитав еще раз, я смог более точно сформулировать поисковый запрос и сразу нашел объяснение. Например, здесь:
libb
зависимости, вероятно, это недостающаяDT_NEEDED
зависимость вlibb
. - person Sam Varshavchik   schedule 29.01.2021libc
указан в его зависимостях. - person nikitablack   schedule 29.01.2021