stackoverflow.com/questions/45213145/...
сполняемый файл такой, что:
>objdump -x someprog | grep c++
NEEDED libstdc++.so.6
Я хочу изменить требование на полную версию (включая младшую версию и уровень исправления):
>objdump -x someprog | grep c++
NEEDED libstdc++.so.6.0.22
Я знаю два способа сделать это:
создать фиктивную библиотеку согласно этому вопросу (Принудительное или запрещающее использование определенной минорной версии libstdc ++)использовать патчелф>patchelf --add-needed libstdc++.so.6.0.22 someprog >objdump -x someprog | grep c++ NEEDED libstdc++.so.6 NEEDED libstdc++.so.6.0.22
(Я не разобрался в рабочей командной строке для --replace-required)
Обе эти вещи кажутся мне хакерами.Есть ли способ добиться того же во время компиляции или компоновки, используя соответствующие флаги -Wl для gcc?
В идеале я хочу избегать использования -nostdlib, так как это требует от меня специфики не только libstd ++, но и libc и всего остального, для которого мне нужны стандартные версии.
Для обычной библиотеки достаточно просто указать ссылку на конкретную версию, а для libstdc ++ ее нет (или, скорее, я подозреваю, что -stdlib переопределяет последующие полные имена, которые я предоставляю).
Фон: У меня есть исполняемые файлы, которые требуют более поздней версииlibstdc++
чем установлено в системе. К сожалению, установленная версия может быть той же основной версией, и если такld
будет счастливо использовать версию системы, так как она соответствуетигнорирован libstdc++.so.6
Я предпочитаю не связывать статически, так как на самом деле я хочу установить множество небольших программ, использующих одну и ту же среду выполнения C ++, и это значительно увеличит объем установки.
Некоторая информация о моем пути поиска библиотеки доступна здесь:
ld --verbose | grep SEARCH_DIR SEARCH_DIR ("/ usr / x86_64-redhat-linux / lib64"); SEARCH_DIR ( "/ USR / lib64"); SEARCH_DIR ( "/ USR / местные / lib64"); SEARCH_DIR ( "/ lib64"); SEARCH_DIR ( "/ USR / x86_64-RedHat-Linux / Библиотека"); SEARCH_DIR ( "/ USR / местные / Библиотека"); SEARCH_DIR ( "/ Lib"); SEARCH_DIR ( "/ USR / Lib");
В моем случае ясно, что / usr / lib64 ищется перед RPATH исполняемого файла:
>objdump -x /opt/foo/bin/bar | grep PATH
RPATH $ORIGIN/../lib64/private:$ORIGIN/../lib64:$ORIGIN/
man ld.so
предлагает порядок поиска должен быть:
Если зависимость библиотеки не содержит косую черту, то она ищется в следующем порядке:
o (ELF only) Using the directories specified in the DT_RPATH dynamic section attribute of the binary if present and DT_RUNPATH attribute does not exist. Use of DT_RPATH is deprecated.
o Using the environment variable LD_LIBRARY_PATH. Except if the executable is a set-user-ID/set-group-ID binary, in which case it is ignored.
o (ELF only) Using the directories specified in the DT_RUNPATH dynamic section attribute of the binary if present.
o From the cache file /etc/ld.so.cache, which contains a compiled list of candidate libraries previously found in the augmented library path. If, however, the binary was linked with the -z node‐
flib linker option, libraries in the default library paths are skipped. Libraries installed in hardware capability directories (see below) are preferred to other libraries.
o In the default path /lib, and then /usr/lib. If the binary was linked with the -z nodeflib linker option, this step is skipped.
по аналогииhttps://software.intel.com/sites/default/files/m/a/1/e/dsohowto.pdf
Кажется, что оба превзойдены фактическим использованием, но на самом деле это не так. Нужно искать символические ссылки:
>LD_LIBRARY_PATH= LD_DEBUG=libs ldd /opt/foo/bin/bar
21720: find library=libstdc++.so.6 [0]; searching
21720: search path=/opt/foo/bin/../lib64/private:/opt/foo/bin/../lib64:/opt/foo/bin (RPATH from file /opt/foo/bin/bar)
21720: trying file=/opt/foo/bin/../lib64/private/libstdc++.so.6
Это взаимодействие с другим вопросом, который у меня былустановить разделяемую импортированную библиотеку с необходимыми ссылками где было предположение, что ссылки не требуются. Они явнонаходятся требуется, если вы не укажете полную семантическую версию.