前言:本文将介绍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库压缩包出来,并进入解压出来的库目录。
接下来请按以下步骤进行:
配置编译工具链:
$ vi qtbase/mkspecs/linux-arm-gnueabi-g++/qmake.conf
请回到库的根目录下操作。
有以下2种情况:
配置如下:
$ ./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-arm
Prior to reconfiguration, make sure you remove any leftovers from
the 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
执行编译命令:
$ make
Make过程可能发生以下错误:
错误1:
In file included from qtiffhandler.cpp:40:0:
tiffio.h:33:18: fatal error: tiff.h: No such file or directory
compilation 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 type
canfd_frame m_frame;
^
Makefile:944: recipe for target '.obj/main.o' failed
make[5]: *** [.obj/main.o] Error 1
make[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' failed
make[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' failed
make[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;
$ 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.cpp
qtiffhandler.cpp:40:20: fatal error: tiffio.h: No such file or directory
compilation terminated.
Makefile:1357: recipe for target '.obj/qtiffhandler.o' failed
make[5]: *** [.obj/qtiffhandler.o] Error 1
make[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' failed
make[4]: *** [sub-tiff-install_subtargets] Error 2
make[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' failed
make[3]: *** [sub-imageformats-install_subtargets] Error 2
make[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' failed
make[2]: *** [sub-plugins-install_subtargets] Error 2
make[2]: Leaving directory '/data/open_source/qt-everywhere-opensource-src-5.6.0/qtimageformats/src'
Makefile:55: recipe for target 'sub-src-install_subtargets' failed
make[1]: *** [sub-src-install_subtargets] Error 2
make[1]: Leaving directory '/data/open_source/qt-everywhere-opensource-src-5.6.0/qtimageformats'
Makefile:159: recipe for target 'module-qtimageformats-install_subtargets' failed
make: *** [module-qtimageformats-install_subtargets] Error 2
未解待解
注:虽然报错了,但在安装目录下也安装了库,可当作安装成功,暂跳过此步,实验证明库可以正常使用,可能未安装完全而已。继续下面的操作,回来再解。
编写测试程序如下:
$ vi qt_ts.cpp
#include
#include
#include
#include
#include
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格式的。
交叉编译出来的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
这是因为运行环境还没有配置好,详见下节。
在/etc/profile中添加以下环境变量:
不带触摸屏tslib的:
# qt-lib environment variables
export QT_ROOT=/lib/qt-5.6.0
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$QT_ROOT/lib/
export QT_QPA_PLATFORM_PLUGIN_PATH=$QT_ROOT/plugins
export QT_QPA_PLATFORM=linuxfb:tty=/dev/fb0
export QT_QPA_FONTDIR=/usr/share/fonts/SourceHanSans
带触摸屏tslib的:
# qt-lib environment variables
export QT_ROOT=/lib/qt-5.6.0
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$QT_ROOT/lib/
export QT_QPA_PLATFORM_PLUGIN_PATH=$QT_ROOT/plugins
export QT_QPA_PLATFORM=linuxfb:tty=/dev/fb0
export QT_QPA_FONTDIR=/usr/share/fonts/SourceHanSans
export QT_QPA_GENERIC_PLUGINS=tslib
export 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
用手操控滑动条是可以的,成功!
若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库,补上即可。