Почему мой исполняемый файл работает с `RPATH`, но не с` RUNPATH`

Я создаю исполняемый файл 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:

Прочитав еще раз, я смог более точно сформулировать поисковый запрос и сразу нашел объяснение. Например, здесь:

вторичное разрешение зависимостей c ++ с путем выполнения

Динамическое связывание с rpath не работает в Ubuntu 17.10


person nikitablack    schedule 29.01.2021    source источник
comment
Можете ли вы сбросить свои libb зависимости, вероятно, это недостающая DT_NEEDED зависимость в libb.   -  person Sam Varshavchik    schedule 29.01.2021
comment
Обновил вопрос. libc указан в его зависимостях.   -  person nikitablack    schedule 29.01.2021