BSD系统在Qt世界里压根不是Tier 1的级别啊,看看Digia只提供Windows, Linux, Mac, Android的预编译文件就知道了。。没关系,好歹Qt是个开源软件,自己动手编译,丰衣足食。下载Qt 5.2.0的源代码这一步我就跳过去了,下面的路径都是Qt源码目录里的。
示例环境:DragonFly BSD 3.6.0(因DragonFly的dports是基于FreeBSD的ports树,所以下面的操作也适用于FreeBSD,详细附在正文后)
修改源码
Qt 5.2.0没有DragonFly BSD的mkspec,可以在FreeBSD的mkspec基础上做点改动来适配dfly,此外qtbase的qfileselector.cpp也需要做一个dirty patch不然编译会出错。
- 复制一份qtbase/mkspecs/freebsd-g++,改名为qtbase/mkspecs/freebsd-dfly(必须以freebsd-开头,不然会导致KqueneFileSystemWatcher后端没有被正确编译[1])
- 执行下面这条指令安装依赖:
sudo pkg install gmake libxcb xcb xcb-util xcb-util-cursor xcb-util-image xcb-util-keysyms xcb-util-renderutil xcb-util-wm v4l_compat flex gperf bison libxkbcommon
注:DragonFly自带的GCC无法编译Qt 5.2.0(好像是因为静态链接的缘故),因此需要安装gcc48(port里的是动态链接的)作为Qt 5.2.0的编译器(反正我已经凌乱了,昨天编译运行正常的,改天编译通不过,昨天自带GCC编译不能通过的,今天又能编译了)。此外,BSD的make编译qtwebkit时有问题,没有深究,我换成GNU make(gmake)就好了。
编辑qtbase/mkspecs/freebsd-dfly/qmake.conf,修改部份内容如下所示。
# Addon software goes into /usr/local on the BSDs, by default we will look there QMAKE_INCDIR = /usr/include /usr/local/include QMAKE_LIBDIR = /usr/lib /usr/local/lib QMAKE_INCDIR_X11 = /usr/local/include/X11 QMAKE_LIBDIR_X11 = /usr/local/lib/X11 QMAKE_INCDIR_OPENGL = /usr/local/include/X11 QMAKE_LIBDIR_OPENGL = /usr/local/lib/X11
编译安装
./configure
正常configure然后编译结果却出错(未定义的引用什么qt_functionForModeSolid_SSE2,还有avx和ssse3等),干脆把这些CPU指令集都禁用掉。后面则不编译examples和tests以加快编译速度、节约时间。
./configure -prefix /usr/local/qt5 -opensource -confirm-license -no-largefile -no-sse2 -no-sse3 -no-ssse3 -no-sse4.1 -no-sse4.2 -no-avx -no-avx2 -no-neon -no-mips_dsp -no-mips_dspr2 -nomake examples -nomake tests -platform freebsd-dfly
查看全部的configure选项: ./configure -help
指定模块
如果全部编译安装则gmake -j4然后sudo gmake install就可以了,但是从各方面考虑(如一些模块的代码可能有需要改动才能编译通过的地方),还是一个模块一个模块按需编译和安装的比较好。
qtbase
编辑qtbase/src/corelib/io/qfileselector.cpp,第370行新加一个判断段,如下所示:
# elif defined(Q_OS_FREEBSD) ret << QStringLiteral("freebsd");
然后开始编译qtbase:
gmake -j4 module-qtbase
没问题的话就可以用下面这个指令安装qtbase了。
sudo gmake module-qtbase-install_subtargets
qtx11extras, qtsvg, qtxmlpatterns
这三个模块仅依赖于qtbase,而且不用作任何修改,可以直接gmake module-qtXXXX编译。
完整的Qt5模块之间的依赖关系可以通过源码顶级目录下的qt.pro文件查看。
qtdeclarative
qtdeclarative依赖于qtbase, qtsvg, qtxmlpatterns三个模块。这个模块的代码有些地方没考虑到众BSD系统,所以需要做一些改动才能编译通过,这里是我的commit(汇报的bug在这),不管有没有合并到upstream,你可以先下载patch文件在本地打上然后编译。
qtquickcontrols
qtquickcontrols依赖于qtdeclarative,本身无需做代码改动即可编译通过。
qtmultimedia
qtmultimedia依赖于qtdeclarative,代码和Linux有些地方耦合了。同样需要改动,我的commit在这(提交的bug在这),你可以下载patch打上再编译。
qtlocation, qtsensors
qtlocation依赖于qtmultimedia,qtsensors依赖于qtdeclarative,这两个模块的代码都无需改动可以直接编译。
qtwebkit
FreeBSD无需做任何改动,可以直接编译。DragonFly需要修改qtwebkit/Source/ThirdParty/ANGLE/src/compiler/osinclude.h,把DragonFly增加到ANGLE_OS_POSIX里(汇报的bug在此),把文件第21行修改成:
defined(__QNX__) || defined(__DragonFly__)
然后gmake module-qtwebkit编译模块即可。注:用BSD make可能会编译失败。
qttools
依赖于qtdeclarative和qtwebkit,需要使用gmake,代码本身无需改动。
qtimageformats, qtgraphicaleffects, qttranslations, qtserialport, qtdoc, qtquick1
这些模块都无需改动(他们的依赖关系请看源码根目录的qt.pro),可以直接编译。
qtscript
DragonFly平台编译qtscript首先得先去修改qtscript/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Platform.h文件,修改第398行,该段文件如下所示(FreeBSD不必改):
#if defined(__FreeBSD__) || defined(__DragonFly__) #define WTF_OS_FREEBSD 1 #endif
然后gmake module-qtscript编译模块即可。
这里还有一个FreeBSD的area51分支,由KDE团队贡献,目前还处于开发状态,完成后就是FreeBSD的Qt5的port了。
完整的Qt5移植、维护、支持确实需要一支team来完成port和维护的工作,个人自用的话这样应该是没有问题的(我用这份Qt5编译了Qt Creator运行都没有问题。)
如果没有用-prefix指定安装路径的话,默认是安装到/usr/local/Qt-5.2.0/,需要修改系统环境变量PATH增加/usr/local/Qt-5.2.0/bin
元旦快乐!
补:关于FreeBSD
FreeBSD编译Qt 5.2.0只需要安装GCC 4.6,然后configure时指定platform为freebsd-g++46即可。不过我没有进行过实机测试,或许也得对源码进行一点加工以适配FreeBSD(参见上面的补丁们)
P.S. 随着系统的组件更新,你可能发现有些事实(比如是否要用GNU make)有所出入,don’t panic!
参考来源:
[1] [SOLVED] Error in cross compilation for ARM OMAP35x development kit
Comments
4 responses to “DragonFly BSD编译安装Qt 5.2.0”
原本还想等FreeBSD升10.0出Qt5的port呢,看了10.0好多人升了之后各种问题,放弃了。
看来还是自己在9.2上自己动手丰衣足食吧,之前试过两次连configure就失败,报错在timezone那块的代码,囧~
文中提到的area51里面有timezone的patch,我在dfly下不需要patch timezone就能编译通过所以没提这回事。。。
晕,有patch不直接push到gerrit里… 请参考:
* http://qt-project.org/contribute
* http://qihome.org/qiliang/2012/10/24/how-to-contribute-to-qt/
寒假放假回家就去push