Qt 5.7 on Pi3 cross compiled on Ubuntu - let's build a how-to that really works

  • My experience is that cross compiling Qt5.7 on a Pi3 is still as painful as building 4.x on a Pi2 years ago. (Sorry for such a negative opening...) Not being enough of an expert to write a how-to on my own I would highly appreciate if we could throw our findings together and create something useful for the whole community.
    For the currently blocking problem please scroll down to the end.

    Mysteries and Trial-and-Error Experiences

    • Add all the dependencies on your Pi so that Qt compiles. My current list is
    sudo apt-get update
    sudo apt-get upgrade
    sudo reboot
    sudo apt-get install build-essential cmake git
    sudo apt-get install libdbus-1-dev libudev-dev sqlite symlinks
    sudo apt-get install xcb libxcb-keysyms1-dev libxcb-image0-dev libxcb-shm0-dev libxcb-icccm4-dev 
    sudo apt-get install libxcb-sync0-dev libxcb-xfixes0-dev libxcb-shape0-dev libxcb-randr0-dev libxcb-render-util0-dev
    • symlinks-package is - to my opinion - the most transparent way of converting absolute to relative symbolic links. I use a script like
    sudo symlinks -cr /lib
    sudo symlinks -cr /usr/lib
    sudo symlinks -cr /usr/local/lib
    • we could do without the xcb stuff and use -qt-xcb for the built-in xcb support - is there any drawback compared to the system libs?
    • ARM-toolchain on host : I am slightly confused about the 32-bit (gcc-linaro-arm-linux-gnueabihf-raspbian) and 64-bit (gcc-linaro-arm-linux-gnueabihf-raspbian-x64) versions of the toolchain. The x64 sounds like we are talking about the architecture of the host, not the target, right? In some location I read that you have to install lib32z1 lib32ncurses5 lib32bz2-1.0 in order to run the 32-bit on a 64-bit system. Well, why should I want to do this? 64-bit on Pi3 should be possible one day but right now we lack a 64-bit kernel there, as far as I know.
    • Now for the -device option in configure. According to mkspec there are 3 Pi related devices: linux-rasp-pi-g++ (which worked fine for Qt5.5 on Pi2), linux-rasp-pi2-g++ and linux-rpi3-g++. I could not find any doc for these and I am not enough expert to read (and understand) the qmake.conf files and get any wiser. Does anyone know more about it?
    • using -device linux-rpi3-g++ results in -std=c++1z as compiler option, which is a far shot: Qt 5.7 requires C++11 so it should read -std=c++11. -std=c++1z denotes the upcoming C++17 and is not supported by the toolchain. Is this a bug in configure? Similar story about -march=armv8-a+crc. From my point of view linux-rpi3-g++ is broken.
    • Know nothing about linux-rasp-pi2-g++ - anyone else?
    • Pi-libs on host: Most resources use the Pi-SDcard mounted on the host. This works but is quite cumbersome - whenever you update your target system you have to recreate your "crosscompile-SD" or you may create very subtle runtime errors on the target. (Had this issue once, it took me weeks to fully recover...) Thus I like the rsync approach used in the EGLFS article very much. It is fast and works without touching the Pi physically. Does anyone see drawbacks? Or is this sufficient on the host: (Any ideas how you could avaoid to type the password four times?)
    mkdir rfs rfs/usr rfs/opt
    rsync -avz pi@ rfs
    rsync -avz pi@ rfs/usr
    rsync -avz pi@ rfs/usr
    rsync -avz pi@ rfs/opt
    • Now lets .configure qtbase which seems to work fine on my setup: (since most resource use the 32-bit compiler I do the same...)
    cd qtbase
    ./configure -release -opensource -confirm-license -v \
     -opengl es2 -qt-sql-sqlite -optimized-qmake -no-pch -reduce-exports \
     -make libs -make tools \
     -device linux-rasp-pi-g++ \
     -device-option CROSS_COMPILE=/anypath/pi-tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf- \
     -sysroot /anypath/pi-tools/rfs \
     -prefix /usr/local/qt5.7pi -extprefix /usr/local/qt5.7pi -hostprefix /usr/local/qt5.7pi
    • Why should anyone want to point extpath somewhere local and merge the result back in the Pi filesytem manually later as in Pi2EGLFS? The ARM binaries are quite useless on the host.

    Blocking Problems

    • After flawless configure I make it: (Actually I don't make it for the errors :-)
    <compiling show no problems>
    make[2]: Entering directory `/anypath/pi-tools/qt-src-5.7.0/qtbase/src/gui'
    rm -f libQt5Gui.so.5.7.0 libQt5Gui.so libQt5Gui.so.5 libQt5Gui.so.5.7
    /anypath/pi-tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf-g++ -Wl,-rpath-link,/anypath/pi-tools/rfs/opt/vc/lib -Wl,-rpath-link,/anypath/pi-tools/rfs/usr/lib/arm-linux-gnueabihf -Wl,-rpath-link,/anypath/pi-tools/rfs/lib/arm-linux-gnueabihf -mfloat-abi=hard --sysroot=/anypath/pi-tools/rfs -Wl,--no-undefined -Wl,--version-script,QtGui.version -Wl,-O1 -fuse-ld=gold -Wl,--enable-new-dtags -Wl,-z,origin -Wl,-rpath,\$ORIGIN -shared -Wl,-soname,libQt5Gui.so.5 -o libQt5Gui.so.5.7.0 .obj/qaccessible.o .obj/qaccessiblecache.o .obj/qaccessibleobject.o .obj/qaccessibleplugin.o .obj/qplatformaccessibility.o .obj/qaccessiblebridge.o .obj/qgenericpluginfactory.o .obj/qgenericplugin.o .obj/qwindowsysteminterface.o .obj/qplatforminputcontextfactory.o .obj/qplatforminputcontextplugin.o .obj/qplatforminputcontext.o .obj/qplatformintegration.o .obj/qplatformdrag.o .obj/qplatformscreen.o .obj/qplatformintegrationfactory.o .obj/qplatformintegrationplugin.o .obj/qplatformtheme.o .obj/qplatformthemefactory.o .obj/qplatformthemeplugin.o .obj/qplatformwindow.o .obj/qplatformoffscreensurface.o .obj/qplatformcursor.o .obj/qplatformclipboard.o .obj/qplatformnativeinterface.o .obj/qsessionmanager.o .obj/qshapedpixmapdndwindow.o .obj/qsimpledrag.o .obj/qsurfaceformat.o .obj/qguiapplication.o .obj/qwindow.o .obj/qoffscreensurface.o .obj/qplatformsurface.o .obj/qsurface.o .obj/qclipboard.o .obj/qcursor.o .obj/qdrag.o .obj/qdnd.o .obj/qevent.o .obj/qinputmethod.o .obj/qkeysequence.o .obj/qkeymapper.o .obj/qpalette.o .obj/qguivariant.o .obj/qscreen.o .obj/qshortcutmap.o .obj/qstylehints.o .obj/qtouchdevice.o .obj/qplatformsharedgraphicscache.o .obj/qplatformdialoghelper.o .obj/qplatformservices.o .obj/qplatformsystemtrayicon.o .obj/qplatformsessionmanager.o .obj/qplatformmenu.o .obj/qpixelformat.o .obj/qpaintdevicewindow.o .obj/qrasterwindow.o .obj/qplatformgraphicsbuffer.o .obj/qplatformgraphicsbufferhelper.o .obj/qinputdevicemanager.o .obj/qhighdpiscaling.o .obj/qplatformopenglcontext.o .obj/qopenglcontext.o .obj/qopenglwindow.o .obj/qbitmap.o .obj/qimage.o .obj/qimage_conversions.o .obj/qimageiohandler.o .obj/qimagereader.o .obj/qimagewriter.o .obj/qpaintengine_pic.o .obj/qpicture.o .obj/qpictureformatplugin.o .obj/qpixmap.o .obj/qpixmapcache.o .obj/qplatformpixmap.o .obj/qmovie.o .obj/qpixmap_raster.o .obj/qpixmap_blitter.o .obj/qnativeimage.o .obj/qimagepixmapcleanuphooks.o .obj/qicon.o .obj/qiconloader.o .obj/qiconengine.o .obj/qiconengineplugin.o .obj/qbmphandler.o .obj/qppmhandler.o .obj/qxbmhandler.o .obj/qxpmhandler.o .obj/qpnghandler.o .obj/qfont.o .obj/qfontengine.o .obj/qfontengineglyphcache.o .obj/qfontsubset.o .obj/qfontmetrics.o .obj/qfontdatabase.o .obj/qtextengine.o .obj/qtextlayout.o .obj/qtextformat.o .obj/qtextobject.o .obj/qtextoption.o .obj/qfragmentmap.o .obj/qtextdocument.o .obj/qtextdocument_p.o .obj/qtexthtmlparser.o .obj/qabstracttextdocumentlayout.o .obj/qtextdocumentlayout.o .obj/qtextcursor.o .obj/qtextdocumentfragment.o .obj/qtextimagehandler.o .obj/qtexttable.o .obj/qtextlist.o .obj/qtextdocumentwriter.o .obj/qsyntaxhighlighter.o .obj/qcssparser.o .obj/qzip.o .obj/qtextodfwriter.o .obj/qstatictext.o .obj/qrawfont.o .obj/qglyphrun.o .obj/qdistancefield.o .obj/qfontengine_qpf2.o .obj/qplatformfontdatabase.o .obj/qharfbuzzng.o .obj/qbackingstore.o .obj/qbezier.o .obj/qblendfunctions.o .obj/qblittable.o .obj/qbrush.o .obj/qcolor.o .obj/qcolor_p.o .obj/qcompositionfunctions.o .obj/qcosmeticstroker.o .obj/qcssutil.o .obj/qdrawhelper.o .obj/qemulationpaintengine.o .obj/qgammatables.o .obj/qgrayraster.o .obj/qimagescale.o .obj/qmatrix.o .obj/qmemrotate.o .obj/qoutlinemapper.o .obj/qpagedpaintdevice.o .obj/qpagelayout.o .obj/qpagesize.o .obj/qpaintdevice.o .obj/qpaintengine.o .obj/qpaintengineex.o .obj/qpaintengine_blitter.o .obj/qpaintengine_raster.o .obj/qpainter.o .obj/qpainterpath.o .obj/qpathclipper.o .obj/qpdf.o .obj/qpdfwriter.o .obj/qpen.o .obj/qpolygon.o .obj/qrasterizer.o .obj/qregion.o .obj/qstroker.o .obj/qtextureglyphcache.o .obj/qtransform.o .obj/qplatformbackingstore.o .obj/qpathsimplifier.o .obj/qdesktopservices.o .obj/qvalidator.o .obj/qgridlayoutengine.o .obj/qabstractlayoutstyleinfo.o .obj/qlayoutpolicy.o .obj/qgenericmatrix.o .obj/qmatrix4x4.o .obj/qquaternion.o .obj/qvector2d.o .obj/qvector3d.o .obj/qvector4d.o .obj/qopengl.o .obj/qopenglfunctions.o .obj/qopenglframebufferobject.o .obj/qopenglpaintdevice.o .obj/qopenglbuffer.o .obj/qopenglshaderprogram.o .obj/qopenglgradientcache.o .obj/qopengltexturecache.o .obj/qopenglengineshadermanager.o .obj/qopengl2pexvertexarray.o .obj/qopenglpaintengine.o .obj/qopenglcustomshaderstage.o .obj/qtriangulatingstroker.o .obj/qopengltextureglyphcache.o .obj/qtriangulator.o .obj/qopenglversionfunctions.o .obj/qopenglversionfunctionsfactory.o .obj/qopenglvertexarrayobject.o .obj/qopengldebug.o .obj/qopengltextureblitter.o .obj/qopengltexture.o .obj/qopengltexturehelper.o .obj/qopenglpixeltransferoptions.o .obj/qopenglfunctions_es2.o .obj/qguivariantanimation.o .obj/qstandarditemmodel.o .obj/qimage_compat.o .obj/moc_qaccessible.o .obj/moc_qaccessiblecache_p.o .obj/moc_qaccessibleplugin.o .obj/moc_qaccessiblebridge.o .obj/moc_qgenericplugin.o .obj/moc_qplatforminputcontext.o .obj/moc_qplatforminputcontextplugin_p.o .obj/moc_qplatformintegrationplugin.o .obj/moc_qplatformthemeplugin.o .obj/moc_qplatformnativeinterface.o .obj/moc_qplatformmenu.o .obj/moc_qshapedpixmapdndwindow_p.o .obj/moc_qoffscreensurface.o .obj/moc_qclipboard.o .obj/moc_qdrag.o .obj/moc_qdnd_p.o .obj/moc_qevent.o .obj/moc_qkeysequence.o .obj/moc_qkeymapper_p.o .obj/moc_qpalette.o .obj/moc_qsessionmanager.o .obj/moc_qscreen.o .obj/moc_qstylehints.o .obj/moc_qtouchdevice.o .obj/moc_qplatformsharedgraphicscache.o .obj/moc_qplatformdialoghelper.o .obj/moc_qpaintdevicewindow.o .obj/moc_qrasterwindow.o .obj/moc_qplatformgraphicsbuffer.o .obj/moc_qinputdevicemanager_p.o .obj/moc_qopenglwindow.o .obj/moc_qimageiohandler.o .obj/moc_qpictureformatplugin.o .obj/moc_qiconengineplugin.o .obj/moc_qfont.o .obj/moc_qfontdatabase.o .obj/moc_qtextformat.o .obj/moc_qtextobject.o .obj/moc_qtextdocument.o .obj/moc_qtextimagehandler_p.o .obj/moc_qtexttable.o .obj/moc_qtextlist.o .obj/moc_qbrush.o .obj/moc_qpainter.o .obj/moc_qpdfwriter.o .obj/moc_qplatformbackingstore.o .obj/moc_qvalidator.o .obj/moc_qopenglshaderprogram.o .obj/moc_qopenglengineshadermanager_p.o .obj/moc_qopengltexture.o  -L/anypath/pi-tools/rfs/usr/lib/arm-linux-gnueabihf -L/anypath/pi-tools/qt-src-5.7.0/qtbase/lib -lQt5Core -lpthread -lpng -lqtharfbuzzng -lz -lGLESv2 
    .obj/qaccessible.o:qaccessible.cpp:function QAccessibleEvent::accessibleInterface() const: error: undefined reference to 'QDebug::~QDebug()'
    .obj/qaccessible.o:qaccessible.cpp:function QAccessibleEvent::accessibleInterface() const: error: undefined reference to 'QDebug::~QDebug()'
    .obj/qaccessible.o:qaccessible.cpp:function QAccessibleEvent::accessibleInterface() const: error: undefined reference to 'QDebug::~QDebug()'
    .obj/qaccessible.o:qaccessible.cpp:function operator<<(QDebug, QAccessibleEvent const&): error: undefined reference to 'QDebug::~QDebug()'
    .obj/qaccessible.o:qaccessible.cpp:function operator<<(QDebug, QAccessibleInterface const*): error: undefined reference to 'QDebug::putString(QChar const*, unsigned int)'
    <more errors removed>

    So the generation of libQt5Gui.so.5.7.0 fails because the linker can't find QDebug (or parts of it). But it is not that simple, it should be found:

    nm -D -C libQt5Core.so.5.7.0 | grep QDebug
    00172f20 T QDebug::~QDebug()

    So the dtor is there and the lib is in the right place (/anypath/pi-tools/qt-src-5.7.0/qtbase/lib). What is going wrong here?

    ROUNDUP and Solution:
    It seems there were leftovers of an older Qt version, probably 5.4 on my development machine. No idea why this interfered with my build, but who cares :-) Now on a machine freshly set up everything works fine.
    And synapticviod down in the discussion pointed to a great page.

  • Hi and thanks for the post!
    I am trying to compile Qt and faced an issue even on the stage of ./configure
    My first question - do we need to have Raspberry Pi connected to PC when we execute ./configure ?
    I do have Rasp Pi3 but I am trying to configure without it connected.

    I have ""Symbolic function binding on this architecture may be broken, disabling it (see QTBUG-36129)."" message then. Assuming that something wrong with slinking.

  • @Yurii-Chernyshov During ./configure you need the tool chain and the root file system of your Pi mounted at the sysroot-path given in the command line of configure. Usually you mount a clone of the Pi SD-card on your host. But I guess copying the relevant library and include folders (like /usr, /lib, /opt) from Pi to host should work too. See my comment on rsync above.
    Regarding your error: I get something similar when I try to use the x64 flavour oft he toolchain. Using gcc-linaro-arm-linux-gnueabihf-raspbian instead of gcc-linaro-arm-linux-gnueabihf-raspbian-x64 should help.

  • @stryga42 Thanks.
    I ran configuration with Rasp Pi connected and slinked and it completed. There was some errors while configuration but it completed well.
    Now, during "make" I am facing:
    qxcbscreen.h:49:26: fatal error: xcb/xinerama.h: No such file or directory
    #include <xcb/xinerama.h>

  • I finally made it!
    There was missing library on the Raspberry Pi side:

    Now, I have Qt able to build and deploy from PC Ubuntu 16 into Raspberry Pi 3

  • Also,
    In final step, when I tried to deploy application into RaspPi board I faced the issue:
    Solution provided in the link was enough to solve it.

  • Hi,
    I get it work with these two tutorials:

    Please keep in mind if you are using a 64 bit Ubuntu to edit the ./configure command. Refer to step 7 of the second tutorial.
    Hope this helps.

  • I have the same problem. The configuration went flawless with this configure:

    ./configure -release -opengl es2 -device linux-rasp-pi2-g++ -device-option CROSS_COMPILE=~/raspi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf- -sysroot ~/raspi/sysroot -opensource -confirm-license -make libs -prefix /usr/local/qt5pi -extprefix ~/raspi/qt5pi -hostprefix ~/raspi/qt5 -qt-xcb -qreal float -v

    But when I run make it says after 15 minutes:

    recipe for target '../../lib/libQt5Gui.so.5.6.2' failed

    I followed the same tutorials as you did. I don't understand why I have an older version than you, maybe that could be my problem. I think my lib is in the right place..
    I'll keep you updated if I found the solution. ;)

  • Hi there,

    If you still face issues to cross-compile Qt on Raspberry Pi, we created the qtrpi project to automate the full process with bash scripts.

    Qtrpi can be used in 2 ways:

    • qtrpi-full, in which everything is built automatically on your host machine (sysroot, Qt)
    • qtrpi-minimal, in which you download a ready-to-use sysroot with pre-compiled Qt binaries

    Everything is open-source, you can find more information at the following URLs:

  • @synapticvoid This was the solution for me

  • @synapticvoid Great resource, many thanks!

Log in to reply

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.