【问题标题】:Distributing Qt/C++ application cross-platform跨平台分发 Qt/C++ 应用程序
【发布时间】:2017-05-09 06:25:07
【问题描述】:

我正在努力部署我的 Qt/C++ 应用程序,可能是因为我没有在网上找到关于此的好的介绍。简而言之,我的问题是我如何设置一个安装框架,在发送给用户之前只需要最少的编译,或者最好不需要编译

我想将 GUI 部署给不同平台上的用户,这些用户可能在他们的机器上拥有或没有管理员权限。我找到了不同的选择:

  • 静态编译 Qt -> 静态编译可执行文件 -> 分发可执行文件。使用此设置,我遇到了 Windows 安全警告,它需要管理员权限(我尚未在 Linux / macOS 上尝试过)。坦率地说,这种方法似乎不是最理想的,因为我的编译器不知道如何为我的用户进行最佳编译。

  • 创建安装程序。但是我开始感到困惑......我需要提供我的 GUI 的静态编译可执行文件,还是只提供安装程序的可执行文件,或者两者都不需要?或者我可以通过使用带有内置编译器/库的 Qt 安装程序来避免一起预编译吗?

【问题讨论】:

标签: c++ qt cross-platform


【解决方案1】:

使用此设置我遇到了 Windows 安全警告

您没有签署二进制文件。这个问题与Qt无关。即使在分发一个微不足道的“Hello World”时,你也会面对它。

确保您签署所有以下各项:

  1. 可执行文件。

  2. 您重新分发且未签名的所有 DLL(验证每个 DLL)。

  3. 安装程序。

我的编译器不知道如何为我的用户进行最佳编译。

由于 C++ 不使用即时编译,因此这种说法是不言而喻的。当您动态链接时,如果您暗示您需要代码的特定于 CPU 的变体,您的编译器也将“不知道”如何“为您的用户优化”编译。这必须通过拥有多个可执行文件来解决,每个可执行文件都针对特定的 CPU 进行编译,并在安装时选择它们。不过,我不认为你是那个意思。但是我不知道您所说的“为我的用户进行最佳编译”是什么意思。

我是否需要提供我的 GUI 的静态编译可执行文件

这取决于你。如果您不提供静态编译的可执行文件,则需要提供所有依赖项:编译器的 C++ 运行时,以及 Qt 所需的所有库和插件。

在 Windows、Linux 和 OS X 上生成静态链接可执行文件的过程是相同的。您从静态配置的 Qt 副本 (configure -static -static-runtime) 开始,然后构建它,然后使用它来构建您的应用程序。最终产品将与 C++ 运行时和 Qt 库静态链接。

我是否需要提供 [...] 安装程序的静态编译可执行文件

仅当您使用 C++ 编译器自己编译安装程序时。大多数安装程序生成器包负责创建没有额外依赖项的安装程序,即您可以在裸 Windows 系统上运行它。

我可以通过使用 Qt 的安装程序来避免一起预编译吗

Qt 不提供可重复使用的预构建安装程序。

您可以使用例如NSIS 部署编译器运行时、Qt 库和插件,以及您的应用程序和它需要的任何数据文件。

或者您可以静态编译您的应用程序,使其没有依赖关系并且是单个 .exe 文件,并将其作为可移植应用程序。它也可以自行安装,即您可以将安装程序捆绑在应用程序中,并且在启动时应用程序可以检测它是否已经安装,如果没有,它会在管理模式下重新启动并执行安装。

【讨论】:

  • 谢谢,这进一步澄清了一切。特别是签署代码是我不知何故忽略的事情。我想我可以轻松地分发我的静态编译的 EXE。在 Windows 上,我已经弄清楚了这一点,尽管因为我不是 Windows 专家,所以获得静态编译的 Qt 版本需要相当多的痛苦。我希望这在 Linux/macOS 上会更快,因为我更清楚自己在做什么。
【解决方案2】:

显然,您需要在您希望将其分发到的每个平台上构建您的应用程序。最简单的方法是将所有 QT 库动态链接到您的应用程序。之后,您需要做的就是提供您的应用程序(如 Windows 上的 exe 文件,或 linux 上的可执行文件等)和您使用的 QT 库(Windows 上的 DLL,我认为在 linux 上的 SO 文件等)

例如(在 Windows 上)如果您的应用名为 MyApp 并使用 QTGui、QTWidgets 和 QTNetwork,那么您需要分发以下文件:

  • MyApp.exe
  • QTCore.dll 和其他几个所需的 DLL 称为 icu*.dll 什么的,不记得了)
  • QTGui.dll
  • QTWidgets.dll
  • QTNetwork.dll

您可以将它们全部压缩到一个 zip 中,创建安装程序等。

EDIT在评论中跟进后的一些注释。

标准库(您称之为具有vector 类的默认库)是 c/c++ 运行时(在 Windows 上)或安装在 linux 系统等上的一部分,所以不,您不必担心这个.我不能说所有编译器都适用,但对于某些编译器,您可以指定一个标志/参数来静态链接此运行时(很少需要这样做)。

在 Windows 上,有一个名为 dependency walker 的工具,它为您提供运行应用程序所需的所有 DLL 的列表。在我不知道的 linux 系统上,从来不需要一个。但是对于您自己的应用程序,您确实知道您需要哪些库,因为您编写了它:)

【讨论】:

  • 谢谢,我想这澄清了很多。几个后续问题...系统的/编译器的so/dylib/dll,我需要担心这些吗?我猜默认库(例如vector)是在可执行文件中编译的?最后,有没有办法自动分析我需要哪些共享库?
  • The system's / compiler's so/dylib/dll, do I need to worry about those?这个我没有得到,其余的我已经添加到答案中。
猜你喜欢
  • 2016-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-22
  • 2012-08-02
相关资源
最近更新 更多