DragonFly BSD编译安装Qt 5.2.0

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不然编译会出错。

  1. 复制一份qtbase/mkspecs/freebsd-g++,改名为qtbase/mkspecs/freebsd-dfly(必须以freebsd-开头,不然会导致KqueneFileSystemWatcher后端没有被正确编译[1]
  2. 执行下面这条指令安装依赖:
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”

  1. missdeer avatar
    missdeer

    原本还想等FreeBSD升10.0出Qt5的port呢,看了10.0好多人升了之后各种问题,放弃了。
    看来还是自己在9.2上自己动手丰衣足食吧,之前试过两次连configure就失败,报错在timezone那块的代码,囧~

    1. librehat avatar

      文中提到的area51里面有timezone的patch,我在dfly下不需要patch timezone就能编译通过所以没提这回事。。。

    1. librehat avatar

      寒假放假回家就去push