Как скомпилировать OpenSSL с относительным rpath - PullRequest
8 голосов
/ 22 февраля 2012

Я пытался скомпилировать openssl 1.0.0g со следующим rpath:

$ORIGIN/../lib64

Каждый раз, когда я readelf -d apps/openssl, я получаю результаты, подобные приведенным ниже, в зависимости от того, какие варианты я пробовал:

\RIGIN/../lib64
RIGIN/../lib64
ORIGIN/../lib64

Я хочу настроить свой rpath без использования внешних инструментов, таких как chrpath. Это вообще возможно? Я в основном приму все, что не связано с использованием внешних инструментов, таких как chrpath (хотя я бы с этим уже покончил).

В идеале я хотел бы сделать это, передавая параметры в командной строке (любая форма -Wl,-rpath,$ORIGIN/../lib64).

Я не против редактировать сгенерированный Makefile, который я пробовал в последний раз. Если бы я только мог напечатать глупый знак доллара !!! Я попытался изменить LIBRPATH в блоке BUILDENV = безуспешно. Мои лучшие результаты на данный момент:

LIBRPATH=$$'ORIGIN/../lib64 # result: /../lib64
LIBRPATH=$$$$'ORIGIN/../lib64 # result: 12345<pid>/../lib64 

Я читал различные вопросы, связанные с rpath, и пробовал разные трюки с экранированием и цитированием, но пока ничего не получалось!

Ответы [ 3 ]

7 голосов
/ 22 февраля 2012

В вашем makefile попробуйте:

-Wl,-rpath,${ORIGIN}/../lib64

Я предполагаю, что ORIGIN является переменной оболочки.

EDIT

Я только что нашел ответ на ваш вопрос (лучше поздно, чем никогда): Вы должны запретить интерполяции переменных в make, для этого вам нужно использовать $$ (двойной знак доллара):

-Wl,-rpath,'$$ORIGIN/../lib64'

Я знаю, что это работает, потому что я проверил это с моим собственным приложением, наслаждайтесь:)

2 голосов
/ 16 апреля 2014

Я прошел путь chrpath. http://enchildfone.wordpress.com/2010/03/23/a-description-of-rpath-origin-ld_library_path-and-portable-linux-binaries/

Сложно противостоять расширению оболочки `$$ ORIGIN`` в openssl. Рано или поздно он расширяется из-за знака доллара. Если вы действительно хотите пойти по этому пути, вы можете сделать это. Я нашел следующее для работы с openssl 1.0.1g в Linux. В Makefile.shared найдите эту строку:

DO_GNU_APP=LDFLAGS="$(CFLAGS) -Wl,-rpath,$(LIBRPATH)"

Заменить его следующим. Это цитирование-фу нейтрализует расширение $. Двойной $$ - это способ получить один знак доллара в make-файлах.

DO_GNU_APP=LDFLAGS="$(CFLAGS) -Wl,-rpath,'"'$$'"ORIGIN/../lib64'"

После компиляции:

readelf -d apps/openssl | grep RPATH
 0x000000000000000f (RPATH)              Library rpath: ['$ORIGIN/../lib64']
0 голосов
/ 07 мая 2015

Я не против редактировать сгенерированный Makefile, который я пробовал в последний раз ...

Я не уверен, что вы можете установить его с помощью переменной оболочки и относительного пути. Я не думаю, ldd расширяет $ORIGIN в $ORIGIN/../lib64. В этом случае, я думаю, вам нужно использовать ldconfig - , добавить $ORIGIN/../lib64 к путям поиска библиотеки См. поиск пути поиска ldd при сбое сервера для получения более подробной информации.

Поскольку я не уверен, я все равно предоставлю инструкции. Вам не нужно менять Makefiles. На самом деле, в прошлом мне не везло, потому что что-то перезаписывалось, а другие, такие как CFLAGS и LDFLAGS, игнорировались.

Также см. Сборка OpenSSL с RPATH? Ваш вопрос и процитированный вопрос - это разные вопросы, которые сходятся в похожих ответах (между ними нет дубликатов). Но он предоставляет позицию разработчика OpenSSL по RPATH. Это было личное письмо, поэтому я поделился соответствующими деталями, а не всем сообщением.

Если вам удастся встроить $ORIGIN/../lib64 в раздел ELF, и это сработает, сообщите об этом. Ниже я использую /usr/local/ssl/lib для моего RPATH. Вам следует заменить $ORIGIN/../lib64 на /usr/local/ssl/lib.


OpenSSL поддерживает RPATH из коробки для целей BSD (но не для других). Из Configure:

# Unlike other OSes (like Solaris, Linux, Tru64, IRIX) BSD run-time
# linkers (tested OpenBSD, NetBSD and FreeBSD) "demand" RPATH set on
# .so objects. Apparently application RPATH is not global and does
# not apply to .so linked with other .so. Problem manifests itself
# when libssl.so fails to load libcrypto.so. One can argue that we
# should engrave this into Makefile.shared rules or into BSD-* config
# lines above. Meanwhile let's try to be cautious and pass -rpath to
# linker only when --prefix is not /usr.
if ($target =~ /^BSD\-/)
    {
    $shared_ldflag.=" -Wl,-rpath,\$(LIBRPATH)" if ($prefix !~ m|^/usr[/]*$|);
    }

Самый простой способ сделать это для OpenSSL 1.0.2 выглядит так: добавить его в флаги компоновщика во время настройки

./config -Wl,-rpath=/usr/local/ssl/lib

Вы также можете редактировать строку конфигурации и жесткий код rpath. Например, я работаю над Debian x86_64. Поэтому я открыл файл Configure в редакторе, скопировал linux-x86_64, назвал его linux-x86_64-rpath и внес следующие изменения, добавив параметр -rpath:

"linux-x86_64-rpath",   "gcc:-m64 -DL_ENDIAN -O3 -Wall -Wl,-rpath=/usr/local/ssl/lib::
-D_REENTRANT::-Wl,-rpath=/usr/local/ssl/lib -ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:
${x86_64_asm}:elf:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::64",

Выше поля 2 и 6 были изменены. Они соответствуют $cflag и $ldflag в системе сборки OpenSSL.

Затем настройте новую конфигурацию:

$ ./Configure linux-x86_64-rpath shared no-ssl2 no-ssl3 no-comp \
    --openssldir=/usr/local/ssl enable-ec_nistp_64_gcc_128

Наконец, после make, проверьте настройки застряли:

$ readelf -d ./libssl.so | grep -i rpath
 0x000000000000000f (RPATH)              Library rpath: [/usr/local/ssl/lib]
$ readelf -d ./libcrypto.so | grep -i rpath
 0x000000000000000f (RPATH)              Library rpath: [/usr/local/ssl/lib]
$ readelf -d ./apps/openssl | grep -i rpath 
 0x000000000000000f (RPATH)              Library rpath: [/usr/local/ssl/lib]

Как только вы выполните make install, ldd даст ожидаемые результаты:

$ ldd /usr/local/ssl/lib/libssl.so
    linux-vdso.so.1 =>  (0x00007ffceff6c000)
    libcrypto.so.1.0.0 => /usr/local/ssl/lib/libcrypto.so.1.0.0 (0x00007ff5eff96000)
    ...

$ ldd /usr/local/ssl/bin/openssl 
    linux-vdso.so.1 =>  (0x00007ffc30d3a000)
    libssl.so.1.0.0 => /usr/local/ssl/lib/libssl.so.1.0.0 (0x00007f9e8372e000)
    libcrypto.so.1.0.0 => /usr/local/ssl/lib/libcrypto.so.1.0.0 (0x00007f9e832c0000)
    ...
...