前言:本文将介绍Qt5源码方式的交叉编译及安装
下载源码包:qt-everywhere-src-5.12.8.tar.xz
官网下载网址:Index of /
依次选择:
【official_releases】 =>【qt】 =>【5.12】 =>【5.12.8】 =>【single】 =>【qt-everywhere-src-5.12.8.tar.xz】
先解压QT库压缩包出来,并进入解压出来的库目录。
接下来请按以下步骤进行:
1. 配置
1.1 配置工具链
配置编译工具链:
$ vi qtbase/mkspecs/linux-arm-gnueabi-g++/qmake.conf
1.2 配置编译选项
请回到库的根目录下操作。
有以下2种情况:
1.2.1 不支持触摸屏tslib
配置如下:
$ ./configure -prefix /data/arm-linux/libs/qt-5.6.0-arm -opensource -confirm-license -release -make libs -xplatform linux-arm-gnueabi-g++ -pch -sql-sqlite -qt-libjpeg -qt-libpng -qt-zlib -no-opengl -no-sse2 -no-openssl -no-cups -no-glib -no-iconv -no-separate-debug-info -nomake tests -nomake examples -nomake tools -no-pkg-config配置完成输出如下:Qt is now configured for building. Just run 'make'.Once everything is built, you must run 'make install'.Qt will be installed into /data/arm-linux/libs/qt-5.6.0-armPrior to reconfiguration, make sure you remove any leftovers fromthe previous build.
1.2.2 支持触摸屏tslib
若要支持触摸屏,请先移植触摸屏tslib,请参考以下博文:
触摸屏tslib库交叉编译并移植ARM校准测试_曾哥电子设计的博客-CSDN博客。
首先添加-tslib项,如tslib安装在/data/arm-linux/libs/tslib-1.12-arm目录下,还需通过-I和-L指定include和lib路径,配置如下:
$ ./configure -prefix /data/arm-linux/libs/qt-5.6.0-arm -opensource -confirm-license -release -make libs -xplatform linux-arm-gnueabi-g++ -pch -sql-sqlite -qt-libjpeg -qt-libpng -tslib -qt-zlib -no-opengl -no-sse2 -no-openssl -no-cups -no-glib -no-iconv -no-separate-debug-info -nomake tests -nomake examples -nomake tools -no-pkg-config -I /data/arm-linux/libs/tslib-1.12-arm/include -L /data/arm-linux/libs/tslib-1.12-arm/lib
2. 编译及安装
2.1 编译
执行编译命令:
$ make
Make过程可能发生以下错误:
错误1:
In file included from qtiffhandler.cpp:40:0:tiffio.h:33:18: fatal error: tiff.h: No such file or directorycompilation terminated.Makefile:1357: recipe for target '.obj/qtiffhandler.o' failed
解决1:
找不到tiff.h头文件,在库源码可搜索到此文件,将其复制到qtiffhandler.cpp同目录下:
$ cp ./qtimageformats/src/3rdparty/libtiff/libtiff/tiff.h ./qtimageformats/src/plugins/imageformats/tiff/
错误2:
In file included from main.cpp:37:0:socketcanbackend.h:83:5: error: ‘canfd_frame’ does not name a typecanfd_frame m_frame;^Makefile:944: recipe for target '.obj/main.o' failedmake[5]: *** [.obj/main.o] Error 1make[5]: Leaving directory '/data/open_source/qt-everywhere-src-5.12.8/qtserialbus/src/plugins/canbus/socketcan'Makefile:75: recipe for target 'sub-socketcan-make_first' failedmake[4]: *** [sub-socketcan-make_first] Error 2
解决2:
我们可以/qtserialbus/src/plugins/canbus/socketcan/socketcanbackend.cpp中找到canfd_frame的定义,报错信息显示在socketcanbackend.h中找不到其定义,因此将该定义从.cpp移到.h。
$ vi qtserialbus/src/plugins/canbus/socketcan/socketcanbackend.cpp
再次编译发生以下错误:
In file included from main.cpp:37:0:socketcanbackend.h:63:18: error: ‘CANFD_MAX_DLEN’ was not declared in this scope__u8 data[CANFD_MAX_DLEN] __attribute__((aligned(8)));^Makefile:944: recipe for target '.obj/main.o' failedmake[5]: *** [.obj/main.o] Error 1
同样,该CANFD_MAX_DLEN移到从.cpp移到.h。
修改后:socketcanbackend.cpp
socketcanbackend.h
注:若.cpp和.h中没有这几行代码,则手动输入到.h中即可。
此外,还可能还提示类似未定义,则手动给它定义,如下:
typedef unsigned char __u8;typedef unsigned int __u32;typedef __u32 canid_t;
2.2 安装
$ make install
Install过程发生以下错误:
make[5]: Entering directory '/data/open_source/qt-everywhere-opensource-src-5.6.0/qtimageformats/src/plugins/imageformats/tiff'arm-linux-g++ -c -pipe -O2 -std=c++0x -fvisibility=hidden -fvisibility-inlines-hidden -fno-exceptions -Wall -W -D_REENTRANT -fPIC -DQT_NO_MTDEV -DQT_NO_LIBUDEV -DQT_NO_LIBINPUT -DQT_NO_EXCEPTIONS -D_LARGEFILE64_SOURCE -D_LARGEFILE_SOURCE -DQT_NO_DEBUG -DQT_PLUGIN -DQT_GUI_LIB -DQT_CORE_LIB -I. -I/data/arm-linux/libs/tslib-1.12-arm/include -I/data/open_source/qt-everywhere-opensource-src-5.6.0/qtbase/include -I/data/open_source/qt-everywhere-opensource-src-5.6.0/qtbase/include/QtGui -I/data/open_source/qt-everywhere-opensource-src-5.6.0/qtbase/include/QtCore -I.moc -I/data/open_source/qt-everywhere-opensource-src-5.6.0/qtbase/mkspecs/linux-arm-gnueabi-g++ -o .obj/qtiffhandler.o qtiffhandler.cppqtiffhandler.cpp:40:20: fatal error: tiffio.h: No such file or directorycompilation terminated.Makefile:1357: recipe for target '.obj/qtiffhandler.o' failedmake[5]: *** [.obj/qtiffhandler.o] Error 1make[5]: Leaving directory '/data/open_source/qt-everywhere-opensource-src-5.6.0/qtimageformats/src/plugins/imageformats/tiff'Makefile:134: recipe for target 'sub-tiff-install_subtargets' failedmake[4]: *** [sub-tiff-install_subtargets] Error 2make[4]: Leaving directory '/data/open_source/qt-everywhere-opensource-src-5.6.0/qtimageformats/src/plugins/imageformats'Makefile:54: recipe for target 'sub-imageformats-install_subtargets' failedmake[3]: *** [sub-imageformats-install_subtargets] Error 2make[3]: Leaving directory '/data/open_source/qt-everywhere-opensource-src-5.6.0/qtimageformats/src/plugins'Makefile:55: recipe for target 'sub-plugins-install_subtargets' failedmake[2]: *** [sub-plugins-install_subtargets] Error 2make[2]: Leaving directory '/data/open_source/qt-everywhere-opensource-src-5.6.0/qtimageformats/src'Makefile:55: recipe for target 'sub-src-install_subtargets' failedmake[1]: *** [sub-src-install_subtargets] Error 2make[1]: Leaving directory '/data/open_source/qt-everywhere-opensource-src-5.6.0/qtimageformats'Makefile:159: recipe for target 'module-qtimageformats-install_subtargets' failedmake: *** [module-qtimageformats-install_subtargets] Error 2
未解待解
注:虽然报错了,但在安装目录下也安装了库,可当作安装成功,暂跳过此步,实验证明库可以正常使用,可能未安装完全而已。继续下面的操作,回来再解。
3. 测试
3.1 测试程序
编写测试程序如下:
$ vi qt_ts.cpp
#include <QApplication>#include <QWidget>#include <QLabel>#include <QSlider>#include <QHBoxLayout>int main(int argc, char **argv){QApplication app(argc, argv);QWidget *window = new QWidget;window->setWindowTitle("I am a slider");QLabel *label = new QLabel;// QLabel控件,用于显示数字QSlider *slider = new QSlider(Qt::Horizontal);// 滑动条slider->setRange(0, 100);QObject::connect(slider, SIGNAL(valueChanged(int)), label, SLOT(setNum(int)));slider->setValue(50);QHBoxLayout *layout = new QHBoxLayout;//level layout->addWidget(label);layout->addWidget(slider);window->setLayout(layout);window->resize(400, 240);window->show();return app.exec();}
可先在PC端测试:(若ubuntu未安装qt则跳过此步)
$ qmake –project
$ vi qt_ts.pro
在qt_ts.pro中加入一行:QT += widgets
$ qmake
$ make
PC端验证成功!
3.2 交叉编译
qmake用交叉编译出来的库的bin目录下的,如/data/arm-linux/libs/qt-5.6.0-arm/bin/qmake
相同的步骤:
最后编译出来的可执行文件为qt_ts,通过file命令可知其是ARM格式的。
3.3 移植到开发板
交叉编译出来的QT库有以下目录:
bin doc include lib mkspecs plugins
将交叉编译出来的库移植到开发板的/lib目录下,或其他目录(需设置环境变量LD_LIBRARY_PATH)。
如将整个库qt-5.6.0-arm(或lib和plugins)移到开发板的/lib/下,并命名为qt-5.6.0。
Qt库在开发板下的路径:/lib/qt-5.6.0
编译程序时要链接的为.so动态库文件,在lib目录下,因此配置环境变量:
$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH: /lib/qt-5.6.0/lib
将测试程序qt_ts也放于开发板上。
移植好库及设置好环境变量后,运行程序:
[root@GEC210 mnt]#./qt_ts This application failed to start because it could not find or load the Qt platform plugin "xcb"in "".Reinstalling the application may fix this problem.Aborted
这是因为运行环境还没有配置好,详见下节。
3.4 配置运行环境
在/etc/profile中添加以下环境变量:
不带触摸屏tslib的:
# qt-lib environment variablesexport QT_ROOT=/lib/qt-5.6.0export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$QT_ROOT/lib/export QT_QPA_PLATFORM_PLUGIN_PATH=$QT_ROOT/pluginsexport QT_QPA_PLATFORM=linuxfb:tty=/dev/fb0export QT_QPA_FONTDIR=/usr/share/fonts/SourceHanSans
带触摸屏tslib的:
# qt-lib environment variablesexport QT_ROOT=/lib/qt-5.6.0export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$QT_ROOT/lib/export QT_QPA_PLATFORM_PLUGIN_PATH=$QT_ROOT/pluginsexport QT_QPA_PLATFORM=linuxfb:tty=/dev/fb0export QT_QPA_FONTDIR=/usr/share/fonts/SourceHanSansexport QT_QPA_GENERIC_PLUGINS=tslibexport LD_PRELOAD=$TS_ROOT/lib/libts.so
其中,QT_QPA_FONTDIR项,指定字体,为/usr/share/fonts/下某一字体,请检查该目录文件是否存在字体,若无则可从其他路径复制过来。PS:附件有提供该文件。
否则,可能出现如下错误:找不到字体
QFontDatabase: Cannot find font directory /lib/qt-5.12.8/lib/fonts.Note that Qt no longer ships fonts. Deploy some (from https://dejavu-fonts.github.io/ for example) or switch to fontconfig.QFontDatabase: Cannot find font directory /lib/qt-5.12.8/lib/fonts.Note that Qt no longer ships fonts. Deploy some (from https://dejavu-fonts.github.io/ for example) or switch to fontconfig.QFontDatabase: Cannot find font directory /lib/qt-5.12.8/lib/fonts.Note that Qt no longer ships fonts. Deploy some (from https://dejavu-fonts.github.io/ for example) or switch to fontconfig.
注意,包含了tslib的变量,请自行修改为对应的路径,如下:
配置好环境后,更新:
#source /etc/profile
重新运行测试程序:
#./qt_ts
用手操控滑动条是可以的,成功!
3.5 附
若QT插件出现问题,如:
This application failed to start because it could not find or load the Qt platform plugin "linuxfb"in "/lib/qt-5.6.0/plugins".Available platform plugins are: linuxfb, minimal, offscreen.Reinstalling the application may fix this problem.
可通过以下变量来调试追踪:
$ export QT_DEBUG_PLUGINS=1
QFactoryLoader::QFactoryLoader() checking directory path "/face_sys/platforms" ...loaded library "/lib/qt-5.6.0/plugins/platforms/libqlinuxfb.so"QLibraryPrivate::loadPlugin failed on "/lib/qt-5.6.0/plugins/platforms/libqlinuxfb.so" : "Cannot load library /lib/qt-5.6.0/plugins/platforms/libqlinuxfb.so: (libts.so.0: cannot open shared object file: No such file or directory)"This application failed to start because it could not find or load the Qt platform plugin "linuxfb"in "/lib/qt-5.6.0/plugins".Available platform plugins are: linuxfb, minimal, offscreen.Reinstalling the application may fix this problem.
由上可知:缺少libts.so.0库,补上即可。