Я собрал программу в своей собственной системе 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
, так как он генерируется автоматически внутри ядра.
На Linux динамический компоновщик не делает взглядом по умолчанию в текущем каталоге. Если Вы действительно включаете все необходимые библиотеки в текущий каталог, он должен работать:
LD_LIBRARY_PATH=. ./myprogram
, Если Вы не обеспечиваете все необходимые библиотеки, это могло бы жаловаться или просто отказать (из-за двоичных несовместимостей, что компоновщик не может обнаружить только сравнение номеров версий библиотеки).
Ссылка: укомплектуйте ld.so
LD_LIBRARY_PATH разделенный от двоеточия список каталогов, в которых можно искать библиотеки ELF во время выполнения. Подобный переменной окружения PATH. Проигнорированный в идентификаторе пользователя набора и программах идентификатора группы набора.
Благодаря этот ответ 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
.
Однако я думаю, что это работает, потому что только версии ядра (не архитектура) отличаются между обеими машинами.
На Linux существует большое усилие для совместимости на уровне двоичных кодов на уровне ядра, не так на уровне библиотеки.
то, Что я несколько раз делал и работал отлично, должно сделать на машине разработки chroot с целевой средой машины, включая компилятор. (Можно заменить chroot виртуальной машиной или любым типом контейнера.)
двоичные файлы, которые Вы сделаете из такой среды, будут всегда соответствовать отлично целевой машине.
профессионалы/недостатки:
schroot
мог бы помочь настроить и использовать chroot.. В любом случае, chroot/container/VM может быть сохранен и много раз снова использоваться.