Как заставить RPATH с $ ORIGIN работать на Code :: Blocks GCC? - PullRequest
17 голосов
/ 23 октября 2008

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

-Wl,-R$ORIGIN

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

g++ -Wl,-R

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

Ответы [ 3 ]

35 голосов
/ 23 октября 2008

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

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

-Wl,-R\$ORIGIN

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

-Wl,-R\\$$ORIGIN

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

-Wl,-R\\$ORIGIN

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

-Wl,-R\$ORIGIN

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

Какая боль.

15 голосов
/ 01 октября 2009

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

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

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

1 голос
/ 17 января 2013

Если ваш исполняемый файл создается из огромной сложной среды сценариев, не созданной вами, и вы не хотите вникать в это, попробуйте запустить с 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, чтобы переопределить это. Пробег может отличаться . Только для одноразового использования. Не гарантируется, что он будет менее ужасным, чем любой другой подход).

...