Как настроить 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, обходной путь которой я также упомянул.