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

时间:2012-06-07 15:14:24

标签: 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-g ++是我修改过的win32-g ++配置。

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

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

问题:

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

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

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

5 个答案:

答案 0 :(得分:61)

只需使用M cross environment (MXE)即可。它会消除整个过程中的痛苦:

  • 获取它:

    $ git clone https://github.com/mxe/mxe.git
    
  • 安装build dependencies

  • 为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上运行良好。

答案 1 :(得分:16)

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

建立Qt

您可以使用make qt来控制目标计算机和工具链(32位或64位),而不是使用MXE_TARGETS来构建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'

在@ 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

答案 2 :(得分: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列出了一些配置参数。

答案 3 :(得分:3)

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

我还添加了这个标志: -xplatform win32-g++ 它指定了我使用的工具链的前缀,它将被添加到&#39; gcc&#39;或者&#39; g ++&#39;在所有为windows构建二进制文件的makefile中。

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

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

-skip qtactiveqt

关于你的问题:

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

2 - 抱歉。我不知道compilers = /的上下文中的specs文件是什么。但据我所知,你不必处理这个问题。

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

答案 4 :(得分:1)

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

首先,您需要一个基于arch的计算机(虚拟机或docker容器就足够了)。它不一定是Arch Linux,衍生品也会这样做。我用过Manjaro Linux。 大多数mingw-w64软件包在官方Arch存储库中不可用,但有plenty in AUR。 Arch(pacman)的默认包管理器不支持直接从AUR安装,因此您需要安装和使用像pacaur或yaourt这样的AUR包装器。然后安装mingw-w64版本的Qt5和Boost库就像这样简单:

pacaur -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

要部署您的程序,您需要从/usr/x86_64-w64-mingw32/bin/复制相应的dll。

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

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

1)启动docker容器:

sudo docker run -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)也很简单。您需要write a PKBUILD file,这是最直观的,例如,请参阅mingw-w64-rapidjson