Search |
Cross-compiling QtWebKit for Windows on Linux using MinGWThe first question which might arise when reading the title: The answer is simpleConsider a situation where you have a build farm consisting of high performance Linux servers and you have to build QtWebKit for Windows. Of course you can use virtual machines, but you'll waste energy, time and precious resources of your build farm. Besides that, you can't use tools like distcc for example, to speed up things. So if these issues matter to you, cross-compiling with MinGW is the solution. I assume you have all the basic development tools installed on your Linux machine (meta-packages may be called build-essential or base-devel, depending on your distribution). PrerequisitesI had some issues with the newer version of the MinGW GCC compiler, that's why I compiled 4.4.0.
Additionally we need to compile zlib with the MinGW toolchain (zlib-1.2.5.tar.gz). I'll give you a detailed how-to explaining the steps of preparing the toolchain. Building the cross-compiler toolchainFirst, we need a compiler which can produce exe files but runs on Linux, so we have to compile mingw-gcc with the system compiler. I used GCC 4.5.0 to compile the toolchain, but all this should work with other versions too. As first configure, build and install binutils (binutils-2.20.1-src.tar.gz): $ ./configure \ --target=i486-mingw32 \ --prefix=/usr \ --disable-nls \ --enable-shared [...] $ make -j24 [...] $ make install Extract gcc-4.4.0-src.tar.bz2 and create a directory called build into the extracted tree. We need a C and a C++ compiler so use the following commands to configure mingw-gcc. $ mkdir build && cd build $ unset CFLAGS CXXFLAGS $ ../configure --enable-languages=c,c++ \ --target=i486-mingw32 \ --disable-sjlj-exceptions \ --enable-shared \ --with-dwarf2 \ --disable-win32-registry \ --enable-version-specific-runtime-libs \ --prefix=/usr
Now you need to set your PATH to contain the new toolchain. $ make -j24 [...] $ make install Next is the MinGW runtime (mingwrt-3.18-mingw32-src.tar.gz), which is a bit tricky. After extraction we need to change the line endings to Unix and set the correct include path: $ sed -i "s%\r%%g" `find . -type f` $ sed -i -e "s%^W32API_INCLUDE=.*%W32API_INCLUDE=-I/usr/i486-mingw32/include%" \ `find -type f -name 'configure'` Then export the -mms-bitfields flag which is essential because we want our application to actually run on win32: $ export CFLAGS="-mms-bitfields" Configure, then make and make install as usual: $ ./configure \ --prefix=/usr/i486-mingw32 \ --target=i486-mingw32 \ --host=i486-mingw32 [...] $ make -j24 [...] $ make install Now comes the win32 API (w32api-3.14-mingw32-src.tar.gz): $ export CFLAGS="-mms-bitfields" $ ./configure \ --prefix=/usr/i486-mingw32 \ --target=i486-mingw32 \ --host=i486-mingw32 [...] $ make -j24 [...] $ make install And as last prerequisite we build a static zlib using the MinGW toolchain: $ ./configure --static [...] $ make MKDIR="mkdir -p" \ ASM=i486-mingw32-as \ CP=install \ RM=rm \ MKLIB="i486-mingw32-ar r" \ CC=i486-mingw32-gcc \ RANLIB=i486-mingw32-ranlib \ AR="i486-mingw32-ar r" \ LD="i486-mingw32-ld" [...] $ make install After that we have all the needed tools and libs we need to cross-compile the Qt framework and then QtWebKit. Building the Qt frameworkBecause Qt is a cross-paltform framework you would expect cross-compiling to be fairly straightforward. Nonetheless I experienced some issues using the current stable release (4.6.3), which didn't allow me to cross compile Qt, so finally I tried to build it from the git repository (qt.gitorious.org/qt/qt) and succeeded without major issues, which indicates that the Qt guys are doing a good job in Oslo. First, clone the Qt repository from Gitorious: $ git clone git://gitorious.org/qt/qt.git The main changes you need to apply to the Qt source tree are needed because of the custom MinGW compiler. Beneath you can find the patches and configuration file attached. To make things easier I use the following script to automate the process. (Let's call this build.sh.) #!/bin/bash find . -name '.gitignore'|xargs rm git clean -xdf git reset --hard a98bda4b42b068c9c3220ae2aded41a263387ac2 test -f ../buildfix.diff \ && git apply ../buildfix.diff \ && test -f ../crossqt_patch.diff \ && git apply ../crossqt_patch.diff \ && test -f ../crossqt_config.txt \ && echo yes|./configure $(cat ../crossqt_config.txt) \ && make -j24 You can also use this if you want to make a clean build. It will clean up the repository, check out the revision which I built, apply the patches, configure and build Qt. The configuration I used was (crossqt_config.txt): -xplatform win32-g++ -no-phonon -nomake examples -nomake demos -nomake docs -make tools -no-exceptions -no-webkit -opensource -no-qt3support -little-endian -host-little-endian -prefix /usr/local/Trolltech/mingw-cross-qt-4.7 Feel free to adjust these to your needs. The crossqt_patch.diff patch changes the following files: mkspecs/features/debug_and_release.prf mkspecs/win32-g++/qmake.conf These changes are needed, so that qmake uses the MinGW toolchain and correctly creates dll files. The other patch (buildfix_patch.diff) is only needed if you want to use the build.sh script, it applies some changes which fix the build of the revision I succeeded with. If you use the script, building Qt is really simple (given that you downloaded the patches and the configuration file from below). $ cd qt $ sh ../build.sh That's all, you just have to install it afterwards. Before building QtWebKit, you have to copy the qmake binary to the install directory, because - for some reason - make install doesn't do that. $ make install [...] $ cp bin/qmake /usr/local/Trolltech/mingw-cross-qt-4.7/bin Building QtWebKitAt this point you have everything you need to cross-compile the Qt port of WebKit, since the only change needed to be able to do that has already landed in the trunk (Changeset 63203). $ export QTDIR=/usr/local/Trolltech/mingw-cross-qt-4.7 $ export PATH=$QTDIR/bin:$PATH Clone the WebKit repository and build it: $ git clone git://git.webkit.org/WebKit.git WebKit $ cd WebKit $ WebKitTools/Scripts/build-webkit --qt -spec win32-g++ --makeargs=-j24 Now copy the Qt and MinGW dll files next to the binaries: $ cp /usr/local/Trolltech/mingw-cross-qt-4.7/lib/*.dll WebKitBuild/Release/bin/ $ cp /usr/lib/gcc/i486-mingw32/4.4.0/libgcc_s_dw2-1.dll WebKitBuild/Release/bin/ $ cp /usr/i486-mingw32/lib/mingwm10.dll WebKitBuild/Release/bin/ And finally, you are able to test the binaries on a Windows machine.
|
Monthly archive
|
İsmail Dönmez (not verified) - 07/25/2010 - 20:54
Neato!
Lothar (not verified) - 10/19/2010 - 10:51
I tried to cross compile Qt 4.7 (official release) but it failed. When using some older gcc, it fails because of some include order issue which is fixed in a more recent gcc. When using latest mingw-w64 cross compiler, then mmx stuff fails and if this is disabled, some things which are only for Linux are suddenly compiled.
Is cross compiling Qt for Windows no longer possible? Did you try with the official version? It seems that your buildbot actually uses Windows systems at the moment.
andras.becsi - 10/19/2010 - 12:49
Hi, Lothar,
I just finished to build the official Qt-4.7.0 release with 32bit mingw-gcc-4.5.0 and to cross-compile a correctly working QtWebKit (with previous git versions we experienced a jpeg plugin issue). We plan to substitute our Windows virtual machine bots with the cross buildbots this week (new bots can currently be found here).
To answer your question: We did not try to build Qt with 64bit mingw, so maybe your issues are related to that. However previously I also experienced the include order issue, you mentioned, with 32bit mingw which I fixed by substituting the two float.h headers, back then. Also, we have no plans to try the 64bit mingw in the near future.
If I manage to get some spare time I'll update this blog post with more recent information.
Post new comment