转载请注明出处。谢谢合作
发表时间:2015年12月27日12:23:47
最后修改:2015年12月27日12:23:47
由于近期在做QGIS的二次开发。期间走了不少弯路,为了发扬开源的精神,让各位Qter们少踩坑,所以写出这篇文章。
如果遇到什么问题,欢迎提出,大家一起学习,共同提高。
那就让我们直接切入正题了。
这是一篇原创教程,完美实现调试,不是网上传播的RelWithDebugInfo。
一、开发环境的搭建
1.1需要的软件
下载链接:http://pan.baidu.com/s/1o7aAs1G 密码:uyq4
(链接若失效,请回复。)
VS2010
Qt4.8.6 qt-opensource-windows-x86-vs2010-4.8.6
Cmake cmake-3.0.2-win32-x86
Cygwin Cygwin-setup-x86
Osgeo4w osgeo4w-setup
Qgis源码 qgis-latest.tar(注:QGIS2.10.1)
.NET Framework 4dotNetFx40_Full_x86_x64
Flex、bison win_flex_bison-latest
Python源码 Python-2.7.4
Qwt5源码 qwt-5.2.1
QScintilla源码QScintilla-gpl-2.9.1
以下的三项可选(仅用于生成API文档)
Doxygen doxygen-1.8.10-setup
Graphviz graphviz-2.38
Winchm WinCHM_setup
以上版本的软件是我编译的时候使用的,你也可以去官网下载最新的。
1.2 开始安装
这里的安装顺序并无先后之后,只不过我推荐按照下面的顺序安装。
1.2.1 安装.NET Framework 4.0
这个是离线安装包。
1.2.2安装VS2010
我提供的这个镜像是旗舰版自动激活的。这个的安装一般默认就好,如果硬盘空间不够大,请一定要保证C++的安装(这好像是一句废话⊙﹏⊙∥)。
1.2.3 安装Qt
这个一般选择默认就好。安装完成记得把Qt的bin目录添加到环境变量的系统path变量。
1.2.4 安装CMake
还选默认安装吧。安装的时候可选自动添加到环境变量的系统path变量里。如果忘记添加,则可以手动添加,比如C:\Program Files (x86)\CMake\bin。
1.2.5 安装Doxygen
这个安装是可选的,如果你不需要生成API文档,可以不安装。
若安装需要将bin目录添加到系统环境path变量。
1.2.6 安装Graphviz
同上。
1.2.7 安装winchm
同上。
但是这个不需要添加到系统环境path变量。
1.2.8 安装Cygwin
这个的安装需要联网,当然也可以选择从本地文件夹安装。离线安装包在。需要安装两个bison和flex。
图,是我安装之后再次点击安装后截的图。点击keep位置,即可选择操作。所以,如果忘了安装哪个也没有关系,重新打开安装程序,安装即可。
一直点击下一步,等待完成。
1.2.9 安装OSGeo4w
这个的安装需要联网,当然也可以选择从本地文件夹安装。这个需要安装的比较多,建议搜索安装。直接附图。
在官方的安装文档里也有这部分的详细说明,原文是英文的。欲知详情,请查看pdf文档。QGIS Install Help。
一直点击下一步,等待完成。
1.2.10 安装win_flex_bison
解压到某一目录,并将该目录添加到系统环境变量。比如C:\win_flex_bison-latest。此时目录结构为
C:\win_flex_bison-latest\
custom_build_rules
data
FlexLexer.h
README.txt
UNISTD_ERROR.readme
win_bison.exe
win_flex.exe。
1.3检查环境变量
此时已经添加的系统环境path变量有:
C:\Qt\4.8.6\bin;
C:\ProgramFiles(x86)\CMake\bin;
C:\ProgramFiles\doxygen\bin;
C:\win_flex_bison-latest;
C:\Program Files(x86)\Graphviz2.38\bin
1.4 替换库
复制C:\Qt\4.8.6\lib下所有的prl和lib文件到C:\OSGeo4W\lib替换。
复制C:\Qt\4.8.6\bin下的所有dll和pdb文件到C:\OSGeo4W\bin替换。
1.5编译Python源码Python-2.7.4
解压。用VS2010打开PCbuild目录下的pcbuild.sln。
右击解决方案,生成解决方案。
复制PCbuild目录下的python27_d.lib 到C:\OSGeo4W\apps\Python27\libs目录下。
复制PCbuild目录下的python27_d.dll 到C:\OSGeo4W\bin目录下。
1.6编译Qwt5源码qwt-5.2.1
解压qwt-5.2.1.tar.bz2。
修改修改qwtconfig.pri文件
CONFIG += release # release/debug/debug_and_release
#CONFIG += debug_and_release
#CONFIG += build_all
为
#CONFIG += release # release/debug/debug_and_release
CONFIG += debug_and_release
CONFIG += build_all
打开VisualStudio 命令提示(2010)
cdD:\qwt\qwt-5.2.1.tar\qwt-5.2.1\qwt-5.2.1
d:
qmake
nmake
出错:忽略
qwt_designer_plugin.obj : error LNK2001: 无法解析的外部符号"__declspec(dllimpor
t) public: static struct QMetaObject constQwtDial::staticMetaObject" (__imp_?st
aticMetaObject@QwtDial@@2UQMetaObject@@B)
nmake install
在C盘C:\Qwt-5.2.1生成,只要lib下的文件
拷贝
qwt5.dll
qwtd5.dll
qwtd5.pdb
文件到C:\OSGeo4W\bin目录
拷贝
qwt5.lib
qwtd5.lib
文件到C:\OSGeo4W\lib目录
1.7编译QScintilla源码 QScintilla-gpl-2.9.1
解压QScintilla-gpl-2.9.1.zip文件
打开VisualStudio 命令提示(2010)
修改qscintilla.pro文件
CONFIG += qt warn_off release thread exceptions
修改为
CONFIG += qt warn_off debug_and_release build_all threadexceptions
TARGET = qscintilla2
修改为
Debug:TARGET = qscintilla2d
Release:TARGET = qscintilla2
cd D:\qscintilla\QScintilla-gpl-2.9.1\QScintilla-gpl-2.9.1\Qt4Qt5
d:
nmake
在debug目录下生成qscintilla2d文件
qscintilla2d.dll
qscintilla2d.ilk
qscintilla2d.lib
qscintilla2d.pdb
在release目录下生成qscintilla2文件
qscintilla2.dll
qscintilla2.lib
将两个lib文件复制到C:\OSGeo4W\lib目录
将剩下的4个文件复制到C:\OSGeo4W\bin目录
二、开始编译QGIS
解压QGIS的源码。
双击运行runme.bat,然后输入cmake-gui,打开cmake。
输入QGIS的目录和编译目录。
点击Configure然后配置编译器。
点击Finish。
修改CMAKE_CONFIGURATION_TYPES: Debug;Release;MinSizeRel;RelWithDebInfo
-->Debug;Release
勾选WITH_APIDOC
WITH_CUSTOM_WIDGETS
WITH_INTERNAL_QWTPOLAR
QT_TAG_FILE指向Qt的tag文件,即C:/Qt/4.8.6/.tag
一直点击Finish,直到没有红色的行。
最后点击Generate。
修改D:\qgis-latest-2.12.1\qgis-2.12.1\scripts目录下的pyuic4-wrapper.bat文件。
@echo off
setPYUIC4=%1
setPATH=%2;%PATH%
setPYTHONPATH=%3;%PYTHONPATH%
%PYUIC4% %4 %5 %6 %7 %8 %9
修改为:
@echo off
call "C:\OSGeo4W\bin\o4w_env.bat"
set PYUIC4=%1
set PATH=%2;%PATH%
set PYTHONPATH=C:\OSGeo4W\apps\Python27\Lib;%3;%PYTHONPATH%
%PYUIC4% %4 %5 %6 %7 %8 %9
还从刚才的命令行运行VS2010。
打开qgis2.10.1解决方案。
首先修改个文件。不然会有下面这个错误。
..\..\..\qgis-2.10.1\src\core\pal\feature.cpp(85): errorC3861: “finite”: 找不到标识符
打开..\..\..\qgis-2.10.1\src\core\pal\feature.cpp(85)
第85行:assert(finite( lx ) && finite( ly ) );
替换成:assert( _finite(lx ) && _finite( ly ) );
首先编译release版本,这个比较简单。
右击ALL_BUILD项目-->仅用于项目-->仅生成ALL_BUILD。后面的这个时间就比较长了。
这个过程中会有错误,可以忽略,因为致命的错误已经解决了。
右击INSTALL项目-->仅用于项目-->仅生成INSTALL。由于权限的文件,可能会失败。因为是安装到C:\Program Files (x86)\目录下。可以手动创建文件夹qgis2.10.1。然后修改文件夹权限。取消只读,然后修改用户权限全为完全控制。
再次右击INSTALL项目-->仅用于项目-->仅生成INSTALL。然后就Okay了。
C:\Program Files (x86)\ qgis2.10.1文件夹复制到别处,比如D:\qgis2.10.1。
切回VS2010,修改为debug编译模式。后面这个过程比较繁琐。
不过核心思路将库文件替换成debug版本的,前提是该库文件有debug版本。
1. 首先是qgis_core项目,右击项目属性。
切换到配置属性:
1) 常规目标文件名 --- +d,注意文件类型不变。
2) 链接器 ---输入附加依赖项+d注意文件类型不变。
我要详细说一下这个附加依赖项中的lib文件。凡是涉及qt的(qt开头的)库文件,都是在文件名后面的版本前添加d。例如QtCore4.lib文件应该修改为QtCored4文件。python的库文件python27.lib换成python27_d.lib。qwt的库文件qwt5.lib文件替换成qwtd5.lib。qscintilla2的库文件qscintilla2.lib换成qscintilla2d.lib。这样的规则同样适用于后面的编译plugins。但是plugins的编译还需要把qgis_core.lib、qgis_gui.lib、qgis_analysis.lib、qgis_networkanalysis.lib文件替换成debug版本的,即qgis_cored.lib、qgis_guid.lib、qgis_analysisd.lib、qgis_networkanalysisd.lib。这也就是为什么先编译这四个项目的原因。
3) 链接器 ---输入忽略特定库msvcrt.lib 。
4) 链接器 ---调试生成程序数据库文件+d注意文件类型不变。
5) 链接器 ---高级导入库+d注意文件类型不变。
2. qgis_gui 项目
同qgis_core项目的编译。
3. qgis_analysis项目
同qgis_core项目的编译。
4. qgis_networkanalysis项目
同qgis_core项目的编译。
5. 编译plugins库。
coordinatecaptureplugin
delimitedtextprovider
dxf2shpconverterplugin
evis
gdalprovider
georefplugin
gpsimporterplugin
gpxprovider
qgisgrass6
grassplugin6
grassprovider6
grassrasterprovider6
heatmapplugin
interpolationplugin
memoryprovider
mssqlprovider
offlineeditingplugin
ogrprovider
oracleplugin
owsprovider
postgresprovider
rasterterrainplugin
roadgraphplugin
spatialiteprovider
spatialqueryplugin
spitplugin
topolplugin
wcsprovider
wfsprovider
wmsprovider
zonalstatisticsplugin
编译debug版本我没有用INSTALL项目。我是把每次生成的lib文件和dll文件单独拷贝出来的。因为写这个教程的时候距编译已经有一个多月了。因为工作的原因一直比较忙,所以没有来得及写。
将4个lib文件(在对应的项目生成文件下面找)qgis_cored.lib、qgis_guid.lib、qgis_analysisd.lib、qgis_networkanalysisd.lib复制到D:\qgis2.10.1\lib目录下。
将plugins的文件全部复制到D:\qgis2.10.1\plugins目录下。在使用的时候发现如果把plugins的debug版本的dll文件和release版本的dll文件放在同一个目录下,会出现问题。所以我在plugins目录下创建了debug目录和release目录,将debug版本的动态库文件复制到D:\qgis2.10.1\plugins\debug目录下。将release版本的动态库文件复制到D:\qgis2.10.1\plugins\release目录下。
注意D:\qgis2.10.1\include文件夹下面的头文件不全。可以将源码中的所有头文件复制到该目录下。(这样做头文件会多了。)
将C:\OSGeo4W\bin目录下的下面所有dll文件
comerr32.dll
freexl.dll
gdal111.dll
geos_c.dll
geotiff.dll
gssapi32.dll
hdf5.dll
hdf_fw.dll
iconv.dll
jpeg12_osgeo.dll
jpeg_osgeo.dll
k5sprt32.dll
krb5_32.dll
libcurl.dll
libeay32.dll
libexpat.dll
libgcc_s_dw2-1.dll
libiconv-2.dll
libintl-8.dll
libmysql.dll
libpq.dll
libtiff.dll
libxml2.dll
mfhdf_fw.dll
netcdf.dll
ogdi_32b1.dll
openjp2.dll
proj.dll
qscintilla2.dll
qscintilla2d.dll
qwt5.dll
qwtd5.dll
spatialindex1.dll
spatialite4.dll
sqlite3.dll
ssleay32.dll
szip.dll
xerces-c_3_1.dll
zlib1.dll
zlib_osgeo.dll
复制到D:\qgis2.10.1\bin目录下。
将C:\OSGeo4W\include文件夹复制到D:\qgis2.10.1\OSGeo4W目录下。
三、使用
创建Qt项目。
在pro文件中添加。
win32 {
INCLUDEPATH += C:/qgis2.10.1/include \
C:/qgis2.10.1/OSGeo4W/include
CONFIG(debug, debug|release) {
LIBS += C:/qgis2.10.1/lib/qgis_guid.lib\
C:/qgis2.10.1/lib/qgis_cored.lib
}
else {
LIBS += C:/qgis2.10.1/lib/qgis_gui.lib\
C:/qgis2.10.1/lib/qgis_core.lib
}
}
在初始化插件目录的时候这么写。
QString pluginsDir ="C:/qgis2.10.1/plugins/release";
#ifdefQT_DEBUG
pluginsDir ="C:/qgis2.10.1/plugins/debug";
#endif
QgsProviderRegistry *providerRegistry =QgsProviderRegistry::instance(pluginsDir);
四、生成API文档(chm格式)
打开Winchm软件。API文档目录在D:\qgis2.10.1\doc\api。
这个软件的安装很简单。不再赘述。
五、写在后面
1. 可能遇到的问题。
289>qgspythonutilsimpl.obj: error LNK2038: 检测到“_ITERATOR_DEBUG_LEVEL”的不匹配项: 值“0”不匹配值“2”(qgispython.obj 中)
打开qgispython项目下面的qgspythonutilsimpl.cpp文件
#ifdef _MSC_VER
#ifdef _DEBUG
#undef _DEBUG
#endif
#endif
#include <Python.h>
修改为
#ifdef _MSC_VER
//#ifdef _DEBUG
//#undef _DEBUG
//#endif
#endif
#include <Python.h>
六、后记
本来想把这篇教程写得更好一些的(多贴些图等等)。但是由于时间和精力有限。就先写成这样了。
希望对Qter们有所帮助。