当开发者需要在嵌入式设备上实现图形界面时,QT框架往往是首选方案。全志H3作为一款性价比较高的Cortex-A7处理器,广泛应用于智能家居、工业控制等领域。本文将手把手带你完成Ubuntu 18.04环境下针对全志H3的QT5.12.9交叉编译全流程,包含你可能遇到的所有技术细节。
在开始之前,确保你的Ubuntu 18.04系统已经安装以下基础工具:
bash复制sudo apt-get update
sudo apt-get install -y build-essential git flex bison gperf python \
libgl1-mesa-dev libssl-dev libxcb1-dev libx11-dev libxext-dev \
libxfixes-dev libxi-dev libxrender-dev libxkbcommon-dev \
libxkbcommon-x11-dev zlib1g-dev
针对全志H3的ARM Cortex-A7架构,我们推荐使用Linaro GCC 4.9.4工具链。这个版本经过验证与QT5.12.9兼容性良好。下载地址:
下载后解压到/opt目录:
bash复制sudo tar -xvf gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabi.tar.xz -C /opt
将交叉编译器路径加入系统环境变量:
bash复制echo 'export PATH=/opt/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabi/bin:$PATH' >> ~/.bashrc
source ~/.bashrc
验证安装是否成功:
bash复制arm-linux-gnueabi-gcc --version
预期输出应包含gcc version 4.9.4 (Linaro GCC 4.9-2017.01)字样。
QT官方提供了完整的源代码包,可以直接从以下地址获取:
bash复制wget https://download.qt.io/archive/qt/5.12/5.12.9/single/qt-everywhere-src-5.12.9.tar.xz
tar -xvf qt-everywhere-src-5.12.9.tar.xz
cd qt-everywhere-src-5.12.9
QT的交叉编译需要通过qmake.conf文件指定工具链。我们需要修改qtbase/mkspecs/linux-arm-gnueabi-g++/qmake.conf:
makefile复制MAKEFILE_GENERATOR = UNIX
CONFIG += incremental
QMAKE_INCREMENTAL_STYLE = sublib
include(../common/linux.conf)
include(../common/gcc-base-unix.conf)
include(../common/g++-unix.conf)
# 工具链路径配置
QMAKE_CC = arm-linux-gnueabi-gcc
QMAKE_CXX = arm-linux-gnueabi-g++
QMAKE_LINK = arm-linux-gnueabi-g++
QMAKE_LINK_SHLIB = arm-linux-gnueabi-g++
QMAKE_AR = arm-linux-gnueabi-ar cqs
QMAKE_OBJCOPY = arm-linux-gnueabi-objcopy
QMAKE_NM = arm-linux-gnueabi-nm -P
QMAKE_STRIP = arm-linux-gnueabi-strip
load(qt_config)
注意:如果交叉编译器不在PATH中,需要将上述命令改为绝对路径,如
/opt/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabi/bin/arm-linux-gnueabi-gcc
创建config.sh配置脚本,根据全志H3的实际需求裁剪QT模块:
bash复制#!/bin/bash
./configure \
-prefix /opt/qt5.12.9-arm \
-xplatform linux-arm-gnueabi-g++ \
-confirm-license \
-opensource \
-release \
-shared \
-qt-zlib \
-qt-freetype \
-qt-libjpeg \
-qt-libpng \
-sql-sqlite \
-no-opengl \
-no-tslib \
-no-icu \
-no-pch \
-no-dbus \
-no-glib \
-no-iconv \
-no-cups \
-no-openssl \
-no-xcb \
-no-eglfs \
-no-compile-examples \
-nomake examples \
-nomake tests \
-skip qtdoc \
-skip qtwebengine
关键参数说明:
| 参数 | 说明 |
|---|---|
| -prefix | 指定安装目录 |
| -xplatform | 指定交叉编译平台 |
| -no-opengl | 禁用OpenGL(H3无GPU加速) |
| -no-tslib | 禁用触摸屏支持(如需触摸需启用) |
| -nomake examples | 不编译示例程序(节省时间) |
给配置脚本添加执行权限并运行:
bash复制chmod +x config.sh
./config.sh
配置完成后开始编译:
bash复制make -j$(nproc)
编译过程可能需要1-2小时,取决于你的机器性能。如果遇到内存不足的问题,可以减少并行编译线程数:
bash复制make -j4
编译完成后安装到指定目录:
bash复制sudo make install
安装完成后,你可以在/opt/qt5.12.9-arm目录下看到以下结构:
code复制qt5.12.9-arm/
├── bin/
├── include/
├── lib/
├── mkspecs/
├── plugins/
└── translations/
将编译好的QT库复制到开发板文件系统中:
bash复制sudo cp -r /opt/qt5.12.9-arm /path/to/rootfs/opt/
提示:
/path/to/rootfs应替换为你实际的开发板根文件系统路径,可能是通过NFS挂载或直接修改SD卡镜像
在开发板的/etc/profile文件中添加以下环境变量:
bash复制export QT_ROOT=/opt/qt5.12.9-arm
export QT_QPA_PLATFORM_PLUGIN_PATH=$QT_ROOT/plugins
export QT_QPA_PLATFORM=linuxfb:fb=/dev/fb0
export LD_LIBRARY_PATH=$QT_ROOT/lib:$LD_LIBRARY_PATH
export PATH=$QT_ROOT/bin:$PATH
这些变量的作用:
QT_ROOT:指定QT安装根目录QT_QPA_PLATFORM_PLUGIN_PATH:QT插件路径QT_QPA_PLATFORM:指定使用Linux帧缓冲作为显示后端LD_LIBRARY_PATH:确保系统能找到QT库文件在开发板上运行一个简单的QT示例:
bash复制cd /opt/qt5.12.9-arm/examples/widgets/widgets/analogclock
./analogclock -platform linuxfb
如果看到时钟界面显示正常,说明QT环境已经配置成功。
如果运行时出现类似/lib/arm-linux-gnueabi/libc.so.6: version 'GLIBC_2.28' not found的错误,说明开发板上的glibc版本过低。解决方案:
bash复制cp /opt/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabi/arm-linux-gnueabi/libc/lib/* /path/to/rootfs/lib/
bash复制cd /path/to/rootfs/lib
ln -sf libc.so.6 libc.so
ln -sf libm.so.6 libm.so
ln -sf libpthread.so.0 libpthread.so
如果提示缺少其他库文件,可以从以下位置查找:
/opt/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabi/arm-linux-gnueabi/libc/lib/opt/qt5.12.9-arm/lib如果应用运行但没有显示,可以尝试以下调试步骤:
bash复制ls /dev/fb*
bash复制cat /dev/urandom > /dev/fb0
bash复制export QT_DEBUG_PLUGINS=1
./your_qt_app -platform linuxfb
配置QT Creator使用交叉编译环境:
创建部署脚本deploy.sh,自动完成编译和文件传输:
bash复制#!/bin/bash
# 编译项目
make clean
make -j$(nproc)
# 传输到开发板
scp your_qt_app user@board_ip:/home/user/
# 在开发板上运行
ssh user@board_ip "export DISPLAY=:0; /home/user/your_qt_app -platform linuxfb"
针对全志H3的性能特点,推荐以下优化措施:
main.cpp中启用硬件加速:cpp复制#include <QApplication>
#include <QFontDatabase>
int main(int argc, char *argv[])
{
qputenv("QT_LOGGING_RULES", "qt.qpa.*=false");
QApplication app(argc, argv);
// 设置适合嵌入式环境的字体
QFontDatabase::addApplicationFont("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf");
app.setFont(QFont("DejaVu Sans"));
// 你的主窗口代码
return app.exec();
}
.pro文件中添加优化选项:makefile复制QMAKE_CXXFLAGS += -O2 -march=armv7-a -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard
如果需要触摸屏支持,需进行以下额外配置:
bash复制./configure \
... \
-tslib \
-I /usr/local/tslib/include \
-L /usr/local/tslib/lib
bash复制export QT_QPA_GENERIC_PLUGINS=tslib:/dev/input/event0
export TSLIB_CONSOLEDEVICE=none
export TSLIB_FBDEVICE=/dev/fb0
export TSLIB_TSDEVICE=/dev/input/event0
export TSLIB_CALIBFILE=/etc/pointercal
export TSLIB_CONFFILE=/etc/ts.conf
export TSLIB_PLUGINDIR=/usr/lib/ts
QT提供了完善的国际化支持。要添加中文支持:
.pro文件中添加:makefile复制TRANSLATIONS += translations/myapp_zh_CN.ts
.qm文件随应用程序一起部署将QT应用作为系统服务运行,创建/etc/systemd/system/myqtapp.service:
ini复制[Unit]
Description=My QT Application
After=syslog.target network.target
[Service]
Type=simple
Environment="DISPLAY=:0"
Environment="QT_QPA_PLATFORM=linuxfb:fb=/dev/fb0"
ExecStart=/opt/myapp/myqtapp
Restart=always
User=root
[Install]
WantedBy=multi-user.target
然后启用服务:
bash复制systemctl enable myqtapp
systemctl start myqtapp
嵌入式环境下内存资源有限,可以使用以下工具监控:
bash复制# 查看进程内存使用
top -p $(pgrep your_qt_app)
# 详细内存分析
cat /proc/$(pgrep your_qt_app)/status | grep -E 'VmSize|VmRSS|VmData'
如果使用QML,注意以下性能要点:
ListView代替Column/Row处理大量项目qml复制import QtQuick 2.12
ApplicationWindow {
visible: true
renderType: Text.NativeRendering // 使用原生文本渲染
}
创建日志配置文件qtlogging.ini:
ini复制[Rules]
*.debug=false
qt.qpa.*=true
qt.qpa.input=true
qt.qpa.pointer=true
然后在启动应用时指定:
bash复制export QT_LOGGING_RULES=qt.qpa.*=true
./your_qt_app -platform linuxfb
确保QT库和应用程序文件权限合理:
bash复制chown -R root:root /opt/qt5.12.9-arm
chmod -R 755 /opt/qt5.12.9-arm
chmod 700 /opt/myapp/myqtapp
在.pro文件中添加安全编译选项:
makefile复制QMAKE_CXXFLAGS += -fstack-protector-strong -D_FORTIFY_SOURCE=2
QMAKE_LFLAGS += -Wl,-z,now -Wl,-z,relro
发布版本移除调试符号:
bash复制arm-linux-gnueabi-strip --strip-unneeded your_qt_app
创建完整的构建脚本build_all.sh:
bash复制#!/bin/bash
# 清理旧构建
make distclean
rm -rf /opt/qt5.12.9-arm
# 配置
./configure \
-prefix /opt/qt5.12.9-arm \
... # 其他配置参数
# 编译安装
make -j$(nproc) && make install
# 打包
tar -czvf qt5.12.9-arm-h3.tar.gz /opt/qt5.12.9-arm
使用Docker创建可重复的构建环境:
dockerfile复制FROM ubuntu:18.04
RUN apt-get update && apt-get install -y \
build-essential git flex bison gperf python \
libgl1-mesa-dev libssl-dev libxcb1-dev libx11-dev \
libxext-dev libxfixes-dev libxi-dev libxrender-dev \
libxkbcommon-dev libxkbcommon-x11-dev zlib1g-dev
COPY gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabi.tar.xz /opt/
RUN tar -xvf /opt/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabi.tar.xz -C /opt && \
rm /opt/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabi.tar.xz
ENV PATH="/opt/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabi/bin:${PATH}"
WORKDIR /build
COPY qt-everywhere-src-5.12.9.tar.xz .
RUN tar -xvf qt-everywhere-src-5.12.9.tar.xz && \
rm qt-everywhere-src-5.12.9.tar.xz
COPY build_qt.sh /build/
RUN chmod +x /build/build_qt.sh
CMD ["/build/build_qt.sh"]
建议采用以下版本管理方式:
code复制qt5.12.9-arm-h3/
├── v1.0/ # 基础版本
├── v1.1-touch/ # 带触摸支持
├── v1.2-minimal/ # 最小化裁剪
└── latest -> v1.2-minimal # 符号链接指向最新稳定版