1. Qt环境搭建及部署

1.1. 交叉编译环境

在配置交叉编译环境之前,我们需要了解一下X86和RISC-V架构。

X86架构是微处理器执行的计算机语言指令集,是Intel等厂商推出的一系列复杂指令集(CISC)架构的统称。我们常用的台式机、笔记本电脑大多基于X86架构,它在桌面计算和服务器领域占据重要地位,凭借复杂指令集能够高效处理多样化的计算任务,拥有庞大的软件生态和广泛的硬件支持。

RISC-V架构是一种基于精简指令集(RISC)理念设计的开放指令集架构,它具有高度灵活、开源免费的特点。与X86不同,RISC-V的指令集简洁、高效,开发者可以根据自身需求自由扩展和定制指令集,这使得它在嵌入式系统、物联网设备、高性能计算等领域具有巨大的发展潜力,并且逐渐在新兴技术领域崭露头角。

由于X86和RISC-V架构最底层的指令集截然不同,二者在指令编码、寄存器结构、内存访问模式等方面都存在显著差异,因此两个平台的程序无法直接通用,不仅需要分开编译,而且编译所使用的工具链也完全不同。

基于日常开发习惯、资源获取便利性等因素,我们常常选择在X86架构的平台上编写代码,随后将其编译成能够在RISC-V架构上运行的程序。为实现这一目标,就需要搭建交叉编译环境。

什么是交叉编译环境呢?简单来说,就是在一个架构的处理器上构建出能够编译适用于另一个架构的程序的环境。更具体地讲,就是在X86架构的计算机上安装针对RISC-V架构的编译工具,通过该工具将源代码编译成RISC-V架构下可执行的二进制文件,从而实现跨架构的程序开发与运行。

提示

如果不想自己搭建环境,也可以访问资料网盘/7-SDK源码压缩包及虚拟机获取虚拟机镜像,访问资料网盘/6-开发软件/QT章节脚本与软件获取交叉编译后的产物。

1.1.1. 获取交叉编译链

LubanCat-sg200x的RISCV核使用的交叉编译工具链为riscv64-unknown-linux-gnu-gcc,版本10.2.0,访问资料网盘/7-SDK源码压缩包及虚拟机获取虚拟机镜像, 下载host-tools.tar.gz交叉编译工具链压缩包。

下载完成后传到虚拟机或服务器,进行解压:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
#创建存放工具链和后续编译脚本的工作目录
mkdir sg200x

#解压编译工具链到工作目录
tar xvf host-tools.tar.gz -C sg200x/

#进交叉编译链目录
cd sg200x/host-tools/gcc/riscv64-linux-x86_64/bin

#查看编译工具链版本
./riscv64-unknown-linux-gnu-gcc -v
#信息输出如下
Using built-in specs.
COLLECT_GCC=./riscv64-unknown-linux-gnu-gcc
COLLECT_LTO_WRAPPER=/opt/sg200x/host-tools/gcc/riscv64-linux-x86_64/bin/../libexec/gcc/riscv64-unknown-linux-gnu/10.2.0/lto-wrapper
Target: riscv64-unknown-linux-gnu
Configured with: /mnt/ssd/jenkins_iotsw/slave/workspace/Toolchain/build-gnu-riscv_2/./source/riscv/riscv-gcc/configure --target=riscv64-unknown-linux-gnu --with-gmp=/mnt/ssd/jenkins_iotsw/slave/workspace/Toolchain/build-gnu-riscv_2/build-gcc-riscv64-unknown-linux-gnu/build-Xuantie-900-gcc-linux-5.10.4-glibc-x86_64-V2.6.1/lib-for-gcc-x86_64-linux --with-mpfr=/mnt/ssd/jenkins_iotsw/slave/workspace/Toolchain/build-gnu-riscv_2/build-gcc-riscv64-unknown-linux-gnu/build-Xuantie-900-gcc-linux-5.10.4-glibc-x86_64-V2.6.1/lib-for-gcc-x86_64-linux --with-mpc=/mnt/ssd/jenkins_iotsw/slave/workspace/Toolchain/build-gnu-riscv_2/build-gcc-riscv64-unknown-linux-gnu/build-Xuantie-900-gcc-linux-5.10.4-glibc-x86_64-V2.6.1/lib-for-gcc-x86_64-linux --with-libexpat-prefix=/mnt/ssd/jenkins_iotsw/slave/workspace/Toolchain/build-gnu-riscv_2/build-gcc-riscv64-unknown-linux-gnu/build-Xuantie-900-gcc-linux-5.10.4-glibc-x86_64-V2.6.1/lib-for-gcc-x86_64-linux --with-libmpfr-prefix=/mnt/ssd/jenkins_iotsw/slave/workspace/Toolchain/build-gnu-riscv_2/build-gcc-riscv64-unknown-linux-gnu/build-Xuantie-900-gcc-linux-5.10.4-glibc-x86_64-V2.6.1/lib-for-gcc-x86_64-linux --with-pkgversion='Xuantie-900 linux-5.10.4 glibc gcc Toolchain V2.6.1 B-20220906' CXXFLAGS='-g -O2 -DTHEAD_VERSION_NUMBER=2.6.1 ' --prefix=/mnt/ssd/jenkins_iotsw/slave/workspace/Toolchain/build-gnu-riscv_2/build-gcc-riscv64-unknown-linux-gnu/Xuantie-900-gcc-linux-5.10.4-glibc-x86_64-V2.6.1 --with-sysroot=/mnt/ssd/jenkins_iotsw/slave/workspace/Toolchain/build-gnu-riscv_2/build-gcc-riscv64-unknown-linux-gnu/Xuantie-900-gcc-linux-5.10.4-glibc-x86_64-V2.6.1/sysroot --with-system-zlib --enable-shared --enable-tls --enable-languages=c,c++,fortran --disable-libmudflap --disable-libssp --disable-libquadmath --enable-libsanitizer --disable-nls --disable-bootstrap --src=/mnt/ssd/jenkins_iotsw/slave/workspace/Toolchain/build-gnu-riscv_2/./source/riscv/riscv-gcc --enable-multilib --with-abi=lp64d --with-arch=rv64gcxthead 'CFLAGS_FOR_TARGET=-O2   -mcmodel=medany' 'CXXFLAGS_FOR_TARGET=-O2   -mcmodel=medany'
Thread model: posix
Supported LTO compression algorithms: zlib
gcc version 10.2.0 (Xuantie-900 linux-5.10.4 glibc gcc Toolchain V2.6.1 B-20220906)

从输出信息可见,交叉编译工具链适用于riscv64平台,版本为10.2.0。

如果需要导出环境变量,可进行以下操作:

1
2
3
4
5
#导出环境变量,需要根据实际指定编译工具链的绝对路径
export PATH=/opt/sg200x/host-tools/gcc/riscv64-linux-x86_64/bin/:$PATH

#查看编译工具链,如果COLLECT_LTO_WRAPPER变量为指定的路径,即配置成功
riscv64-unknown-linux-gnu-gcc -v

以上配置为临时导出环境变量,打开其他终端或者重启都需要重新导出环境变量,如需永久保存需要将导出环境变量的命令写入~/.bashrc文件末尾,并执行source ~/.bashrc 重新加载配置。

1.2. 交叉编译tslib

tslib是一个用于触摸屏设备的开源函数库,能够为触摸屏驱动获得的采样提供诸如滤波、去抖、校准等功能, 通常作为触摸屏驱动的适配层, 为上层的应用提供了一个统一的接口,比如Qt就是上层应用,数据通过tslib传入Qt应用程序, Qt应用程序就知道哪里被触摸了,然后进行正确的响应。

通过这样一个函数库,可以将编程者从繁琐的数据处理中解脱出来,因为触摸屏的坐标和液晶显示屏之间的坐标并不是一一对应的, 所以,要让从触摸屏上得到的坐标正确转换为液晶显示屏上的坐标,需要经过一个转换过程,而tslib就是完成这个功能的。

因此在这里预先编译安装tslib,这样在后面编译Qt的时候才能将tslib打包编译进去。

野火提供 build-tslib.sh 脚本一键下载、配置、编译及安装 tslib。

build-tslib.sh脚本内容如下,也可以通过访问资料网盘/6-开发软件/QT章节脚本与软件获取脚本。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#!/bin/sh
# set -v

#交叉编译工具链前缀
HOST=riscv64-unknown-linux-musl

#脚本当前路径
SCRIPT_PATH=$(pwd)

#创建编译输出目录
mkdir -p ${SCRIPT_PATH}/out

#添加交叉编译工具链路径
CROSS_CHAIN_PREFIX=${SCRIPT_PATH}/host-tools/gcc/riscv64-linux-musl-x86_64/bin/riscv64-unknown-linux-musl

#修改源码包解压后的名称
MAJOR_NAME=tslib

#修改需要下载的源码前缀和后缀
OPENSRC_VER_PREFIX=1
OPENSRC_VER_SUFFIX=.21

PACKAGE_NAME=${MAJOR_NAME}-${OPENSRC_VER_PREFIX}${OPENSRC_VER_SUFFIX}

#定义压缩包名称
COMPRESS_PACKAGE=${PACKAGE_NAME}.tar.bz2

#定义编译后安装--生成的文件,文件夹位置路径
INSTALL_PATH=${SCRIPT_PATH}/out/${PACKAGE_NAME}

#无需修改--下载地址
DOWNLOAD_LINK=https://github.com/libts/${MAJOR_NAME}/releases/download/${OPENSRC_VER_PREFIX}${OPENSRC_VER_SUFFIX}/${COMPRESS_PACKAGE}

#下载源码包
do_download_src () {
echo "\033[1;33mstart download ${PACKAGE_NAME}...\033[0m"

if [ ! -f "${COMPRESS_PACKAGE}" ];then
    if [ ! -d "${PACKAGE_NAME}" ];then
        wget -c ${DOWNLOAD_LINK}
    fi
fi

echo "\033[1;33mdone...\033[0m"
}

#解压源码包
do_tar_package () {
echo "\033[1;33mstart unpacking the ${PACKAGE_NAME} package ...\033[0m"
if [ ! -d "${PACKAGE_NAME}" ];then
    tar -xf ${COMPRESS_PACKAGE}
fi
echo "\033[1;33mdone...\033[0m"
cd ${PACKAGE_NAME}
}

#配置选项
do_configure () {
echo "\033[1;33mstart configure ${PACKAGE_NAME}...\033[0m"

export CC=${CROSS_CHAIN_PREFIX}-gcc
#添加额外的编译参数
export CFLAGS="-march=rv64imafdcvxthead -mcmodel=medany -mabi=lp64d"

./configure \
--prefix=${INSTALL_PATH} \
--host=${HOST} \

echo "\033[1;33mdone...\033[0m"
}

#编译并且安装
do_make_install () {
echo "\033[1;33mstart make and install ${PACKAGE_NAME} ...\033[0m"
make -j8 && make install
echo "\033[1;33mdone...\033[0m"
}

#删除下载的文件
do_delete_file () {
cd ${SCRIPT_PATH}
if [ -f "${PACKAGE_NAME}" ];then
    sudo rm -f ${PACKAGE_NAME}
fi
}

do_download_src
do_tar_package
do_configure
do_make_install
# do_delete_file

exit $?

野火此处选用的tslib版本为tslib-1.21,更多版本大家可以在官方发布的github网站上查看: https://github.com/libts/tslib/releases , 然后只需要修改版本对应的前缀OPENSRC_VER_PREFIX与后缀OPENSRC_VER_SUFFIX即可。

在sg200x工作目录创建build-tslib.sh添加执行权限,并运行:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#进入前面创建的工作目录
cd sg200x

#创建脚本,并添加内容
vi build-tslib.sh

#添加执行权限
chmod 777 build-tslib.sh

#运行脚本
./build-tslib.sh

提示

如果将网盘的源码压缩包放到脚本同目录,就不用从GitHub再下载,如果访问GitHub困难,可提前下载网盘的源码。

脚本运行后会获取tslib源码压缩包,进行解压,然后交叉编译,最终编译产生的文件在当前目录的out目录下

1
2
3
4
#查看输出目录
ls out/tslib-1.21/
#信息输出如下
bin  etc  include  lib  share

1.3. 交叉编译alsa

高级Linux声音体系(英语:Advanced Linux Sound Architecture,缩写为ALSA),在Linux内核中,ALSA为声卡提供的驱动组件。

ALSA支持声卡的自动配置,以及可以完美的处理系统中的多个声卡设备,所以可能会使用到ALSA, 此时就预先将ALSA交叉编译完成,以便在交叉编译Qt时能将ALSA包含编译进去。

野火提供 build-alsa.sh 脚本一键下载、配置、编译及安装 alsa。

build-alsa.sh脚本内容如下,也可以通过访问资料网盘/6-开发软件/QT章节脚本与软件获取脚本。

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
#!/bin/sh

#交叉编译工具链前缀
HOST=riscv64-unknown-linux-musl

#脚本当前路径
SCRIPT_PATH=$(pwd)

#创建编译输出目录
mkdir -p ${SCRIPT_PATH}/out

#修改源码包解压后的名称
MAJOR_NAME=alsa-lib

#修改需要下载的源码前缀和后缀
OPENSRC_VER_PREFIX=1.2
OPENSRC_VER_SUFFIX=.2

PACKAGE_NAME=${MAJOR_NAME}-${OPENSRC_VER_PREFIX}${OPENSRC_VER_SUFFIX}

#定义压缩包名称
COMPRESS_PACKAGE=${PACKAGE_NAME}.tar.bz2

#定义编译后安装--生成的文件,文件夹位置路径
INSTALL_PATH=${SCRIPT_PATH}/out/${PACKAGE_NAME}

#添加交叉编译工具链路径
CROSS_CHAIN_PREFIX=${SCRIPT_PATH}/host-tools/gcc/riscv64-linux-musl-x86_64/bin/riscv64-unknown-linux-musl

#无需修改--下载地址
DOWNLOAD_LINK=ftp://ftp.alsa-project.org/pub/lib/${COMPRESS_PACKAGE}

#下载源码包
do_download_src () {
echo "\033[1;33mstart download ${PACKAGE_NAME}...\033[0m"

if [ ! -f "${COMPRESS_PACKAGE}" ];then
    if [ ! -d "${PACKAGE_NAME}" ];then
        wget -c ${DOWNLOAD_LINK}
    fi
fi

echo "\033[1;33mdone...\033[0m"
}

#解压源码包
do_tar_package () {
echo "\033[1;33mstart unpacking the ${PACKAGE_NAME} package ...\033[0m"
if [ ! -d "${PACKAGE_NAME}" ];then
    tar -xf ${COMPRESS_PACKAGE}
fi
echo "\033[1;33mdone...\033[0m"
cd ${PACKAGE_NAME}
}

#配置选项
do_configure () {
echo "\033[1;33mstart configure ${PACKAGE_NAME}...\033[0m"

export CC=${CROSS_CHAIN_PREFIX}-gcc
#添加额外的编译参数
export CFLAGS="-march=rv64imafdcvxthead -mcmodel=medany -mabi=lp64d"

mkdir -p ${INSTALL_PATH}/config
mkdir -p ${INSTALL_PATH}/plugin

export CC=${CROSS_CHAIN_PREFIX}-gcc

./configure \
--prefix=${INSTALL_PATH} \
--host=${HOST} \
# --enable-static \
--enable-shared \
--disable-python \
--with-configdir=${INSTALL_PATH}/config \
--with-plugindir=${INSTALL_PATH}/plugin

echo "\033[1;33mdone...\033[0m"
}


#编译并且安装
do_make_install () {
echo "\033[1;33mstart make and install ${PACKAGE_NAME} ...\033[0m"
make -j8 && make install
echo "\033[1;33mdone...\033[0m"
}

#删除下载的文件
do_delete_file () {
cd ${SCRIPT_PATH}
if [ -f "${PACKAGE_NAME}" ];then
    sudo rm -f ${PACKAGE_NAME}
fi
}

do_download_src
do_tar_package
do_configure
do_make_install
# do_delete_file

exit $?

野火此处选用的alsa版本为1.2.2,更多版本只需要修改版本对应的前缀OPENSRC_VER_PREFIX与后缀OPENSRC_VER_SUFFIX即可。

在sg200x工作目录创建build-alsa.sh添加执行权限,并运行:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#进入前面创建的工作目录
cd sg200x

#创建脚本,并添加内容
vi build-alsa.sh

#添加执行权限
chmod 777 build-alsa.sh

#运行脚本
./build-alsa.sh

提示

如果将网盘的源码压缩包放到脚本同目录,就不用从源上再下载,如果访问下载源困难,可提前下载网盘的源码。

脚本运行后会获取alsa源码压缩包,进行解压,然后交叉编译,最终编译产生的文件在当前目录的out目录下

1
2
3
4
#查看输出目录
ls out/alsa-lib-1.2.2/
#信息输出如下
bin  config  include  lib  plugin  share

1.4. 交叉编译Qt源码

野火提供 build-qt.sh 脚本一键下载、配置、编译及安装 qt。

build-qt.sh脚本内容如下,默认使用Qt 5.15.8版本,也可以通过访问资料网盘/6-开发软件/QT章节脚本与软件获取脚本。

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
#!/bin/sh
# set -v

PLATFORM=my-linux-arm-qt

#脚本当前路径
SCRIPT_PATH=$(pwd)

#创建编译输出目录
mkdir -p ${SCRIPT_PATH}/out

#修改需要下载的源码前缀和后缀
OPENSRC_VER_PREFIX=5.15
OPENSRC_VER_SUFFIX=.8

#添加tslib交叉编译的动态库文件和头文件路径
TSLIB_LIB=${SCRIPT_PATH}/out/tslib-1.21/lib
TSLIB_INC=${SCRIPT_PATH}/out/tslib-1.21/include

#添加alsa交叉编译的动态库文件和头文件路径
ALSA_LIB=${SCRIPT_PATH}/out/alsa-lib-1.2.2/lib
ALSA_INC=${SCRIPT_PATH}/out/alsa-lib-1.2.2/include

#添加交叉编译工具链路径
CROSS_CHAIN_PREFIX=${SCRIPT_PATH}/host-tools/gcc/riscv64-linux-musl-x86_64/bin/riscv64-unknown-linux-musl

#根据不同版本定义前缀
case ${OPENSRC_VER_PREFIX} in
    5.15 )
    MAJOR_NAME=qt-everywhere-opensource-src
    DOWNLOAD_LINK_PREFIX=http://download.qt.io/official_releases/qt
    ;;
    *)
    MAJOR_NAME=qt-everywhere-src
    DOWNLOAD_LINK_PREFIX=http://download.qt.io/new_archive/qt
    ;;
esac

#定义压缩包名称,不同版本压缩包名称前缀不一样
COMPRESS_PACKAGE=${MAJOR_NAME}-${OPENSRC_VER_PREFIX}${OPENSRC_VER_SUFFIX}.tar.xz

#源码包解压后的名称,不同版本解压后目录名称前缀一样
PACKAGE_NAME=qt-everywhere-src-${OPENSRC_VER_PREFIX}${OPENSRC_VER_SUFFIX}

#定义编译后安装--生成的文件,文件夹位置路径
INSTALL_PATH=${SCRIPT_PATH}/out/${PACKAGE_NAME}

#无需修改--自动组合下载地址
OPENSRC_VER=${OPENSRC_VER_PREFIX}${OPENSRC_VER_SUFFIX}

#下载链接+包名
DOWNLOAD_LINK=${DOWNLOAD_LINK_PREFIX}/${OPENSRC_VER_PREFIX}/${OPENSRC_VER}/single/${COMPRESS_PACKAGE}

#无需修改--自动组合平台路径
CONFIG_PATH=${SCRIPT_PATH}/${PACKAGE_NAME}/qtbase/mkspecs/${PLATFORM}

#无需修改--自动组合配置平台路径文件
CONFIG_FILE=${CONFIG_PATH}/qmake.conf

#下载源码包
do_download_src () {
    echo "\033[1;33mstart download ${PACKAGE_NAME}...\033[0m"

    if [ ! -f "${COMPRESS_PACKAGE}" ];then
    if [ ! -d "${PACKAGE_NAME}" ];then
        wget -c ${DOWNLOAD_LINK}
    fi
    fi

    echo "\033[1;33mdone...\033[0m"
}

#解压源码包
do_tar_package () {
    echo "\033[1;33mstart unpacking the ${PACKAGE_NAME} package ...\033[0m"
    if [ ! -d "${PACKAGE_NAME}" ];then
    tar -xf ${COMPRESS_PACKAGE}
    fi
    echo "\033[1;33mdone...\033[0m"
    cd ${PACKAGE_NAME}

    # 修复5.11.3 版本的bug
    if [ ${OPENSRC_VER_PREFIX}=="5.11" -a ${OPENSRC_VER_SUFFIX}==".3" ]; then
    sed 's/asm volatile /asm /' -i qtscript/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITStubs.cpp
    fi
}

#安装依赖项
do_install_config_dependent () {
    sudo apt install python -y
    sudo apt install g++ make qt3d5-dev-tools -y
    sudo apt install qml-module-qtquick-xmllistmodel -y
    sudo apt install qml-module-qtquick-virtualkeyboard qml-module-qtquick-privatewidgets qml-module-qtquick-dialogs qml -y
    sudo apt install libqt53dquickscene2d5 libqt53dquickrender5 libqt53dquickinput5 libqt53dquickextras5 libqt53dquickanimation5 libqt53dquick5 -y
    sudo apt install qtdeclarative5-dev qml-module-qtwebengine qml-module-qtwebchannel qml-module-qtmultimedia qml-module-qtaudioengine -y
}

#修改配置平台
do_config_before () {
    echo "\033[1;33mstart configure platform...\033[0m"

if [ ! -d "${CONFIG_PATH}" ];then
    cp -a ${SCRIPT_PATH}/${PACKAGE_NAME}/qtbase/mkspecs/linux-arm-gnueabi-g++ ${CONFIG_PATH}
fi

    echo "#" > ${CONFIG_FILE}
    echo "# qmake configuration for building with arm-linux-gnueabi-g++" >> ${CONFIG_FILE}
    echo "#" >> ${CONFIG_FILE}
    echo "" >> ${CONFIG_FILE}
    echo "MAKEFILE_GENERATOR      = UNIX" >> ${CONFIG_FILE}
    echo "CONFIG                 += incremental" >> ${CONFIG_FILE}
    echo "QMAKE_INCREMENTAL_STYLE = sublib" >> ${CONFIG_FILE}
    echo "" >> ${CONFIG_FILE}
    echo "include(../common/linux.conf)" >> ${CONFIG_FILE}
    echo "include(../common/gcc-base-unix.conf)" >> ${CONFIG_FILE}
    echo "include(../common/g++-unix.conf)" >> ${CONFIG_FILE}
    echo "" >> ${CONFIG_FILE}
    echo "# modifications to g++.conf" >> ${CONFIG_FILE}
    echo "QMAKE_CC                = ${CROSS_CHAIN_PREFIX}-gcc -lts" >> ${CONFIG_FILE}
    echo "QMAKE_CXX               = ${CROSS_CHAIN_PREFIX}-g++ -lts" >> ${CONFIG_FILE}
    echo "QMAKE_LINK              = ${CROSS_CHAIN_PREFIX}-g++ -lts" >> ${CONFIG_FILE}
    echo "QMAKE_LINK_SHLIB        = ${CROSS_CHAIN_PREFIX}-g++ -lts" >> ${CONFIG_FILE}
    echo "" >> ${CONFIG_FILE}
    echo "# modifications to linux.conf" >> ${CONFIG_FILE}
    echo "QMAKE_AR                = ${CROSS_CHAIN_PREFIX}-ar cqs" >> ${CONFIG_FILE}
    echo "QMAKE_OBJCOPY           = ${CROSS_CHAIN_PREFIX}-objcopy" >> ${CONFIG_FILE}
    echo "QMAKE_NM                = ${CROSS_CHAIN_PREFIX}-nm -P" >> ${CONFIG_FILE}
    echo "QMAKE_STRIP             = ${CROSS_CHAIN_PREFIX}-strip" >> ${CONFIG_FILE}
    echo "load(qt_config)" >> ${CONFIG_FILE}
    echo "" >> ${CONFIG_FILE}
    echo "QMAKE_INCDIR=${TSLIB_INC}" >> ${CONFIG_FILE}
    echo "QMAKE_LIBDIR=${TSLIB_LIB}" >> ${CONFIG_FILE}

    echo "QMAKE_CXXFLAGS += -march=rv64imafdcvxthead -mcmodel=medany -mabi=lp64d" >> ${CONFIG_FILE}

    cat ${CONFIG_FILE}
    echo "\033[1;33mdone...\033[0m"
}

#配置选项
do_configure () {
    echo "\033[1;33mstart configure ${PACKAGE_NAME}...\033[0m"

    #添加额外的编译参数
    export CFLAGS="-march=rv64imafdcvxthead -mcmodel=medany -mabi=lp64d"

    export CC="${CROSS_CHAIN_PREFIX}-gcc"
    export CXX="${CROSS_CHAIN_PREFIX}-g++"

    ./configure \
    -prefix ${INSTALL_PATH} \
    -xplatform ${PLATFORM} \
    -release \
    -opensource \
    -confirm-license \
    -no-openssl \
    -no-opengl \
    -no-xcb \
    -no-eglfs \
    -no-compile-examples \
    -no-pkg-config \
    -no-iconv \
    -no-glib \
    -linuxfb \
    -tslib \
    -skip qtdeclarative \
    -I"${TSLIB_INC}" \
    -L"${TSLIB_LIB}" \
    -alsa \
    -I"${ALSA_INC}" \
    -L"${ALSA_LIB}" \

    echo "\033[1;33mdone...\033[0m"
}


#编译并且安装
do_make_install () {
    echo "\033[1;33mstart make and install ${PACKAGE_NAME} ...\033[0m"
    make -j8 && make install
    echo "\033[1;33mdone...\033[0m"
}

#删除下载的文件
do_delete_file () {
    cd ${SCRIPT_PATH}
    if [ -f "${COMPRESS_PACKAGE}" ];then
    sudo rm -f ${COMPRESS_PACKAGE}
    fi
}

do_download_src
do_tar_package
do_install_config_dependent
do_config_before
do_configure
do_make_install
# do_delete_file

exit $?

在sg200x工作目录创建build-qt.sh添加执行权限,并运行:

注意

交叉编译Qt源码前需提前交叉编译tslib和alsa。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#进入前面创建的工作目录
cd sg200x

#创建脚本,并添加内容
vi build-qt.sh

#添加执行权限
chmod 777 build-qt.sh

#运行脚本
./build-qt.sh

提示

如果将网盘的源码压缩包放到脚本同目录,就不用从源上再下载,如果访问下载源困难,可提前下载网盘的源码。

脚本运行后会获取qt源码压缩包,进行解压,然后交叉编译,最终编译产生的文件在当前目录的out目录下

1
2
3
4
#查看输出目录
ls out/qt-everywhere-src-5.15.8/
#信息输出如下
bin  doc  examples  include  lib  mkspecs  plugins  qml  translations

1.5. Qt组件说明

Qt有非常多的模块,每个模块都有其特定的功能,有很多模块在默认安装是不会启用的,需要我们手动配置。

首先我们需要了解一下Qt源码编译的过程,其实也无外乎四步:

  • 源码,Qt官方提供了Qt源码,比如整个Qt的源码包,单个功能的模块包。需要什么去Qt官网下载什么。

  • 配置,编译配置,比如设置工具链、设置我们想要使用的Qt功能、组件,指定安装位置等等

  • 编译,上一步配置完毕之后,会生成Makefile,直接执行make就可以编译Qt。

  • 安装,make install,会将编译好的库安装到我们指定目录。

野火提供了一键编译Qt的脚本build-qt.sh,里面有一些基础的配置,比如tslib,alsa等等。

启用Qt组件和配置功能主要是修改脚本build-qt.sh中的do_configure()函数。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#配置选项
do_configure () {
echo "\033[1;33mstart configure ${PACKAGE_NAME}...\033[0m"

export CC="${CROSS_CHAIN_PREFIX}-gcc"
export CXX="${CROSS_CHAIN_PREFIX}-g++"

./configure \
-prefix ${INSTALL_PATH} \
-xplatform ${PLATFORM} \
-release \
-opensource \
-confirm-license \
-no-openssl \
-no-opengl \
-no-xcb \
-no-eglfs \
-no-compile-examples \
-no-pkg-config \
-no-iconv \
-no-glib \
-tslib \
-I"${TSLIB_INC}" \
-L"${TSLIB_LIB}" \
-alsa \
-I"${ALSA_INC}" \
-L"${ALSA_LIB}" \

echo "\033[1;33mdone...\033[0m"
}

实际上这个函数就是去到Qt源码目录,在该源码目录执行 ./configure xxxx。

configure 是一个命令行工具,它确定如何为特定平台构建Qt, 使能Qt中的功能,也可以确定Qt如何在主机平台上构建和部署应用程序。

我们可以去到Qt源码目录下,运行 ./configure -h 命令查看Qt支持的配置,运行configure后,会自动生成构建Qt的makefile。 build-qt.sh脚本也主要是配置 configure 后面的参数。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#进入源码目录
cd qt-everywhere-src-5.15.8

#参考配置
./configure -h

[....省略大部分的配置内容]

Optional Features:
--disable-option-checking  ignore unrecognized --enable/--with options
--disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
--enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
--enable-silent-rules   less verbose build output (undo: "make V=1")
--disable-silent-rules  verbose build output (undo: "make V=0")
--disable-maintainer-mode
                        disable make rules and dependencies not useful (and
                        sometimes confusing) to the casual installer
--enable-dependency-tracking
                        do not reject slow dependency extractors
--disable-dependency-tracking
                        speeds up one-time build
--enable-static[=PKGS]  build static libraries [default=no]
--enable-shared[=PKGS]  build shared libraries [default=yes]
--enable-fast-install[=PKGS]
                        optimize for fast installation [default=yes]
--disable-libtool-lock  avoid locking (might break parallel builds)
--enable-symbolic-functions
                        use -Bsymbolic-functions option if available
                        (optmization for size and speed)
--enable-debug          enable assert call at the default error message
                        handler
--enable-resmgr         support resmgr (optional)
--disable-aload         disable reading /dev/aload*
--disable-mixer         disable the mixer component

[....省略大部分的配置内容]

不需要逐一浏览,而是选择性查阅,也就是你想要用Qt什么功能,查阅相关的部分,按照步骤操作即可。

1.6. 搭建Qt Creator交叉编译套件

Ubutun虚拟机如何安装Qt Creator可以参考 Ubutun 安装 Qt Creator

安装完成Qt Creator并且交叉编译了Qt源码后,可配置Qt Creator交叉编译套件,用于交叉编译自己的Qt程序。

1.6.1. 配置交叉编译工具

首先打开Qt Creator,选择 【工具】 -> 【外部】 -> 【配置】

../../_images/qt_0.jpg

在弹出来的选项配置界面中选择【Kits】->【编译器】, 点击【添加】按钮选择添加【GCC】,定义名字为 riscv64-unknown-linux-gnu

点击浏览,选择编译器路径,路径为前面创建的工作目录 sg200x/host-tools/gcc/riscv64-linux-x86_64/bin/riscv64-unknown-linux-gnu-gcc,如下图:


../../_images/qt_1.jpg

配置完成后点击Apply。

1.6.2. 配置Qt源码版本

在前面已经交叉编译并安装了Qt5.15.8版本,那么在这里只需要将qmake添加进来即可, 具体操作如下:在选项配置界面中选择【Kits】->【Qt Versions】,然后点击【添加】按钮,在Qt的安装目录下选择qmake: sg200x/out/qt-everywhere-src-5.15.8/bin/qmake ,然后添加完成后点击【Apply】完成应用。

../../_images/qt_3.jpg

1.6.3. 配置构建套件

要添加构建套件,在选项配置界面中选择【Kits】->【构建套件(Kit)】, 点击【添加】,然后设置名称, 此处名称设置为 ebf_sg200x 。

接着选择设备的类型,选择通用的Linux设备(GenericLinuxDevice), 因为这是为开发板构建的环境。

然后选择编译器,此处使用我们刚刚添加的交叉编译工具即可,最后选择Qt的版本,此处也是选择我们刚刚添加的交叉编译安装的版本,最后点击【Apply】完成应用。

../../_images/qt_4.jpg

1.6.4. 交叉编译Qt自带的例程

首先点击欢迎,然后选择Qt Creator自带的Qt版本,最后在搜索框输入analog,选择不带gui标签的版本。

../../_images/qt_5.jpg

选择编译套件的时候选择我们前面创建的 ebf_sg200x 编译套件。

../../_images/qt_6.jpg

选择构建Release版本,然后点击“锤子”进行构建。

../../_images/qt_7.jpg

构建生成文件在保存项目目录对应的build目录下。

../../_images/qt_8.jpg

1.7. 板卡Qt环境部署及运行程序

1.7.1. 板卡Qt环境部署

将前面编译出的编译产物分别压缩,传到板卡,再进行解压,也可以访问资料网盘/6-开发软件/QT章节脚本与软件,获取对应编译好的产物。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#进入编译输出目录
cd sg200x/out

#打包Qt源码编译产物
tar cvf qt-everywhere-src-5.15.8.tar.gz qt-everywhere-src-5.15.8/

#打包tslib源码编译产物
tar cvf tslib-1.21.tar.gz tslib-1.21/

#打包alsa源码编译产物
tar cvf alsa-lib-1.2.2.tar.gz alsa-lib-1.2.2/

1.7.1.1. 测试tslib

将压缩包传到板卡并解压:

1
2
#解压
tar xvf tslib-1.21.tar.gz -C /opt/

配置环境变量,修改/etc/profile文件,在文件末尾添加以下内容:

1
2
3
4
5
6
7
8
export TSLIB_ROOT=/opt/tslib-1.21
export TSLIB_CONSOLEDEVICE=none
export TSLIB_FBDEVICE=/dev/fb0
export TSLIB_TSDEVICE=/dev/input/event0
export TSLIB_CONFFILE=$TSLIB_ROOT/etc/ts.conf
export TSLIB_PLUGINDIR=$TSLIB_ROOT/lib/ts
export TSLIB_CALIBFILE=/etc/pointercal
export LD_LIBRARY_PATH=$TSLIB_ROOT/lib:$LD_LIBRARY_PATH

以上环境变量指定使用/opt/目录下的tslib,避免与系统原有的tslib冲突,然后执行以下命令重新加载配置文件并进行测试:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
#重新加载环境配置
source /etc/profile

#屏幕初始化
#5.5寸mipi屏幕初始化
sudo /mnt/system/usr/bin/sample_panel --panel=HX8399_1080P

#7寸mipi屏幕初始化
sudo /mnt/system/usr/bin/sample_panel --panel=EK79007

#10.1寸mipi屏幕初始化
sudo /mnt/system/usr/bin/sample_panel --panel=ILI9881C

#加载fb驱动
sudo insmod /mnt/system/ko/cvi_fb.ko

#运行测试
/opt/tslib-1.21/bin/ts_test

如果屏幕出现测试界面则tslib配置成功,如果触摸没反应请检查TSLIB_TSDEVICE触摸对应的event是否正确。

1.7.1.2. 测试Qt

将压缩包传到板卡并解压:

1
2
3
4
5
6
7
#解压
tar xvf qt-everywhere-src-5.15.8.tar.gz -C /opt/

#查看文件
ls /opt/qt-everywhere-src-5.15.8
bin  examples  lib      plugins  qtvirtualkeyboard
doc  include   mkspecs  qml      translations
  • examples:该目录包含了大量的Qt示例代码,建议删除。

  • doc:该目录包含Qt的说明文档,建议删除。

  • mkspecs:该目录包含不同平台和编译器的配置文件,用于指导Qt的构建过程,建议删除。

  • translations:目录包含了Qt界面的多语言翻译文件,建议删除。

  • bin:支持Qt应用程序的构建、调试和运行的工具,按需删除。

其他目录需要保留。

创建run_qt.sh文件,用于配置环境变量和运行Qt应用,添加以下内容:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#!/bin/bash

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/lib64v0p7_xthead/lp64d

export TSLIB_ROOT=/opt/tslib-1.21
export TSLIB_CONSOLEDEVICE=none
export TSLIB_FBDEVICE=/dev/fb0
export TSLIB_TSDEVICE=/dev/input/event1
export TSLIB_CONFFILE=$TSLIB_ROOT/etc/ts.conf
export TSLIB_PLUGINDIR=$TSLIB_ROOT/lib/ts
export TSLIB_CALIBFILE=/etc/pointercal
export LD_LIBRARY_PATH=$TSLIB_ROOT/lib:$LD_LIBRARY_PATH

export QT_ROOT=/opt/qt-everywhere-src-5.15.8
export QT_QPA_GENERIC_PLUGINS=tslib:/dev/input/event1
export QT_QPA_FONTDIR=/opt/fonts
export QT_QPA_PLATFORM_PLUGIN_PATH=$QT_ROOT/plugins
export QT_QPA_PLATFORM=linuxfb:tty=/dev/fb0
export QT_PLUGIN_PATH=$QT_ROOT/plugins
export LD_LIBRARY_PATH=$QT_ROOT/lib:$QT_ROOT/plugins/platforms:$LD_LIBRARY_PATH
export QML2_IMPORT_PATH=$QT_ROOT/qml
export QT_QPA_FB_TSLIB=1

if [ ! -e /lib/ld-musl-riscv64xthead.so.1 ]; then
    ln -sf /usr/lib64v0p7_xthead/lp64d/libc.so /lib/ld-musl-riscv64xthead.so.1
fi

#Qt App
/home/cat/analogclock

值得注意的是QT_QPA_FONTDIR指定了字体文件目录,可自行添加字体到/opt/fonts目录, 此处可使用作者提前下载好的可商用思源宋体, 访问资料网盘/6-开发软件/QT章节脚本与软件/Qt章节交叉编译后的文件/用于板卡版本的fonts.tar.gz获取。

环境配置好后可在虚拟机交叉编译Qt程序传到板卡运行,作者此处也提供编译好的Qt官方例程供大家测试,访问资料网盘/6-开发软件/QT章节脚本与软件/Qt章节交叉编译好的例程获取。

将字体和测试程序传到板卡,然后运行测试:

1
2
3
4
5
6
7
8
9
#解压字体文件
tar xvf fonts.tar.gz -C /opt/

#给测试程序加运行权限
chmod 777   run_qt.sh
chmod 777  /home/cat/analogclock

#运行测试
./run_qt.sh

效果如下:

../../_images/qt_9.jpg
../../_images/qt_10.jpg