本帖最后由 Syylc120317 于 2015-12-27 12:24 编辑
转载请注明出处。谢谢合作 发表时间:2015年12月27日12:23:47
最后修改:2015年12月27日12:23:47
由于近期在做QGIS的二次开发。期间走了不少弯路,为了发扬开源的精神,让各位Qter们少踩坑,所以写出这篇文章。 如果遇到什么问题,欢迎提出,大家一起学习,共同提高。 那就让我们直接切入正题了。 这是一篇原创教程,完美实现调试,不是网上传播的RelWithDebugInfo。 一、开发环境的搭建 1.1需要的软件 (链接若失效,请回复。) 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们有所帮助。
新年就要到了!预祝新年快乐!
Syylc120317@beijing 2015.12.27
|