cross-compile Qt for beaglebone black

cross-compile Qt 6 for BBB. Compiled example returns errors:
./gui_analogclock: /lib/arm-linux-gnueabihf/libc.so.6: version GLIBC_2.34' not found (required by ./gui_analogclock) ./gui_analogclock: /lib/arm-linux-gnueabihf/libm.so.6: version GLIBC_2.35’ not found (required by /usr/local/qt6/lib/libQt6Gui.so.6)
Here’s my procedure:
create cross-compile of Qt for BeagleBone Black

ref: QT6 Cross Compilation for Beaglebone Black | Qt Forum

ref: Cross-Compile Qt 6 for Raspberry Pi - Qt Wiki

host is Ubuntu 22.04.02 running on virtual box 7.0

on host

cd ~

mkdir bbb-sysroot bbb-sysroot/usr bbb-sysroot/opt

mkdir qt-host qt-bbb qt-hostbuild qtbbb-build

on beaglebone black, the target

install the package dependencies

sudo apt-get install libboost-all-dev libudev-dev libinput-dev libts-dev libmtdev-dev libjpeg-dev libfontconfig1-dev libssl-dev libdbus-1-dev libglib2.0-dev libxkbcommon-dev libegl1-mesa-dev libgbm-dev libgles2-mesa-dev mesa-common-dev libasound2-dev libpulse-dev gstreamer1.0-omx libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev gstreamer1.0-alsa libvpx-dev libsrtp2-dev libsnappy-dev libnss3-dev “^libxcb.*” flex bison libxslt-dev ruby gperf libbz2-dev libcups2-dev libatkmm-1.6-dev libxi6 libxcomposite1 libfreetype6-dev libicu-dev libsqlite3-dev libxslt1-dev

sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev libx11-dev freetds-dev libpq-dev libiodbc2-dev firebird-dev libgst-dev libxext-dev libxcb1 libxcb1-dev libx11-xcb1 libx11-xcb-dev libxcb-keysyms1 libxcb-keysyms1-dev libxcb-image0 libxcb-image0-dev libxcb-shm0 libxcb-shm0-dev libxcb-icccm4 libxcb-icccm4-dev libxcb-sync1 libxcb-sync-dev libxcb-render-util0 libxcb-render-util0-dev libxcb-xfixes0-dev libxrender-dev libxcb-shape0-dev libxcb-randr0-dev libxcb-glx0-dev libxi-dev libdrm-dev libxcb-xinerama0 libxcb-xinerama0-dev libatspi2.0-dev libxcursor-dev libxcomposite-dev libxdamage-dev libxss-dev libxtst-dev libpci-dev libcap-dev libxrandr-dev libdirectfb-dev libaudio-dev libxkbcommon-x11-dev

sudo mkdir /usr/local/qt6

on host

install dependencies

sudo apt-get install make cmake build-essential libclang-dev clang ninja-build gcc git bison python3 gperf pkg-config libfontconfig1-dev libfreetype6-dev libx11-dev libx11-xcb-dev libxext-dev libxfixes-dev libxi-dev libxrender-dev libxcb1-dev libxcb-glx0-dev libxcb-keysyms1-dev libxcb-image0-dev libxcb-shm0-dev libxcb-icccm4-dev libxcb-sync-dev libxcb-xfixes0-dev libxcb-shape0-dev libxcb-randr0-dev libxcb-render-util0-dev libxcb-util-dev libxcb-xinerama0-dev libxcb-xkb-dev libxkbcommon-dev libxkbcommon-x11-dev libatspi2.0-dev libgl1-mesa-dev libglu1-mesa-dev freeglut3-dev

install cross-compiler

sudo apt-get install crossbuild-essential-armhf

get linaro toolchain for linaro.org

gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf

extract

add path to bin folder to bottom ./bashrc file

PATH=$PATH:/home/ram/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf/bin

sudo apt install rsync

rsync -avzS --rsync-path=“rsync” --delete debian@192.168.1.23:/lib/* bbb-sysroot/lib

rsync -avzS --rsync-path=“rsync” --delete debian@192.168.1.23:/usr/include/* bbb-sysroot/usr/include

rsync -avzS --rsync-path=“rsync” --delete debian@192.168.1.23:/usr/lib/* bbb-sysroot/usr/lib

sudo apt install symlinks

cd ~

symlinks -rc bbb-sysroot

building Qt6

first build for host

cd ~

git clone "https://codereview.qt-project.org/qt/qt5

cd qt5

git checkout 6.4.0

perl init-repository -f --module-subset=default,-qtwebengine

cd …

mkdir $HOME/qt-hostbuild

cd $HOME/qt-hostbuild

cmake …/qt5/ -GNinja -DCMAKE-BUILD_TYPE=Release -DQT_BUILD_EXAMPLES=OFF -DQT_BUILD_TESTS=OFF -DCMAKE_INSTALL_PREFIX=$HOME/qt-host

cmake --build . --parallel

cmake --install .

build Qt 6 for BBB

cd ~

nano toolchain.cmake

reference Cross-Compile Qt 6 for Raspberry Pi - Qt Wiki

cmake_minimum_required(VERSION 3.18)

include_guard(GLOBAL)

set(CMAKE_SYSTEM_NAME Linux)

set(CMAKE_SYSTEM_PROCESSOR arm)

#set(TARGET_SYSROOT /path/to/your/sysroot)

set(TARGET_SYSROOT $HOME/bbb_sysroot)

set(CMAKE_SYSROOT ${TARGET_SYSROOT})

set(ENV{PKG_CONFIG_PATH} $PKG_CONFIG_PATH:/usr/lib/pkgconfig)

set(ENV{PKG_CONFIG_LIBDIR} /usr/lib/pkgconfig:/usr/share/pkgconfig/:${TARGET_SYSROOT}/usr/lib/arm-linux-gnueabihf/pkgconfig:${TARGET_SYSROOT}/usr/lib/pkgconfig)

set(ENV{PKG_CONFIG_SYSROOT_DIR} ${CMAKE_SYSROOT})

if you use other version of gcc and g++ than gcc/g++ 9, you must change the following variables

#set(CMAKE_C_COMPILER /usr/bin/aarch64-linux-gnu-gcc-9)

set(CMAKE_C_COMPILER /usr/bin/arm-linux-gnueabihf-gcc)

#set(CMAKE_CXX_COMPILER /usr/bin/aarch64-linux-gnu-g+±9)

set(CMAKE_CXX_COMPILER /usr/bin/arm-linux-gnueabihf-g++)

set(CMAKE_C_FLAGS “${CMAKE_C_FLAGS} -I${TARGET_SYSROOT}/usr/include”)

#set(CMAKE_C_FLAGS “${CMAKE_C_FLAGS} -I${TARGET_SYSROOT}/usr/include -static”)

set(CMAKE_CXX_FLAGS “${CMAKE_C_FLAGS}”)

set(QT_COMPILER_FLAGS “-march=armv7-a -mfpu=neon -mfloat-abi=hard”)

#set(QT_COMPILER_FLAGS “-march=armv7-a -mfpu=neon -mfloat-abi=hard -static”)

set(QT_COMPILER_FLAGS_RELEASE “-O2 -pipe”)

set(QT_LINKER_FLAGS “-Wl,-O1 -Wl,–hash-style=gnu -Wl,–as-needed”)

set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)

set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)

set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

#set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)

set(CMAKE_BUILD_RPATH ${TARGET_SYSROOT})

include(CMakeInitializeConfigs)

function(cmake_initialize_per_config_variable _PREFIX _DOCSTRING)

if (PREFIX MATCHES "CMAKE(C|CXX|ASM)_FLAGS")

set(CMAKE_${CMAKE_MATCH_1}_FLAGS_INIT “${QT_COMPILER_FLAGS}”)

foreach (config DEBUG RELEASE MINSIZEREL RELWITHDEBINFO)

if (DEFINED QT_COMPILER_FLAGS_${config})

set(CMAKE_${CMAKE_MATCH_1}FLAGS${config}INIT "${QT_COMPILER_FLAGS${config}}")

endif()

endforeach()

endif()

if (PREFIX MATCHES "CMAKE(SHARED|MODULE|EXE)_LINKER_FLAGS")

foreach (config SHARED MODULE EXE)

set(CMAKE_${config}_LINKER_FLAGS_INIT “${QT_LINKER_FLAGS}”)

endforeach()

endif()

_cmake_initialize_per_config_variable(${ARGV})

endfunction()

#set(XCB_PATH_VARIABLE ${TARGET_SYSROOT})

#set(GL_INC_DIR ${TARGET_SYSROOT}/usr/include)

#set(GL_LIB_DIR ${TARGET_SYSROOT}:${TARGET_SYSROOT}/usr/lib/aarch64-linux-gnu/:${TARGET_SYSROOT}/usr:${TARGET_SYSROOT}/usr/lib)

#set(EGL_INCLUDE_DIR ${GL_INC_DIR})

#set(EGL_LIBRARY ${XCB_PATH_VARIABLE}/usr/lib/aarch64-linux-gnu/libEGL.so)

#set(OPENGL_INCLUDE_DIR ${GL_INC_DIR})

#set(OPENGL_opengl_LIBRARY ${XCB_PATH_VARIABLE}/usr/lib/aarch64-linux-gnu/libOpenGL.so)

#set(GLESv2_INCLUDE_DIR ${GL_INC_DIR})

#set(GLESv2_LIBRARY ${XCB_PATH_VARIABLE}/usr/lib/aarch64-linux-gnu/libGLESv2.so)

#set(gbm_INCLUDE_DIR ${GL_INC_DIR})

#set(gbm_LIBRARY ${XCB_PATH_VARIABLE}/usr/lib/aarch64-linux-gnu/libgbm.so)

#set(Libdrm_INCLUDE_DIR ${GL_INC_DIR})

#set(Libdrm_LIBRARY ${XCB_PATH_VARIABLE}/usr/lib/aarch64-linux-gnu/libdrm.so)

#set(XCB_XCB_INCLUDE_DIR ${GL_INC_DIR})

#set(XCB_XCB_LIBRARY ${XCB_PATH_VARIABLE}/usr/lib/aarch64-linux-gnu/libxcb.so)

cd ~qtbbb-build

…/qt5/configure -release -no-opengl -nomake examples -nomake tests -qt-host-path $HOME/qt-host -extprefix $HOME/qt-bbb -prefix /usr/local/qt6 -device linux-beagleboard-g++ -device-option CROSS-COMPILE=arm-linux-gnueabihf- – -DCMAKE_TOOLCHAIN_FILE=$HOME/toolchain.cmake

cmake --build . --parallel

cmake --install .

Qt will be installed at ~/qt-bbb on Host and at /usr/local/qt6 on BBB

so to copy from ~/qt-bbb(on host) to /usr/local/qt6 on BBB

first copy to ~/qt6 on BBB

cd ~/qt-bbb

scp -r * debian@192.168.1.23:/home/debian/qt6

then on BBB: mv qt6 /usr/local/

set environment variables (eventually add to ./bashrc)

ssh debian@192.168.1.xx

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/qt6/lib/

export DISPLAY=:0

Compile and run Qt project

cd ~/qt5/qtbase/examples/gui/analogclock/

~/qt-bbb/bin/qt-cmake CMakeLists.txt

cmake --build . --parallel

cmake --install .

scp -r gui_analogclock debain@192.168.1.xx:/home/debian

ssh debain@192.168.1.xx

./gui_analogclock

errors:

debian@BeagleBone:~$ ./gui_analogclock

./gui_analogclock: /lib/arm-linux-gnueabihf/libc.so.6: version `GLIBC_2.34’ not found (required by ./gui_analogclock)

./gui_analogclock: /lib/arm-linux-gnueabihf/libm.so.6: version `GLIBC_2.35’ not found (required by /usr/local/qt6/lib/libQt6Gui.so.6)

./gui_analogclock: /usr/lib/arm-linux-gnueabihf/libstdc++.so.6: version `GLIBCXX_3.4.29’ not found (required by /usr/local/qt6/lib/libQt6Gui.so.6)

./gui_analogclock: /lib/arm-linux-gnueabihf/libc.so.6: version `GLIBC_2.33’ not found (required by /usr/local/qt6/lib/libQt6Gui.so.6)

./gui_analogclock: /lib/arm-linux-gnueabihf/libc.so.6: version `GLIBC_2.32’ not foun

Not sure why CC is needed, it is much simpler to build it natively. CC is a throw back from the days of “vacuum tubes”. The little boards are fast, the BBB is a little light on CPU’s however we do not use any graphics packages on it. All you need is ssh and you don’t even realize you are doing a native build, it is slower than on the host. However, its hassle free.

I, for one, would love to know how to setup a system for cross compiling a Qt app for the BeagleBone Black.

I have a Qt 5 app that can run in Windows or on a BBB with a 7" touchscreen.

The Windows build take a couple minutes to build.

The native build on the BBB takes about 3 hours.

1 Like

That is a long time, most certainly need to cc that one.

Quite a lot going on there, Cross compiling can be a pain. My guess is at some point when compiling the example, the compiler is not using the sysroot you created, but the sysroot that came with the compiler.

I know that the linaro compilers have the sysroot hard coded to default to the compiler install location. I assume that this can be overridden, but have never tried.

First try running ldd on the BBB on some of the qt6 libraries you have built to see what libraries they require. This will at least tell you if your cross compiled qt6 is correct

Also then use the same on the example to check what it needs.

Many years ago I used buildroot to generate a BBB image and cross compiler, including Qt, then used QT creator on my build machine to compile and debug. That worked very well for me and was not that hard to get up and running, probably less than a day to get the BBB image going. Will have to try building it again to see if it is still an easy thing to do.

some time back i played with Qt cross compiling
maybe this can provide some in site.
http://doc.qt.io/qt-4.8/qt-embedded-crosscompiling.html
http://doc.qt.io/qt-6.0

That’s the main reason I made it also work for Windows.

I can make changes to the code and quickly test them in Windows. Once I get everything looking good I do the painfully slow native build on the BBB.

1 Like

./gui_analogclock: /lib/arm-linux-gnueabihf/libc.so.6: version `GLIBC_2.32’ not foun

what version is your real libc.so.6 ??

file /lib/arm-linux-gnueabihf/libc.so.6
/lib/arm-linux-gnueabihf/libc.so.6: symbolic link to libc-2.31.so

this is not cross compiling the app, it does run on the host

I have not yet tried this, it should run on bbb even if you compile it on a imx6ul, that is 32 bit soc and I build gtk and fltk on it. Its not like nvme on ubuntu but it is not that slow. That would get you a binary fairly quickly without all the headaches of CC. This works in my mind, it seems possible.

I think the issue with that is getting the underlying libraries synced between the BBB and the imx6ul.

Years ago I picked up a Wandboard with the thought of doing something like what you suggest. If I remember correctly, I could get a very simple “Hello World” to compile on it and run on the BBB. But anything more complex ran into issues of some sort. Either missing libraries or some incompatible issue.

I still have the Wandboard but have not used it in years…

It does not run on my host. See below:
ram@ram-VirtualBox:~/qt5/qtbase/examples/gui/analogclock$ ./gui_analogclock
bash: ./gui_analogclock: cannot execute binary file: Exec format error

Don’t have that board we are using SoM with 6ul core. If they have a debian OS for that board you should be able to install the same packages as the host has. If memory is correct the 6ul’s bsp is in the 6.x range so they are keeping it up. Might be worth another look.

If you can do hello world it will work, its just a matter of getting your cmake to link everything. GTK3 is working good with touchscreen, just found one widget that did not work with touch and it was some radio buttons, mouse click was fine but no touch. Just replaced them with buttons. That is the only package I have been able to use on all the targets except bbb.

yup, his instructions has it compiled for the host.
will spend some more time today after yard work is done. LOL

1 Like

debian@BeagleBone:~$ ldd gui_analogclock
./gui_analogclock: /lib/arm-linux-gnueabihf/libc.so.6: version `GLIBC_2.34’ not found (required by ./gui_analogclock)
linux-vdso.so.1 (0xbed62000)
libQt6Gui.so.6 => not found
libQt6Core.so.6 => not found
libstdc++.so.6 => /usr/lib/arm-linux-gnueabihf/libstdc++.so.6 (0xb6dc1000)
libgcc_s.so.1 => /lib/arm-linux-gnueabihf/libgcc_s.so.1 (0xb6d98000)
libc.so.6 => /lib/arm-linux-gnueabihf/libc.so.6 (0xb6c99000)
/lib/ld-linux-armhf.so.3 (0xb6f23000)
libm.so.6 => /lib/arm-linux-gnueabihf/libm.so.6 (0xb6c31000)

Thanks for your input

find: ‘file’: No such file or directory
find: ‘libQt6Gui.so.6’: No such file or directory
debian@BeagleBone:/usr/local/qt6/bin$ find / file “libQt6Gui.so.6”

the file listed as a dependency does not exist on the BBB. So, I will try to find out why.

not all of the files had been copied to the BBB. After correcting that, it is again not able to find GLIBC_ versions. For a non-Qt C++ compile I can correct this by adding ‘-static’ flag; but, my attempts to add that to the toolchain.cmake have not worked.

debian@BeagleBone:~$ ldd /usr/local/qt6/lib/libQt6Gui.so.6
/usr/local/qt6/lib/libQt6Gui.so.6: /lib/arm-linux-gnueabihf/libm.so.6: version GLIBC_2.35' not found (required by /usr/local/qt6/lib/libQt6Gui.so.6) /usr/local/qt6/lib/libQt6Gui.so.6: /usr/lib/arm-linux-gnueabihf/libstdc++.so.6: version GLIBCXX_3.4.29’ not found (required by /usr/local/qt6/lib/libQt6Gui.so.6)
/usr/local/qt6/lib/libQt6Gui.so.6: /lib/arm-linux-gnueabihf/libc.so.6: version GLIBC_2.33' not found (required by /usr/local/qt6/lib/libQt6Gui.so.6) /usr/local/qt6/lib/libQt6Gui.so.6: /lib/arm-linux-gnueabihf/libc.so.6: version GLIBC_2.32’ not found (required by /usr/local/qt6/lib/libQt6Gui.so.6)
/usr/local/qt6/lib/libQt6Gui.so.6: /lib/arm-linux-gnueabihf/libm.so.6: version GLIBC_2.35' not found (required by /usr/local/qt6/lib/libQt6Core.so.6) /usr/local/qt6/lib/libQt6Gui.so.6: /usr/lib/arm-linux-gnueabihf/libstdc++.so.6: version GLIBCXX_3.4.29’ not found (required by /usr/local/qt6/lib/libQt6Core.so.6)
/usr/local/qt6/lib/libQt6Gui.so.6: /usr/lib/arm-linux-gnueabihf/libstdc++.so.6: version GLIBCXX_3.4.30' not found (required by /usr/local/qt6/lib/libQt6Core.so.6) /usr/local/qt6/lib/libQt6Gui.so.6: /usr/lib/arm-linux-gnueabihf/libstdc++.so.6: version CXXABI_1.3.13’ not found (required by /usr/local/qt6/lib/libQt6Core.so.6)
/usr/local/qt6/lib/libQt6Gui.so.6: /lib/arm-linux-gnueabihf/libc.so.6: version GLIBC_2.32' not found (required by /usr/local/qt6/lib/libQt6Core.so.6) /usr/local/qt6/lib/libQt6Gui.so.6: /lib/arm-linux-gnueabihf/libc.so.6: version GLIBC_2.33’ not found (required by /usr/local/qt6/lib/libQt6Core.so.6)
/usr/local/qt6/lib/libQt6Gui.so.6: /lib/arm-linux-gnueabihf/libc.so.6: version `GLIBC_2.34’ not found (required by /usr/local/qt6/lib/libQt6Core.so.6)
linux-vdso.so.1 (0xbecaf000)
libQt6DBus.so.6 => /usr/local/qt6/lib/libQt6DBus.so.6 (0xb694e000)
libQt6Core.so.6 => /usr/local/qt6/lib/libQt6Core.so.6 (0xb649f000)
libstdc++.so.6 => /usr/lib/arm-linux-gnueabihf/libstdc++.so.6 (0xb6353000)
libm.so.6 => /lib/arm-linux-gnueabihf/libm.so.6 (0xb62eb000)
libgcc_s.so.1 => /lib/arm-linux-gnueabihf/libgcc_s.so.1 (0xb62c2000)
libc.so.6 => /lib/arm-linux-gnueabihf/libc.so.6 (0xb61c3000)
/lib/ld-linux-armhf.so.3 (0xb6f95000)

This should be:
debian@BeagleBone:/usr/local/qt6/bin$ find / -name “libQt6Gui.so.6”

The example was cross compiled for arm and not the host (x86). If it had been compiled for x86, when running on the BBB it would have complained about not being an arm executable. The fact that it complains about the libc library at least indicates that it has been cross compiled for arm.

This tells me your cross compile of Qt has not worked correctly. Sorry to say without spending a lot of time and trying the same process I can’t say what exactly the problem is. Probably something somewhere in the build process is not using your sysroot, but the sysroot that comes with the Linaro compiler. When compiling the source, I expect it is using your sysroot otherwise there would be missing include files. The problem is with the linking of the object files.

You could try getting hold of an older version of the Linaro compiler that more closely matches the Debian version on the BBB, at least has the same version of glibc.

There is also the Buildroot/Yocto path and create your own image and cross compiler and depending on your dependencies may give other problems.