After compiling Qt 5.0 for Raspberry Pi, I wanted to try all the modules. I compiled and tested the simplest modules first, like:
qtbase
qtdeclarative
qtjsbackend
qtquick1
qtscript
qtxmlpatterns
Everything worked quite smoothly, without any change, except the patch to the v8 engine in qtjsbackend module for ARM hardfp (read here).
I then turned my attention to the QtWebKit module: I know that many changes have been applied to this module for in Qt 5.0, so it is very interesting to try it. Therefore, I started to compile it the usual way:
cd your_qt_sources/qtwebkit your_qt_prefix/bin/qmake make -jn make install
Unfortunately, at the moment of writing, it didn't work for me: the module compiled and linked successfully, but crashed almost as soon as the page load procedure started. I therefore had to start searching around and asking Qt guys about this issue, and during this, I was frequently directed here. Turned out this is exactly the issue I encountered: I applied the latest patch (consider reading the entire report and check that a more stable fix is available):
cd your_qt_sources/qtwebkit patch -p1 < ~/webkit_patch
where webkit_patch is the linked diff. So, now you can compile the module to include the differences and try again. Consider that the patch seems to be near land, so it might not be necessary for you in the future. As a first test, this is the code I tried:
At this point, it should work. As you can see, performance is unacceptable. This is not the way an embedded browser is supposed to work indeed, this is more like classes that can be used for a desktop browser.
Next step was testing WebKit2 with tiling and all that nice stuff. So I tried to create a simple application loading a WebView QML element, like this:
When I tried this the first time, it closed with an anonymous error on QtWebProcess:
Failed to start " QtWebProcess 14"
After looking into the sources, I found this is simply a failure to find the QtWebProcess binary. It is needed because WebKit2 uses a separate process to draw the content. Placing it in /usr/bin is sufficient:
cd /usr/bin sudo ln -s your_qt_prefix/bin/QtWebProcess QtWebProcess
Or better use a relative path. Now what you might get is... nothing at all... At least this is what I got. After some seconds a crash occurred and often nothing was drawn.
It took me some time to guess what was happening: it seems that QtWebKit is trying to draw with 32 bit color depth, while instead the rest of Qt is rendering using 16 bit color depth (especially if you're using the eglfs platform plugin) on a RGB565 EGL configuration.
According to the Qt WebKit code, it seems that the entire code is assuming 32 bit color depth is being used, and this is hardcoded instead of negotiated with the main process. As a quick fix, I made the entire EGL configuration to be 32 bit (read this).
By setting this, it is possible to make QtWebKit work in 1080p with 32 bit color depth. If I'll find the time I'll do the needed modifications to have the same configuration with the correct color depth.
Consider that, at the moment of writing, the configuration of the wheezy image does not assign sufficient memory to the GPU.You'll see therefore pages where many tiles are black: that is the result of insufficient GPU memory when trying to allocate for the texture. Just assign some more memory to the GPU editing the /boot/config.txt file of your Pi.
EDIT: I see this post is still consulted very often. The solution below was the only one I found years ago. Now it seems that setting the env variable QT_QPA_EGLFS_FORCE888 to 1 works perfectly.
Some days ago I was asked to test the performance of 32 bit EGL config color depth with Qt on Raspberry Pi using the eglfs platform plugin. I tried to set the framebuffer to 32 bit color depth using the usual command:
fbset -depth 32
Nothing changed unfortunately. I also tried some other changes I was suggested but no way.
This seems due to some strange parameter passed to the q_configFromGLFormat function in the qeglconvenience.cpp source file. What I did to make Qt render 32 bits per pixel is to simply rewrite the function to always return a 32 bit EGL configuration. This is not a fix of the issue nor a good modification, it is just a hack to make it render true color. I hope I'll find the time to analyze the situation more accurately.
NOTE: For updated information read here.
Ok, so I got my brand new Raspberry Pi! :-) I found a couple of guides on how to compile Qt 5.0 for it, but still I had some troubles doing that, and this guide is to speed up the process for others. Let's start from the beginning...
As you might already know, Qt 5.0 comes with the QPA (Qt Platform Abstraction) mechanism. This means you can choose from the command line what platform driver to use. At the beginning I thought I could use the xcb plugin, but that turned out to be a bad idea: I had some troubles with libxcb being unable to communicate with X11 for some protocol-related incompatibility, like some version mismatching, I don't know (if you do, please share! :-)).
So, I went directly to the interesting part: getting rid of X11 in favor of the eglfs plugin. I'm leaving the wayland integration for a later time.
Setting up the image
You already know all this, anyway I downloaded to last wheezy image from the Pi website, and printed it in my SD card:
I later discovered the space was insufficient, so, I used gparted to enlarge it. You should have that for your distribution: I was using a Kubuntu 12.10 in a VM on Mac OS X.
Setting up the compilation environment
I chose to go with the Linaro toolchain, using hardfp support of course. If you don't know what hardfp support, look for that on the Internet: there is a simple explaination here. I found that toolchain for the Pi here: https://github.com/raspberrypi/tools/tree/master/arm-bcm2708. Download it and place it in a safe place (your_toolchain_path) :-)
The toolchain is not sufficient to compile Qt, you also need some other lib. To make sure to use the same libs that are in the wheezy image, I created an image for the Pi with all the dependencies I needed, downloading with aptitude and then bringing that image back to my compilation environment. By using that sysroot, I'm confident everything will be fine.
Another possible way to go is to simply scp all the libs from the Pi to the compilation system, but that is quite bothering. Also, I tried to use rsync, that is quite more simple to use, I don't have to spend time looking for the installed files any time I install a new package I need for the compilation.
My dream would anyway being able to mount the root of my Pi using NFS. This way, without any work at all I would have all my libs. NFS is actually available for the Pi, but still I was unable to make it work. If you are, please share! ;-)
Ok, this is what I wrote down while setting everything up. To compile the xcb platform driver I had to apt-get these libs on my Pi image.
Everything should now be fine: using one of the proposed methods get the root filesystem of the Pi into the compilation environment and compilation shall begin!
How you do that is up to you: simple way is to shutdown your Pi, place the SD back in your Linux Box and: sudo dd if=/dev/your_sd_device of=your_pi_image.img
then mount your image as a loopback device:
sudo mount -o loop,offset=62914560 your_pi_image.imgyour_sysroot_path
Also pay attention: the offset might change, so use fdisk to find the correct offset in the image file.
Now there is a problem: it seems that in the multi-arch image there are some symlinks which points to files with an absolute path. This is a problem since, typically, you want to place your_sysroot somewhere which is not the root, and therefore the symlink becomes invalid. The page I linked above provides a script to fix these paths: https://gitorious.org/cross-compile-tools/cross-compile-tools/blobs/master/fixQualifiedLibraryPaths. Give it as parameter the location of your sysroot on the compilation machine and it should fix the paths.
You'll also need some instruments on the compilation system: if you're running Kubuntu or Ubuntu, you'll need these packages, otherwise use the instruments provided by your distribution:
I hope I didn't forget anything... if I did, please consider adding a comment!
NOTE: If you're compiling in a virtual environment, like I am, beware that QtWebKit compilation will require more than 512MB of RAM! I spent half a day trying to recompile a new toolchain because of "internal compiler error". At least 1GB of RAM should be reserved, but 2GB might be better for QtWebKit.
Getting the source code
This is pretty standard, anyway:
git clone git://gitorious.org/qt/qt5.git qt5 cd qt5 perl init-repository
This will download everything you need.
Configuration and build
You'll need to configure, building and installing the qtbase module first of all. This is the configure line I used:
I didn't select tests because it failed compilation asking for libboost, which I had no time to provide. If you want, packages for wheezy are available. In case any error occurs in the configuration process, use the -v parameter to try to guess what went wrong
If your configuration succeeds, you should see a smiling table like this:
Result is: Building on: linux-g++ Building for: devices/linux-rasp-pi-g++ Architecture: arm, features: Host architecture: unknown, features: Platform notes:
- Also available for Linux: linux-kcc linux-icc linux-cxx
qmake vars .......... qmake switches ......... Build .................. libs Configuration .......... cross_compile qpa largefile precompile_header neon pcre minimal-config small-config medium-config large-config full-config no-pkg-config evdev xcb-poll-for-queued-event linuxfb c++11 egl eglfs opengl opengles2 shared qpa reduce_exports reduce_relocations clock-gettime clock-monotonic mremap getaddrinfo ipv6ifname getifaddrs inotify png freetype system-zlib nis iconv openssl xcb rpath icu concurrent audio-backend v8 release Debug .................. no C++11 support .......... yes pkg-config ............. yes QtDBus module .......... yes QtConcurrent code ...... yes QtGui module ........... yes QtWidgets module ....... yes JavaScriptCore JIT ..... To be decided by JavaScriptCore QML debugging .......... yes PCH support ............ yes iWMMXt support ......... no NEON support ........... yes IPv6 ifname support .... yes getaddrinfo support .... yes getifaddrs support ..... yes Accessibility .......... no NIS support ............ yes CUPS support ........... no Iconv support .......... yes Glib support ........... no GStreamer support ...... no PulseAudio support ..... no Large File support ..... yes GIF support ............ plugin JPEG support ........... plugin (qt) PNG support ............ yes (qt) zlib support ........... system Session management ..... auto libudev support ........ yes OpenGL support ......... yes (OpenGL ES 2.x) OpenVG support ......... no XShape support ......... auto XVideo support ......... auto XSync support .......... auto Xinerama support ....... runtime Xcursor support ........ runtime Xfixes support ......... runtime Xrandr support ......... runtime Xi support ............. runtime Xi2 support ............ no MIT-SHM support ........ auto FontConfig support ..... no XKB Support ............ auto immodule support ....... yes GTK theme support ...... no SQLite support ......... plugin (qt) OpenSSL support ........ yes (run-time) Alsa support ........... no libICU support ......... yes PCRE support ........... qt Xcb support ............ yes Xrender support ........ no EGLFS support .......... yes DirectFB support ....... no LinuxFB support ........ yes KMS support ............ no
This means you're pretty ok now, you can start compilation using something like:
make -j(number_of_cpus + 1)
This is the time where you might want to have a coffee.
If everything builds correctly, you're at a good point, so install:
sudo make install
and be happy now! You should see on your system your_qt_prefix now exists and contains at least the bin directory with the qmake executable. Also, in your_sysroot_path/your_qt_prefix/ you should see the compiled libs, the imports, the plugins etc...
You are done!
Compile some other exciting module
Just qtbase alone is pretty interesting, but you can now try to compile other modules! All the modules can be compiled the same way:
cd your_qt_module your_qt_prefix/bin/qmake make -j(number_of_cpus + 1) sudo make install
Some of the modules should compile without bloodsheds, while for some others I'll reserve some other post. Just consider that qjsbackend seems to need a patch at the moment of writing, so, before building it:
cd qtjsbackend git fetch https://codereview.qt-project.org/p/qt/qtjsbackend refs/changes/56/27256/4 && git cherry-pick FETCH_HEAD
This should make it work correctly.
Consider that qtmultimedia, qtwayland and qtwebkit might need more work. I'll write about QtWebKit when I'll find the time to.
Also, I tried to run Qt with 32bit color depth, and it seems again the algorithm of choice of the EGL configuration still chooses 16bit. I solved by modifying the sources, I'll write about this as soon as I'll have the time to.
Running the examples
Now, you can write some test app or try to run some of the examples on the Pi. You'll have to copy your Qt libraries back to your Pi, or create a new image to place on the SD card. To create the new image just dd your_pi_image.img back on the SD card and boot the Pi with that new filesystem. Now check your_qt_prefix to confirm that the Qt libs have been placed there. Now, in your_pi_prefix/examples you should see many possible application to test. To have a look at the performance, I suggest trying some of the Qt3d or qtquick examples on the eglfs platform plugin:
This is some QML code I wrote in 10 minutes using a PathView just to show somehow the performance. Very gooooood! This is Qt 5.0 running 1080p 32 bit color depth QtQuick2 with the eglfs plugin!