最近,我已成功将Qt4应用程序迁移到Qt5。实际上,应用程序使用qt-opensource-linux-x64-5.3.1发行版中预构建的二进制Qt5库在开发机器上构建和运行。
由于我的应用程序需要符合LGPL 2.1许可证,因此与Qt5的链接必须是动态的。 (所以我不能**静态链接到Qt!)
我的问题是部署此应用程序。我无法想出一个包含所有可共享库的包,它们可以在现有的Linux发行版中运行。
我可以容忍用户需要从qt-opensource-linux-x64-5.3.1二进制文件中自行安装Qt5的要求。事实上,这将确保更严格地遵守LGPL 2.1。所以,我可以假设兼容的Qt5库已在主机上安装并可用(虽然我不知道我是否可以为Qt安装假设一个特定目录)
但是,我不清楚如何打包我的应用程序以在主机上运行。任何帮助将不胜感激!
答案 0 :(得分:5)
我认为其他有类似问题的人会对我最终做的事感兴趣。所以,我用最简单的方式对标准预构建二进制Qt5共享库的动态链接进行了实验。事实证明,我可以提出一个适用于以下Linux发行版的发行版:CentOS 7 64位,64位Ubuntu 12.04和带有KDE桌面的Slackware 14.1 64位。诀窍是不包含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发行版:
我希望这会有所帮助。
答案 1 :(得分:4)
LGPL的一个常被误解的方面是它需要动态链接。它没有。它只需要获得代码的一方能够重新链接它与LGPL的库,他们能够从您使用的来源重建构建随应用程序一起提供的Qt。
动态链接按照定义进行处理,因为每次在应用程序启动时都会执行链接(预链接只是一个缓存),并且库的源是可用的(在发行版的包中)。
因此,您需要做的就是将您的应用程序拆分为两个项目:
包含所有代码的静态库项目(.a)。这是封闭的源部分。
将静态库与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
您需要在静态库中引用至少一个符号才能将其链接。这也避免了a different problem peculiar to MSVC。例如:
// dummy.cpp
int main(int argc, char ** argv);
void dummy__reference() {
main(0, 0);
}
最小程序包需要四个文件:MiroProject.sh
- 上面的脚本,步骤#1中的MiroProject.a
,dummy.cpp
和MiroProject.pro
。当然,您必须为您构建MiroProject.a
的Qt库提供源代码。
理想情况下,您的软件包应该包含整个shebang:Qt源代码,您的闭源.a
或.lib
,开源包装器以及构建它的脚本。