Многие современные проекты C / C ++ используют Autotools для создания системы сборки GNU, например генерировать файлы make на основе платформы. Исполняемые файлы (двоичные файлы) создаются в процессе сборки / сборки и могут выполняться локально на машине, на которой выполняется компиляция. Однако, если тот же исполняемый файл был перемещен на другой компьютер или просто в другую папку на том же компьютере, при запуске исполняемого файла может возникнуть ошибка «библиотека не найдена».

Что такое RPATH и $ ORIGIN

RPATH обозначает путь поиска во время выполнения. Согласно Википедии, rpath обозначает путь поиска во время выполнения, жестко запрограммированный в исполняемом файле или библиотеке. Загрузчики с динамической компоновкой используют rpath для поиска необходимых библиотек ». Динамическое связывание - это своего рода ленивое связывание необходимых разделяемых библиотек не на этапе компиляции, а на более позднем этапе запуска одного исполняемого файла. Путь к разделяемым библиотекам будет закодирован в заголовке исполняемого файла, если установлен rpath, переопределив или дополняя пути поиска разделяемой библиотеки по умолчанию, аналогично тому, как расширяется цепочка системной переменной PATH.

$ ORIGIN - это специальная переменная, указывающая фактическое имя исполняемого файла. Он разрешается туда, где исполняемый файл находится во время выполнения, и может быть весьма полезен при установке RPATH.

Как проверить значение RPATH / RUNPATH

Существуют различные способы проверки значения RPATH для исполняемого файла или библиотеки. objdump, readelf и chrpath - три наиболее часто используемых утилиты.

$ objdump -x путь / к / исполняемому файлу | grep RPATH

or

$ readelf -d путь / к / исполняемому файлу | голова -20

or

$ chrpath -l путь / к / исполняемому файлу

RUNPATH, представленный после RPATH для упрощения тестирования библиотек (без необходимости их перестраивать каждый раз), в наши дни получает все более широкое распространение и делает последние устаревшими. Есть еще один пост, посвященный более подробной информации по этой теме. Поэтому не удивляйтесь, если для исполняемого файла установлен RUNPATH вместо RPATH.

На снимке экрана ниже показан пример вывода readelf с RUNPATH и $ ORIGIN:

Зачем и как устанавливать RPATH

Цель настройки RPATH - изменить путь поиска библиотеки, чтобы один исполняемый файл или библиотека могли связывать нужные зависимые библиотеки во время выполнения.

Можно установить 2 разных этапа RPATH:

Во время компиляции

$ ./configure LDFLAGS = -Wl, -rpath = $ ORIGIN / путь / к / библиотеке

сообщит компоновщику, что нужно создать и запустить исполняемый файл по указанному пути к библиотеке, который обычно используется для переопределения путей к библиотекам по умолчанию.

После компиляции перед выполнением

$ chrpath -r «\ $ \ ORIGIN / путь / к / библиотеке» ‹executable›

Вышеупомянутая команда может завершиться ошибкой, если для исполняемого файла ранее не был установлен rpath.

Попробуйте выполнить приведенную ниже команду с помощью утилиты patchelf, которая не будет жаловаться на неустановленный rpath и установит RUNPATH для достижения аналогичной цели.

$ patchelf - set-rpath ‘$ ORIGIN / path / to / library’ ‹executable›

Вывод

После установки RPATH / RUNPATH в каталог, в котором находятся зависимые библиотеки, с помощью $ ORIGIN исполняемый файл Linux может быть успешно запущен либо на месте, либо перемещен в другие каталоги или даже на хосты, достигая желаемых свойств перемещаемости и гибкости. .