|
Qt5.8,Qt5.9.0交叉编译,配置经验分享
发表于 2017-3-12 14:27:23
浏览:40126
|
回复:11
打印
只看该作者
[复制链接]
楼主
本帖最后由 scrin 于 2017-6-13 12:20 编辑
本文不再更新,不会回复,请勿私信。本经验可以使用linuxfb,x11。opengl有人在3288上失败了,主要还是3288的linux的opengl支持不全,没办法。本经验的思路理论上适用于所有不老的开发板。不含触屏库,因为我没有触屏,测试不了。
关于Qt5.9.0的交叉编译:现阶段交叉编译不带opengl版本的qt有一些小bug,据说将在5.9.1修复,解决bug需要修改源码,且可能会导致qtlocation无法使用。具体的后面有
qt5.8 arm预编译库(不含opengl)下载地址:百度网盘 ,解压后必须复制到PC机的/usr/local里才能用qtcreator交叉编译,qtcreator请用最新版本(我是421),太老的版本已证实无法识别高版本qt。该库在开发板上的使用方法见第三节。注意如果使用中提示缺库,就参照1.2装一装库。
qt5.9.0 arm预编译库(不含opengl)下载地址:百度网盘,对应qtcreator版本为4.3,其余同上
效果图:
1. 准备工作
1.1 参考http://developer.t-firefly.com/thread-818-1-1.html在内核中启用nfs,然后将开发板的根文件系统挂载到pc上,我挂载到了/home/yy/mntnfs里。(如果你不想动内核,就在1.2步,所有qt编译需要的库都弄完后把开发板内的/lib,/usr/lib,/usr/include三个文件夹复制到电脑上,建立起和开发板相同的目录结构,将它作为挂载目录,但是不推荐这么做,因为开发板库没装对的话configure结果没有你要的库,就白复制了,比较浪费时间)
1.2 为开发板安装qt需要的库(不一定真的需要,我就不测试了,太麻烦):
sudo apt-get install build-essential
sudo apt-get install libfontconfig1 libfontconfig1-dev
sudo apt-get install libxrender-dev libxrender1 libxkbcommon-dev libxkbcommon-x11-0 libxkbcommon-x11-dev libxkbcommon0
sudo apt-get install libglib2.0-dev libglib2.0-0
sudo apt-get install libfreetype6 libfreetype6-dev
*OpenGL ES是平台相关的,需要在下面的conf文件里添加你自己平台的opengl库路径和头文件。目前fireprime没有库,3288是有opengl库的,但是有人给rk3288编译opengl失败了。
可能有少的,可以根据qt配置结果(源码目录中的config.log)看还需要哪些库,然后去http://packages.ubuntu.com/搜索库名字,在开发板上自行安装。例如蓝牙库BlueZ等,默认开发板是没有的,需要你自己提前安装。另外如果有些库你安装了配置结果里也没有,就去看config.log,看是什么原因,例如我这有找不到glib的原因是符号链接在pc端下无法正确识别问题,解决办法见第二部分错误解决办法
注:tslib无法通过apt-get获得,需要自行下载源码包交叉编译
1.3 准备一个交叉编译工具链。本人使用linaro gnueabihf 5.3.1。下载地址:
https://releases.linaro.org/comp ... rm-linux-gnueabihf/
1.4 解压qt5.8源码包,修改qtbase/mkspecs/linux-arm-gnueabi-g++/qmake.conf如下(需要按你自己的情况修改一些路径):
#
# qmake configuration for building with arm-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)
#QMAKE_CXXFLAGS和QMAKE_CFLAGS用来添加头文件搜索路径,QMAKE_LFLAGS用来添加库文件搜索路径。如果你有什么要链接的第三方库,例如触屏库tslib,就需要在这两个里设置路径。
QMAKE_CXXFLAGS += -I/home/yy/mntnfs/usr/include
QMAKE_CXXFLAGS += -I/home/yy/mntnfs/usr/include/arm-linux-gnueabihf
QMAKE_CFLAGS += -I/home/yy/mntnfs/usr/include
QMAKE_CFLAGS += -I/home/yy/mntnfs/usr/include/arm-linux-gnueabihf
#这个搜索路径必须放在所有路径的最前面,因为如果你开发板已经通过诸如apt-get install qtcreator的方式安装了qt5,qt5.8编译就可能错误地
#链接到开发板内的库,出错。当然如果你开发板没装qt就不需要它。保险起见可以带着
QMAKE_LFLAGS += -L/home/yy/qt5_8/qtbase/lib
#lib/arm-linux-gnueabihf最好放在usr/lib/arm-linux-gnueabihf前面,原因之后说,其他路径就随意了,按自己需求添加
QMAKE_LFLAGS += -L/home/yy/mntnfs/lib/arm-linux-gnueabihf
QMAKE_LFLAGS += -Wl,-rpath-link,/home/yy/mntnfs/lib/arm-linux-gnueabihf
QMAKE_LFLAGS += -L/home/yy/mntnfs/usr/lib/arm-linux-gnueabihf
QMAKE_LFLAGS += -Wl,-rpath-link,/home/yy/mntnfs/usr/lib/arm-linux-gnueabihf
QMAKE_LFLAGS += -L/home/yy/mntnfs/lib
QMAKE_LFLAGS += -Wl,-rpath-link,/home/yy/mntnfs/lib
QMAKE_LFLAGS += -L/home/yy/mntnfs/usr/lib
QMAKE_LFLAGS += -Wl,-rpath-link,/home/yy/mntnfs/usr/lib
#以下这一行用来应对检测不到gstreamer和glib的奇怪问题,也许有更好的解决方案。
QMAKE_LIBS += -lpthread -lgobject-2.0 -lglib-2.0 -lpcre
#这两行有可能没有用
QMAKE_CFLAGS += -O2 -march=armv7-a -mfpu=neon -mfloat-abi=hard
QMAKE_CXXFLAGS += -O2 -march=armv7-a -mfpu=neon -mfloat-abi=hard
# modifications to g++.conf 修改成你自己的交叉编译工具链的东西
QMAKE_CC = /home/yy/linaro-gnueabihf/bin/arm-linux-gnueabihf-gcc
QMAKE_CXX = /home/yy/linaro-gnueabihf/bin/arm-linux-gnueabihf-g++
QMAKE_LINK = /home/yy/linaro-gnueabihf/bin/arm-linux-gnueabihf-g++
QMAKE_LINK_SHLIB = /home/yy/linaro-gnueabihf/bin/arm-linux-gnueabihf-g++
# modifications to linux.conf
QMAKE_AR = /home/yy/linaro-gnueabihf/bin/arm-linux-gnueabihf-ar cqs
QMAKE_OBJCOPY = /home/yy/linaro-gnueabihf/bin/arm-linux-gnueabihf-objcopy
QMAKE_NM = /home/yy/linaro-gnueabihf/bin/arm-linux-gnueabihf-nm -P
QMAKE_STRIP = /home/yy/linaro-gnueabihf/bin/arm-linux-gnueabihf-strip
load(qt_config)
2. 开始交叉编译
重要:强烈建议先交叉编译qtbase,成功了再编译整个源码包,免得浪费时间。除非你用的是amd新的8核16线程的处理器,能够make -j16
2.1 进qt源码目录,输入
./configure -v -release -xplatform linux-arm-gnueabi-g++ -qt-zlib -nomake examples -opensource -confirm-license -qt-xcb -qpa xcb -no-opengl -make libs -qt-libjpeg -qt-libpng -sysroot /home/yy/mntnfs -extprefix /usr/local/qtarm580
注1 这里面如果你用opengl,就把-no-opengl换成-opengl es2,但是已经有位先生试过为rk3288编译带OpenGL的qt,失败了
注2 -sysroot要指定你开发板根文件系统的挂载目录。网上有教程说还要加-no-gcc-sysroot,这个纯属误导,不要加
注3 -extprefix指定编译好后的安装目录。不要使用-prefix,在指定了sysroot的情况下,-prefix会把东西安装到开发板里。
注4 如果编译中出错:找不到qt_linux_find_symbol_sys相关 这个错误目前是玄学,试着在configure里加上 -platform linux-g++,或者参考我那个成功编译的百度网盘压缩包里的qmake.conf,那个qmake.conf和文中有些微妙的不同,但是目前无法证明有没有问题。
2.2 make -j4
在这一步我遇到了两种错误(改完错误接着编译即可,不用重新配置)。
第一种错误: 提示relocation相关的东西。产生原因是库搜索路径找不到libxxx.so,于是链接上了libxxx.a。这种情况基本上都是在/usr/lib/armxxx里有个符号链接指向/lib/armxxx,但是交叉编译的时候对PC来说这个符号链接是失效的。
解决办法: 在开发板的/lib/arm-linux-gnueabihf内创建到libxxx的符号链接。例如ln -s libm-2.21.so libm.so
第二种错误: 提示找不到某某库,但是这个库明明就在我的开发板里。产生原因是相关库的符号链接libxxx.so在/usr/lib/arm-linux-gnueabihf
里,而pc机上这些符号链接的路径是有问题的,导致不能跨文件夹进行符号链接。而且这些有问题的符号链接在我这恰好都是usr/lib/arm-linux-gnueabihf指向/lib/arm-linux-gnueabihf里的。所以在前面的qmake.conf里按照那样的顺序写路径。
解决办法: 在开发板的/lib/arm-linux-gnueabihf内创建到libxxx库的符号链接。例如ln -s libxxx.so.x.x.x libxxx.so
Qt5.9.0专属错误1:提示 undefined reference to `QSGDefaultImageNode::setAnisotropyLevel。产生错误的原因是这是编译带有opengl的时候不会出问题,但是如果没有带opengl,这个函数会在某个地方被调用,然后出错。临时解决办法是修改qtlocation/src/location/maps/qgeotiledmapscene.cpp中第609行和第634行,把if(ogl)及后面那条语句注释掉。这个bug据说在5.9.1修复
Qt5.9.0专属错误2:提示qmapbox相关。这依旧是没带opengl出现的bug。临时解决办法:进入qtlocation/src/plugins,打开plugins.pro,把最后一行注释掉。暂无bug何时被修复的消息。
处理完这些错误后,我这里make阶段会顺利完成。
2.3 再次执行make
检查是否有漏编译的东西,这是多进程编译的弊端,可能错误信息被刷没了。再次执行可以发现这些问题。我这就发现了漏编译的东西。
2.4 sudo make install
这一步请不要使用-j4进行多进程编译,我这里一旦出错了,错误信息能够被很多其余未完成job生成的信息刷没了,看不出来它出没出错
在这一步我遇到了两种错误。
第一种就是2.2节的第二种错误。解决办法相同
第二种错误: 提示找不到lchip2tri lpoly2tri lclipper 产生原因,本人认为是Qt本身的bug。因为这三个库的源码qt已经带了。(这个bug似乎已经在Qt5.9.0被修复)
解决办法: 进qtlocation/src/3rdparty make一下貌似就行了,然后接着make install
2.5 再次执行sudo make install
检查是否有漏编译的东西,这是多进程编译的弊端,可能错误信息被刷没了。再次执行可以发现这些问题
至此交叉编译完成。
3. qt5.8开发板相关配置,pc端相关配置
3.1 将5.8安装到开发板上
重要:以下所有复制建议先在pc上压缩,复制进开发板,再解压。直接复制的话我这以前似乎遇到过符号链接损坏的问题。
你可以选择把那些lib都复制进开发板的/lib之类的地方,我为了删除方便,选择将编译出来的东西拷进了/home/firefly/qarmlib里。
然后如果你使用了比较新的交叉工具链,你需要将工具链里的库复制进开发板。我把arm-linux-gnueabihf/lib里的东西复制进了/home/firefly/gnueabihf/lib里。
然后你需要在开发板内添加一些环境变量使qt能够正常工作。
本人添加环境变量的方法:
1. 用户环境变量,每次登陆后生效:
打开/etc/default/locale,然后添加(这里不能使用引用其他环境变量来定义路径,如下文中$QT_ROOT)
QT_QPA_PLATFORM_PLUGIN_PATH=/home/firefly/qt5.8-arm/plugins
LD_LIBRARY_PATH=/home/firefly/gnueabihf/lib:/home/firefly/ffmpeg-arm/lib:/home/firefly/qt5.8-arm/lib:/home/firefly/opencvlib_noopengl/lib
#QT_QPA_PLATFORM=linuxfb:fb=/dev/fb0:tty=/dev/tty1
#QT_QPA_PLATFORM=vnc:size=1280x720
QT_QPA_PLATFORM=xcb
QT_QPA_FONTDIR=/usr/share/fonts/truetype/droid
QT_QPA_EVDEV_MOUSE_PARAMETERS=Intellimouse:/dev/input/event2
QT_QPA_EVDEV_KEYBOARD_PARAMETERS=Linuxinput:/dev/input/event3
QML_IMPORT_PATH=/home/firefly/qt5.8-arm/plugins/qml
QML2_IMPORT_PATH=/home/firefly/qt5.8-arm/plugins/qml
2. 全局环境变量(我这有问题,不一定生效)
打开/etc/profile, 然后添加
export QT_ROOT=/home/firefly/qarmlib
export QT_QPA_PLATFORM_PLUGIN_PATH=$QT_ROOT/plugins
export LD_LIBRARY_PATH=/home/firefly/gnueabihf/lib:/home/firefly/ffmpeg-arm/lib:$QT_ROOT/lib:$LD_LIBRARY_PATH
#export QT_QPA_PLATFORM=linuxfb:fb=/dev/fb0:tty=/dev/tty1
#export QT_QPA_PLATFORM=vnc:size=1280x720
export QT_QPA_PLATFORM=xcb
export QT_QPA_FONTDIR=/usr/share/fonts/truetype/droid
export QT_QPA_EVDEV_MOUSE_PARAMETERS=Intellimouse:/dev/input/event2
export QT_QPA_EVDEV_KEYBOARD_PARAMETERS=Linuxinput:/dev/input/event3
export QML_IMPORT_PATH=$QT_ROOT/qml
export QML2_IMPORT_PATH=$QT_ROOT/qml
3. bash环境变量:每次在开发版内启动虚拟shell,以ssh方式启动shell时都会执行:
打开~/.bashrc加入和2. 全局环境变量一样的东西。
这些环境变量需要稍微解释一下:
LD_LIBRARY_PATH中:添加了qt,交叉工具链的库,还有其他库的搜索路径。
QT_QPA_PLATFORM中:
linuxfb代表qt无视x11桌面,在framebuffer上直接绘图。这种方式绘图的话需要你首先进入纯终端,也就是按ctrl+alt+f1~f6进入6个纯终端,然后执行程序。如果你的板子按那个键没反应,但是按ctrl+alt+f7能退出来,说明你的内核没有纯终端驱动。自己去找。tty=/dev/tty1参数代表qt绘图在了哪个终端上。大家用linuxfb花屏就是因为qt无视桌面进行绘图。
vnc代表qt无视x11桌面,自行启动一个vncserver,在vnc上绘图。通过电脑的vnc viewer可以查看qt程序界面。这个在你能用x11的情况下可以彻底弃用。
xcb代表qt程序在x11桌面环境里执行。
实际上还有个eglfs选项,那个跟opengl有关,我暂时不研究。
QT_QPA_FONTDIR: 指定qt默认字体路径。如果你启动程序发现没有字显示,那就是你没有设置对这个路径。
QT_QPA_EVDEV_MOUSE_PARAMETERS:用在linuxfb,eglfs里,指定输入设备,如果你用触摸屏也会有个差不多的参数要指定。
QML_IMPORT_PATH:指定QML路径。
详细参数可以参考http://doc.qt.io/qt-5/embedded-linux.html
3.2 在pc qtcreator上配置交叉开发环境
这个就是在manage kits里配置,大家摸索摸索就会了。只有三个要注意的点:
1. 在配置开发板的ip,用户名,密码时,用户名一定要写成你当前桌面环境的用户名,默认是firefly,如果设置错误,比如root,会提示无法连接xcb。
2. 如果发现无法调试,提示找不到gdbserver,这时你需要把交叉工具链的gdbserver复制进开发板的/bin里。
3. 交叉编译调试时需要开发板里的库,把它们复制出来,挂载nfs都可以
3.3 qt程序相关要点
3.3.1 在.pro文件里,要注释掉原来的target.path和INSTALLS(如果有的话),添加如下(可以自己改路径,但是有些路径不行):
target.path = /home/firefly/test
INSTALLS += target
3.3.2 由于linaro的交叉工具链的默认搜索路径只有/lib,/usr/lib,没有/lib/armxxx,所以需要手动指定include目录和库目录。如果提示某个被库需要的库找不到,就需要用rpath进行链接。例子如下:
LIBS += -Wl,-rpath,/home/yy/mntnfs/lib/arm-linux-gnueabihf -Wl,-rpath,/home/yy/mntnfs/usr/lib/arm-linux-gnueabihf
3.3.3 如果提示undefined reference to Qt相关库,说明开发板里有其他版本的qt库,但你在链接的时候又不得不添加开发板路径。这时有三种办法:第一种是修改pro文件,但是具体的我忘了,以后会补上。第二种是在你交叉编译的时候把那些开发板内qt库临时复制到其他地方,之后再还原。
|
|