Thursday, November 05, 2009

Compiling Qt 4.6 from sources

If you feel like trying the new Qt 4.6, which is currently in beta, and if you're using Linux, for which it is available only in source code package, or if you need the current development version from the git repository (for instance, for building the git repository version of Qt-Creator, you'll have to compile qt from sources.

This is quite straightforward, but I'll blog it here, in case it might provide some help for those who never compiled it.

If you obtained the source package, then you'll need to unpack it somewhere in your home.

If you want the git version (of course you need the git program), you'll first obtain the sources from the git repository:

git clone git://gitorious.org/qt/qt.git
and then switch to the 4.6 branch
cd qt
git checkout -b 4.6 origin/4.6
Now, instead of compiling qt in the same directory where the sources are, let's make a shadow build, so that the source directory will stay untouched; this will also allow us to do possible several builds of the library (e.g., we may want to do a static build of the library, a debug build, etc.). Thus we create a build directory where we'll run the compilation (note that at the moment the build directory must be at the same level, thus we must not create the build directory inside the source directory).

Thus, for instance, this are the directories I have for building qt
bettini@bettini-desktop-karmic:~/install/qt-git$ ll
total 8
drwxr-xr-x 2 bettini bettini 4096 2009-11-04 21:33 build
drwxr-xr-x 17 bettini bettini 4096 2009-11-04 21:33 qt
(where qt is where you have the qt sources; in case you got the source archive, this directory might be called something like qt-everywhere-opensource-src-4.6.0-beta1).

Now, let's enter the build directory and run the configure script. If you don't pass any -prefix option to configure, the library will be built to be installed into the directory /usr/local/Trolltech/Qt-4.6.0/):
cd build
../qt/configure
you'll have to answer some questions, and then you'll be ready to compile:
Which edition of Qt do you want to use ?

Type 'c' if you want to use the Commercial Edition.
Type 'o' if you want to use the Open Source Edition.

Preparing build tree...

This is the Qt/X11 Open Source Edition.

You are licensed to use this software under the terms of
the Lesser GNU General Public License (LGPL) versions 2.1.

Type 'L' to view the Lesser GNU General Public License version 2.1.
Type 'yes' to accept this license offer.
Type 'no' to decline this license offer.

Do you accept the terms of the license?


Qt is now configured for building. Just run 'make'.
Once everything is built, you must run 'make install'.
Qt will be installed into /usr/local/Trolltech/Qt-4.6-git

To reconfigure, run 'make confclean' and 'configure'.
Now you're ready to run make and wait for about a couple of hours (even more if you don't have a fast machine); of course you may want to tweak the configuration so that you don't build some parts of qt (e.g., the examples); you may want to take a look at configure options by running configure --help.

After compilation ended, you can install the library; if you chose to install it in a path which is not your home, remember that you need superuser privileges:
sudo make install
When this ended, you'll have your qt installed in the path specified at configuration time (or the default one), e.g.:
bettini@bettini-prog-karmic:~$ ll /usr/local/Trolltech/Qt-4.6.0/
total 364
drwxr-xr-x 2 root root 4096 2009-11-05 07:30 bin
drwxr-xr-x 22 root root 4096 2009-11-05 07:29 demos
drwxr-xr-x 5 root root 4096 2009-11-05 07:30 doc
drwxr-xr-x 36 root root 4096 2009-11-05 07:29 examples
drwxr-xr-x 21 root root 4096 2009-11-05 07:28 include
drwxr-xr-x 3 root root 4096 2009-11-05 07:28 lib
drwxr-xr-x 96 root root 4096 2009-11-05 07:30 mkspecs
drwxr-xr-x 2 root root 4096 2009-11-05 07:28 phrasebooks
drwxr-xr-x 10 root root 4096 2009-11-05 07:28 plugins
-rw-r--r-- 1 root root 332881 2009-10-13 09:43 q3porting.xml
Note that sometimes documentation is not installed (you can take a look at the doc directory which should have html and qch subdirectories). I experienced this if I use a different prefix at configuration time. If this is the case, you need to first build explicitly the documentation with make docs and then, run the same configure command again (i.e., with the same options), and then run the make install command another time, and the documentation should be installed correctly.

Now, you're ready to enjoy the qtdemo, by running /usr/local/Trolltech/Qt-4.6.0/bin/qtdemo

Now, if you have another version of qt already installed in your system (e.g., the one packaged for your distribution) and you want to use the one you've just compiled it?

Well, thanks to qmake, this is quite easy: it's just a matter of invoking the qmake of your compiled version of qt (instead of the one in the system path).

For instance, let's take the mdi example that comes with qt, and let's take, for instance, the one already installed in your system (if you don't have qt examples already installed from your distribution, you can still take the one that is in the sources you downloaded), and copy it into a local folder:
bettini@bettini-prog-karmic:~/tmp/qt$ cp -rf /usr/lib/qt4/examples/mainwindows/mdi .
cd mdi

If I want to build this example using the version of qt we've just compiled it's just a matter of running
/usr/local/Trolltech/Qt-4.6.0/bin/qmake mdi.pro
Now, if I run make, the g++ compiler will be invoked with the right include path and library path for our compiled version of qt:
make
For instance, here's some output (note the -I and -L options):
g++ -c -pipe -O2 -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/local/Trolltech/Qt-4.6.0/mkspecs/linux-g++ -I. -I/usr/local/Trolltech/Qt-4.6.0/include/QtCore -I/usr/local/Trolltech/Qt-4.6.0/include/QtGui -I/usr/local/Trolltech/Qt-4.6.0/include -I. -o main.o main.cpp
...
/usr/local/Trolltech/Qt-4.6.0/bin/moc -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/local/Trolltech/Qt-4.6.0/mkspecs/linux-g++ -I. -I/usr/local/Trolltech/Qt-4.6.0/include/QtCore -I/usr/local/Trolltech/Qt-4.6.0/include/QtGui -I/usr/local/Trolltech/Qt-4.6.0/include -I. mdichild.h -o moc_mdichild.cpp
...
g++ -Wl,-O1 -Wl,-rpath,/usr/local/Trolltech/Qt-4.6.0/lib -o mdi main.o mainwindow.o mdichild.o moc_mainwindow.o moc_mdichild.o qrc_mdi.o -L/usr/local/Trolltech/Qt-4.6.0/lib -lQtGui -L/usr/local/Trolltech/Qt-4.6.0/lib -L/usr/X11R6/lib -lQtCore -lpthread
By the way, note that the right version of the moc compiler is used (and the same holds for uic if your application needs it).

If you now run the mdi program, and choose the Help -> About Qt menu item, you'll get the proof you're using your version of qt 4.6


Let's do some more experiments, and recompile the mdi example with the system version of qt (thus, it's better to get rid of the mdi directory and get a fresh new copy of the mdi example). Now we use the system version of qmake:
qmake -version
QMake version 2.01a
Using Qt version 4.5.2 in /usr/lib
and let's build the example this way
qmake mdi.pro
make
Note that the compiler options are now different

g++ -c -pipe -O2 -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++ -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4 -I. -o main.o main.cpp
...
/usr/bin/moc-qt4 -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++ -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4 -I. mdichild.h -o moc_mdichild.cpp
...
g++ -c -pipe -O2 -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++ -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4 -I. -o qrc_mdi.o qrc_mdi.cpp
g++ -Wl,-O1 -o mdi main.o mainwindow.o mdichild.o moc_mainwindow.o moc_mdichild.o qrc_mdi.o -L/usr/lib -lQtGui -lQtCore -lpthread
If we run the application and select the about qt menu item we can see that we have the 4.5 version of qt:


However, you can run this application, which is built using qt 4.5, so that it uses the 4.6 version of the library you compiled from source (assuming that we are using dynamically linked library):
LD_LIBRARY_PATH=/usr/local/Trolltech/Qt-4.6.0/lib ./mdi
This will force the dynamic linker to use the 4.6 version of the dynamic libraries.

Again, you can get the evidence using the about qt menu item.

This is possible due to version 4.6 being backward compatible.

Have fun with Qt :-)

13 comments:

Maxwell said...

hi. i didn't understand how can i run my kde qith compiled qt 4.6.0. can you help me? now i have an opensuse machine, with qt 4.5.3

thanks
Marco

betto said...

you may want to try by setting LD_LIBRARY_PATH before starting X and kde...

Maxwell said...

so i must set "export LD_LIBRARY_PATH=/usr/local/Trolltech/Qt-4.6.0/lib", isn't it??

thanks
Marco

betto said...

yes, probably that should work

you might also want to set the PATH so that it points to /usr/local/Trolltech/Qt-4.6.0/bin

please, let me know whether it works

Maxwell said...

at the beginning i followed your method, but when i rebooted my pc it used qt 4.5.3. so i googled till i found qt install page (http://doc.trolltech.com/4.6/install-x11.html). It sais that for compiled qt you must modify yur .login or .profile (depending on your shell type, that is bash, sh, csh....). Now when i type qtconfig, it opens an horrible qtconfig....but in "About QT" i can read "This program uses QT version 4.6.0". But if i run it from kde (Alt+F2) it says i'm using 4.5.3. Where is the problem??

betto said...

you may want to put it into your .bashrc

however, I'd try something different first: try to run a KDE program from the command line by putting first the LD_LIBRARY_PATH

for instance, using ldd:

LD_LIBRARY_PATH=/usr/local/Trolltech/Qt-4.6.0/lib/ ldd /usr/bin/konqueror | grep Qt
libQtXml.so.4 => /usr/local/Trolltech/Qt-4.6.0/lib/libQtXml.so.4 (0x00bbf000)
libQtDBus.so.4 => /usr/lib/libQtDBus.so.4 (0x0014c000)
libQtCore.so.4 => /usr/local/Trolltech/Qt-4.6.0/lib/libQtCore.so.4 (0x07378000)
libQtGui.so.4 => /usr/local/Trolltech/Qt-4.6.0/lib/libQtGui.so.4 (0x014dc000)
libQtNetwork.so.4 => /usr/local/Trolltech/Qt-4.6.0/lib/libQtNetwork.so.4 (0x00a43000)
libQtSvg.so.4 => /usr/local/Trolltech/Qt-4.6.0/lib/libQtSvg.so.4 (0x009d0000)

however, at least for me, if I run

LD_LIBRARY_PATH=/usr/local/Trolltech/Qt-4.6.0/lib/ /usr/bin/konqueror

I get

symbol lookup error: /usr/lib/libQtDBus.so.4: undefined symbol: _ZN14QObjectPrivate15checkWindowRoleEv

so you must check first that you have a Qt version compiled with everything that's needed

for instance, using the installation package for the new Qt 4.6 I can run

LD_LIBRARY_PATH=/opt/qtsdk-2009.05/lib/ /usr/bin/dolphin

and it works :-)

Maxwell said...

ok, i tryed and got the same error, and the same result (for dolphyn). but i'm not sure that in this way it uses qt 4.6. if i try to run
LD_LIBRARY_PATH=/usr/local/Trolltech/Qt-4.6.0/lib/ yast2
it shows me a terrible version of yast....and you ca see the differences here http://img697.imageshack.us/img697/3294/yast.jpg
why dolphin should be perfect?? :-)

betto said...

probably dolphin kde widgets are more scalable to new versions of qt, while yast relies on a specific qt version heavily; it doesn't look that bad anyway, it's just that it does not seem to use antialiasing for fonts and the smooth color scaling, but that might depend on the fact that it uses another qt configuration version I guess... :)

betto said...

I tried with konqueror also and it looks pretty fine, apart from not showing icons in the menus (thus I'm pretty sure it's using /opt/qtsdk-2009.05/lib/).

Besides that, did you notice this when installing qtsdk-2009.05?

"Apart from a C++ compiler, a number of development libraries need to be present to enable Qt Creator to build your Qt applications. On Debian and Ubuntu, use the following command in a terminal to make sure they are installed:

sudo apt-get install libglib2.0-dev libSM-dev libxrender-dev libfontconfig1-dev libxext-dev

If you're using QtOpenGL, you'll also need:

sudo apt-get install libglui-dev"

thus, probably, in your case, it does not use open gl?

Maxwell said...

i'm sorry, but i'm not a developer. i was trying to compile and use qt because (just for fun) i want to compile also kde trunk (and it needs qt 4.6.0). i just want to try if compiling all by myself i have a faster and lighter os. That's all :) Right now yast upgraded qt to qt4.6.0..maybe i will try on a virtual machine. But can i ask a direct contact t you?? if that's not a problem for you, obviously!

Grazie mille
Marco

betto said...

No problem Marco :)
you can find my direct contact email at my home page (see the link in my blog)

Maxwell said...

Hi. Here i am again!! :) I can't find your e-mail address. Could you take mine from my comments?

thanks
Marco

betto said...

Marco, I can't find your email in the comments.

But you can find mine at my home page http://www.lorenzobettini.it

hope to hear from you soon :)