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

Mr.*_*nce 78 linux qt mingw cross-compiling

我想使用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的克++是我的改性Win32的克++结构.

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

以下是我最新尝试的一些输出:http://pastebin.com/QCpKSNev.

问题:

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

  2. 如果我使用的是mingw交叉编译器,何时需要处理specs文件?GCC的规范文件对我来说仍然是一个谜,所以我想知道这里的一些背景是否对我有帮助.

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

tsh*_*ang 67

只需使用M cross environment(MXE).这需要整个过程的痛苦:

一些说明:

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

  • 输出是一个32位静态二进制文件,在64位Windows上运行良好.

  • **注意**:这些说明适用于Qt 4; 对于Qt 5,请参阅http://stackoverflow.com/a/14170591 (17认同)

Tim*_* Gu 16

(这是@ Tshepang答案的更新,因为自从他的回答以来MXE已经发展了)

建立Qt

make qt您可以使用MXE_TARGETS来控制目标计算机和工具链(32位或64位),而不是使用构建Qt .MXE开始使用.static.shared作为目标名称的一部分来显示您要构建的lib类型.

# 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'
Run Code Online (Sandbox Code Playgroud)

在@ 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
Run Code Online (Sandbox Code Playgroud)

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

<mxe root>/usr/i686-w64-mingw32.static/qt/bin/qmake
Run Code Online (Sandbox Code Playgroud)

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

  • 这应该是对另一个答案的编辑/更新,而不是新答案. (3认同)
  • @Hugo编辑页面说:如何编辑:►修正语法或拼写错误►澄清意义而不更改►正确的小错误►添加相关资源或链接►始终尊重原作者这不是任何一个.这是Tshepang答案的延伸. (2认同)

Myk*_*ura 7

在 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
Run Code Online (Sandbox Code Playgroud)

这还将安装 MinGW-w64 工具链 ( mingw-w64-gcc) 和其他依赖项。为 Windows (x64) 交叉编译 Qt 项目就像这样简单:

x86_64-w64-mingw32-qmake-qt5
make
Run Code Online (Sandbox Code Playgroud)

要部署计划,您将需要复制相应的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
Run Code Online (Sandbox Code Playgroud)
  1. 克隆并编译 QNapi
git clone --recursive 'https://github.com/QNapi/qnapi.git' 
cd qnapi/ 
x86_64-w64-mingw32-qmake-qt5
make
Run Code Online (Sandbox Code Playgroud)

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