rpath = $ ORIGIN не дало желаемого эффекта?

У меня есть двоичный CeeloPartyServer, которому нужно найти libFoundation.so во время выполнения на машине FreeBSD. Они оба находятся в одном каталоге. Я компилирую (на другой платформе, используя кросс-компилятор) CeeloPartyServer, используя флаг компоновщика -rpath=$ORIGIN.

> readelf -d CeeloPartyServer |grep -i rpath
 0x0000000f (RPATH)                      Library rpath: [$ORIGIN]
> ls
CeeloPartyServer    Contents        Foundation.framework    libFoundation.so
> ./CeeloPartyServer 
/libexec/ld-elf.so.1: Shared object "libFoundation.so" not found, required by "CeeloPartyServer"

Почему он не находит библиотеку, когда я пытаюсь ее запустить?

Моя точная строка компоновщика: -lm -lmysql -rpath=$ORIGIN.

Я почти уверен, что мне не нужно экранировать $ или что-то в этом роде, поскольку мой анализ readelf действительно показывает, что rpath библиотеки установлен на $ ORIGIN. Что мне не хватает?


person Nektarios    schedule 12.06.2011    source источник
comment
Также см. Описание RPATH $ ORIGIN LD_LIBRARY_PATH и переносимых двоичных файлов Linux. В статье используется XORIGIN/../lib для резервирования места в заголовке, а затем используется chrpath для изменения на $ORIGIN/../lib, чтобы избежать проблем с цитированием. Вы также можете захотеть -Wl,--enable-new-dtags.   -  person jww    schedule 19.10.2018


Ответы (3)


Я предполагаю, что вы используете gcc и binutils.

Если ты это сделаешь

readelf -d CeeloPartyServer | grep ORIGIN

Вы должны вернуть строку RPATH, которую вы нашли выше, но вы также должны увидеть некоторые записи о флагах. Следующее - из библиотеки, которую я построил.

0x000000000000000f (RPATH)              Library rpath: [$ORIGIN/../lib]
0x000000000000001e (FLAGS)              ORIGIN
0x000000006ffffffb (FLAGS_1)            Flags: ORIGIN

Если вы не видите какие-то записи FLAGS, вы, вероятно, не сказали компоновщику пометить объект как требующий обработки происхождения. С binutils ld вы делаете это, передавая флаг -z origin.

Я предполагаю, что вы используете gcc для управления ссылкой, поэтому в этом случае вам нужно будет передать флаг через компилятор, добавив -Wl,-z,origin в строку ссылки gcc.

person acm    schedule 13.06.2011
comment
Все ваши предположения верны. Я не использую флаг происхождения -z, нигде не видел, чтобы это было задокументировано. Дам вам знать, если это решит проблему. - person Nektarios; 13.06.2011
comment
Из некоторых кратких экспериментов этот флаг кажется ненужным: у меня есть двоичный файл, которому определенно нужен rpath для работы, rpath начинается с $ORIGIN, флаг не установлен, но он работает. - person Ralf Jung; 12.02.2019
comment
Как мне это сделать с помощью cmake на этапе установки? Установка для свойства INSTALL_RPATH значения $ ORIGIN выполняет только половину работы. - person jaskmar; 10.01.2020
comment
Очевидно ld игнорирует флаг происхождения при чтении / обработка вашей библиотеки, хотя некоторые разновидности BSD явно требуют этого - person rcoup; 25.05.2020

В зависимости от того, через сколько слоев проходит этот флаг, прежде чем компоновщик его увидит, вам может потребоваться использовать $$ORIGIN или даже \$$ORIGIN. Вы поймете, что правы, когда readelf покажет заголовок RPATH, который выглядит как $ORIGIN/../lib или аналогичный. Дополнительные $ и обратная косая черта предназначены только для предотвращения обработки $ другими инструментами в цепочке.

person Michael Dillon    schedule 15.06.2011
comment
Просто чтобы прояснить для других (например, меня), которые менее знакомы с RPATH: при установке RPATH во время компиляции попробуйте LDFLAGS="-Wl,-rpath,'\$\$ORIGIN' -Wl,-z,origin"; где echo $LDFLAGS даст: -Wl,-rpath,'$$ORIGIN' -Wl,-z,origin. (Есть некоторая магия Makefile с $$.) - person kevinarpe; 12.06.2015
comment
\ $$ ORIGIN работал у меня при компиляции Python 3. \ $ \ $ ORIGIN не работал и в результате в качестве RPATH использовался RIGIN /../ lib. - person nicktalbot; 06.04.2020

\ $ \ ORIGIN, если вы используете chrpath, и \ $ \ $ ORIGIN, если вы предоставляете напрямую в LDFLAGS

person vikram kedlaya    schedule 28.06.2016