Как установить RPATH и RUNPATH с GCC / LD? - PullRequest
0 голосов
/ 25 августа 2018

Я недавно столкнулся с этой проблемой после обновления системы: использование параметра GCC -Wl,-rpath= работает иначе, чем раньше.

Я использовал его, чтобы задать пути поиска для некоторых общих библиотек, которые были встроены вподмодуль моего проекта.В то время я считал, что это лучше, чем настройка LD_LIBRARY_PATH для всей системы (я не хотел устанавливать ее каждый раз при включении компьютера).Все работало нормально, и эти два подхода казались эквивалентными.

Теперь кажется, что поведение -rpath изменилось.Он по-прежнему работает для напрямую зависимых библиотек, но не для тех, которые связывают другие библиотеки из того же каталога, установленного через -rpath=.Экспорт LD_LIBRARY_PATH по-прежнему работает как прежде.

Я проверил вывод компиляции, используя readelf, и есть разница.Перед обновлением (Linux Mint 18.2 с GCC 5.4) динамическая секция имела следующую строку:

0x000000000000000f (RPATH)            Library rpath: [submod/lib]

После обновления (Linux Mint 19 с GCC 7.3) строка изменилась на:

0x000000000000001d (RUNPATH)            Library runpath: [submod/lib]

В использовать RPATH, но не RUNPATH? предполагается, что RPATH был заменен на RUNPATH (или что он, по крайней мере, обслуживает другое назначение, поскольку имеет более низкий приоритет), но это нене дает ответа относительно того, почему это влияет на косвенные ссылки.Сами библиотеки не имеют ни RPATH, ни RUNPATH в выводе readelf.

Поэтому мой вопрос таков: Почему компоновщик вдруг начал интерпретировать опцию -rpath= по-другому, и есть ли способзаставить старое поведение? (или сделать что-то другое, что приведет к эквивалентному результату.)

Другой вопрос будет: Можно ли сказать старой версии компоновщика создать новуювывод (т.е. RUNPATH вместо RPATH)?


РЕДАКТИРОВАТЬ

Это не дубликат Как установить RunPath двоичного файла? - у меня вопрос наоборот: я хочу поведение RPATH.Я понял это (благодаря подсказке в комментарии), и я отвечу на мои вопросы здесь.

Ответы [ 2 ]

0 голосов
/ 21 марта 2019

Проект GNU Binutils (содержащий компоновщик GNU (ld)) не является источником этого изменения поведения, но Debian (2016) 1 и Gentoo (2013!) 2 .

Согласно сообщению gentoo от Mike Frysinger от января 2013 года:

«Новые» опции dtags существуют уже более 14 лет, поэтому для Linux и GNUцели, включите их по умолчанию. "

Это изменение не принято 3 , 4 , 5 , как RUNPATH иУ RPATH "недокументированная разница в поведении" ... Удивительно, но теперь эти изменения применяются к стабильной версии Debian.

Проблема в том, что использование RUNPATH приводит к непредсказуемым проблемам ... Но в основном это работает.Из википедии:

Динамический компоновщик ld не ищет местоположения DT_RUNPATH для транзитивных зависимостей , в отличие от DT_RPATH.

0 голосов
/ 25 августа 2018

Есть ли способ заставить старое поведение?

Да. Вы можете использовать эту опцию -Wl,--disable-new-dtags, чтобы указать компоновщику new использовать поведение old , т.е. RPATH.

Можно ли сказать старой версии компоновщика произвести новый вывод (т.е. RUNPATH вместо RPATH)?

Да. Используйте -Wl,--enable-new-dtags, чтобы указать старому компоновщику использовать поведение new , т.е. RUNPATH.

Я проверил исполняемый файл с readelf, и эти две опции, кажется, управляют тем, что будет написано в разделе ELF Dynamic. Я думаю, что проблема была вызвана изменением настроек по умолчанию для новой версии, хотя, что интересно, страница руководства для ld предполагает, что она должна оставаться такой же:

- включить-новые-dtags
--disable-новый-dtags
Этот компоновщик может создавать новые динамические теги в ELF. Но старые системы ELF могут не понимать их. Если вы укажете --enable-new-dtags, новые динамические теги будут создаваться по мере необходимости и более старые динамические теги будут опущены. Если вы укажете --disable-new-dtags, новые динамические теги не будут созданы. По умолчанию новые динамические теги не создаются. Обратите внимание, что эти параметры доступно только для систем ELF.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...