[cmake-developers] Building with Qt for the Raspberry Pi with CMake

Stephen Kelly steveire at gmail.com
Wed Apr 10 19:41:24 EDT 2013


Hi,

This is mostly just feedback on some experience with cross-compiling.

As part of trying to figure out to what extent Qt 5 needs to be patched to 
solve the kind of issue raised in 

 http://public.kitware.com/Bug/view.php?id=14041

and fixed in 6c613b433c45efb0bb013a6bd668cbb8ac740259, I've been toying with 
building Qt 5 for the Raspberry Pi (raspbian image).

I configured Qt like this:

 /home/stephen/dev/src/qtbase-stable/configure -prefix 
/home/stephen/dev/prefix/rpi -release -device linux-rasp-pi-g++ -make libs -
device-option CROSS_COMPILE=/home/stephen/rpi/gcc-4.7-linaro-rpi-
gnueabihf/bin/arm-linux-gnueabihf- -sysroot /home/stephen/rpi/rasp-pi-
rootfs/ -opensource -confirm-license -no-pch

[From the prefix you'll notice I'm not trying to reproduce #14041 here yet]

I can use the resulting Qt 5 build by passing a prefix and toolchain:

 cmake .. -DCMAKE_PREFIX_PATH=/home/stephen/rpi/rasp-pi-
rootfs/home/stephen/dev/prefix/rpi/ -
DCMAKE_TOOLCHAIN_FILE=../rpiToolchain.cmake

 $ cat ../rpiToolchain.cmake 

 set(CMAKE_SYSTEM_NAME Linux)

 set(CMAKE_C_COMPILER /home/stephen/rpi/gcc-4.7-linaro-rpi-
gnueabihf/bin/arm-linux-gnueabihf-gcc)

 set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
 set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
 set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

[Side note, a colleague is working on a patch to generate such a toolchain 
file as part of the Qt build. The Qt mkspecs have all needed information. 
Any comments on that?]

I can then build GammaRay for the Pi if I patch it like this:

diff --git a/CMakeLists.txt b/CMakeLists.txt
index ca7a377..ea0b8d6 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -91,6 +91,32 @@ if(Qt5Core_FOUND)
   include("cmake/ECMQt4To5Porting.cmake")
   include_directories(${QT_INCLUDES}) # TODO: Port away from this.
 
+
+  find_library(QTGUI_EGL_LIB EGL
+    PATHS /home/stephen/rpi/rasp-pi-rootfs/opt/vc/lib NO_DEFAULT_PATH)
+  if (QTGUI_EGL_LIB)
+    set_property(TARGET Qt5::Gui APPEND PROPERTY
+      IMPORTED_LINK_DEPENDENT_LIBRARIES_DEBUG "${QTGUI_EGL_LIB}")
+    set_property(TARGET Qt5::Gui APPEND PROPERTY
+    IMPORTED_LINK_DEPENDENT_LIBRARIES_RELEASE "${QTGUI_EGL_LIB}")
+  endif()
+
+  set(CMAKE_EXTRA_SHARED_LIBRARY_SUFFIXES ".so.1")
+  find_library(QTCORE_Z_LIB_1 libz.so.1 PATHS
+    /home/stephen/rpi/rasp-pi-rootfs/lib/arm-linux-gnueabihf/
+    NO_DEFAULT_PATH)
+  find_library(QTCORE_Z_LIB z PATHS
+    /home/stephen/rpi/rasp-pi-rootfs/usr/lib/arm-linux-gnueabihf/
+    NO_DEFAULT_PATH)
+  if (QTCORE_Z_LIB_1 AND QTCORE_Z_LIB)
+    set_property(TARGET Qt5::Core APPEND PROPERTY
+      IMPORTED_LINK_DEPENDENT_LIBRARIES_DEBUG
+        "${QTCORE_Z_LIB}" "${QTCORE_Z_LIB_1}")
+    set_property(TARGET Qt5::Core APPEND PROPERTY
+      IMPORTED_LINK_DEPENDENT_LIBRARIES_RELEASE
+        "${QTCORE_Z_LIB}" "${QTCORE_Z_LIB_1}")
+  endif()


This is working toward a patch to generate the 
IMPORTED_LINK_DEPENDENT_LIBRARIES_* in Qt itself. 

In regular builds of Qt 5, the IMPORTED_LINK_DEPENDENT_LIBRARIES_* does not 
need to be specified because libz and libEGL are usually in standard 
locations, so they don't need to be in -rpath-link specified directories.

However, the Raspberry Pi has libz.so in some funny locations:

 stephen at hal:~/rpi/rasp-pi-rootfs$ find -name "*libz*"
 ./lib/arm-linux-gnueabihf/libz.so.1
 ./lib/arm-linux-gnueabihf/libz.so.1.2.7
 ./usr/lib/arm-linux-gnueabihf/libz.so
 ./usr/lib/arm-linux-gnueabihf/libz.a


 stephen at hal:~/rpi/rasp-pi-rootfs$ ll usr/lib/arm-linux-gnueabihf/libz.*
 -rw-r--r-- 1 stephen stephen 104598 Jun 24  2012 usr/lib/arm-linux-
gnueabihf/libz.a
 lrwxrwxrwx 1 stephen stephen     46 Apr  9 17:03 usr/lib/arm-linux-
gnueabihf/libz.so -> ../../../lib/arm-linux-gnueabihf/libz.so.1.2.7

 stephen at hal:~/rpi/rasp-pi-rootfs$ ll lib/arm-linux-gnueabihf/libz.*
 lrwxrwxrwx 1 stephen stephen    13 Jun 24  2012 lib/arm-linux-
gnueabihf/libz.so.1 -> libz.so.1.2.7
 -rw-r--r-- 1 stephen stephen 87792 Jun 24  2012 lib/arm-linux-
gnueabihf/libz.so.1.2.7


So, the libz.so.1 and libz.so are in different directories.

 stephen at hal:~/rpi/rasp-pi-rootfs/home/stephen/dev/prefix/rpi/lib$ 
~/rpi/gcc-4.7-linaro-rpi-gnueabihf/bin/arm-linux-gnueabihf-ldd --root 
~/rpi/rasp-pi-rootfs/ libQt5Core.so.5.1.0 
         libpthread.so.0 => /lib/arm-linux-gnueabihf/libpthread.so.0 
(0xdeadbeef)
         libc.so.6 => /lib/arm-linux-gnueabihf/libc.so.6 (0xdeadbeef)
         ld-linux-armhf.so.3 => /lib/ld-linux-armhf.so.3 (0xdeadbeef)
         libz.so.1 => /lib/arm-linux-gnueabihf/libz.so.1 (0xdeadbeef)
         libgcc_s.so.1 => /lib/arm-linux-gnueabihf/libgcc_s.so.1 
(0xdeadbeef)
         libdl.so.2 => /lib/arm-linux-gnueabihf/libdl.so.2 (0xdeadbeef)
         librt.so.1 => /lib/arm-linux-gnueabihf/librt.so.1 (0xdeadbeef)
         libstdc++.so.6 => /usr/lib/arm-linux-gnueabihf/libstdc++.so.6 
(0xdeadbeef)
         libm.so.6 => /lib/arm-linux-gnueabihf/libm.so.6 (0xdeadbeef)


The libQt5Core.so links to the libz.so.1 version. So, for some reason I seem 
to need both usr/lib/arm-linux-gnueabihf/ and lib/arm-linux-gnueabihf to 
appear in the -rpath-link. Therefore I'm adding both to the LINK_DEPENDENT 
libraries. The qmake files already add -rpath-link entries for these paths:

 https://qt.gitorious.org/qt/qtbase/blobs/HEAD/mkspecs/devices/linux-rasp-pi-g++/qmake.conf
 https://qt.gitorious.org/qt/qtbase/blobs/HEAD/mkspecs/devices/common/linux_device_post.conf

On the RPi image, these paths are preconfigured:

 rasp-pi-rootfs/etc/ld.so.conf.d$ cat 00-vmcs.conf 
 /opt/vc/lib
 rasp-pi-rootfs/etc/ld.so.conf.d$ cat arm-linux-gnueabihf.conf 
 # Multiarch support
 /lib/arm-linux-gnueabihf
 /usr/lib/arm-linux-gnueabihf


I also need to 

 set(CMAKE_EXTRA_SHARED_LIBRARY_SUFFIXES ".so.1")

to tell CMake that libz.so.1 is a shared library, otherwise it gets ignored.

So, for feedback, it seems like it might make sense to automatically treat 
".so.<number>" as shared libraries for systems which split the libs and 
symlinks like this. 

It seems that if binaries are linked to shared libs with the sonumber 
appended, and libraries without it are in the LINK_DEPENDENT_LIBRARIES, that 
only 'happens' to work because they are usually in the same directory.

Comments?

I also tried other variations of the cmake command before realizing I had to 
join the sysroot path and the install_prefix myself for the 
CMAKE_PREFIX_PATH. My first attempt was like this:

 cmake .. -DCMAKE_PREFIX_PATH=/home/stephen/dev/prefix/rpi/ -
DCMAKE_FIND_ROOT_PATH=/home/stephen/rpi/rasp-pi-rootfs/ -
DCMAKE_TOOLCHAIN_FILE=../rpiToolchain.cmake

which did not work.

 -- The C compiler identification is GNU 4.7.2
 -- The CXX compiler identification is GNU 4.7.2
 -- Check for working C compiler: /home/stephen/rpi/gcc-4.7-linaro-rpi-
gnueabihf/bin/arm-linux-gnueabihf-gcc
 -- Check for working C compiler: /home/stephen/rpi/gcc-4.7-linaro-rpi-
gnueabihf/bin/arm-linux-gnueabihf-gcc -- broken
 CMake Error at /usr/share/cmake-2.8/Modules/CMakeTestCCompiler.cmake:61 
(message):
   The C compiler
   "/home/stephen/rpi/gcc-4.7-linaro-rpi-gnueabihf/bin/arm-linux-gnueabihf-
gcc"
   is not able to compile a simple test program.

   It fails with the following output:

   Change Dir: /home/stephen/dev/src/kdab/gammaray/rpi/CMakeFiles/CMakeTmp

   Run Build Command:/home/stephen/rpi/rasp-pi-rootfs/usr/bin/make
   "cmTryCompileExec1792583416/fast"

   /home/stephen/rpi/rasp-pi-rootfs/usr/bin/make: 1:
   /home/stephen/rpi/rasp-pi-rootfs/usr/bin/make: Syntax error: word
   unexpected (expecting ")")

   CMake will not be able to correctly generate this project.
 Call Stack (most recent call first):
   CMakeLists.txt:17 (project)


The problem is that it is finding make in the sysroot, but it does work if I 
additionally pass:

 -DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM=NEVER

to cmake. Even though CMAKE_FIND_ROOT_PATH_MODE_PROGRAM is set to NEVER in 
my toolchain file, I suppose that is processed to late already to take 
effect for the compiler sanity check. 

Maybe CMake should imply -DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM=NEVER for the 
make tool (and for other tools needed that early in the cmake run).

Comments?

Thanks,

Steve.





More information about the cmake-developers mailing list