Chcę skompilować krzyżowo biblioteki Qt (i ostatecznie moją aplikację) dla docelowego systemu Windows x86_64 przy użyciu hosta Linux x86_64. Czuję, że jestem blisko, ale mogę mieć fundamentalne niezrozumienie niektórych części tego procesu.
Zacząłem od zainstalowania wszystkich pakietów mingw na moim komputerze Fedora, a następnie zmodyfikowania win32-g++
pliku qmake.conf, aby pasował do mojego środowiska. Jednak wydaje mi się, że utknąłem z niektórymi pozornie oczywistymi opcjami konfiguracyjnymi dla Qt: -platform
i -xplatform
. Dokumentacja Qt mówi, że -platform
powinna to być architektura komputera hosta (na którym kompilujesz) i -xplatform
powinna być platformą docelową, dla której chcesz wdrożyć. W moim przypadku ustawiam -platform linux-g++-64
i -xplatform linux-win32-g++
gdzie linux-win32-g ++ jest moją zmodyfikowaną konfiguracją win32-g ++.
Mój problem polega na tym, że po wykonaniu konfiguracji z tymi opcjami widzę, że wywołuje kompilator mojego systemu zamiast kompilatora krzyżowego (x86_64-w64-mingw32-gcc). Jeśli pominę tę -xplatform
opcję i ustawię -platform
na moją specyfikację docelową (linux-win32-g ++), wywoła kompilator krzyżowy, ale wtedy błędy, gdy znajdzie niektóre funkcje związane z Uniksem, nie są zdefiniowane.
Oto niektóre wyniki mojej ostatniej próby: http://pastebin.com/QCpKSNev .
Pytania:
Czy podczas kompilacji krzyżowej czegoś takiego jak Qt dla systemu Windows z hosta systemu Linux należy kiedykolwiek wywoływać kompilator natywny ? To znaczy, czy podczas procesu kompilacji krzyżowej nie powinniśmy używać tylko kompilatora krzyżowego? Nie rozumiem, dlaczego skrypt konfiguracyjny Qt próbuje wywołać natywny kompilator mojego systemu, gdy określę
-xplatform
opcję.Jeśli używam cross-kompilatora mingw, kiedy będę musiał radzić sobie z plikiem specyfikacji? Pliki specyfikacji dla GCC wciąż są dla mnie tajemnicą, więc zastanawiam się, czy jakieś tło tutaj mi pomoże.
Ogólnie rzecz biorąc, poza określeniem kompilatora krzyżowego w moim qmake.conf, co jeszcze powinienem wziąć pod uwagę?
źródło
x86_64-w64-mingw32-as
zamiast natywnego.Odpowiedzi:
Po prostu użyj środowiska M cross environment (MXE) . Eliminuje ból z całego procesu:
Zdobyć:
$ git clone https://github.com/mxe/mxe.git
Zainstaluj zależności kompilacji
Kompiluj Qt dla systemu Windows, jego zależności i narzędzia kompilacji krzyżowej; zajmie to około godziny na szybkiej maszynie z przyzwoitym dostępem do Internetu; pobieranie to około 500 MB:
Przejdź do katalogu swojej aplikacji i dodaj narzędzia cross-build do zmiennej środowiskowej PATH :
$ export PATH=<mxe root>/usr/bin:$PATH
Uruchom narzędzie generatora Qt Makefile, a następnie skompiluj:
Plik binarny powinieneś znaleźć w katalogu ./release:
Kilka uwag :
Użyj głównej gałęzi repozytorium MXE; wydaje się, że zespół programistów cieszy się o wiele większym uznaniem.
Dane wyjściowe to 32-bitowy statyczny plik binarny, który będzie dobrze działać w 64-bitowym systemie Windows.
źródło
$ cd mxe && make qt
należy zainstalować wymagania. W przypadku systemów Debian oznacza tosudo apt-get install autoconf automake autopoint bash bison bzip2 cmake flex gettext git g++ gperf intltool libffi-dev libtool libltdl-dev libssl-dev libxml-parser-perl make openssl patch perl pkg-config python ruby scons sed unzip wget xz-utils
. W przypadku innych systemów patrz mxe.cc/#requirements(To jest aktualizacja odpowiedzi @ Tshepang, ponieważ MXE ewoluowało od czasu jego odpowiedzi)
Budynek Qt
Zamiast używać
make qt
do budowania Qt, możesz użyćMXE_TARGETS
do sterowania maszyną docelową i łańcuchem narzędzi (32- lub 64-bitowe). MXE zaczęło używać.static
i.shared
jako części nazwy docelowej, aby pokazać, jaki typ biblioteki chcesz zbudować.# 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's 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'
W pierwotnej odpowiedzi @ Tshepang nie określił znaku
MXE_TARGETS
i używana jest wartość domyślna. W chwili, gdy pisał swoją odpowiedź, domyślnym byłoi686-pc-mingw32
, teraz jesti686-w64-mingw32.static
. Jeśli jawnie ustawionaMXE_TARGETS
nai686-w64-mingw32
, pomijając.static
, ostrzeżenie zostanie wydrukowany ponieważ składnia jest teraz przestarzała. Jeśli spróbujesz ustawić cel nai686-pc-mingw32
, wyświetli się błąd, ponieważ MXE usunęło obsługę MinGW.org (tj. I686-pc-mingw32).Bieganie
qmake
Jak zmienił
MXE_TARGETS
The<mxe root>/usr/i686-pc-mingw32/qt/bin/qmake
komenda nie będzie działać. Teraz musisz zrobić:Jeśli nie określiłeś
MXE_TARGETS
, zrób to:<mxe root>/usr/i686-w64-mingw32.static/qt/bin/qmake
Aktualizacja: nowe ustawienie domyślne to teraz
i686-w64-mingw32.static
źródło
Ok, myślę, że już to rozgryzłem.
Oparty częściowo na https://github.com/mxe/mxe/blob/master/src/qt.mk i https://www.videolan.org/developers/vlc/contrib/src/qt4/rules.mak
Wygląda na to, że "początkowo", kiedy uruchamiasz configure (z -xtarget itp.), Konfiguruje, a następnie uruchamia gcc "hostów", aby zbudować lokalny plik binarny ./bin/qmake
następnie uruchamiasz normalne "make" i buduje je dla mingw
więc
tak
tylko jeśli potrzebujesz użyć czegoś innego niż msvcrt.dll (jest to ustawienie domyślne). Chociaż nigdy nie korzystałem z niczego innego, więc nie wiem na pewno.
https://stackoverflow.com/a/18792925/32453 zawiera listę niektórych parametrów konfiguracji.
źródło
Aby skompilować Qt, należy uruchomić jego
configure
skrypt, podając platformę hosta-platform
(np.-platform linux-g++-64
Jeśli budujesz na 64-bitowym Linuksie z kompilatorem g ++) i platformę docelową-xplatform
(np.-xplatform win32-g++
Jeśli kompilujesz cross do Windows ).Dodałem również tę flagę:
-device-option CROSS_COMPILE=/usr/bin/x86_64-w64-mingw32-
która określa przedrostek łańcucha narzędzi, którego używam, który zostanie dodany do „gcc” lub „g ++” we wszystkich plikach Makefile, które budują pliki binarne dla systemu Windows.Wreszcie, możesz napotkać problemy podczas budowania icd , co najwyraźniej jest czymś, co jest używane do dodawania obsługi ActiveX do Qt. Możesz tego uniknąć, przekazując flagę
-skip qtactiveqt
do skryptu konfiguracji. Mam ten z tego raportu o błędzie: https://bugreports.qt.io/browse/QTBUG-38223Oto całe polecenie konfiguracji, którego użyłem:
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
A jeśli chodzi o pytania:
1 - Tak. Natywny kompilator zostanie wywołany w celu zbudowania niektórych narzędzi potrzebnych w procesie kompilacji. Może takie rzeczy jak qconfig lub qmake, ale nie jestem do końca pewien, które dokładnie narzędzia.
2 - Przepraszam. Nie mam pojęcia, jakie pliki specyfikacji są w kontekście kompilatorów = /. Ale o ile wiem, nie musiałbyś się tym zajmować.
3 - Możesz określić przedrostek kompilatora krzyżowego w linii poleceń konfiguracji zamiast robić to w pliku qmake.conf, jak wspomniano powyżej. Jest też ten problem z idc, którego obejście również wspomniałem.
źródło
Innym sposobem kompilacji krzyżowej oprogramowania dla systemu Windows w systemie Linux jest łańcuch narzędzi MinGW-w64 w Archlinux. Jest łatwy w obsłudze i utrzymaniu oraz udostępnia najnowsze wersje kompilatora i wiele bibliotek. Osobiście uważam to za łatwiejsze niż MXE i wydaje się, że szybciej adaptuje nowsze wersje bibliotek.
Po pierwsze, będziesz potrzebować maszyny opartej na architekturze arch (wystarczy maszyna wirtualna lub kontener docker). Nie musi to być Arch Linux, nadadzą się też pochodne. Użyłem Manjaro Linux. Większość pakietów MinGW-w64 nie jest dostępna w oficjalnych repozytoriach Arch, ale jest ich mnóstwo w AUR . Domyślny menedżer pakietów dla Arch (Pacman) nie obsługuje instalacji bezpośrednio z AUR, więc będziesz musiał zainstalować i używać opakowania AUR, takiego jak yay lub yaourt. Następnie instalacja bibliotek Qt5 i Boost w wersji MinGW-w64 jest tak prosta, jak:
yay -Sy mingw-w64-qt5-base mingw-w64-boost #yaourt -Sy mingw-w64-qt5-base mingw-w64-qt5-boost #if you use yaourt
Spowoduje to również zainstalowanie narzędzia MinGW-w64 toolchain (
mingw-w64-gcc
) i innych zależności. Kompilowanie krzyżowe projektu Qt dla Windows (x64) jest wtedy tak proste, jak:Aby wdrożyć program, musisz skopiować odpowiednie biblioteki DLL z
/usr/x86_64-w64-mingw32/bin/
. Na przykład, można zazwyczaj trzeba skopiować/usr/x86_64-w64-mingw32/lib/qt/plugins/platforms/qwindows.dll
doprogram.exe_dir/platforms/qwindows.dll
.Aby uzyskać wersję 32-bitową, wystarczy użyć
i686-w64-mingw32-qmake-qt5
zamiast tego. Projekty oparte na Cmake działają równie łatwo zx86_64-w64-mingw32-cmake
. To podejście zadziałało dla mnie wyjątkowo dobrze, było najłatwiejsze do skonfigurowania, utrzymania i rozszerzenia. Dobrze sprawdza się również w przypadku usług ciągłej integracji. Dostępne są również obrazy dockera .Na przykład, powiedzmy, że chcę zbudować GUI programu do pobierania napisów QNapi. Mogłem to zrobić w dwóch krokach:
Uruchom kontener Docker:
sudo docker run -it burningdaylight / mingw-arch: qt / bin / bash
Klonuj i kompiluj QNapi
git clone --recursive 'https://github.com/QNapi/qnapi.git' cd qnapi / x86_64-w64-mingw32-qmake-qt5 make
Otóż to! W wielu przypadkach będzie to takie proste. Dodanie własnych bibliotek do repozytorium pakietów (AUR) jest również proste. Musiałbyś napisać plik PKBUILD , który jest tak intuicyjny, jak to tylko możliwe, zobacz na przykład mingw-w64-rapidjson .
źródło