在 Linux 中正确部署 Qt 应用程序
Posted
技术标签:
【中文标题】在 Linux 中正确部署 Qt 应用程序【英文标题】:Deploying Qt applications in Linux properly 【发布时间】:2018-09-03 02:59:25 【问题描述】:我已经使用 Qt 编写了一个应用程序,我正在尝试部署它。我构建了我的应用程序并尝试分发它,但我最终不得不静态构建 Qt,这样用户就不需要安装 Qt 的库来运行我的应用程序。唯一的问题是字体坏了,图片无法加载。
为了静态构建 Qt,我这样做了:
./configure -static -release -ltcg -optimize-size -no-pch -prefix "/home/myuser/Qt/5.11.1-static" -skip webengine -nomake tools -nomake tests -nomake examples -fontconfig
make -j4
make -j4 install
然后是字体不工作的问题。我不断收到错误“QFontDatabase:找不到字体目录(Qt 安装目录)/libs/fonts”,因此我将系统上的 dejavu 字体文件夹复制到程序目录中名为“fonts”的文件夹中,并创建了一个 Bash 脚本将 QT_QPA_FONTDIR 设置为新的字体目录。这使错误消失并使我的应用程序上的文本可见,但是当输入密码时,会显示空白字符而不是星号或任何其他字符。此外,图像不显示。我在与应用程序相同的目录中有一个文件夹,名为“images”,里面有我的图像,所以我这样做了:
QIcon home("(program directory)/images/home.svg");
QIcon ***("./images/***.svg");
ui->tabWidget->setTabIcon(0, home);
ui->tabWidget->setTabIcon(1, ***);
图像不显示,但如果程序是使用动态 Qt 构建的,它们会显示。我尝试了完整路径和使用 ./ 来引用当前目录,但都没有导致图像出现。
【问题讨论】:
“避免使用 Qt 的库”——如果您的应用程序是使用 Qt 构建的,那么 Qt 在逻辑上将是一个依赖项。这没有任何意义。 @SamVarshavchik 我的意思是用户不应该仅仅为了运行我的应用程序而安装 Qt 库,并且所需的库应该是静态链接的,因此我的问题的重点。我会修改那句话。 这并不是 Linux 的基本设计方式。你正在努力游到上游。一个失败的提议。所有主要的 Linux 发行版都有一个包管理器来跟踪包依赖关系。您所要做的就是指定您的应用程序需要 Qt,并为其准备一个包,然后在安装时,如果未安装 Qt,包管理器将自动执行此操作。如果你坚持这种分发方式,那么目前做类似事情的技术涉及容器和虚拟化,这是一个相当高级的话题。 @SamVarshavchik 我正在静态构建它,因为它是 Qt 文档中推荐的。 “静态链接通常是在 Unix 上分发应用程序的最安全和最简单的方法,因为它使您从分发 Qt 库并确保它们位于目标系统上库的默认搜索路径中的任务中解脱出来”。您是否建议我改为使用 Qt 的动态链接?我只是在寻找最可靠的方法来做到这一点,因为这是我第一次发布必须在许多系统上都可用的 Qt 应用程序。 我不确定那些 Qt 文档指的是什么,但是如果您花几分钟时间查看所有已经在您的 Linux 发行版中的基于 Qt 的软件,您会发现它们都会无一例外地与 Qt 库和所有其他库动态链接。 Qt 没有什么特别之处,使它与任何其他软件库都不同。静态链接仅用于非常狭窄的特殊异常情况。 Run of the mill 软件与它使用的所有库动态链接。 【参考方案1】:FWIW,我的公司打包其 Qt 应用程序的 Linux 版本的方式是使用动态库,如随附的屏幕截图所示。请注意,实际的可执行文件(在屏幕截图中显示为“MyApp”,我对其进行了一些修改以保护无辜者)与所有必要的共享库文件一起位于“bin”子目录中。在主目录中有一个简短的 shell 脚本(“MyApp.sh”),如下所示:
#!/bin/bash
unset QT_PLUGIN_PATH
appname=$(basename "$0" .sh)
dirname=$(dirname "$0")
cd "$dirname/bin"
export LD_LIBRARY_PATH=`pwd`
./$appname "$@"
...用户应该运行 MyApp.sh 脚本,该脚本将适当地设置 LD_LIBRARY_PATH 变量,然后运行可执行文件。
它不是世界上最优雅的东西,但它可以完成工作(很像 Linux 本身,呵呵)。
【讨论】:
感谢您的详细解答。我最终只是用动态 Qt 部署了应用程序,并使所需的库依赖于包,因为只需要 3 个 Qt 库以上是关于在 Linux 中正确部署 Qt 应用程序的主要内容,如果未能解决你的问题,请参考以下文章
使用静态 Qt 构建在 Linux 上部署 Qt5 应用程序
在 Linux 上部署 Qt 应用程序二进制文件,与 LSB 兼容