首页 文章

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

提问于
浏览
73

我想使用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 .

问题:

  • 当从Linux主机交叉编译Qt for Windows之类的东西时,是否应该调用本机编译器?也就是说,在交叉编译过程中,我们不应该只使用交叉编译器吗?当我指定 -xplatform 选项时,我没有't see why Qt'的配置脚本尝试调用我的系统的本机编译器 .

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

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

5 回答

  • 3

    只需使用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
    

    Some notes

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

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

  • 15

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

    建筑Qt

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

    Update: 新默认值现在为 i686-w64-mingw32.static

  • 59

    好吧,我想我已经明白了 .

    部分基于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
    

    所以

    • 是的

    • 仅当您需要使用msvcrt.dll(默认值)以外的其他内容时 . 虽然我从未使用过其他任何东西,所以我不确定 .

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

  • 0

    为了编译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中指定了工具链的前缀'm using, which will get prepended to ' gcc ' or ' g' .

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

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

    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 - 抱歉 . 我不知道compilers = /的上下文中的specs文件是什么 . 但据我所知,你不必处理这个问题 .

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

  • 2

    另一种在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 代替 . 使用 x86_64-w64-mingw32-cmake 可以轻松实现基于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 .

相关问题