I have been developing an app built upon Qt 5 on Ubuntu in Qt Creator. The project format used is CMake. It's time to cross-compile the stuff into a binary which can be run on Windows. So I have
x86_64-w64-mingw32
(this triple is used because it corresponds to the path where the gcc toolchain is installed).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).When I tried to build, some files (6) of my project have compiled fine, but 4 have caused nasty compilation errors:
/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? In fact it is, it is 6.0 in Ubuntu repos, but on MinGW-w64 website 8.1 is available.
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).
Well, I have tried to build something simplier in terms of dependencies and what is known to be buildable by g++ - ninja.
The same result. I have tried then MinGW-w64 toolchain (the Windows version) run in wine. The same result. Damn.
A simple hello world app builds and works fine in all cases.
How to cross-build an app more complex than a hello world for Windows using MinGW-w64 stdlib?
Also I wonder how to setup Qt Creator to use this toolchain correctly.
It was the bug in the stdlib headers shipped with the toolchains. It was the conflict between C and C++ headers. 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. 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.
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