Как развернуть приложение Qt5 в Linux в соответствии с LGPL?

Недавно я успешно перенес свое приложение Qt4 на Qt5. Фактически, приложение собирается и работает на компьютере разработчика, используя предварительно собранные двоичные библиотеки Qt5 из дистрибутива qt-opensource-linux-x64-5.3.1.

Поскольку мое приложение должно соответствовать лицензии LGPL 2.1, ссылка на Qt5 должна быть динамичной. (Так что я могу ** не ** ссылаться на Qt статически!)

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

Я могу допустить требование, чтобы пользователи сами устанавливали Qt5 из двоичного файла qt-opensource-linux-x64-5.3.1. Фактически это обеспечит еще более строгое соблюдение LGPL 2.1. Таким образом, я могу предположить, что совместимые библиотеки Qt5 установлены и доступны на хост-компьютере (хотя я не знаю, могу ли я использовать конкретный каталог для установки Qt)

Однако мне не ясно, как упаковать мое приложение для запуска на хост-машине. Любая помощь будет принята с благодарностью!

2 ответа

Решение

Я думал, что другие люди с подобной проблемой будут заинтересованы в том, что я в итоге делаю. Итак, я поэкспериментировал еще с самой простой для меня динамической компоновкой стандартных готовых двоичных разделяемых библиотек Qt5. Оказалось, что я мог бы создать дистрибутив, который работал бы на следующих дистрибутивах Linux: 64-битный CentOS 7, 64-битный Ubuntu 12.04 и 64-битный Slackware 14.1 с рабочим столом KDE. Хитрость заключалась не в том, чтобы включить все зависимости, показанные ldd команда. Вместо этого мой бинарный дистрибутив содержит только следующие файлы:

+-platforms/
| +-libqxcb.so
+-libicudata.so.52
+-libicui18n.so.52
+-libicuuc.so.52
+-libQt5Core.so.5
+-libQt5DBus.so.5
+-libQt5Gui.so.5
+-libQt5PrintSupport.so.5
+-libQt5Widgets.so.5
+-qm
+-qm.sh

Куда, qm является исполняемым приложением и qm.sh скрипт bash для запуска приложения Сценарий выглядит следующим образом:

#!/bin/sh
dirname=`dirname $0`
tmp="${dirname#?}"

if [ "${dirname%$tmp}" != "/" ]; then
dirname=$PWD/$dirname
fi
LD_LIBRARY_PATH=$dirname
export LD_LIBRARY_PATH
$dirname/qm "$@"

Приложение (qm) не имеет плагинов и использует только базовую библиотеку виджетов Qt.

Возможно, мне следует добавить, что я использовал бинарный дистрибутив qt-opensource-linux-x64-5.3.1:

http://download.qt-project.org/official_releases/qt/5.3/5.3.1/qt-opensource-linux-x64-5.3.1.run.mirrorlist

Я надеюсь, что это полезно.

IANAL

Обычно неправильно понимаемый аспект LGPL заключается в том, что он требует динамического связывания. Это не так. Это просто требует от стороны, которая получила код, связать его с библиотеками LGPL, которые они смогли восстановить из источника, который вы использовали, и предоставить его для создания Qt, поставляемого с вашим приложением.

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

Итак, все, что вам нужно сделать, это разделить ваше приложение на два проекта:

  1. Проект статической библиотеки (.a), который содержит весь ваш код. Это закрытая исходная часть.

  2. Исполняемый файл приложения, который связывает статическую библиотеку с библиотекой Qt, средой выполнения C++ и т. Д. На данный момент не имеет значения, является ли библиотека Qt статически или динамически связанной.

Чтобы соответствовать LGPL, ваши пользователи должны иметь возможность получить, согласно условиям LGPL, все файлы, необходимые для выполнения шага № 2 (в простейшем случае просто.pro-файл!), И статическую библиотеку (.a) из шага № 1.

Фактически, шаг № 2 позволяет очень просто предоставить платформо-зависимый способ связать ваш проект с локально установленным Qt. Например, если вы нацелены на системы RedHat, вы можете использовать следующий скрипт:

#! /bin/bash
# MiroProject.sh
yum install qt5-devel
qmake MiroProject
make install

Файл проекта может выглядеть следующим образом, при условии, что статическая библиотека находится в том же месте, что и MiroProject.pro а также dummy.cpp,

# MiroProject.pro
template = app
LIBS += -L. -lMiroProject
SOURCES += dummy.cpp

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

// dummy.cpp
int main(int argc, char ** argv);
void dummy__reference() {
  main(0, 0);
}

Минимальный пакет требует четыре файла: MiroProject.sh - скрипт выше, MiroProject.a из шага № 1, dummy.cpp а также MiroProject.pro, И, конечно, вы должны предоставить исходные тексты для библиотеки Qt, которую вы создали MiroProject.a с.

В идеале, ваш пакет должен включать весь shebang: Qt sources, ваш закрытый источник .a или же .lib, обертка с открытым исходным кодом и скрипт, который все это создает.

IANAL

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