Какой принятый метод развертывания приложения linux, основанного на использовании разделяемых библиотек?

У меня есть приложение, которое полагается на Qt, GDCM и VTK, с основной строительной средой является Qt. Все эти библиотеки являются кросс-платформенными и компилируются в Windows, Mac и Linux. Мне нужно развернуть приложение в Linux после развертывания в Windows. Версии vtk и gdcm, которые я использую, являются версиями trunk от git (около месяца), более поздними, чем то, что я могу получить apt-get на Ubuntu 11.04, который является моим текущим (и единственным) местом развертывания Linux.

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

Должен ли я статически ссылаться сюда, чтобы избежать LD_LIBRARY_PATH? Я вижу конфликтующие отчеты по LD_LIBRARY_PATH; такие как этот позволяют предположить, что это "правильный путь", чтобы изменить путь к библиотеке для использования разделяемых библиотек при перезагрузке системы. Другие предложить, что я никогда не должен устанавливать LD_LIBRARY_PATH. В версии GDCM по умолчанию установка уже помещает библиотеки в каталог /usr/local/lib, поэтому эти библиотеки видны при запуске ldd <my program>. С другой стороны, VTK помещает свои библиотеки в /usr/local/lib/vtk-5.9, который не является частью LD_LIBRARY_PATH на большинстве пользовательских машин, и поэтому не найден, если в систему не внесены какие-либо изменения. Копирование файлов VTK в '/usr/local/lib' не позволяет 'ldd' видеть файлы.

Итак, как я могу заставить мое приложение видеть VTK для использования библиотек?

В окнах развертывание DLL очень просто, потому что я могу просто включить их в установщик, и приложение находит их, потому что они находятся в локальном каталоге. Этот подход не работает в Linux, поэтому я собираюсь установить пользователей Qt, GDCM и VTK из любого подходящего источника и использовать местоположения по умолчанию, а затем указать, что приложение указывает на эти местоположения по умолчанию. Однако, поскольку VTK помещает вещи в нестандартное место, должен ли я также ожидать, что пользователи изменят LD_LIBRARY_PATH? Должен ли я включать конкретные версии библиотек, которые я хочу, а затем выяснить, как сделать исполняемый файл в локальном каталоге для этих библиотек и игнорировать те, которые он находит в пути к библиотеке?

Ответ 1

Каждое "серьезное" коммерческое приложение, которое я когда-либо видел, использует LD_LIBRARY_PATH. Они неизменно включают оболочку script, которая выглядит примерно так:

#!/bin/sh

here="${0%/*}"  # or you can use `dirname "$0"`

LD_LIBRARY_PATH="$here"/lib:"$LD_LIBRARY_PATH"
export LD_LIBRARY_PATH
exec "$0".bin "[email protected]"

Они называют это script чем-то вроде .wrapper и создают дерево каталогов, которое выглядит так:

.wrapper
lib/  (directory full of .so files)
app1 -> .wrapper (symlink)
app1.bin (executable)
app2 -> .wrapper (symlink)
app2.bin (executable)

Теперь вы можете скопировать все это дерево туда, где хотите, и вы можете запускать "/path/to/tree/app1" или "/path/to/tree/app2 -with -some -arguments" и это будет работать. Так будет помещать/путь/в/дерево в вашем PATH.

Кстати, это также то, как Firefox и Chrome делают это, более или менее.

Тот, кто сказал вам не использовать LD_LIBRARY_PATH, полон его, ИМХО.

Какие системные библиотеки, которые вы хотите разместить в lib, зависят от того, какие версии Linux вы хотите официально поддерживать.

Даже не думайте о статической привязке. Разработчикам glibc это не нравится, они не заботятся об их поддержке, и им как-то удается сломать его немного сложнее с каждым выпуском.

Удачи.

Ответ 2

В общем, вам лучше всего в зависимости от "нормальных" версий библиотек для любого дистрибутива, на который вы нацеливаетесь (и заявляете, что не поддерживаете диски, которые не поддерживают последние версии lib) но если вам действительно нужно зависеть от версии с кратким выпуском некоторой общей библиотеки, вы можете связать свое приложение с -Wl,-rpath,'$ORIGIN', а затем установить копию точной версии, которую вы хотите, в том же каталоге, что и ваш исполняемый файл.

Обратите внимание, что если вы используете make, вам понадобится $$ в make файле, чтобы получить единственный $ в аргументе, который фактически отправлен в компоновщик. Отдельные qutoes необходимы, чтобы оболочка не искажала вещи...

Ответ 3

Ну, есть два варианта развертывания приложения Linux.

Правильный способ:

  • создайте пакет для своего приложения и для библиотек, если они такие специальные, что они не могут быть установлены из стандартных репозиториев

  • Существует два основных формата пакета. RPM и DEB.

Простой способ:

  • создайте файл самораскрытия, который установит "путь к окнам" в /opt.

  • У вас могут быть библиотеки в том же каталоге, что и исполняемый файл, это не самый предпочтительный способ.