如何配置 Qt 以进行从 Linux 到 Windows 目标的交叉编译?

2024-10-18 09:00:00
admin
原创
92
摘要:问题描述:我想使用 Linux x86_64 主机为 Windows x86_64 目标交叉编译 Qt 库(最终编译我的应用程序)。我觉得我已经很接近了,但我可能对这个过程的某些部分存在根本性的误解。我首先在 Fedora 机器上安装所有 mingw 软件包,然后修改win32-g++qmake.conf 文...

问题描述:

我想使用 Linux x86_64 主机为 Windows x86_64 目标交叉编译 Qt 库(最终编译我的应用程序)。我觉得我已经很接近了,但我可能对这个过程的某些部分存在根本性的误解。

我首先在 Fedora 机器上安装所有 mingw 软件包,然后修改win32-g++qmake.conf 文件以适应我的环境。但是,我似乎被一些看似明显的 Qt 配置选项困住了:-platform-xplatform。Qt 文档说-platform应该是主机体系结构(您正在编译的位置),-xplatform应该是您希望部署的目标平台。在我的例子中,我设置了-platform linux-g++-64-xplatform linux-win32-g++,其中 linux-win32-g++ 是我修改后的 win32-g++ 配置。

我的问题是,使用这些选项执行 configure 后,我发现它调用了我系统的编译器而不是交叉编译器 (x86_64-w64-mingw32-gcc)。如果我省略该-xplatform选项并设置-platform为我的目标规范 (linux-win32-g++),它会调用交叉编译器,但当它发现一些与 Unix 相关的函数未定义时,就会出错。

这是我最近尝试的一些输出:http ://pastebin.com/QCpKSNev 。

问题:

  1. 当从 Linux 主机交叉编译 Qt for Windows 之类的东西时,是否应该调用本机编译器也就是说,在交叉编译过程中,我们不应该使用交叉编译器吗?我不明白为什么当我指定该选项时,Qt 的配置脚本会尝试调用我系统的本机编译器-xplatform

  2. 如果我使用 mingw 交叉编译器,什么时候需要处理 specs 文件?GCC 的 spec 文件对我来说仍然有点神秘,所以我想知道这里的一些背景知识是否会对我有所帮助。

  3. 一般来说,除了在 qmake.conf 中指定交叉编译器之外,我还需要考虑什么?


解决方案 1:

只需使用M 交叉环境 (MXE)即可。它可以消除整个过程的痛苦:

  • 得到它:

$ git clone https://github.com/mxe/mxe.git
  • 安装构建依赖项

  • 为 Windows 构建 Qt、其依赖项以及交叉构建工具;这将在具有良好互联网接入的快速机器上花费大约一个小时;下载内容约为 500MB:

$ cd mxe && make qt
  • 转到应用程序的目录并将交叉构建工具添加到PATH环境变量中:

$ export PATH=<mxe root>/usr/bin:$PATH
  • 运行 Qt Makefile 生成器工具然后构建:

$ <mxe root>/usr/i686-pc-mingw32/qt/bin/qmake && make
  • 您应该在 ./release 目录中找到该二进制文件:

$ wine release/foo.exe

一些注意事项

  • 使用 MXE 存储库的主分支;它似乎得到了开发团队的更多喜爱。

  • 输出是 32 位静态二进制文件,可在 64 位 Windows 上正常运行。

解决方案 2:

(这是@Tshepang 答案的更新,因为 MXE 自他的答案以来已经发生了变化)

构建 Qt

除了使用make qt构建 Qt 之外,您还可以使用MXE_TARGETS来控制目标机器和工具链(32 位或 64 位)。MXE 开始使用.static.shared作为目标名称的一部分来显示您要构建的库类型。

# The following is the same as `make qt`, see explanation on default settings after the code block.
make qt MXE_TARGETS=i686-w64-mingw32.static   # MinGW-w64, 32-bit, static libs

# Other targets you can use:
make qt MXE_TARGETS=x86_64-w64-mingw32.static # MinGW-w64, 64-bit, static libs
make qt MXE_TARGETS=i686-w64-mingw32.shared   # MinGW-w64, 32-bit, shared libs

# You can even specify two targets, and they are built in one run:
# (And that's why it is MXE_TARGET**S**, not MXE_TARGET ;)
# MinGW-w64, both 32- and 64-bit, static libs
make qt MXE_TARGETS='i686-w64-mingw32.static x86_64-w64-mingw32.static'

在@Tshepang的原始答案中,他没有指定MXE_TARGETS,而是使用默认值。在他写答案的时候,默认值是i686-pc-mingw32,现在是i686-w64-mingw32.static。如果您明确设置MXE_TARGETSi686-w64-mingw32,省略.static,则会打印警告,因为此语法现已弃用。如果您尝试将目标设置为i686-pc-mingw32,它将显示错误,因为MXE已删除对MinGW.org(即i686-pc-mingw32)的支持。

跑步qmake

由于我们更改了MXE_TARGETS,该<mxe root>/usr/i686-pc-mingw32/qt/bin/qmake命令将不再起作用。现在,您需要做的是:

<mxe root>/usr/<TARGET>/qt/bin/qmake

如果您未指定MXE_TARGETS,请执行以下操作:

<mxe root>/usr/i686-w64-mingw32.static/qt/bin/qmake

更新:新的默认设置现在是i686-w64-mingw32.static

解决方案 3:

在 Linux 上交叉编译 Windows 软件的另一种方法是 Archlinux 上的 MinGW-w64 工具链。它易于使用和维护,并且提供最新版本的编译器和许多库。我个人觉得它比 MXE 更容易,而且它似乎能更快地采用较新版本的库。

首先,你需要一台基于 Arch 的机器(虚拟机或 Docker 容器就足够了)。不一定非要 Arch Linux,衍生产品也可以。我使用了 Manjaro Linux。大多数 MinGW-w64 软件包在官方 Arch 存储库中都不可用,但AUR 中有很多。Arch 的默认软件包管理器(Pacman)不支持直接从 AUR 安装,因此你需要安装并使用 AUR 包装器,如 yay 或 yaourt。然后安装 MinGW-w64 版本的 Qt5 和 Boost 库就很简单了:

yay -Sy mingw-w64-qt5-base mingw-w64-boost
#yaourt -Sy mingw-w64-qt5-base mingw-w64-qt5-boost #if you use yaourt

这还将安装 MinGW-w64 工具链 ( mingw-w64-gcc) 和其他依赖项。交叉编译适用于 Windows (x64) 的 Qt 项目非常简单:

x86_64-w64-mingw32-qmake-qt5
make

要部署您的程序,您需要从复制相应的 dll/usr/x86_64-w64-mingw32/bin/。例如,您通常需要复制/usr/x86_64-w64-mingw32/lib/qt/plugins/platforms/qwindows.dllprogram.exe_dir/platforms/qwindows.dll

要获得 32 位版本,您只需使用i686-w64-mingw32-qmake-qt5。基于 Cmake 的项目与 一样容易运行x86_64-w64-mingw32-cmake。这种方法对我来说非常有效,最容易设置、维护和扩展。它也适用于持续集成服务。还有可用的docker 镜像。

例如,假设我想构建 QNapi 字幕下载器 GUI。我可以分两步完成:

  1. 启动docker容器:

sudo docker run -it burningdaylight/mingw-arch:qt /bin/bash
  1. 克隆并编译 QNapi

git clone --recursive 'https://github.com/QNapi/qnapi.git' 
cd qnapi/ 
x86_64-w64-mingw32-qmake-qt5
make

就是这样!在很多情况下,就是这么简单。将您自己的库添加到软件包存储库 (AUR) 也很简单。您需要编写一个 PKBUILD 文件,这是最直观的,例如mingw-w64-rapidjson 。

解决方案 4:

好的,我想我已经明白了。

部分基于https://github.com/mxe/mxe/blob/master/src/qt.mkhttps://www.videolan.org/developers/vlc/contrib/src/qt4/rules.mak

看起来“最初”当你运行 configure(使用 -xtarget 等)时,它会配置然后运行你的“主机”gcc 来构建本地二进制文件 ./bin/qmake

 ./configure -xplatform win32-g++ -device-option CROSS_COMPILE=$cross_prefix_here -nomake examples ...

然后你运行正常的“make”,它会为 mingw 构建它

  make
  make install

所以

  1. 是的

  2. 仅当您需要使用 msvcrt.dll(其默认值)以外的其他程序时。尽管我从未使用过其他程序,所以我并不确定。

  3. https://stackoverflow.com/a/18792925/32453列出了一些配置参数。

解决方案 5:

为了编译 Qt,必须运行它的configure脚本,指定主机平台-platform (例如,-platform linux-g++-64如果您使用 g++ 编译器在 64 位 Linux 上构建)和目标平台-xplatform(例如-xplatform win32-g++,如果您交叉编译到 Windows)。

我还添加了这个标志:
-device-option CROSS_COMPILE=/usr/bin/x86_64-w64-mingw32-
它指定我正在使用的工具链的前缀,它将被添加到所有为 Windows 构建二进制文件的 makefile 中的“gcc”或“g++”前面。

最后,您可能会在构建idc时遇到问题,这显然是用于向 Qt 添加 ActiveX 支持的东西。您可以通过将标志传递-skip qtactiveqt给 configure 脚本来避免这种情况。我从这个错误报告中找到了这个:https://bugreports.qt.io/browse/QTBUG-38223

这是我使用过的整个配置命令:

    cd qt_source_directory
    mkdir my_build
    cd my_build
    ../configure \n      -release \n      -opensource \n      -no-compile-examples \n      -platform linux-g++-64 \n      -xplatform win32-g++ \n      -device-option CROSS_COMPILE=/usr/bin/x86_64-w64-mingw32- \n      -skip qtactiveqt \n      -v

至于您的问题:

1 - 是的。将调用本机编译器来构建构建过程中所需的一些工具。可能是 qconfig 或 qmake 之类的东西,但我不完全确定具体是哪些工具。

2 – 抱歉。我不知道 specs 文件在编译器上下文中是什么 =/ 。但据我所知,您不必处理这个问题。

3 - 您可以在 configure 命令行中指定交叉编译器前缀,而不是在 qmake.conf 文件中指定,如上所述。此外,idc 也存在这个问题,我也提到了它的解决方法。

相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   681  
  在项目管理领域,集成产品开发(IPD)流程以其高效、协同的特点,被众多企业视为提升产品竞争力的关键。IPD流程强调跨部门、跨职能的紧密合作,以确保产品从概念到市场各个环节的无缝衔接。然而,实现这一目标并非易事,它需要企业深刻理解并掌握IPD流程中的跨部门协作艺术。本文将深入探讨IPD流程中跨部门协作的三个关键点,旨在为...
IPD项目管理咨询   9  
  掌握IPD流程图:提升团队协作的关键路径在当今快速变化的商业环境中,团队协作的效率与效果直接关系到项目的成功与否。集成产品开发(Integrated Product Development,简称IPD)作为一种先进的研发管理理念,通过跨部门、跨领域的协同工作,能够显著提升产品开发的速度与质量。而IPD流程图,则是这一理...
IPD流程阶段   9  
  IPD流程概述:理解其核心价值与实施背景集成产品开发(Integrated Product Development,简称IPD)是一种先进的产品开发管理理念,它强调跨部门协作、市场导向和快速响应变化的能力。IPD流程不仅关注产品本身的技术创新,更注重将市场、研发、生产、销售等各个环节紧密集成,以实现产品从概念到市场的高...
华为IPD是什么   7  
  在项目管理领域,IPD(Integrated Product Development,集成产品开发)流程以其跨部门协作、高效决策和快速响应市场变化的特点,被众多企业视为提升竞争力的关键。然而,实践IPD流程并非易事,项目管理中的种种错误往往阻碍了其效果的充分发挥。本文旨在深入探讨如何在实施IPD流程时避免这些常见错误,...
IPD框架   7  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用