Как настроить Qt для кросс-компиляции с Linux на целевой Windows?

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

Я начал с установки всех пакетов mingw на моем компьютере Fedora и затем изменения файла 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.

Вопросы:

  • Если кросс-компилировать что-то вроде Qt для Windows с хоста Linux, должен ли когда-нибудь использоваться собственный компилятор? То есть, во время процесса кросс-компиляции мы не должны использовать только кросс-компилятор? Я не понимаю, почему Qt configure script пытается вызвать мой системный собственный компилятор, когда я указываю опцию -xplatform.

  • Если я использую кросс-компилятор mingw, когда мне придется иметь дело со спецификационным файлом? Файлы спецификаций для GCC по-прежнему являются для меня загадкой, поэтому мне интересно, поможет ли мне какой-то фон.

  • В общем, помимо указания кросс-компилятора в моем qmake.conf, что еще мне нужно рассмотреть?

Ответ 1

Просто используйте M cross environment (MXE). Это снимает боль из всего процесса:

  • Получите его:

    $ git clone https://github.com/mxe/mxe.git
    
  • Установите установить зависимости

  • Создайте Qt для Windows, его зависимости и инструменты кросс-сборки; это займет около часа на быстрой машине с приличным доступом в Интернет; загрузка составляет около 500 МБ:

    $ 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
    

Некоторые заметки:

  • Использовать основную ветвь репозитория MXE; он, похоже, получает больше любви от команды разработчиков.

  • Вывод представляет собой 32-битный статический двоичный файл, который будет хорошо работать на 64-разрядной Windows.

Ответ 2

(Это обновление ответа @Tshepang, поскольку MXE развился после его ответа)

Построение Qt

Вместо того, чтобы использовать make qt для сборки Qt, вы можете использовать MXE_TARGETS для управления вашей целевой машиной и инструментальной цепочкой (32- или 64-разрядной). MXE начал использовать .static и .shared как часть целевого имени, чтобы показать, какой тип библиотеки вы хотите создать.

# 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 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

Обновление: Новый по умолчанию теперь i686-w64-mingw32.static

Ответ 3

Хорошо, думаю, я понял.

Основываясь частично на https://github.com/mxe/mxe/blob/master/src/qt.mk и https://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(по умолчанию). Хотя я никогда не использовал ничего другого, поэтому я не знаю наверняка.

  • fooobar.com/questions/83972/... перечисляет некоторые параметры конфигурации.

Ответ 4

Чтобы скомпилировать Qt, нужно запустить его configure script, указав платформу хоста с помощью -platform (например, -platform linux-g++-64, если вы строите на 64-битном Linux с компилятором g++) и целевую платформу с -xplatform (например, -xplatform win32-g++, если вы перекрестно компилируете в окна).

Я также добавил этот флаг: -device-option CROSS_COMPILE=/usr/bin/x86_64-w64-mingw32- который указывает префикс используемой инструментальной привязки, которая будет добавлена ​​к gcc или g++ во всех make файлах, которые создают двоичные файлы для окон.

Наконец, у вас могут возникнуть проблемы при построении icd, который, по-видимому, является тем, что используется для добавления поддержки ActiveX в Qt. Вы можете избежать этого, передав флаг -skip qtactiveqt в configure script. У меня есть этот из отчета об ошибке: https://bugreports.qt.io/browse/QTBUG-38223

Здесь вся команда configure, которую я использовал:

    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 - Извините. Я понятия не имею, какие файлы спецификаций находятся в контексте компиляторов =/. Но, насколько я знаю, вам не придется иметь дело с этим.

3 - Вы можете указать префикс кросс-компилятора в командной строке configure вместо того, чтобы делать это в файле qmake.conf, как упоминалось выше. И есть также проблема с idc, обходной путь которой я также упомянул.