前言: 本文参考了网上全志D1-H,官方SDK Tina 移植 QT5.15等文章, 本文特点,使用电视盒子H616,搭建了QT运行环境, 后续,将发布Tina系统运行QT计算器的例子,重点是,适配盒子特有的遥控器。
- 硬件设备是一个H616的电视盒子,跑的是tina系统,而不是Android系统
- 目录结构
.
├── qt5.14.1
├── tina
3. 建立两个脚本,第一个脚本,build.qt.sh,内容如下
export PATH=$PATH:/home/joyt/storage/allwin/tina0.7/tina/prebuilt/gcc/linux-x86/arm/toolchain-sunxi-glibc/toolchain/bin
mkdir -p /opt/qt-5.14.1-prefix
cd qt-everywhere-src-5.14.1
mkdir build
cd build
time ../configure -prefix /opt/qt-5.14.1-prefix \
-v \
-opensource \
-confirm-license \
-release \
-strip \
-shared \
-xplatform linux-arm-gnueabi-g++ \
-optimized-qmake \
-c++std c++11 \
--rpath=no \
-pch \
-skip qt3d \
-skip qtactiveqt \
-skip qtandroidextras \
-skip qtcanvas3d \
-skip qtconnectivity \
-skip qtdatavis3d \
-skip qtdoc \
-skip qtgamepad \
-skip qtlocation \
-skip qtmacextras \
-skip qtnetworkauth \
-skip qtpurchasing \
-skip qtremoteobjects \
-skip qtscript \
-skip qtscxml \
-skip qtsensors \
-skip qtspeech \
-skip qtsvg \
-skip qttools \
-skip qttranslations \
-skip qtwayland \
-skip qtwebengine \
-skip qtwebview \
-skip qtwinextras \
-skip qtx11extras \
-skip qtxmlpatterns \
-make libs \
-make examples \
-nomake tools -nomake tests \
-gui \
-widgets \
-dbus-runtime \
--glib=no \
--iconv=no \
--pcre=qt \
--zlib=qt \
-no-openssl \
--freetype=qt \
--harfbuzz=qt \
-no-opengl \
-linuxfb \
--xcb=no \
-no-tslib \
--libpng=qt \
--libjpeg=qt \
--sqlite=qt \
-plugin-sql-sqlite \
-I/mnt/data/joyt/storage/allwin/tina0.7/tina/out/h616-p2/staging_dir/target/usr/include/ \
-I/mnt/data/joyt/storage/allwin/tina0.7/tina/out/h616-p2/staging_dir/target/usr/include/allwinner/ \
-I/mnt/data/joyt/storage/allwin/tina0.7/tina/out/h616-p2/staging_dir/target/usr/include/allwinner/include/ \
-L/mnt/data/joyt/storage/allwin/tina0.7/tina/out/h616-p2/staging_dir/target/usr/lib/ \
-L/home/joyt/storage/allwin/tina0.7/tina/prebuilt/gcc/linux-x86/arm/toolchain-sunxi-glibc/toolchain/lib \
-recheck-all | tee configure.log
cd qt-everywhere-src-5.14.1/build
source ../../path.build.qt.envsetup.sh
time make -j40 2>&1| tee build`date '+%Y%m%d-%H-%M-%S'`.log
echo "now you can run below command: "
echo "cd qt-everywhere-src-5.14.1/build/"
echo "rm /opt/qt-5.14.1-prefix/* -rf"
echo "time make install 2>&1| tee install.log, result is at /opt/qt-5.14.1-prefix"
第二个脚本,path.build.qt.envsetup.sh,内容如下
# before run build.qt.sh, need source path.build.qt.envsetup.sh
export PATH=$PATH:/home/joyt/storage/allwin/tina0.7/tina/prebuilt/gcc/linux-x86/arm/toolchain-sunxi-glibc/toolchain/bin
export STAGING_DIR=/home/joyt/storage/allwin/tina0.7/tina/out/h616-p2/staging_dir
4.改动代码
qtbase/mkspecs/linux-arm-gnueabi-g++/qmake.conf
内容如下
#
# qmake configuration for building with arm-openwrt-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-openwrt-linux-gnueabi-gcc
QMAKE_CXX = arm-openwrt-linux-gnueabi-g++
QMAKE_LINK = arm-openwrt-linux-gnueabi-g++
QMAKE_LINK_SHLIB = arm-openwrt-linux-gnueabi-g++
# modifications to linux.conf
QMAKE_AR = arm-openwrt-linux-gnueabi-ar cqs
QMAKE_OBJCOPY = arm-openwrt-linux-gnueabi-objcopy
QMAKE_NM = arm-openwrt-linux-gnueabi-nm -P
QMAKE_STRIP = arm-openwrt-linux-gnueabi-strip
QMAKE_LIBS_THREAD += -ldl
load(qt_config)
5.运行脚本
source ./path.build.qt.envsetup.sh
./build.qt.sh
time make install 2>&1| tee install.log
运行结果在 /opt/qt-5.14.1-prefix
6.板子上部署qt
把运行结果 /opt/qt-5.14.1-prefix 所有的文件adb push 到板子上,目录是/mnt/UDISK
建立运行脚本 qt-path
内容如下
echo begin
export QT_HOME=/mnt/UDISK/opt/qt-5.14.1-prefix
export QT_LIBRARY=/mnt/UDISK/opt/qt-5.14.1-prefix/lib
export QT_QPA_PLATFORM=linuxfb:tty=/dev/fb0
export QT_QPA_FB_DRM=1
export QT_QPA_GENERIC_PLUGINS=evdevkeyboard
export QT_QPA_GENERIC_PLUGINS=evdevmouse
export QT_QPA_EVDEV_MOUSE_PARAMETERS=/dev/input/event1
export QT_QPA_EVDEV_KEYBOARD_PARAMETERS=/dev/input/event0
export QT_PLUGIN_PATH=/mnt/UDISK/opt/qt-5.14.1-prefix/plugins
export LD_LIBRARY_PATH=/lib:/usr/lib:$QT_LIBRARY
echo $LD_LIBRARY_PATH
echo $QT_PLUGIN_PATH
echo =====================
cd /mnt/UDISK/opt/qt-5.14.1-prefix/examples/gui/analogclock
./analogclock
7. 运行的结果:
8.运行自己的helloworld
然后随便在哪新建个目录 mkdir helloworld 然后创建个hello.cpp输入如下代码:
#include <QtWidgets/QApplication>
#include <QtWidgets/QLabel>
int main(int argc, char** argv)
{
QApplication app(argc,argv);
QLabel *label = new QLabel("Hello world!");
label->setGeometry(300,100,200,200);
label->show();
return app.exec();
}
然后就的用上prefix里编出来的qmake了。没有加入查找目录就带上路径运行qmake
在hello.cpp 目录下
1) /opt/qt-5.14.1-prefix/bin/qmake -project helloworld
生成helloworld.pro 这个名字是根据你的工程目录名字来命令的
2) /opt/qt-5.14.1-prefix/bin/qmake helloworld.pro
生成Makefile
3) make 生成可运行程序helloworld
遇到问题,
undefined reference to `QApplication::QApplication
解决方法
vi Makefile
加一行
LIBS += -lQt5Widgets -L/opt/qt-5.14.1-prefix/lib
这个方案有缺陷, 一般不直接手动修改makefile, 现在试试第二个方案
helloworld.pro 增加一行
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
一样可以解决
Make成功以后
adb push helloworld /mnt/UDISK
adb shell
cd /mnt/UDISK
chmod 777 helloworld
./helloworld
出现问题 QFontDatabase: Cannot find font directory /mnt/UDISK/opt/qt-5.14.1-prefix/lib/fonts.
解决方法
git clone GitHub - adobe-fonts/source-sans: Sans serif font family for user interface environments 这个下载很慢
或者第二个方法直接在tina的生成out目录里头找字库
tina/out$ find -name *.ttf
./h616-p2/compile_dir/target/nghttp2-1.24.0/doc/_themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.ttf
./h616-p2/compile_dir/host/u-boot-2018.03/drivers/video/fonts/ankacoder_c75_r.ttf
./h616-p2/compile_dir/host/u-boot-2018.03/drivers/video/fonts/cantoraone_regular.ttf
./h616-p2/compile_dir/host/u-boot-2018.03/drivers/video/fonts/nimbus_sans_l_regular.ttf
./h616-p2/compile_dir/host/u-boot-2018.03/drivers/video/fonts/rufscript010.ttf
板子上运行
mkdir -p /mnt/UDISK/opt/qt-5.14.1-prefix/lib/fonts
cmd窗口运行
cd .\h616-p2\compile_dir\host\u-boot-2018.03\drivers\video\fonts\
adb push . /mnt/UDISK/opt/qt-5.14.1-prefix/lib/fonts
问题解决
运行结果
使用qt creater运行此例子,运行结果
9.遇到的坑以及填坑的记录
1)ERROR: Feature 'tslib' was enabled, but the pre-condition 'libs.tslib' failed.
因为是电视盒子的原因,不需要触摸屏,之前configure是 -tslib \ 修改为 -no-tslib \
2)qt-everywhere-src-5.14.1/build/qtbase/examples/corelib/ipc/sharedmemory$ make
…
/storage/joyt/allwin/tina0.7/qt5.14.1/qt-everywhere-src-5.14.1/build/qtbase/lib/libQt5Core.so: undefined reference to `dladdr@GLIBC_2.17'
看makefile, 里头有LIBS = … libQt5Core.so –lpthread
测试一下, 编辑Makefile, 这一行, 加 -ldl, make 通过了. 但是这样不行, 因为总不能每个Makefile都加, 需要系统性的解决此问题,
解决方法
qmake.conf
QMAKE_LIBS_THREAD += -ldl
3)想看遥控案件的event, 发现我的tina系统,居然没有getevent
解决方法
make menuconfig 进入 openWrt 配置页面,找到 getevent 软件包。打勾,重新编一下tina, 在out目录里就可以找到 getevent了
4)上面建立的qt-path, 是为了建立 qt的运行环境, source qt-path 就把这些export的环境变量建立起来, 但是我发现, 这些环境变量居然不工作, 导致无法板子上运行例子, 比如
set | grep QT_PLUG
set | grep QT_PLUG
'T_PLUGIN_PATH='/mnt/UDISK/opt/qt-5.14.1-prefix/plugins
尝试了好多方法, 比如重新编译busybox,最后找到解决方法,利用windows的xshell,在里头运行adb shell,然后,使用xshell 粘贴qt-path的内容,并运行。这样就暂时解决了这个头疼的问题。 应该还有更好的方法。 因为现在重点是掌握qt系统在嵌入系统里的运用,解决了就行。