Проблема переносимого двоичного файла Linux C++

Я пытаюсь упаковать свой двоичный файл и все его общие библиотеки в архив. Я хочу, чтобы пользователь извлекал архив только для того, чтобы двоичный файл работал. Исполняемый файл запускается с помощью сценария оболочки, в котором я устанавливаю LD_LIBRARY_PATH для пути к общей библиотеке, содержащейся в архиве.

В первый раз я хотел заставить его работать с дистрибутивом RHEL 6.7, поэтому я скомпилировал свой двоичный файл с этим дистрибутивом, и когда я протестировал его, он работал хорошо. Проблема в том, что теперь я должен заставить его работать на RHEL 7.2 (и поддерживать работу RHEL 6.7), и когда я запустил двоичный файл, он не работает... он падает внутри функции glibc (isspace без мусора в аргументе) . Я вижу, что за этими двумя выпусками RHEL изменилась версия glibc. В разделяемых библиотеках, которые содержатся в архиве, не было разделяемой библиотеки glibc, поэтому я попытался добавить ее и теперь получил следующую ошибку:

./XXX: ���:ELF: zR: Error 892688562

Кажется, это ошибка ELF (подробная информация присутствует каждый раз, когда я ее запускаю), я проверяю все свои общие библиотеки, и они являются библиотеками x64 (например, двоичными файлами) ... Я не хочу компилировать на RHEL 7.2, потому что у меня есть очень много зависимостей и я не хочу все это компилировать, а также мне проще поддерживать одну версию.

Я пробовал много вещей, таких как Statifier и Ermine, которые оба работают, но первый имеет ошибку и должен отключить рандомизацию адресного пространства, а второй является условно-бесплатным, и я предпочитаю бесплатное решение. Я также пробовал CDE, который тоже работает, но он генерирует такой большой пакет, что это немного беспорядок...

Почему с таким решением это работает, а с моим самодельным решением не работает? Что я делаю не так?

Спасибо за чтение, я надеюсь, что у кого-то есть решение для меня, потому что я долго искал...

ИЗМЕНИТЬ:

Я нашел решение, прежде чем мой сценарий оболочки был похож на:

# Binary location
LOCATION=$(dirname $0)
# Shared libraries directory
BINDIR=${LOCATION}/bin/
# Define LD_LIBRARY_PATH
export LD_LIBRARY_PATH=${BINDIR}:${LD_LIBRARY_PATH}
# Launch binary
${LOCATION}/XXX $*

Я изменил на:

# Binary location
LOCATION=$(dirname $0)
# Shared libraries directory
BINDIR=${LOCATION}/bin/
# Changed shared library default location and launch binary
${BINDIR}/ld-linux-x86-64.so.2 --library-path ${BINDIR} ${LOCATION}/XXX $*

Я действительно не понимаю, почему, но это работает, кто-нибудь может объяснить мне, пожалуйста? (ld-linux-x86-64.so.2 взят из дистрибутива RHEL 6.7)


person user3513887    schedule 13.10.2016    source источник
comment
Я знаю парня, который пытался это сделать с помощью Scientific Linux 5/6 iirc. В итоге он создал и использовал свой собственный glibc. Доставка бинарных файлов для Linux не доставляет удовольствия. (Кстати, не мой DVD.)   -  person Baum mit Augen    schedule 13.10.2016
comment
Кстати, сборка разных двоичных файлов для множества целевых платформ — это то, что делает llvm, и это не является неразумным подходом как таковым.   -  person Baum mit Augen    schedule 13.10.2016


Ответы (1)


Я действительно не понимаю, почему, но это работает, кто-нибудь может объяснить мне, пожалуйста?

Это объясняется здесь. Ваше решение — «явный вызов загрузчика», упомянутый здесь.

Кстати, это неправильно: ${LOCATION}/XXX $* Вместо этого вы должны сделать это:

${LOCATION}/XXX "$@"

(Ваш вариант не будет правильно обрабатывать аргументы со встроенными пробелами.)

person Employed Russian    schedule 14.10.2016