简体   繁体   English

如何将 Ubuntu 上的应用程序交叉编译到 Windows

[英]How to crosscompile applications on Ubuntu to Windows

I have been developing an app built upon Qt 5 on Ubuntu in Qt Creator.我一直在使用 Qt Creator 在 Ubuntu 上开发基于 Qt 5 的应用程序。 The project format used is CMake.使用的项目格式是 CMake。 It's time to cross-compile the stuff into a binary which can be run on Windows.是时候将这些东西交叉编译成可以在 Windows 上运行的二进制文件了。 So I have所以我有

  1. installed clang and mingw-w64安装了 clang 和 mingw-w64
  2. created a CMake toolchain file pointing to the right tools (the ones from the installed MiGW toolchain) and set the target triple to x86_64-w64-mingw32 (this triple is used because it corresponds to the path where the gcc toolchain is installed).创建了一个指向正确工具(来自已安装 MiGW 工具链的工具)的 CMake 工具链文件,并将目标三元组设置为x86_64-w64-mingw32 (使用此三元组是因为它对应于安装 gcc 工具链的路径)。
  3. downloaded packages beginning from mingw64-qt from https://dl.fedoraproject.org/pub/fedora/linux/development/30/Everything/x86_64/os/Packages/m/ , unpacked them, merged the unpacked dirs, removed anything unneeded, fixed the CMake scripts to make them correspond to the paths in the system (there are some hardcoded paths in the scripts).mingw64-qt开始从https://dl.fedoraproject.org/pub/fedora/linux/development/30/Everything/x86_64/os/Packages/m/下载包,解压它们,合并解压的目录,删除任何不需要的东西, 修复了 CMake 脚本,使它们与系统中的路径相对应(脚本中有一些硬编码的路径)。
  4. added the paths to the needed dirs of the unpacked Qt into the toolchain file, to make the autodiscovery work将解压后的 Qt 所需目录的路径添加到工具链文件中,以使自动发现工作
  5. Tried to build.试图建立。

When I tried to build, some files (6) of my project have compiled fine, but 4 have caused nasty compilation errors:当我尝试构建时,我的项目的一些文件 (6) 编译得很好,但 4 个导致了令人讨厌的编译错误:

/usr/share/mingw-w64/include/rpcndr.h:64:11: error: reference to ‘byte’ is ambiguous
/usr/share/mingw-w64/include/objidlbase.h:2067:5: error: ‘byte’ has not been declared

OK, I thought, maybe MinGW-w64 in Ubuntu repos is rotten?好吧,我想,也许 Ubuntu 存储库中的 MinGW-w64 已经烂了? In fact it is, it is 6.0 in Ubuntu repos, but on MinGW-w64 website 8.1 is available.事实上,它在 Ubuntu 存储库中是 6.0,但在 MinGW-w64 网站上可以使用 8.1。

OK.好的。 I have uninstalled the package, downloaded https://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/8.1.0/threads-posix/seh/x86_64-8.1.0-release-posix-seh-rt_v6-rev0.7z , unpacked it, set the toolchain file to use clang and clang++ as compilers and llvm binutils, set the sysroot pointing to the unpacked dir, tried to rebuild ... and got the same errors (but in the new sysroot).我已经卸载了包,下载了https://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/8.1.0/threads-posix/seh/x86_64-8.1 .0-release-posix-seh-rt_v6-rev0.7z ,解压它,设置工具链文件使用clang和clang++作为编译器和llvm binutils,设置sysroot指向解压目录,尝试重建......并得到相同的错误(但在新的 sysroot 中)。

Well, I have tried to build something simplier in terms of dependencies and what is known to be buildable by g++ - ninja.好吧,我试图在依赖项方面构建一些更简单的东西,以及已知可以由 g++ 构建的东西 - ninja。

The same result.同样的结果。 I have tried then MinGW-w64 toolchain (the Windows version) run in wine.我曾尝试在 wine 中运行 MinGW-w64 工具链(Windows 版本)。 The same result.同样的结果。 Damn.该死。

A simple hello world app builds and works fine in all cases.一个简单的 hello world 应用程序构建并在所有情况下都能正常工作。

How to cross-build an app more complex than a hello world for Windows using MinGW-w64 stdlib?如何使用 MinGW-w64 stdlib 交叉构建比 Windows 的 hello world 更复杂的应用程序?

Also I wonder how to setup Qt Creator to use this toolchain correctly.另外我想知道如何设置 Qt Creator 以正确使用此工具链。

I use https://mxe.cc to cross-compile my Qt applications to Windows. 我使用https://mxe.cc将Qt应用程序交叉编译到Windows。 You can set it up in your home directory. 您可以在主目录中进行设置。 After you tell it to fetch and compile the dependencies you need (like qtbase, cmake, etc.) you can compile your application with: 告诉它获取并编译所需的依赖项(如qtbase,cmake等)后,可以使用以下命令编译应用程序:

i686-w64-mingw32.static-cmake path_to_your_project
make

For a qmake project, you'd use i686-w64-mingw32.static-qmake instead. 对于qmake项目,请改用i686-w64-mingw32.static-qmake

It was the bug in the stdlib headers shipped with the toolchains. 这是工具链附带的stdlib标头中的错误。 It was the conflict between C and C++ headers. 这是C和C ++标头之间的冲突。 I still have no idea why this bug doesn't fire when the toolchain is invoked on Windows, but I have solved the issue by introducing a macrodef guarding the problematic types definitions. 我仍然不知道为什么在Windows上调用工具链时不会出现此错误,但是我已经通过引入可以保护有问题的类型定义的macrodef解决了该问题。 A dirty hack it is: a better solution is to move them into an own header, guard it with #pragma once and include it where it is needed. 这是一个肮脏的技巧:更好的解决方案是将它们移动到自己的标头中,使用#pragma once保护,并将其包含在需要的位置。

From: KOLANICH
Date: Thu, 11 Apr 2019 20:06:23 +0300
Subject: Fixed the bug with conflict between C and C++ definitions of byte.

---
 lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/functional | 3 ++-
 x86_64-w64-mingw32/include/rpcndr.h                     | 6 ++++++
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/functional b/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/functional
index 2b46ba8..6b4e027 100644
--- a/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/functional
+++ b/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/functional
@@ -893,7 +893,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #if __cplusplus >= 201703L
   // Declare std::byte (full definition is in <cstddef>).
   enum class byte : unsigned char;
-
+  #define _BYTE_DEFINED_AdTydTeKkpRvvDuzZisXJMGxPRSHkr
+  
   template<>
     struct __is_byte_like<byte, equal_to<byte>>
     : true_type { };
diff --git a/x86_64-w64-mingw32/include/rpcndr.h b/x86_64-w64-mingw32/include/rpcndr.h
index 52de4ad..a490aa4 100644
--- a/x86_64-w64-mingw32/include/rpcndr.h
+++ b/x86_64-w64-mingw32/include/rpcndr.h
@@ -60,7 +60,13 @@ extern "C" {
 #ifdef RC_INVOKED
 #define small char
 #endif
+
+#ifndef _BYTE_DEFINED_AdTydTeKkpRvvDuzZisXJMGxPRSHkr
   typedef unsigned char byte;
+  #define _BYTE_DEFINED_AdTydTeKkpRvvDuzZisXJMGxPRSHkr
+#else:
+  typedef std::byte byte;
+#endif
   typedef byte cs_byte;
   typedef unsigned char boolean;

-- 
2.20.1


You can use MXE as mentioned earlier.您可以使用前面提到的MXE For Debian/Ubuntu users you can add the repo to APT via:对于 Debian/Ubuntu 用户,您可以通过以下方式将 repo 添加到 APT:

sudo apt-key adv \
    --keyserver keyserver.ubuntu.com \
    --recv-keys 86B72ED9 && \
sudo add-apt-repository \
    "deb [arch=amd64] https://pkg.mxe.cc/repos/apt `lsb_release -sc` main" && \
sudo apt-get update

After which you should be able to install any packages (libs) you may need for cross-compiling.之后,您应该能够安装交叉编译可能需要的任何包(库)。 An example for GTK3 (for Windows 64-bit): sudo apt install mxe-x86-64-w64-mingw32.static-gtk3 GTK3 示例(适用于 Windows 64 位): sudo apt install mxe-x86-64-w64-mingw32.static-gtk3

For Qt5 you just need to install: sudo apt install mxe-x86-64-w64-mingw32.static-qt5对于 Qt5,您只需要安装: sudo apt install mxe-x86-64-w64-mingw32.static-qt5

You do need to update your PATH (so edit your ~/.bashrc file), add to the bottom:你确实需要更新你的 PATH(所以编辑你的 ~/.bashrc 文件),添加到底部:

export PATH="/usr/lib/mxe/usr/bin:$PATH"

Now you can start cross-compiling!现在你可以开始交叉编译了! I'm trying the wrapper script provided by MXE for CMake: x86_64-w64-mingw32.static-cmake我正在尝试 MXE 为 CMake 提供的包装器脚本: x86_64-w64-mingw32.static-cmake

I hope this helps somebody!我希望这对某人有所帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM