QT5.9.8版本在海思3521平台上的移植

date
Sep 15, 2020
slug
2020-09-15-hi3521-QT-porting
status
Published
tags
QT
海思
summary
本文总结了在海思3521平台上移植QT5.9.8版本的完整流程,移植完成后可以在3521平台上进行QT的应用开发。
type
Post

QT源码的下载及交叉编译工具的准备

  • QT源码的下载地址:https://download.qt.io/archive/qt/5.9/5.9.8/single/qt-everywhere-opensource-src-5.9.8.tar.xz;
  • 交叉编译工具:
    • 交叉编译工具使用的是海思3521 SDK带的arm-hisiv500-linux交叉编译工具链,这个交叉编译工具链的sysyroot位置为:x86-arm/arm-hisiv500-linux/target,这一点在QT的configure中需要用到;

修改QT的mkspecs

针对我们要进行的海思3521平台的QT编译,在QT源码根目录中,进入qtbase/mkspecs子目录中,从linux-arm-gnueabi-g++目录上拷贝重命名一个hisi3521-linux-gnueabi-g++目录,并修改其中的qmake.conf文件如下:
#
# qmake configuration for building with arm-linux-gnueabi-g++
#

MAKEFILE_GENERATOR      = UNIX
CONFIG                 += incremental
QMAKE_INCREMENTAL_STYLE = sublib

QT_QPA_DEFAULT_PLATFORM = linuxfb
QMAKE_CFLAGS_RELEASE += -O2 -march=armv7-a
QMAKE_CXXFLAGS_RELEASE += -O2 -march=armv7-a

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

# modifications to g++.conf
QMAKE_CC                = arm-hisiv500-linux-uclibcgnueabi-gcc
QMAKE_CXX               = arm-hisiv500-linux-uclibcgnueabi-g++
QMAKE_LINK              = arm-hisiv500-linux-uclibcgnueabi-g++
QMAKE_LINK_SHLIB        = arm-hisiv500-linux-uclibcgnueabi-g++
QMAKE_CFLAGS +=-DEGL_FBDEV -std=c++11
QMAKE_CXXFLAGS +=-DEGL_FBDEV -std=c++11

# modifications to linux.conf
QMAKE_AR                = arm-hisiv500-linux-uclibcgnueabi-ar cqs
QMAKE_OBJCOPY           = arm-hisiv500-linux-uclibcgnueabi-objcopy
QMAKE_NM                = arm-hisiv500-linux-uclibcgnueabi-nm -P
QMAKE_STRIP             = arm-hisiv500-linux-uclibcgnueabi-strip
load(qt_config)
  • 对于QT的交叉编译而言,针对自己交叉编译的平台及其工具链修改mkspecs是交叉编译过程的第一步,后续对QT进行configure的时候需要通过xplatform来传递自己的平台类型。

交叉编译配置脚本

在QT目录下创建一个编译配置脚本buildsetup.sh如下:
#!/bin/sh

PWD=`pwd`

export QT_SRC_DIR=$PWD
export QT_INSTALL_DIR=$QT_SRC_DIR/Qt_5.9.8
export SYSROOT=/home/pavel/hisi-linux/x86-arm/arm-hisiv500-linux/target
export PATH=/home/pavel/hisi-linux/x86-arm/arm-hisiv500-linux/bin:$PATH
export CROSS_COMPILE=/home/pavel/hisi-linux/x86-arm/arm-hisiv500-linux
export CPLUS_INCLUDE_PATH=$PWD/qtbase/src/3rdparty/angle/include:$CPLUS_INCLUDE_PATH

QT_ENV_CFG=qtenv.sh

sed -i '/^export  QTDIR*/d' $QT_ENV_CFG
sed -i '1 a \export  QTDIR='$QT_RUN_DIR'' $QT_ENV_CFG

cpu_cores=`cat /proc/cpuinfo | grep "processor" | wc -l`
if [ ${cpu_cores} -le 8 ] ; then
    LICHEE_JLEVEL=${cpu_cores}
else
    LICHEE_JLEVEL=${cpu_cores}
fi

function cdqtroot
{
cd $QT_SRC_DIR
}

function qtmakeconfig
{
    mkdir -p $QT_INSTALL_DIR

    $QT_SRC_DIR/configure \
        -opensource \
        -confirm-license \
        -sysroot $SYSROOT \
        -extprefix $QT_INSTALL_DIR \
        -platform linux-g++-64 \
        -xplatform hisi3521-linux-gnueabi-g++ \
        -device-option CROSS_COMPILE=$CROSS_COMPILE \
        -R /usr/lib \
        -no-strip \
        -c++std c++11 \
        -shared \
        -nomake examples \
        -accessibility \
        -no-sql-db2 -no-sql-ibase -no-sql-mysql -no-sql-oci \
        -no-sql-odbc -no-sql-psql -no-sql-sqlite2  -no-sql-tds \
        -no-sql-sqlite -plugin-sql-sqlite \
        -no-qml-debug \
        -no-sse2 \
        -no-sse3 \
        -no-ssse3 \
        -no-sse4.1 \
        -no-sse4.2 \
        -no-avx \
        -no-avx2 \
        -no-mips_dsp \
        -no-mips_dspr2 \
        -qt-zlib \
        -no-journald \
        -qt-libpng \
        -qt-libjpeg \
        -qt-freetype \
        -qt-harfbuzz \
        -no-openssl \
        -no-opengl \
        -no-xcb-xlib \
        -no-glib \
        -no-pulseaudio \
        -gui \
        -widgets \
        -v \
        -optimized-qmake \
        -no-cups \
        -no-iconv \
        -evdev \
        -no-icu \
        -no-fontconfig \
        -no-strip \
        -pch \
        -dbus \
        -no-use-gold-linker \
        -no-directfb \
        -linuxfb \
        -no-kms \
        -no-system-proxies \
        -no-slog2 \
        -no-pps \
        -no-imf \
        -no-lgmon \
        -no-tslib
}

function qtmakeall
{
    make  -j${LICHEE_JLEVEL} -C $QT_SRC_DIR
}

function qtmakeinstall
{
    make  -j${LICHEE_JLEVEL} -C $QT_SRC_DIR install

    #cp fonts to Install directory
    cp -rf fonts $QT_INSTALL_DIR
    
    #Remove redundant files
    rm -rf $QT_INSTALL_DIR/bin
    rm -rf $QT_INSTALL_DIR/include
    rm -rf $QT_INSTALL_DIR/doc
    rm -rf $QT_INSTALL_DIR/mkspecs
    rm -rf $QT_INSTALL_DIR/lib/cmake
    rm -rf $QT_INSTALL_DIR/lib/pkgconfig
    rm -rf $QT_INSTALL_DIR/lib/*.a
    rm -rf $QT_INSTALL_DIR/lib/*.prl
    rm -rf $QT_INSTALL_DIR/lib/*.la
}

function qtmakecleanall
{
    cd $QT_SRC_DIR
    make distclean -j${LICHEE_JLEVEL}
    make -C $QT_SRC_DIR clean -j${LICHEE_JLEVEL}
    rm -rf $QT_INSTALL_DIR
}


echo "  "
echo "********************** useage ***************************"
echo "        please use:"
echo "        qtmakeconfig:         config qt env."
echo "        qtmakeall:            build qt"
echo "        qtmakeinstall:        install qt-lib and cp to target dir."
echo "        qtmakecleanall:       clean qt and rm all target."
echo "        QT_INSTALL_DIR:       " $QT_INSTALL_DIR
echo "        qtmakecleanall:       clean qt and rm all target."
echo "  "
以上脚本主要做了四件事情:
  • 设置必要的环境变量;
  • 把QT交叉编译的configure过程封装在qtmakeconfig中;
  • 把QT交叉编译的完整编译过程封装在qtmakeall中;
  • 把QT交叉编译的安装过程封装在qtmakeinstall中;

交叉编译流程及其问题的解决

在以上编译配置脚本的帮助下,对于QT的交叉编译就非常简单了:
source ./buildsetup.sh
qtmakeconfig
qtmakeall
qtmakeinstall
  • 编译后生成的库、插件等目录在QT根目录下的Qt_5.9.8,把这些目录拷贝到板子的/usr/local/Qt_5.9.8子目录下并设置对应的环境变量即可使用。
1.编译qmake的时候出现“You cannot configure qt separately within a top-level build.”的错误
完整错误提示如下:
pavel@debian:~/qt-everywhere-opensource-src-5.9.8$ qtmakeconfig
+ cd qtbase
+ /home/pavel/qt-everywhere-opensource-src-5.9.8/qtbase/configure -top-level -opensource -confirm-license -sysroot /home/pavel/hisi-linux/x86-arm/arm-hisiv500-linux/target -extprefix /home/pavel/qt-everywhere-opensource-src-5.9.8/Qt_5.12.5 -platform linux-g++-64 -xplatform hisi-linux-gnueabi-g++ -device-option CROSS_COMPILE=/home/pavel/hisi-linux/x86-arm/arm-hisiv500-linux -R /usr/lib -no-strip -c++std c++11 -shared -nomake examples -accessibility -no-sql-db2 -no-sql-ibase -no-sql-mysql -no-sql-oci -no-sql-odbc -no-sql-psql -no-sql-sqlite2 -no-sql-tds -no-sql-sqlite -plugin-sql-sqlite -no-qml-debug -no-sse2 -no-sse3 -no-ssse3 -no-sse4.1 -no-sse4.2 -no-avx -no-avx2 -no-mips_dsp -no-mips_dspr2 -qt-zlib -no-journald -qt-libpng -qt-libjpeg -qt-freetype -qt-harfbuzz -no-openssl -no-opengl -no-xcb-xlib -no-glib -no-pulseaudio -gui -widgets -v -optimized-qmake -no-cups -no-iconv -evdev -no-icu -no-fontconfig -no-strip -pch -dbus -no-use-gold-linker -no-directfb -linuxfb -no-kms -no-system-proxies -no-slog2 -no-pps -no-imf -no-lgmon -no-tslib
Creating qmake...
make: 对“first”无需做任何事。
Project ERROR: You cannot configure qt separately within a top-level build.
解决办法:
  • 参考http://www.qtcn.org/bbs/apps.php?q=diary&a=detail&did=3026&uid=121778给出的办法,在QT源码的top level目录下创建两个文件:touch .qmake.stash .qymake.super,然后重新进行编译即可。

© Pavel Han 2020 - 2022