如何configurationQt从Linux到Windows目标的交叉编译?

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

我开始在我的Fedora机器上安装所有的mingw包,然后修改win32-g++ qmake.conf文件以适合我的环境。 不过,我似乎被Qt: -platform-xplatform一些看似明显的configuration选项卡住了。 Qt的文档说,平台应该是主机架构(你正在编译的地方),- -xplatform平台应该是你希望部署的目标平台。 在我的例子中,我设置了-platform linux-g++-64-xplatform linux-win32-g++ ,其中linux-win32-g ++是我修改的win32-g ++configuration。

我的问题是,执行configuration这些选项后,我看到它调用我的系统的编译器,而不是交叉编译器(x86_64-w64-mingw32-gcc)。 如果我省略-xplatform选项并将-platform设置为我的目标规范(linux-win32-g ++),那么它会调用交叉编译器,但是如果发现某些与Unix相关的函数没有定义,则会发生错误。

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

问题:

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

  2. 如果我正在使用mingw交叉编译器,那么我何时需要处理规格文件? 海湾合作委员会的规格文件仍然是我的一个谜,所以我想知道如果这里的一些背景将帮助我。

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

只需使用M交叉环境(MXE) 。 它从整个过程中消除了痛苦:

  • 得到它:

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

  • 为Windows构buildQt,依赖关系和跨构build工具; 这将需要大约一个小时,在一个快速的机器上有体面的互联网接入; 下载大约500MB:

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

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

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

     $ wine release/foo.exe 

一些说明

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

  • 输出是一个32位的静态二进制,这将在64位Windows上运行良好。

(这是@ Tshepang的答案的更新,因为MXE从他的答案开始发展)

构buildQt

您可以使用MXE_TARGETS来控制您的目标机器和工具链(32位或64位),而不是使用make qt来构buildQt。 MXE开始使用.static.shared作为目标名称的一部分,以显示您要构build哪种types的库。

 # 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_TARGETS设置为i686-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

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

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

它看起来“最初”当你运行configuration(与-xtarget等),它configuration然后运行你的“主机”gcc构build本地二进制文件./bin/qmake

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

那么你运行正常的“make”,并为它build立它

  make make install 

所以

  1. 只有当你需要使用msvcrt.dll以外的东西(默认)。 虽然我从来没有使用过其他东西,所以我不确定。

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

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

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

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

这里是我使用的整个configuration命令:

  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 – 是的。 本机编译器将被调用以构build一些构build过程中所需的工具。 也许像qconfig或qmake的东西,但我不完全确定哪些工具,确切地说。

2 – 对不起。 我不知道什么specs文件是在编译器= /的上下文。 但据我所知,你不需要处理这个问题。

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