Tuesday, November 11, 2014

Cross Compile Qt v5.3.1: Pandaboard ES


I had spent many hours searching on Google to get instructions for cross compiling Qt v5.3.1 open source code for Pandaboard ES, but couldn't find exact instructions. There are instructions available for Raspberry Pi which is also an ARM platform, so it can serve as reference for Pandaboard ES. This link I used as a reference for starting cross compilation.

Following are steps to cross compile Qt source for Pandaboard ES. These steps include configuring Qt for OpenGL ES 2.0 but one will not be able to run application with OpenGL ES. I am still working on identifying root cause for EGL failures and way to find cross compiling applications using OpenGL ES support.

In following steps,
  • "Host machine" refers to your desktop/workstation/laptop machine with x86 / x86_64 processor running Linux OS. I used Ubuntu 14.04 LTS 64-bit OS.
Cross Compilation Steps:

On Target Machine:
  • Do Ubuntu 12.04 LTS installation as mentioned in section 5.2.1 on 4 GB SD Card. Having a 4 GB SD Card is preferred because rootfs will be created by copying entire card, so card with higher capacity will unnecessary occupy storage on host machine.
  • Update Ubuntu:
                sudo apt-get update
                sudo apt-get upgrade
  • Install required software packages:
       sudo apt-get install libfontconfig1-dev libdbus-1-dev libfreetype6-dev libudev-dev libicu-dev libsqlite3-dev libxslt1-dev libssl-dev libasound2-dev libavcodec-dev libavformat-dev libswscale-dev libgstreamer0.10-dev libgstreamer-plugins-base0.10-dev gstreamer-tools gstreamer0.10-plugins-good gstreamer0.10-plugins-bad libgles2-mesa-dev libxcb-icccm4-dev libjpeg-dev libpng12-dev libmysqlclient-dev libsqlite-dev freetds-dev libcups2-dev libpulse-dev libxrender-dev libxi-dev libxcb-xfixes0-dev firebird-dev libpq-dev libxcb-image0-dev libfbembed2.5 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-sync0 libxcb-sync0-dev libxcb-xfixes0-dev libxrender-dev libxcb-shape0-dev libxcb-randr0-dev libxcb-render-util0 libxcb-render-util0-dev libxcb-glx0-dev libxkbcommon libxkbcommon-x11

On Host Machine:
  • Install generic toolchain for ARM.
           [/opt]$ sudo apt-get install arm-linux-gnueabihf

   Above command should install most of the tools required for cross compilation, if not those can be installed using same command with specific tool name.
  • Create an image of Ubuntu 12.04 installation done on Pandaboard ES.
           [/opt]$ sudo dd if=/dev/sdb of=pandaboard-ubuntu12.04-image.img
  • Find offset of root partition on copied image as follow:
           [/opt]$ sudo losetup /dev/loop0 pandaboard-ubuntu12.04-image.img
           [/opt]$ sudo fdisk -l /dev/loop0

       Output of last command will be as follow:

         Device    Boot   Start        End      Blocks   Id   System

/dev/loop0p1      *         32    147455     73712    C    W95 FAT32(LBA)
/dev/loop0p2          147456   7744511  3798528   83   Linux

       From above output, "Start" value for Linux partition /dev/loop0p2 is important for us. Multiply this value with 512 to get offset value to be used for mounting image as rootfs.
  • Mount the image with following command:
  sudo mount -o loop,offset=75497472 /opt/pandaboard-ubuntu12.04-image.img /mnt/pandaboard-ubuntu12.04-rootfs/


      On mounted image, some of the soft links for required libraries are broken as absolute path is used in creating them, so those needs to be fixed. Following simple shell script can be run to fix them.

#! /bin/bash
ROOTFS=/mnt/pandaboard-ubuntu12.04-rootfs/
CROSS_COMPILER_LIB=${ROOTFS}/usr/lib/arm-linux-gnueabihf
cd $CROSS_COMPILER_LIB
BROKEN_LINK=$(find . -type l -xtype l -exec ls -l {} \;|awk '{print $9 "|" $11}')
echo $BROKEN_LINK
for link in $BROKEN_LINK
do
 SOURCE="../../.."
 SOURCE+=$(echo $link |cut -d'|' -f2)
 DESTINATION=$(echo $link |cut -d'|' -f1)
 sudo ln -sf $SOURCE $DESTINATION
done
  • Extract downloaded zip file to a suitable location. In following steps it is assumed that source is extracted under location “/opt/qt-src”.
  • There is no device configuration provided with Qt v5.3.1 source code, hence it needs to be created with help of existing available configuration. This device configuration is platform specific where one specifies processor architecture, tool chain to use for cross compilation and various compiler, linker options.
  • Following are steps to create device configurations required for Pandaboard ES:
    • Go to “/opt/qt-src/qtbase/mkspecs” and copy directory named “linux-arm-gnueabi-g++” and paste it as “linux-arm-gnueabihf-g++”. 
    • Go to directory “linux-arm-gnueabihf-g++” and edit file qmake.conf as shown below. Difference is highlighted with bold text.
#
# qmake configuration for building with arm-linux-gnueabi-g++
#

MAKEFILE_GENERATOR = UNIX
CONFIG += incremental
QMAKE_INCREMENTAL_STYLE = sublib


include(../common/linux.conf)
include(../common/gcc-base-unix.conf)
include(../common/g++-unix.conf)

# modifications to g++.conf

QMAKE_CC = arm-linux-gnueabihf-gcc
QMAKE_CXX = arm-linux-gnueabihf-g++
QMAKE_LINK = arm-linux-gnueabihf-g++
QMAKE_LINK_SHLIB = arm-linux-gnueabihf-g++


# modifications to linux.conf

QMAKE_AR = arm-linux-gnueabihf-ar cqs
QMAKE_OBJCOPY = arm-linux-gnueabihf-objcopy
QMAKE_NM = arm-linux-gnueabihf-nm -P
QMAKE_STRIP = arm-linux-gnueabihf-strip


load(qt_config)
    • Go to "/opt/qt-src/qtbase/mkspecs/devices" and copy directory named “linux-beagleboard-g++” and paste it as “linux-pandaboard-g++”. 
    • Go to directory “linux-pandaboard-g++” and overwrite contents of qmake.conf with following:

# qmake configuration for the PandaBoards

MAKEFILE_GENERATOR = UNIX

#TARGET_PLATFORM = unix
#TEMPLATE = app
#CONFIG += qt warn_on release incremental link_prl gdb_dwarf_index
#QT += core gui

QMAKE_INCREMENTAL_STYLE = sublib

include(../../common/linux.conf)
include(../../common/gcc-base-unix.conf)
include(../../common/g++-unix.conf)

load(device_config)

QT_QPA_DEFAULT_PLATFORM = eglfs

# modifications to g++.conf

QMAKE_CC = ${CROSS_COMPILE}gcc
QMAKE_CXX = ${CROSS_COMPILE}g++
QMAKE_LINK = ${QMAKE_CXX}
QMAKE_LINK_SHLIB = ${QMAKE_CXX}

# modifications to linux.conf

QMAKE_AR = ${CROSS_COMPILE}ar cqs
QMAKE_OBJCOPY = ${CROSS_COMPILE}objcopy
QMAKE_STRIP = ${CROSS_COMPILE}strip
QMAKE_INCDIR += $[QT_SYSROOT]/usr/include/mysql \
                           $[QT_SYSROOT]/usr/include/postgresql/ \
                           $[QT_SYSROOT]/usr/include/c++/4.6/ \
                           $[QT_SYSROOT]/usr/include/c++/4.6/ext/ \
                           $[QT_SYSROOT]/usr/include/c++/4.6/arm-linux-gnueabihf/ \
                           $[QT_SYSROOT]/usr/include/c++/4.6/arm-linux-gnueabihf/bits \
                           $[QT_SYSROOT]/usr/include/c++/4.6/arm-linux-gnueabihf/sf/ \
                           $[QT_SYSROOT]/usr/include/c++/4.6/arm-linux-gnueabihf/sf/bits/

COMPILER_FLAGS = -march=armv7-a -mtune=cortex-a9 -mfpu=neon -mfloat-abi=hard

#modifications to gcc-base.conf

QMAKE_CFLAGS += ${COMPILER_FLAGS}
QMAKE_CXXFLAGS += ${COMPILER_FLAGS}
QMAKE_CXXFLAGS_RELEASE += -O2

QMAKE_LIBS += -lrt -lpthread -ldl
QMAKE_INCDIR_EGL = $[QT_SYSROOT]/usr/include
QMAKE_LIBDIR_EGL = $[QT_SYSROOT]/usr/lib
QMAKE_INCDIR_OPENGL_ES2 = ${QMAKE_INCDIR_EGL}
QMAKE_LIBDIR_OPENGL_ES2 = ${QMAKE_LIBDIR_EGL}

#QMAKE_INCDIR_OPENVG = ${QMAKE_INCDIR_EGL}
#QMAKE_LIBDIR_OPENVG = ${QMAKE_LIBDIR_EGL}
#QMAKE_LIBS_EGL = -lEGL -lIMGegl -lsrv_um

QMAKE_LIBS_EGL = -lEGL
QMAKE_LIBS_OPENGL_ES2 = -lGLESv2 ${QMAKE_LIBS_EGL}

#QMAKE_LIBS_OPENVG = -lOpenVG ${QMAKE_LIBS_EGL}

QMAKE_LFLAGS += -Wl,-rpath-link,$[QT_SYSROOT]/usr/lib/pvr-omap4-egl \
      -Wl,-rpath-link,$[QT_SYSROOT]/usr/lib/arm-linux-gnueabihf \
      -Wl,-rpath-link,$[QT_SYSROOT]/lib/arm-linux-gnueabihf \
      -Wl,-rpath-link,$[QT_SYSROOT]/usr/lib/arm-linux-gnueabihf/4.6 \
      -Wl,-rpath-link,/usr/lib/gcc/arm-linux-gnueabihf/4.6 \
      -Wl,-rpath-link,/usr/lib/gcc/arm-linux-gnueabihf/4.6/sf

# Sanity check

deviceSanityCheckCompiler()

load(qt_config)

  • Configure Qt source with rootfs location, toolchain path and various other options as follow:
         ./configure -v -release -opengl es2 -opensource -optimized-qmake -qpa xcb -confirm-license -sysroot /mnt/pandaboard-ubuntu12.04-rootfs -device linux-pandaboard-g++ -device-option CROSS_COMPILE=/usr/bin/arm-linux-gnueabihf- -prefix /usr/local/Qt5.3-pandaboard
  • Once configuration is successfully finished, start compilation process with command “make –j4”. Here –jN option specifies how many compilation processes to start in parallel. This option basically speeds up the compilation process.
  • After compilation is successfully over, Qt libraries are compiled for target machine i.e. for Pandaboard ES. These libraries can be installed using following command:
         sudo make install

This command will install cross compiled libraries on rootfs at location "/mnt/pandaboard-ubuntu-12.04-rootfs/usr/local/Qt5.3-pandaboard".

Once cross compilation is over, write back updated image to 4GB SD card and boot from this card or copy entire "/mnt/pandaboard-ubuntu-12.04-rootfs/usr/local/Qt5.3-pandaboard" directory to other SD card having ubuntu installation.

No comments:

Post a Comment