[英]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
所以我有
x86_64-w64-mingw32
(this triple is used because it corresponds to the path where the gcc toolchain is installed).x86_64-w64-mingw32
(使用此三元组是因为它对应于安装 gcc 工具链的路径)。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 脚本,使它们与系统中的路径相对应(脚本中有一些硬编码的路径)。 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.