使用动态链接在 Linux 上为 Windows 交叉编译 Qt 应用程序

Posted

技术标签:

【中文标题】使用动态链接在 Linux 上为 Windows 交叉编译 Qt 应用程序【英文标题】:Cross compiling Qt application for Windows on Linux with dynamic linking 【发布时间】:2013-01-28 21:37:36 【问题描述】:

为了遵守 Qt 的 LGPL 许可证,使用 Qt 库的应用程序必须使源代码可用或动态链接到 Qt(如果我在这几句话中理解正确的话)。

所以我想创建一个封闭源代码的应用程序来做到这一点。此外,我想在 Linux(目前是 Xubuntu 12.04)上使用支持 C++11 的 g++/MinGW 来创建 Windows 二进制文件。我跟着this helpful guide 完成了后者。但正如指南还指出的那样,会创建静态链接的可执行文件。

由于我使用 MXE 自动下载和构建 Qt 库(5.0 版),我没有太多机会影响这个过程。所以我的问题是,如何创建 Qt 库和相应应用程序的动态链接版本?

【问题讨论】:

一个问题:为什么不在windows上使用mingw?我认为 linux 上的 mingw 交叉编译器将支持与 windows 相同级别的 c++11。 @MinLin 对我来说,原因是更舒适的 Linux 环境 【参考方案1】:

更新

现在,使用 MXE 构建库的动态版本的更好方法是为工具链指定“共享”选项:

make MXE_TARGETS=i686-w64-mingw32.shared qt5

原创

编辑:我创建了一个 git 存储库,我已经在其中对 MXE 进行了所有必要的更改,以构建 qtbase 的共享版本。可在https://github.com/jeremysalwen/mxe 获得。要构建,请克隆存储库,然后运行“make qtbase”。我在下面留下了我原来的帖子。

于是我下载了mxe环境,看来编译qt使用的代码在src/qt.mk中有帮助

基本过程是将此代码与构建 qt 的标准说明相匹配。如果您查看 qt.mk 和 qtbase.mk 内部,您会发现它实际上非常简单,基本上只是运行 ./configure、make,然后安装生成的文件。如果你能看到这个,你应该能够匹配静态/动态构建 qt 的方向并修改 qt.mk 使其匹配动态方向。

无论如何,我想我已经找到了问题所在。看起来不同之处在于编译qt时的“-static”标志。因此,如果我们简单地删除在 qt.mk 和 qtbase.mk 中传递给 ./configure 的“-static”标志,我希望 mxe 然后会构建一个动态 qt 版本。当然,您可能需要更改其他内容,但希望这就是您需要做的所有事情。

【讨论】:

@Tshepang:我创建了一个 github 存储库,在其中对 qtbase 及其所有依赖项的构建脚本进行了必要的更改。我已经为我的帖子添加了一个链接。 构建良好,我的应用也是如此;现在我必须弄清楚如何将它打包并在 Windows 上运行 这里也一样,所以到目前为止非常感谢。在 Windows 中运行编译后的应用程序时,首先缺少 dll(当然),但是在复制所需的文件时,我得到的只是运行时错误。我会进一步调查。 我不确定下一步是什么。我看到有a bunch of downloads offered,标记为 MinGW 4.7 的可能是正确的。我只是安装它,一切都会好起来的吗?那是你尝试过的@Ratatwisker 吗?我害怕下载它,才发现它不起作用(它太大了,800MB+)。 我尝试了 MinGW 包中的那些以及 mxe 构建中的那些(位于 /usr/i686-pc-mingw32/qt5/lib/)。尝试运行已编译的应用程序时,这两种方式都会导致相同的消息:“此应用程序已请求运行时以不寻常的方式终止它。”使用 Visual Studio 调试器,我可以看到两条消息“传递给 C 运行时函数的参数无效”。我想尝试的下一步是在调试模式下编译 Qt 和应用程序,但我没有时间这样做。【参考方案2】:

首先您需要设置葡萄酒。

sudo apt-get install wine

然后下载Qt5 Windows MinGW SDK用酒运行

wget http://releases.qt-project.org/qt5/5.0.1/qt-windows-opensource-5.0.1-mingw47_32-x86-offline.exe
wine qt-windows-opensource-5.0.1-mingw47_32-x86-offline.exe

按照向导安装 Qt。 那么

cd ~/.wine/drive_c/Qt/Qt5.0.1/Tools/QtCreator/bin
wine qtcreator.exe

我尝试了qtcreator中的示例,它在linux下编译运行良好,当我将exe文件复制到安装了Qt的windows机器上时,它也运行良好。

当然,一个缺点是使用 qtcreator 和使用 wine 的编译器感觉不是原生的。我不知道它与本机 linux 二进制文件相比要慢多少。但是 jom 是可用的,如果您的项目那么大,您可以使用多个内核进行编译。

要在 qtcreator 中使用 jom 而不是 make,请在 qtcreator 中修改此处。

projects > Build & Run > Build > Build Steps > Make

替换为 jom 并添加 make 参数 -j N 其中 N 是您要使用的核心数。

【讨论】:

什么是jom,名字中的offline是什么意思? jom相当于make,把make替换成jom -j N会启动N个并行的进程来make你的project。离线只是QtSDK安装程序的命名,我认为这意味着安装程序拥有您需要的一切,并且能够在您没有互联网连接时安装qt。【参考方案3】:

我最近一直在磕磕绊绊,发现octave's fork of mxe 取得了一些成功。他不辞辛劳地构建了具有共享(.dll)库支持的 qt,满足了我的需求。这是link to his post。

【讨论】:

【参考方案4】:

您需要为动态链接构建 QT。如果您为静态链接构建了 QT(通常是 .a 文件在 linux 中),您的二进制文件将是静态的。如果您在 linux 中针对共享对象文件 (.so) 构建,您的二进制文件将被动态链接。您还需要在应用程序中包含相关的 .dll,这样当其他人运行可执行文件时,它就可以访问这些库。

来自 qt-project.org 的 QT SDK 包含动态链接的文件。

【讨论】:

以上是关于使用动态链接在 Linux 上为 Windows 交叉编译 Qt 应用程序的主要内容,如果未能解决你的问题,请参考以下文章

在 linux 上为 windows 编译

如何在 Windows 上为 CUDA 链接库(例如 CUBLAS、CUSPARSE)

如何在 Windows 上为 CUDA 链接库(例如 CUBLAS、CUSPARSE)

在 Linux 上为 Windows 开发人员调试

无法使用 VS Code 在 Windows 机器上为 linux 构建 .Net core 3.0 项目

如何在 Windows 上为我的操作系统编译和链接 C 和 ASM