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

18

У меня есть приложение, которое использует Qt, GDCM и VTK , основной средой сборки является Qt. Все эти библиотеки являются кроссплатформенными и компилируются в Windows, Mac и Linux. Мне нужно развернуть приложение в Linux после развертывания в Windows. Версии vtk и gdcm, которые я использую, являются транковыми версиями из 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 для использования библиотек?

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

задан mmr 17.08.2011 в 23:27
источник

3 ответа

25

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

#!/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]"

Они называют этот скрипт как-то .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 / to / tree в вашей переменной PATH.

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

Кто бы вам ни сказал, чтобы вы не использовали LD_LIBRARY_PATH , он полон, ИМХО.

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

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

Удачи.

    
ответ дан Nemo 18.08.2011 в 03:57
  • Этот подход выглядит очень многообещающим, я попробую - спасибо! –  mmr 18.08.2011 в 18:55
  • Извините, что такое «app1 -> .wrapper (symlink)»? –  Michael IV 13.01.2018 в 21:45
  • @MichaelIV Это означает, что app1 является символической ссылкой на .wrapper; то есть кто-то запускал ln -s .wrapper app1. (Из вашего вопроса, похоже, вам может понадобиться узнать о символических ссылках.) –  Nemo 17.01.2018 в 03:01
5

В общем, лучше всего полагаться на «нормальные» версии библиотек для любого дистрибутива, на который вы нацеливаетесь (и говорят, что вы не поддерживаете диски, которые не поддерживают достаточно недавние версии библиотеки), но если вам ДЕЙСТВИТЕЛЬНО нужно зависеть от передовой версии некоторой разделяемой библиотеки, вы можете связать свое приложение с -Wl,-rpath,'$ORIGIN' , а затем установить копию именно той версии, которую вы хотите, в тот же каталог, что и исполняемый файл.

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

    
ответ дан Chris Dodd 18.08.2011 в 02:08
  • @ Chris-- в случае обеих этих библиотек я знаю, что в библиотеках есть вещи, которые мне нужны, которые были добавлены за несколько месяцев или около того, потому что я добавил их. Эти патчи в конечном итоге заставят его выпускать дистрибутивы, но они еще не попали. Следовательно, потребность в библиотеках, которые «истекают кровью». –  mmr 18.08.2011 в 18:54
1

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

Правильный путь:

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

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

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

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

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

ответ дан Let_Me_Be 17.08.2011 в 23:31
  • Чтобы библиотеки были в том же каталоге, что и исполняемый файл, вам нужно либо перейти с LD_LIBRARY_PATH, либо ссылку на -rpath - linux обычно не выглядит в каталоге exec для общих библиотек. –  Chris Dodd 18.08.2011 в 02:14