Cross-compile Qt and development of applications for VIM3

In order to run qt applications on khadas VIM3 using cross compile and qtcreator on Linux host, Four main steps are required:
Step-1: Prepare Khadas vim3 board
Step-2: Prepare Host PC
Step-3: Build qt libraries on host PC and transfer them to khadas vim3 board
Step-4: Prepare and setup qtcreator on host machine

Step-1: Prepare Khadas vim3 board

(1) Download image VIM3_Ubuntu-xfce-bionic_Linux-4.9_arm64_EMMC_V20191231 and install to eMMC using USB-C cable as described in:

(2) Prepare Khadas board for development:
Note: if Error is encountered: You must put some ‘source’ URIs in your sources.list
Then enable source from “software update” options

sudo apt-get update
sudo apt upgrade
reboot

In order to run Qt applications, you need to remove the current GPU packge which is for fbdev not for X11 and install other GPU drivers:

sudo apt-get remove linux-gpu-mali-fbdev
sudo apt-get install --reinstall libegl1-mesa libegl1 libgles2 libgles2-mesa libegl1-mesa-dev libgles2-mesa-dev libglvnd-dev libgles1 libwayland-dev mesa-common-dev

Install required libraries:

sudo apt-get build-dep qt5-default qt5-qmake
sudo apt-get install libiconv-hook-dev libinput-dev libts-dev bluez libbluetooth-dev libgstreamer1.0-dev 
sudo apt-get install "^libxcb.*" libx11-xcb-dev libglu1-mesa-dev libxrender-dev

Also these are required by webengine:

sudo apt-get install libnss3-dev
sudo apt-get install bison build-essential gperf flex ruby python libasound2-dev libbz2-dev libcap-dev \
libcups2-dev libdrm-dev libgcrypt11-dev libpci-dev libpulse-dev libudev-dev \
libxtst-dev gyp ninja-build

sudo apt-get install libssl-dev libxcursor-dev libxcomposite-dev libxdamage-dev libxrandr-dev \
libfontconfig1-dev libxss-dev libsrtp0-dev libwebp-dev libjsoncpp-dev libopus-dev libminizip-dev \
libavutil-dev libavformat-dev libavcodec-dev libevent-dev

Step-2: Prepare Host PC
On host PC you need at least 16GB RAM if qtwebengine is to be built with 30GB hard disk free space and at least 2GB swap
(1) Create directory to clone khadas rootfs

mkdir $HOME/vim
mkdir $HOME/vim/rootfs

(2) On Host PC, Copy required folders from target to host computer rootfs folder sing rsync:
Note: the ip address of khadas board is 192.168.0.109, use your own device ip

rsync -avz -e ssh khadas@192.168.0.109:/lib --relative $HOME/vim/rootfs
rsync -avz -e ssh khadas@192.168.0.109:/usr --relative $HOME/vim/rootfs

Fix symbolic links

git clone https://github.com/alpqr/fixsymlinks_tx1 $HOME/vim/fixsymlinks
chmod +x $HOME/vim/fixsymlinks/fixsymlinks.sh
$HOME/vim/fixsymlinks/fixsymlinks.sh $HOME/vim/rootfs

(3) On Host PC, download Linaro toolchain:
Note: Sometimes compiler version and date are updated, so check the latest from Linaro website

wget -P /tmp "https://releases.linaro.org/components/toolchain/binaries/latest-7/aarch64-linux-gnu/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu.tar.xz"
tar -xvf /tmp/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu.tar.xz -C $HOME/vim/

(4) on Host PC, download qt-everywhere 5.12:

wget -P /tmp "https://download.qt.io/archive/qt/5.12/5.12.6/single/qt-everywhere-src-5.12.6.tar.xz" 

Unpack the archive:

tar -xvf /tmp/qt-everywhere-src-5.12.6.tar.xz -C $HOME/

(5) Create file for our amlogic A311D inside $HOME/qt-everywhere-src-5.12.6/qtbase/mkspecs/devices/
I copied directory linux-jetson-tx1-g++ (aarch64) inside /home/ggg/qt-everywhere-src-5.12.6/qtbase/mkspecs/devices
into linux-amlogica311d-g++
and modifed qmake.conf to be as follows:

include(../common/linux_device_pre.conf)

QMAKE_CXXFLAGS += -std=gnu++11
QMAKE_CFLAGS_ISYSTEM=-I

QMAKE_INCDIR_POST += \
    $$[QT_SYSROOT]/usr/include \
    $$[QT_SYSROOT]/usr/include/aarch64-linux-gnu

QMAKE_LIBDIR_POST += \
    $$[QT_SYSROOT]/usr/lib \
    $$[QT_SYSROOT]/lib/aarch64-linux-gnu \
    $$[QT_SYSROOT]/usr/lib/aarch64-linux-gnu

QMAKE_RPATHLINKDIR_POST += \
    $$[QT_SYSROOT]/usr/lib \
    $$[QT_SYSROOT]/usr/lib/aarch64-linux-gnu \    
    $$[QT_SYSROOT]/lib/aarch64-linux-gnu

DISTRO_OPTS += aarch64
COMPILER_FLAGS += -mtune=cortex-a73.cortex-a53 -march=armv8-a

# When configured with -opengl es2, eglfs will be functional with its
# dummy fullscreen X11 backend, in addition to xcb.
EGLFS_DEVICE_INTEGRATION = eglfs_x11

include(../common/linux_arm_device_post.conf)
load(qt_config)

(6) Fix stlib.h compiler problem, which throws the following errors:
ERROR: Qt requires a compliant STL library
ERROR: C++11 is required and is missing or failed to compile

This occurs throughout Qt in late versions when complied with newer compilers.
The way to fix it is to edit $HOME/qt-everywhere-src-5.12.6/qtbase/mkspecs/common/gcc-base.conf

Change QMAKE_CFLAGS_ISYSTEM = -isystem
to QMAKE_CFLAGS_ISYSTEM = -I (capital i)

Also, make sure to use the following two lines in the qmake.conf of the device:

QMAKE_CXXFLAGS += -std=gnu++11
QMAKE_CFLAGS_ISYSTEM=-I

Step-3: Build qt libraries on host PC and transfer them to khadas vim3 board
Go to qt-everywhere folder

cd  $HOME/qt-everywhere-src-5.12.6
mkdir qt5vim
cd qt5vim

Configure the build:
If qtwebengine is not required, use the following configuration:

$HOME/qt-everywhere-src-5.12.6/configure -shared -c++std c++14 -v \
-opensource -release --confirm-license -opengl es2 -xcb -eglfs -qpa xcb \
-device linux-amlogica311d-g++ \
-device-option CROSS_COMPILE=$HOME/vim/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu- \
-sysroot $HOME/vim/rootfs \
-nomake examples -nomake tests \
-prefix /usr/local/qt5 \
-extprefix $HOME/vim/qt5 \
-hostprefix $HOME/vim/qt5 \
-skip qtandroidextras -skip qtcharts -skip qtdeclarative -skip qtdoc -skip qtgamepad -skip qtlocation -skip qtwayland -skip qtwebengine

another configuration to enable qtwebengine:

$HOME/qt-everywhere-src-5.12.6/configure -shared -c++std c++14 -v \
-opensource -release --confirm-license -opengl es2 -xcb -eglfs -qpa xcb \
-device linux-amlogica311d-g++ \
-device-option CROSS_COMPILE=$HOME/vim/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu- \
-sysroot $HOME/vim/rootfs \
-nomake examples -nomake tests \
-prefix /usr/local/qt5 \
-extprefix $HOME/vim/qt5 \
-hostprefix $HOME/vim/qt5 \
-skip qtwayland \
-no-webengine-pepper-plugins -no-webengine-geolocation -no-webengine-spellchecker \
-no-webengine-webrtc -no-webengine-pulseaudio 

Build and install:
Note: compiler will try to link with existing libQt5* in folder $HOME/vim/rootfs/usr/lib/aarch64-linux-gnu so remove all libQt5* files from this folder
using file explorer nautilus, search for libQt5* and delete them or use:

rm $HOME/vim/rootfs/usr/lib/aarch64-linux-gnu/libQt5*
make -j2
make install

Note: if ninja build failed during qtwebengine compilation this could be due to out of memory problem, reboot the machine, then resume with: make -j2
Also leave only terminal working, close all other programs in host Linux. DO NOT use jN with large number of cpus since it may cause out of memory problem.

if the compilation succeeded, transfer the generated $HOME/vim/qt5 to the target device in order to enable qt application running;
Clone qt5 to khadas board, on Host PC issue the command:

rsync -avz -e ssh $HOME/vim/qt5  khadas@192.168.0.109:/home/khadas

Then on Khadas board, sudo move into usr/local

sudo mv /home/khadas/qt5 /usr/local/qt5

Step-4: Install and Prepare qtcreator on host machine

sudo apt-get install qtcreator

Run Qt Creator
Note: if some General Messages errors appear during project creation or opening, neglect them and ReBuild Project, they will disappear.

  1. From Tools->Options->Devices, Add Generic linux device with ip address 192.168.0.109 (or use your device ip) and set username and password
  2. From Tools->Options->Build and Run->Compilers, Add GCC C compiler: /home/ggg/vim/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-gcc
  3. Tools->Options->Build and Run->Compilers, Add GCC C++ Compiler: /home/ggg/vim/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-g++
  4. Tools->Options->Build and Run->Debuggers, Add debugger: /home/ggg/vim/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-gdb
  5. Tools->Options->Build and Run->Qt versions, add: /home/ggg/vim/qt5/bin/qmake (same as -hostprefix)
  6. Tools->Options->Build and Run->Kit, add new kit and set its sysroot to: /home/username/vim/rootfs
  7. Set the new kit device, C compiler, C++ compiler, Debugger as defined in above steps

** Important: Also add the following Run Environmental Variables to your Qt projects
Open or create a project, from the left side toolbar, click on Projects, Select the required kit and then Run settings
Scroll down to Run Environemnt, click Details->Batch Edit and add the following lines:
DISPLAY =:0
XAUTHORITY =/home/khadas/.Xauthority

Note: Do not forget to add the following lines to your .pro file:

target.path += /home/khadas
INSTALLS += target

Happy Qt-ing

4 Likes

well done @jaferali75,
good tutorial, I suggest publishing this on github or such, so it doesn’t get lost under the multiple forum threads,

p.s mainline kernel for VIM3, uses the new upstreamed panfrost drivers, and hence mesa-devel is already being used,

perhaps you also have a guide for GTK perhaps ? :slight_smile:

cheers!

1 Like

Thanks @Electr1,
The procedure should be the same for other kernels, I tested 5.7-rc7 provided by khadas but there were some issues regarding suspend/resume which is essential for me.
May be need some effort from maintainers or khadas team to overcome suspend/resume problem because the new kernel has many fixes and improvements.
I’m a big fan of Qt development and never tested GTK before
Thank you for your suggestion.

1 Like

@jaferali75

In official document QT at the page:

The default QT packages from Ubuntu official are built with OpenGL Desktop support, but for VIMs, there don’t have Mali GPU driver under X11, so you can’t use QT with GPU.

In order to use QT with GPU (fbdev), we have rebuilt the QT packages with eglfs Mali GPU support, this documentation will describe how to use QT5 with eglfs Mali GPU (fbdev) under Ubuntu.

If I setup cross-compile environment then I can run an application Qt with eglfs Mali GPU support (no need to switch to framebuffer console mode) ?