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

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

> readelf -d CeeloPartyServer | grep -i rpath
 0x0000000f (RPATH) Библиотека rpath: [$ORIGIN]
> лс
CeeloPartyServer    Contents        Foundation.framework    libFoundation.so
> ./CeeloPartyServer 
/libexec/ld-elf.so.1: Общий объект "libFoundation.so" не найден, требуется для "CeeloPartyServer"

Почему он не находит библиотеку, когда я пытаюсь ее запустить? Моя точная строка компоновщика: -lm -lmysql -rpath=$ORIGIN. Я почти уверен, что мне не нужно избегать \$ или чего-то в этом роде, так как мой анализ readelf действительно показывает, что для библиотеки rpath установлено значение $ ORIGIN. Что мне не хватает?

4 ответа

Решение

Я предполагаю, что вы используете 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.

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

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

  1. с использованием ldd CeeloPartyServerчтобы проверить зависимость .so начинается с или нет. (например, и )
    В обычной ситуации это должно быть и без префикса

  2. если ./префикс необходим для какого-то редкого случая, убедитесь, что CWD находится в той же папке, что и , а $ORIGINбудет недействительным.

=======
Например:
g++ --shared -Wl,--rpath="\$ORIGIN" ./libFoundation.so -o lib2.soбыла бы библиотека lib2.soс ./libFoundation.so
g++ --shared -Wl,--rpath="\$ORIGIN" libFoundation.so -o lib2.soполучил бы libFoundation.soвместо.

Другие вопросы по тегам