Вопрос

Я пытаюсь связать RPATH, содержащий специальную строку $ ORIGIN, в исполняемый файл, созданный с использованием GCC, с IDE Code :: Blocks. Я указал

-Wl,-R$ORIGIN

в параметрах компоновщика для проекта, но вывод командной строки в GCC неверен (для ясности удален):

g++ -Wl,-R

Как правильно указать этот аргумент для Code :: Blocks?

Это было полезно?

Решение

Кто бы ни решил создать токен $ ORIGIN, он - злой ублюдок, который заслуживает особого места в аду программистов. Так как '$' является специальным символом для bash и других языков сценариев, таких как make, он все испортил, если его не избежать. Хуже того, в зависимости от того, какую среду сборки вы используете, специфика правильного выхода из нее, скорее всего, изменится.

В bash вам нужно добавить обратную косую черту перед $:

-Wl,-R\$ORIGIN

Code :: Blocks, очевидно, также обрабатывает $ как особый. Затем любой контроллер подпроцесса Code :: Blocks отправляет команду для обработки обратной косой черты как особой. Таким образом, и обратная косая черта, и $ должны быть удвоены для правильного экранирования. Поэтому в настройках компоновщика Code :: Blocks необходимо указать:

-Wl,-R\\$ORIGIN

... который выводит:

-Wl,-R\\$ORIGIN

... в журнал сборки, но оболочка фактически отправляется:

<*>

... который, как упоминалось выше, дает желаемый результат.

Какая боль.

Другие советы

В дополнение к ответу kblucks, который отвечает на вопрос для Code: Blocks .... Для тех, кто, как я, наткнулся на эту страницу и ищет, как это сделать с помощью Make. Хитрость заключается в том, чтобы использовать дополнительный знак $ в качестве escape-символа и заключать его в кавычки:

-Wl,-R,'$ORIGIN/../lib'

Полное объяснение можно найти здесь: Использование ORIGIN для динамического выполнения путь поиска в библиотеке

Если ваш исполняемый файл создается из огромной сложной среды сценариев, не созданной вами, и вы не хотите в нее вникать, попробуйте запустить с помощью setenv LD_RUN_PATH = '$ ORIGIN /../ lib' ; если это не сработает, прагматичный подход заключается в создании оболочки для ld:

#!/bin/sh
exec /usr/bin/ld -R '$ORIGIN/../lib' "$@"

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

(здесь "/ usr / bin / ld" - это ld, который обычно запускался, который может быть где-то еще. gcc может не получить ld из пути, см. переменные среды gcc, чтобы переопределить это. Пробег может различаются. Только для одноразового использования. Не гарантируется, что он будет менее ужасным, чем любой другой подход).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top