麒麟服务器工作站SP1 arm环境qt5.6.3源码编译
qt5.6.3源码准备
一般下载地方
- 官网维护版本中的源码包qt-everywhere-src-x.x.x.tar.xz,地址:https://download.qt.io/
- 三方源:如清华源、阿里云源等,三方源也是跟随官网维护版本同步更新的。
- 从三方仓库下载源码,如github、gitee上。其中github存在访问受限问题,gitee从github搬运,其qt依赖的submodule下载异常。
以上对获取最新版本都可以获取到,但qt5.6.3已不再维护,所以以上渠道一般无法获取。
正确下载地方
qt官方的Qt Project git仓库下载:https://code.qt.io/cgit/
源码下载步骤
代码下载步骤:
git clone git://code.qt.io/qt/qt5.git
cd qt5
git checkout v5.6.3
git submodule update --init --recursive
更新submodule的时候过程耗时,有时停在一个阶段比较长,不要终止,正常就是那样。如下展示关键过程:
qt5 $ ((HEAD detached at v5.6.3)) git submodule update --init --recursive
Submodule 'qt3d' (git://code.qt.io/qt/qt3d.git) registered for path 'qt3d'
...
Submodule 'qtxmlpatterns' (git://code.qt.io/qt/qtxmlpatterns.git) registered for path 'qtxmlpatterns'
Cloning into 'D:/workspace/qt5/qt3d'...
Cloning into 'D:/workspace/qt5/qtxmlpatterns'...
Submodule path 'qt3d': checked out 'fc781fa42287a4f5db62a346ad6eb8bcbb9f49c0'
Submodule path 'qtwebengine': checked out 'fad625e0ba39e855817bbf206ab9a846d07aeeec'
Submodule 'src/3rdparty' (git://code.qt.io/qt/qtwebengine-chromium.git) registered for path 'qtwebengine/src/3rdparty'
Cloning into 'D:/workspace/qt5/qtwebengine/src/3rdparty'...
# 注意这个阶段卡顿比较长,正常现象,不要终止
编译
编译openssl
qt5.6.3依赖openssl版本不能过高否则会出现qt源码编译异常。如本次qt5.6.3期望为openssl 1.0.2版本,则重新编译,如果系统本身已经满足则忽略此步骤。
下载openssl对应版本源码。
https://github.com/openssl/openssl/tree/OpenSSL_1_0_2g
编译动态库,并指定安装路径为/root/myb/openssl
mkdir /root/myb/openssl# centos
./config --prefix=/root/myb/openssl -shared#麒麟server sp1
./config --prefix=/root/myb/openssl --enable-sharedmake
make install
编译完成后结果在/root/myb/openssl下。
生成指定配置Makefile
如下,其中 -prefix指定Makefile设置的install路径,即编译安装时最终将结果安装在什么位置。
mkdir /opt/qt5.6.3/./configure -opensource -confirm-license -largefile -dbus-linked -openssl-linked -I /root/myb/openssl/include -L /root/myb/openssl/lib -no-rpath -make libs -make tools -fontconfig -qt-freetype -debug-and-release -qt-sql-sqlite -qt-zlib -qt-libpng -qt-libjpeg -dbus -openssl -qt-xcb -nomake tests -nomake examples -no-pch -prefix /opt/qt5.6.3/
说明:如果未编译openssl,而是系统安装的或系统自带的已经满足则不用指定openssl链接目录。
mkdir /opt/qt5.6.3/./configure -opensource -confirm-license -largefile -dbus-linked -openssl-linked -no-rpath -make libs -make tools -fontconfig -qt-freetype -debug-and-release -qt-sql-sqlite -qt-zlib -qt-libpng -qt-libjpeg -dbus -openssl -qt-xcb -nomake tests -nomake examples -no-pch -prefix /opt/qt5.6.3/
以上配置选项根据使用,这里会影响make编译后生成哪些,比如sql在这里需要指定,以促使后续make module-qtbase时能基于此选项生成对应动态库或支持对应能力的动态库。以上选项满足我们当前需求,如sqlite、dbus等。
手动构建LLIntAssembly.h报错问题
cd qtwebkit/Source/JavaScriptCore
ruby offlineasm/generate_offset_extractor.rb llint/LowLevelInterpreter.asm generated/LLIntDesiredOffsets.h
ruby offlineasm/asm.rb llint/LowLevelInterpreter.asm LLIntOffsetsExtractor LLIntAssembly.h
make -f Makefile.JavaScriptCore.Target install
执行make编译
如下,选择模块进行编译,也可不指定全编译。指定哪些?
我们当前用到的qtbase就足够了,包括libQt5Core.so.5 libQt5Gui.so.5 libQt5Widgets.so.5 libQt5XcbQpa.so.5 libQt5Sql.so.5 libQt5DBus.so.5 libQt5Network.so.5都在qtbase编译即可。
make module-qtbase #make install的时候实际会编译安装所有模块
注意:以上先单线程编译,稳定运行后觉得没问题了,再启多线程,不然一开始多线程对中间发生错误就刷屏看不到了。
多线程编译命令为:
make module-qtbase -j 8
make后编译结果在,如下:其中/root/myb/qt5/是qt源码项目根目录。
/root/myb/qt5/qtbase/lib/# 项目根目录/qtbase/lib/
# libQt5Core.so.5 libQt5Gui.so.5 libQt5Widgets.so.5 libQt5XcbQpa.so.5 libQt5Sql.so.5 libQt5DBus.so.5 libQt5Network.so.5
安装
前边编译能够支持产品,如果要部署QT环境则需要安装。注意,在前边configure时已经指定了安装目录,如下:
-prefix /opt/qt5.6.3/
安装只需要执行make install即可安装到指定的安装目录。
make install
注意:安装执行make install时候会涉及一部分编译,因为QT安装会保证安装的qtbase包括其中的examples,可能会存在依赖其他模块或者交叉引用的情况。但不会全部编译的。所以install的时候有点编译过程“正常”。
部署安装结束…
产品适配
编译环境构建
(1)基本gcc、g++部署安装。
(2)内核开发依赖安装和环境部署准备。
(3)检查make等工具。
依赖库解决
linux qt项目存在2个主要的部署问题。
问题1:依赖的Qt
编译完的Qt库替换进来即可。这个依赖在产品项目编译的时候指定了rpath设置了。
辅助排查方法如下,通过以下命令可观察到系统查找依赖动态库的过程。
LD_DEBUG=libs ./your_prog
问题2:部署时依赖Qt插件问题解决
(1)通过QT_PLUGIN_PATH环境变量指定qt插件plugins目录位置。
export QT_PLUGIN_PATH=/opt/yourt_product/plugins
(2)通过项目中指定plugins的查找目录,如下是Qt doc的说明。
void QCoreApplication::addLibraryPath(const QString &path)Prepends path to the beginning of the library path list, ensuring that it is searched for libraries first. If path is empty or already in the path list, the path list is not changed.The default path list consists of one or two entries. The first is the installation directory for plugins, which is INSTALL/plugins, where INSTALL is the directory where Qt was installed. The second is the application's own directory (not the current directory), but only after the QCoreApplication object is instantiated.The library paths are reset to the default when an instance of QCoreApplication is destructed.See also removeLibraryPath(), libraryPaths(), and setLibraryPaths().
(3)通过qt.conf指定plugins查找位置
# 创建qt.conf和qt二进制程序部署在同级目录下# cat qt.conf #内容如下,其中Plugins = //plugins目录相对路径
[Paths]
Plugins = plugins
附:Qt源码编译过程问题记录
按照上述步骤和configure选项进行,则不会出现下述问题。这里留着记录。
报错1:致命错误:.pch/xxx
致命错误:.pch/Qt5Xml:没有那个文件或目录
cc1plus: 错误:找到一个或多个 PCH 文件,但它们是无效的
cc1plus: 错误:使用 -Winvalid-pch 以获得更多信息
cc1plus: 致命错误:.pch/Qt5Xml:没有那个文件或目录
编译中断。
make[3]: *** [Makefile:1348:.obj/qdom.o] 错误 1
make[3]: 离开目录“/root/myb/qt5/qtbase/src/xml”
make[2]: *** [Makefile:265:sub-xml-make_first] 错误 2
make[2]: 离开目录“/root/myb/qt5/qtbase/src”
make[1]: *** [Makefile:47:sub-src-make_first] 错误 2
make[1]: 离开目录“/root/myb/qt5/qtbase”
make: *** [Makefile:79:module-qtbase] 错误 2
解决方式1:手动指定pch文件,但项目大了太多。
touch /root/myb/qt5/qtbase/src/xml/.pch/Qt5Xml
解决方式2:configure时指定 -no-pch,这个是生成预编译头文件,加速编译过程,去掉编译时间有影响。
-no-pch# 如:
./configure -opensource -confirm-license -largefile -dbus-linked -openssl-linked -I /root/myb/openssl/include -L /root/myb/openssl/lib -no-rpath -make libs -make tools -fontconfig -qt-freetype -debug-and-release -qt-sql-sqlite -qt-zlib -qt-libpng -qt-libjpeg -dbus -openssl -qt-xcb -nomake tests -nomake examples -no-pch -prefix /opt/qt5.6.3/
报错2:openssl版本不匹配
环境版本为1.1.1,预期1.0.2导致,暂时可以configure时删除openssl的编译选项增加 -no-openssl。或指定链接openssl路径。
ssl/qsslcertificate_openssl.cpp:250:38: 错误:对不完全的类型‘EVP_PKEY {aka struct evp_pkey_st}’的非法使用} else if (q_EVP_PKEY_type(pkey->type) == EVP_PKEY_DH) {^~~~
In file included from /usr/include/openssl/crypto.h:25:0,from /usr/include/openssl/comp.h:16,from /usr/include/openssl/ssl.h:17,from ../../include/QtNetwork/5.6.3/QtNetwork/private/../../../../../src/network/ssl/qsslcontext_openssl_p.h:53,from ../../include/QtNetwork/5.6.3/QtNetwork/private/qsslcontext_openssl_p.h:1,from ssl/qsslsocket_p.h:55,from ssl/qsslsocket_openssl_p.h:63,from ssl/qsslsocket_openssl_symbols_p.h:64,from ssl/qsslcertificate_openssl.cpp:35:
/usr/include/openssl/ossl_typ.h:93:16: 附注:forward declaration of ‘EVP_PKEY {aka struct evp_pkey_st}’typedef struct evp_pkey_st EVP_PKEY;^~~~~~~~~~~
make[3]: *** [Makefile:22220:.obj/qsslcertificate_openssl.o] 错误 1
make[3]: 离开目录“/root/myb/qt5/qtbase/src/network”
make[2]: *** [Makefile:215:sub-network-make_first] 错误 2
make[2]: 离开目录“/root/myb/qt5/qtbase/src”
make[1]: *** [Makefile:47:sub-src-make_first] 错误 2
make[1]: 离开目录“/root/myb/qt5/qtbase”
make: *** [Makefile:79:module-qtbase] 错误 2
解决方式1:不编译openssl
删除 -openssl -openssl-linked等,添加 -no-openssl
解决方式2:重新编译指定版本的openssl,在静态链接进qt中。
openssl编译过程:
(1)下载源码;
(2)解压,进入openssl源码目录中;
(3)./config --prefix=/root/myb/openssl
(4)make
(5)make install
(6)结果在/root/myb/openssl
编译QT时指定openssl的链接,./configure -opensource -confirm-license -largefile -dbus-linked -openssl-linked -I /root/myb/openssl/include -L /root/myb/openssl/lib -no-rpath -make libs -make tools -fontconfig -qt-freetype -debug-and-release -qt-sql-sqlite -qt-zlib -qt-libpng -qt-libjpeg -dbus -openssl -qt-xcb -nomake tests -nomake examples -no-pch -prefix /opt/qt5.6.3/
报错3:LLIntAssembly.h缺失
在centos类系统编译出现异常报错,单独编译查看错误。
#cd qtwebkit/Source/JavaScriptCore
[root@localhost JavaScriptCore]# make -f Makefile.JavaScriptCore.Target install
g++ -c xxxxxxxxxxxxxxxxxxxxxxxxxxxxx -o .obj/llint/LowLevelInterpreter.o llint/LowLevelInterpreter.cpp
llint/LowLevelInterpreter.cpp:414:35: fatal error: LLIntAssembly.h: No such file or directory#include "LLIntAssembly.h"^
compilation terminated.
make: *** [.obj/llint/LowLevelInterpreter.o] Error 1
解决方式:手动生成对应头文件
该问题是,缺失头文件系ruby自动生成的,非系统和qt的源码。属于qt的一个bug,针对该问题需要进行手动生成,参考链接:[95749-Qt] 在 Linux 上启用 LLInt (webkit.org)
**** Csaba Osztrogonác 2012-09-06 02:15:19 PDT
I managed to build JSC with LLInt enabled manually.
But inegrating it to the build system needs more work.As far as I see we have to do the following things:
- generate LLIntDesiredOffsets.h: ruby offlineasm/generate_offset_extractor.rb llint/LowLevelInterpreter.asm generated/LLIntDesiredOffsets.h
- build LLIntOffsetsExtractor binary (It depends on LLIntOffsetsExtractor.cpp,h and the new generated LLIntDesiredOffsets.h)
- generate LLIntAssembly.h: ruby offlineasm/asm.rb llint/LowLevelInterpreter.asm LLIntOffsetsExtractor LLIntAssembly.h (It depends on the binary LLIntOffsetsExtractor)Am I correct?**** 菲利普·皮兹洛 2012-09-06 10:21:27 太平洋夏令时
(In reply to comment #2)
> I managed to build JSC with LLInt enabled manually.
> But inegrating it to the build system needs more work.
>
> As far as I see we have to do the following things:
> - generate LLIntDesiredOffsets.h: ruby offlineasm/generate_offset_extractor.rb llint/LowLevelInterpreter.asm generated/LLIntDesiredOffsets.h
> - build LLIntOffsetsExtractor binary (It depends on LLIntOffsetsExtractor.cpp,h and the new generated LLIntDesiredOffsets.h)
> - generate LLIntAssembly.h: ruby offlineasm/asm.rb llint/LowLevelInterpreter.asm LLIntOffsetsExtractor LLIntAssembly.h (It depends on the binary LLIntOffsetsExtractor)
>
> Am I correct?Yup, that's right!
综上具体解决步骤是执行以下两条命令,即可在当前文件(qtwebkit/Source/JavaScriptCore)下生成
ruby offlineasm/generate_offset_extractor.rb llint/LowLevelInterpreter.asm generated/LLIntDesiredOffsets.h
ruby offlineasm/asm.rb llint/LowLevelInterpreter.asm LLIntOffsetsExtractor LLIntAssembly.h
make -f Makefile.JavaScriptCore.Target install