由于是开源软件,QGis版本迭代比较快,在保持long term release版本的基础上,每个月都会有一个monthly release的新版本发布。源码工程变化快速,给想要上手编译开发的新人朋友带来了一些困惑。
我之前分别写过QGis1.8版本和QGis2.9版本的源码编译指南,我相信还是帮助到了一部分人。但是现在回过头来看,文章中用到的QGis版本又过时了。
显然,我写博客的速度赶不及QGis大大小小的版本发布速度,也没有必要每一个版本,都来写一遍编译指南,这是很笨拙的做法。况且,我发现,有很大一部分朋友在向我提问题的时候,他们是并没有仔仔细细地把博客内容学习过的,大多数是走马观花。还有一部分朋友确实是学习过博客内容了,并且一步一步依照准则进行,但是一旦遇到点错误,就不知所措,急病乱投医。
俗话说,授人以鱼不如授人以渔。这次我想抛开QGis的任何一个特定版本,跟大家谈谈源码编译的根本方法,结合我之前写的两篇QGis的编译指南,希望能够就此终结源码编译的噩梦。
注意:
本文只讲工程组织的一些原理,如果需要具体的编译操作,请移步关于QGis1.8二次开发的环境配置 以及 QGis2.9在windows下的编译以及二次开发包下载。
写在前面的一点忠告
1. 不要轻易尝试用最新版本的Qt进行编译
截止本文撰写的时间,QGis3.0还未正式发布,到那以前,QGis对于Qt5.x的支持都不会非常好。即使支持,也并没有真正用到Qt5的新特性。目前Qt5.5以下的版本,都有成功编译的例子,但更新的版本就很难了。所以,新版本,有风险。
当你想要用最新版本的Qt进行QGis编译时,先想一想,你是否真的需要最新版的功能?举个最简单的例子,你真的需要Qt Quick吗?或者,你知道Qt Quick吗?
2. 不要低估C++的难度,但也不要过分高估C++带来的阻碍
我在这里必须要单独说明这一点,很多朋友误以为C++如同C#、Python那般上手就能看懂,熟悉一下就能运用自如,这是非常错误的,尤其是你现在要自己去研究QGis这般庞大的C++源码工程的时候。记住这句话,当你看不懂编译器出错信息,不知道是哪里出问题的时候,只是因为你不懂C++。
C++是一门博大精深的语言,它的困难在于自身的灵活性,想要精通它并非一朝一夕的功夫。
然而,就我们编译QGis源码,并用它进行二次开发而言,你需要越过的C++门槛其实并不高。你只需要把基本的概念、编译链接流程等理解清楚,就足够了。
3.多在自己身上找原因
这个不用细说,只是作为提醒,不要抱怨别人的方法不行,不要责怪自己的电脑不行,更不要去怀疑自己的操作系统出了故障,大多数时候编译不成功,都是你自己的原因。
原理
源码工程的编译过程,实际上,就是将依赖库与源代码连接起来的过程。
从github下载到QGis的源码后,我们会看到如下图的文件结构:
我们来解释一下这里面的文件夹的用途。
文件名 | 说明 |
---|---|
ci | |
cmake | 工程组织说明文件,主要是依赖库的配置说明 |
cmake_templates | cmake模板文件 |
debian | Linux操作系统所需 |
doc | 帮助文档 |
!18n | 翻译所需文件 |
images | 图片资源文件 |
mac | 苹果Mac操作系统所需 |
ms-windows | 微软Windows操作系统所需 |
postinstall | 软件安装完成之后执行的脚本操作 |
python | python脚本支持 |
resources | 各种资源、配置文件 |
rpm | 默认配置文件 |
scripts | 各种脚本 |
src | 源代码,这个是我们关注的重点 |
tests | 各种测试代码 |
tools | 目前这里面只有一个Qt3迁移到Qt4的工具 |
并且,在这一级目录下面,有一个非常重要的文件“CMakeLists.txt”,它定义了源码工程如何进行编译。这个文件代码很长,梳理一下,删掉不必要的部分,结构大致可以表示为下面这样。(请务必读一下下面的代码,关键地方我都注释在了代码里面)
##############################################################
# 编译版本设置
SET(CPACK_PACKAGE_VERSION_MAJOR "2")
……
# Note the version no is Mmmpp for Major/minor/patch, 0-padded, thus '10100' for 1.1.0
MATH(EXPR QGIS_VERSION_INT "${CPACK_PACKAGE_VERSION_MAJOR}*10000+${CPACK_PACKAGE_VERSION_MINOR}*100+${CPACK_PACKAGE_VERSION_PATCH}")
MESSAGE(STATUS "QGIS version: ${COMPLETE_VERSION} ${RELEASE_NAME} (${QGIS_VERSION_INT})")
#############################################################
# CMake设置
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.6) # CMake最低要求
……
# 配置GRASS插件
FOREACH (GRASS_SEARCH_VERSION 6 7)
……
# 下面是各种编译选项
SET (WITH_DESKTOP TRUE CACHE BOOL "Determines whether QGIS desktop should be built")
SET (WITH_SERVER FALSE CACHE BOOL "Determines whether QGIS server should be built")
……
SET (WITH_CUSTOM_WIDGETS FALSE CACHE BOOL "Determines whet