## Tuesday, February 17, 2009

### Compiling Qt with MinGW in MSYS

Since I wanted to port some Qt4 applications (I always developed under Linux) in Windows, I downloaded from the trolltech site the Qt libraries for Windows (already compiled) which come with a minimal MinGW compiler to build windows applications. This was the first time I was using mingw, since I've always used cygwin instead.

The Qt installation comes with a start menu item called Qt Command Prompt, which sets all the environment variables for you in order to start building Qt applications.

However, being used to the comfortable Unix shell, I couldn't stand using the DOS command shell, also because I wasn't willing to use qmake: I need to use autotools instead. Thus, I installed also the mingw shell: msys.

I tried to build a Qt tutorial example with qmake in msys, and here comes the bad surprise: the Makefiles generated by qmake contains windows paths (e.g., for calling the moc compiler), which the Unix shell does not understand. Here's a screenshot with the error:

Everything works fine if you don't use the moc compiler, but as soon as Makefile invokes it, you get the error due to the windows paths:
C:\Qt\4.4.3\bin/moc.exe -DUNICODE -DQT_LARGEFILE_SUPPORT -DQT_DLL -DQT_GUI_LIB -DQT_CORE_LIB -DQT_THREAD_SUPPORT -DQT_NEEDS_QMAIN -I'c:/Qt/4.4.3/include/QtCore' -I'c:/Qt/4.4.3/include/QtCore' -I'c:/Qt/4.4.3/include/QtGui' -I'c:/Qt/4.4.3/include/QtGui' -I'c:/Qt/4.4.3/include' -I'c:/Qt/4.4.3/include/ActiveQt' -I'debug' -I'.' -I'c:/Qt/4.4.3/mkspecs/default' -D__GNUC__ -DWIN32 cannonfield.h -o debug/moc_cannonfield.cpp
make[1]: *** [debug/moc_cannonfield.cpp] Error 127
I then asked on the nice qtcentre forum, and they pointed me to this blog post where they says it's a well known problem, and that recently Qt can be used also from msys (since qmake will generate Unix shell paths). What wasn't clear to me was that you must recompile Qt libraries yourself to make it work also from msys.

IMPORTANT: I wasn't able to compile the Qt libraries with the standard MinGW distribution; I had to use the MinGW that comes with Qt installation (i.e., the file qt-win-opensource-4.4.3-mingw.exe).

I did this procedure:
1. Set some environment variables (assuming that you unzip the sources in C:\qt-win-opensource-src-4.4.3:
export QTDIR=/c/qt-win-opensource-src-4.4.3/
export PATH=/c/qt-win-opensource-src-4.4.3/bin:\$PATH
export QMAKESPEC=\$QTDIR/mkspecs/win32-g++
2. then you can run configure.exe (this will create the qmake binary and all the Makefiles)
3. now run make and wait for about 3 hours!
By the way, be ready to restart the make process some times (for me it's always twice), due to this error:
`Couldn't reserve space for cygwin's heap...`
(I don't know why this happens, but restarting make simply keeps on compiling from where it left).

Now, if no other errors take place, you'll have your compiled Qt libraries, and binaries, that generate the right Makefiles.

Remember to always set the above environment variables (e.g., in your ~/.profile), so that you'll use your version of Qt.

By removing the previous Makefiles, running qmake again (this time it will generate Unix paths to executables), and then make, everything works fine, and you can build qt applications from the comfortable Unix shell: indeed, now, the moc invocation command line is:
C:/qt-win-opensource-src-4.4.3/bin/moc.exe -DUNICODE -DQT_LARGEFILE_SUPPORT -DQT_DLL -DQT_GUI_LIB -DQT_CORE_LIB -DQT_THREAD_SUPPORT -DQT_NEEDS_QMAIN -I'c:/qt-win-opensource-src-4.4.3/include/QtCore' -I'c:/qt-win-opensource-src-4.4.3/include/QtCore' -I'c:/qt-win-opensource-src-4.4.3/include/QtGui' -I'c:/qt-win-opensource-src-4.4.3/include/QtGui' -I'c:/qt-win-opensource-src-4.4.3/include' -I'c:/qt-win-opensource-src-4.4.3/include/ActiveQt' -I'debug' -I'.' -I'c:/qt-win-opensource-src-4.4.3/mkspecs/win32-g++' -D__GNUC__ -DWIN32 lcdrange.h -o debug/moc_lcdrange.cpp
and you can run the Qt application :-)

che1i0s said...

I would just fix broken Makefiles with streameditor (shell scrcipt):

#!/bin/sh
for rel in Makefile.Debug Makefile.Release Makefile
do
if [ -f \$rel ];
then
echo "Fixing \$rel .."
copyrel=\$rel".orig"
cp \$rel \$copyrel
sed -e 's/C\:\\Qt\\4\.4\.3\\/C\:\/Qt\/4\.4\.3\//g' < \$copyrel > \$rel
fi
done

Anonymous said...

could you explain ti more clearly. too many people have this problem but you can say more clearly for new starter. what did you write also where on it?

betto said...

Anonymous, is your question for me or for che1i0s?

Anonymous said...

yes it was to you. but i did it. i got "Couldn't reserve space for cygwin's heap..." error either. also what`s wrong with mingw?
i had solved the path problem with "junction.exe". but it was still giving "moc" problem. :S so i installed msys. then i did it. but i would like to compile it with mingw. my new question is how can i solve the "moc" problem on minGW. thanks for your quick replay.

betto said...

mhh... junction.exe? What is it?
However msys is only a shell, so if you compile it from there you compile it with mingw.

What do you mean by "but i would like to compile it with mingw"?