Как кросскомпилировать приложения Ubuntu в Windows

Я разрабатываю приложение, основанное на Qt 5, на Ubuntu в Qt Creator. Используемый формат проекта — CMake. Пришло время кросс-компилировать материал в двоичный файл, который можно запустить в Windows. Так что я

  1. установил clang и mingw-w64
  2. создал файл цепочки инструментов CMake, указывающий на нужные инструменты (из установленной цепочки инструментов MiGW), и установил целевую тройку в x86_64-w64-mingw32 (эта тройка используется, поскольку она соответствует пути, по которому установлена ​​цепь инструментов gcc).
  3. скачал пакеты начиная с mingw64-qt из https://dl.fedoraproject.org/pub/fedora/linux/development/30/Everything/x86_64/os/Packages/m/ , распаковал их, объединил распакованные каталоги, удалил все лишнее, поправил скрипты CMake, чтобы они соответствовали путям в системе (в скриптах есть некоторые жестко прописанные пути).
  4. добавил пути к нужным каталогам распакованной Qt в файл набора инструментов, чтобы автообнаружение работало
  5. Пытался построить.

Когда я попытался собрать, некоторые файлы (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

Хорошо, подумал я, может MinGW-w64 в репозиториях Ubuntu гнилой? На самом деле это так, в репозиториях Ubuntu это 6.0, но на сайте MinGW-w64 доступна 8.1.

OK. Я удалил пакет, скачал 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).

Что ж, я попытался построить что-то более простое с точки зрения зависимостей и того, что, как известно, можно собрать с помощью g++ - ниндзя.

Тот же результат. Затем я попытался запустить набор инструментов MinGW-w64 (версия для Windows) в вине. Тот же результат. Проклятие.

Простое приложение hello world создается и работает нормально во всех случаях.

Как кросс-сборить приложение более сложное, чем привет, мир для Windows, используя MinGW-w64 stdlib?

Также мне интересно, как настроить Qt Creator для правильного использования этой цепочки инструментов.

Почему вы не используете MXE mxe.cc?

eyllanesc 09.04.2019 23:42

Потому что 1. впервые слышу об этом проекте; 2. возможно не подходит: в качестве системы сборки я использую CMake, а не GNU Make.

KOLANICH 09.04.2019 23:48

Вы пытались сказать CMake создать решение Qt Creator?

Tzalumen 09.04.2019 23:49

Нет. Обычно я открываю CMakeLists.txt в Qt Creator, и он сам творит чудеса (думаю, у него есть некоторые собственные модули, переопределяющие части CMake stdlib), например, подкачка наборов инструментов щелчками мыши и обнаружение модулей, на которые есть ссылки. Шаги по созданию материала были выполнены с использованием командной строки + текстового редактора + CMake-gui + ninja. Но было бы неплохо правильно настроить Qt Creator. У него есть настройки для цепочек инструментов, но я не очень хорошо знаю, как правильно их использовать для кросс-компиляции - настройки для установки целевой тройки выделены серым цветом.

KOLANICH 09.04.2019 23:55

Обычно я использую Qt с написанным от руки Cmake, генерирующим решение Visual Studio, поэтому я натыкаюсь на ограничения того, что знаю. Возможно, стоит покопаться в вашем CMakeLists.txt и посмотреть, как настроен ваш проект.

Tzalumen 10.04.2019 00:00

CMakeLists.txt написан от руки. Qt Creator просто использует информацию об исходниках и делает некоторые собственные настройки. CMakeLists.txt в порядке, версия приложения без перекрестной сборки собирается и работает нормально. Я предполагаю, что либо я делаю что-то неправильно при настройке цепочки инструментов (например, мне может понадобиться отсутствующее определение, которое может быть жестко запрограммировано в версии компилятора для Windows, но не присутствует в версиях для Linux, хотя проверка заголовков с помощью ошибки ничего подозрительного не выявили) либо это может быть баг в MinGW-w64 (я в этом сомневаюсь - скачанные Qt-либы были собраны с MinGW-w64).

KOLANICH 10.04.2019 00:06
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
6
2 192
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Я использую https://mxe.cc для кросс-компиляции своих приложений Qt для Windows. Вы можете настроить его в своем домашнем каталоге. После того, как вы скажете ему получить и скомпилировать необходимые вам зависимости (например, qtbase, cmake и т. д.), вы можете скомпилировать свое приложение с помощью:

i686-w64-mingw32.static-cmake path_to_your_project
make

Вместо этого для проекта qmake вы должны использовать i686-w64-mingw32.static-qmake.

Я не думаю, что мне следует использовать эту цепочку инструментов вместо родной: Windows — это та, которую я использую при сборке на машинах Windows. Я не понимаю, почему происходит этот ад. Я сравнивал встроенные макродефы, они почти идентичны, я гуглил разные, они не об этом. Но поскольку набор инструментов Windows выдает те же ошибки в Linux, создается впечатление, что ... информация о платформе каким-то образом просочилась и каким-то образом используется. Может быть, дело в путях (хотя у меня нет сообщений об отсутствии заголовка)?

KOLANICH 10.04.2019 15:04

@KOLANICH Ну, я могу сказать вам, что работает для меня. Раньше я пробовал кросс-компиляторы из дистрибутива, ни один из них не работал должным образом. Они просто отправляют ванильную среду, которая может не работать. MXE будет исправлять вещи, чтобы они действительно работали. Кроме того, настроить MXE очень просто, так что вы можете просто попробовать.

Nikos C. 10.04.2019 15:25

МХЕ классный! Гораздо лучше, чем msys2 для кросс-компиляции! Слава Богу!

Melroy van den Berg 11.09.2021 18:50
Ответ принят как подходящий

Это была ошибка в заголовках stdlib, поставляемых с наборами инструментов. Это был конфликт между заголовками C и C++. Я до сих пор не понимаю, почему эта ошибка не срабатывает при вызове цепочки инструментов в Windows, но я решил проблему, введя макрос, защищающий определения проблемных типов. Это грязный хак: лучшее решение — переместить их в собственный заголовок, защитить его с помощью #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


Вы можете использовать МХЕ, как упоминалось ранее. Для пользователей Debian/Ubuntu вы можете добавить репозиторий в 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

После чего вы сможете установить любые пакеты (libs), которые могут вам понадобиться для кросс-компиляции. Пример для GTK3 (для 64-битной Windows): sudo apt install mxe-x86-64-w64-mingw32.static-gtk3

Для Qt5 вам просто нужно установить: sudo apt install mxe-x86-64-w64-mingw32.static-qt5

Вам нужно обновить PATH (поэтому отредактируйте файл ~/.bashrc), добавьте внизу:

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

Теперь можно приступать к кросс-компиляции! Я пробую скрипт-оболочку, предоставленный MXE для CMake: x86_64-w64-mingw32.static-cmake

Я надеюсь, что это поможет кому-то!

Другие вопросы по теме