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


81

我想使用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主机交叉编译Windows版Qt之类的东西时,是否应调用本机编译器?也就是说,在交叉编译过程中,我们不应该使用交叉编译器吗?指定-xplatform选项时,我看不到为什么Qt的configure脚本试图调用系统的本机编译器。

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

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


2
我相信它需要qmake的本地版本来引导其余版本。另请参见stackoverflow.com/questions/1025687/…中的
Martin Beckett 2012年

好的,那很有道理。我现在刚刚发现了另一个问题,似乎混合了本地和跨工具链。我的pastebin输出中的错误似乎是由于调用x86_64-w64-mingw32-as而不是本地调用。
Shickadance先生2012年

2
我很少将SO问题标记为喜欢的问题,但这是一个独特且有趣的问题,答案很酷。
jdi 2012年

Answers:


70

只需使用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信息库的master分支;似乎从开发团队那里获得了更多的爱。

  • 输出是32位静态二进制文件,它将在64位Windows上很好地工作。


17
注意:这些说明适用于Qt 4;有关Qt 5的信息,请参见stackoverflow.com/a/14170591
tshepang 2013年

执行之前,$ cd mxe && make qt您应该安装要求。对于Debian系统,这意味着sudo apt-get install autoconf automake autopoint bash bison bzip2 cmake flex gettext git g++ gperf intltool libffi-dev libtool libltdl-dev libssl-dev libxml-parser-perl make openssl patch perl pkg-config python ruby scons sed unzip wget xz-utils。对于其他系统,请参见mxe.cc/#requirements
Martin Thoma

16

(这是@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


非常感谢您的更新。让直接在项目上工作的人回应也很好。
tshepang 2014年

3
这应该是对其他答案的编辑/更新,而不是新的答案。
WhyNotHugo 2014年

3
@Hugo编辑页面上说:如何编辑:►纠正语法或拼写错误►在不更改的情况下澄清含义►纠正较小的错误►添加相关资源或链接►始终尊重原始作者这不是全部。这是谢庞答案的延伸。
Timothy Gu

我不明白这个答案,当我输入“ make qt ....”时,它只是回答“没有规则使目标qt”。
煤矿

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. 仅当您需要使用msvcrt.dll(默认值)以外的其他内容时。尽管我从未使用过其他任何东西,所以我不确定。

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


4

为了编译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 ++'开头。

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

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

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

至于您的问题:

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

2-对不起。我不知道在编译器= /的上下文中是什么规范文件。但据我所知,您不必对此进行处理。

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


4

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

首先,您将需要一台基于Arch的机器(虚拟机或docker容器就足够了)。不必是Arch Linux,衍生产品也可以。我使用了Manjaro Linux。大多数mingw-w64软件包在官方的Arch存储库中不可用,但是AUR中很多。Arch(pacman)的默认软件包管理器不支持直接从AUR安装,因此您将需要安装和使用yay或yaourt之类的AUR包装器。然后安装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容器:

    须藤码头运行-it burningdaylight / docker-mingw-qt5 / bin / bash

  2. 克隆并编译QNapi

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

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


为了进行部署,您必须复制所有必需的Qt DLL(或doc.qt.io/qt-5/windows-deployment.html)。确保将/mingw64/share/qt5/plugins/platforms/qwindows.dll复制到platform / qwindows.dll中。
develCuy
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.