Как предоставить соответствующие разделяемые библиотеки для самоскомпилированной программы?

Я собрал программу в своей собственной системе Ubuntu. Теперь я хочу запустить его на чужой системе Ubuntu с той же архитектурой, но слегка устаревшими общими библиотеками. Как мне получить библиотеки из моей собственной системы, работающие на чужой? Я не root на чужой машине.

До сих пор я пытался скопировать файлы, перечисленные в me@mymachine> ldd myprogram вместе с myprogram, в один и тот же каталог на чужой машине. После выполнения me@foreignmachine> ./myprogram я ожидал, что библиотеки в одном каталоге будут загружены вместо устаревших в пути к библиотеке. Однако я получаю сообщения об ошибках

/usr/lib64/libgomp.so.1: version `GOMP_4.0' not found (required by ./myprogram)
/lib64/libc.so.6: version `GLIBC_2.14' not found (required by ./myprogram)

Так что очевидно, что скопированные мною библиотеки не были загружены, так как они имели правильную версию в моей системе (где я скомпилировал программу).

Есть еще один рабочий клудж? Статическое связывание тоже не работает (как и ожидалось).


Редактировать: ldd myprogram дал:

    linux-vdso.so.1 =>  (0x00007ffccabf4000)
    libgfortran.so.3 => /usr/lib/x86_64-linux-gnu/libgfortran.so.3 (0x00007f149b334000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f149b038000)
    libgomp.so.1 => /usr/lib/x86_64-linux-gnu/libgomp.so.1 (0x00007f149ae15000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f149abfe000)
    libquadmath.so.0 => /usr/lib/x86_64-linux-gnu/libquadmath.so.0 (0x00007f149a9bf000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f149a7a1000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f149a3e3000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f149b67d000)
    librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f149a1db000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f1499fd6000)

Итак, я скопировал 10 файлов /lib/x86_64-linux-gnu/libdl.so.2, /lib/x86_64-linux-gnu/librt.so.1, /lib64/ld-linux-x86-64.so.2 и т. д. во внешнюю систему. В соответствии с тем, что я обнаружил, все в порядке, если не заботиться о linux-vdso.so.1, так как он генерируется автоматически внутри ядра.

2
задан 21 May 2015 в 17:24

3 ответа

На Linux динамический компоновщик не делает взглядом по умолчанию в текущем каталоге. Если Вы действительно включаете все необходимые библиотеки в текущий каталог, он должен работать:

LD_LIBRARY_PATH=. ./myprogram

, Если Вы не обеспечиваете все необходимые библиотеки, это могло бы жаловаться или просто отказать (из-за двоичных несовместимостей, что компоновщик не может обнаружить только сравнение номеров версий библиотеки).

Ссылка: укомплектуйте ld.so

LD_LIBRARY_PATH разделенный от двоеточия список каталогов, в которых можно искать библиотеки ELF во время выполнения. Подобный переменной окружения PATH. Проигнорированный в идентификаторе пользователя набора и программах идентификатора группы набора.

0
ответ дан 21 May 2015 в 17:24

Благодаря этот ответ Julien, я добавил к компоновщику опции -L. -Wl,-rpath='$ORIGIN'. Эти -L говорит компоновщику искать общие библиотеки в каталоге, где Вы компилируете. Вторая опция более важна в этом теперь во времени выполнения, общие библиотеки в исходном каталоге, где исполняемый файл, будут взяты. Таким образом, если я делаю теперь ldd /home/on/foreign/machine/myprogram на внешней машине, я добираюсь, например,

libgfortran.so.3 => /home/on/foreign/machine/libgfortran.so.3

, Но существует одна библиотека, покинутая, чья запись не изменяется: /lib64/ld-linux-x86-64.so.2. Это - псевдоним для ld.so, @StГ©phane указал. Теперь от того, что он преподавал мне, я завершил для попытки ld-linux-x86-65.so.2 - файл от моей собственной машины на другой:

me@foreign:/home/on/foreign/machine> ./ld-linux-x86-64.so.2 ./myprogram

И это наконец работало над внешней машиной. Обратите внимание, что я не изменился LD_LIBRARY_PATH.

Однако я думаю, что это работает, потому что только версии ядра (не архитектура) отличаются между обеими машинами.

0
ответ дан 21 May 2015 в 17:24

На Linux существует большое усилие для совместимости на уровне двоичных кодов на уровне ядра, не так на уровне библиотеки.

то, Что я несколько раз делал и работал отлично, должно сделать на машине разработки chroot с целевой средой машины, включая компилятор. (Можно заменить chroot виртуальной машиной или любым типом контейнера.)

двоичные файлы, которые Вы сделаете из такой среды, будут всегда соответствовать отлично целевой машине.

профессионалы/недостатки:

  • chroot или контейнерный довод "против": нужны некоторые усилия (особенно в, первый раз) - chroot является более традиционный Unix. schroot мог бы помочь настроить и использовать chroot..
  • chroot или про контейнер: легкий вес на ресурсах (особенно chroot)
  • chroot или про контейнер: так или иначе легче сделать заданным сценарием (с schroot особенно или sudo конфигурацией).
  • про виртуальные машины: легче для новичков (например, VirtualBox).
  • довод "против" виртуальных машин: несколько тяжелый на использовании диска и ЦП
  • довод "против" виртуальных машин: обычно нуждается в графическом доступе (пользователь совершенствовался достаточно, чтобы предпочесть, чтобы доступ оболочки через SSH мог бы быть достаточно здравым смыслом для предпочтения контейнера или chroot).

В любом случае, chroot/container/VM может быть сохранен и много раз снова использоваться.

0
ответ дан 21 May 2015 в 17:24

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

Похожие вопросы: