这些天几乎完全按照网上的教程及教程中提供的编译库版本进行编译,到最后进行osgearth编译时总是一大堆错误,而大多数教程中在进行osgearth cmake配置后,简单说了一下进行sln编译,就结束了,似乎都很顺利,没有对该过程中遇到的错误进行介绍和解决。花了一个周的时间,试了多种版本,仍然是最后的一大堆不知出处的错误,在几乎快要放弃时,终于编译成功了。本文结合了多篇博客教程和自身的编译经历,组织了这篇综合性的教程。当然有许多不对的地方,还望各位大神指正。参考博客:https://blog.csdn.net/qq_34874034/article/details/78630538?locationNum=7&fps=1 https://blog.csdn.net/sunxiaoju/article/details/50396838
一、编译库和第三方库版本介绍
系统:Win1064bit
编译开台:VS2010
OSG版本:3.4.0
OSGEarth版本:2.8.0
Cmake版本:3.11.0_64bit
Curl版本:7.46.0
Gdal版本:2.2.4
Geos版本:3.5.1
OSGEarth编译
编译版本:osg3.4.0+VS2010+win1064bit+osgearth2.8
二、编译OSG
本教程主要参考下面的链接,在实际编译过程的目录也是按照该链接的中教程创建的,只是教程博主是在G盘,本人是在E盘。
https://blog.csdn.net/qq_34874034/article/details/78630538?locationNum=7&fps=1
三、编译OSGEarth的准备工作:
目录构建
1. 我们在G:\OSGCore\osgEarth文件夹下存编译后工程文件(在本文osg编译的第二部分编译准备中已经说明了文件的结构构建)。把源代码放到G:\OSGCore\Bulid文件夹中,源代码解压后重命名为osgearth-osgearth-2.8.0。
2. 将文件结构构建好之后我们开始进行数据拷贝,首先把G:\OSGCore\Bulid\文件夹下的3rdParty文件夹拷贝到G:\OSGCore\Bulid\OpenSceneGraphic\文件夹下。
四、配置第三方库
1. 编译Curl
下载链接:https://curl.haxx.se/download/
使用版本Curl-7.46.0
Curl的编译方式最常用的是先使用cmake进行生成项目,即curl.sln,然后再进行编译。
cmake的方式如下:
1)打开cmake-gui.exe,将curl压缩包解压,在根目录中新建一个build文件夹,然后将该根目录中的CmakeList.txt文件拖入cmake中,两个路径分别按如图所示设置。
2)点击Configure,这时会弹出,完成后会弹出
3)找到CMAKE_INSTALL_PREFIX,填入curl-7.46.0源代码路径,configure后,直接Generate,此时就会在build中生成curl.sln的编译工程。
4)打开build中的curl.sln,生成->批生成,ALL_BUILD中的Debug
x64和Release x64,生成。如下图所示:(其实这一步就已经生成了libcurl.dll和libcurld.dll,以及libcurl.lib和libcurd.lib文件,但仍然需要在生成后进行相关的配置,例如将一些文件配置到system32或SysWOW64,因此要Install,以免在后面发生错误)
5)All_build成功后,再选择INSTALL的Debug
x64和Release x64,生成,就会将所需要的bin、lib安装到G:\OSG\osgEarth\curl-7.46.0目录中,以下是批生成和安装成功的界面,如下图所示:
6)在build目录中搜索*.dll,*.lib,*.h文件,将libcurl.dll和libcurld.dll拷贝到G:\OSG\Build\OpenSceneGraph\3rdParty\bin目录下,将libcurl.lib和libcurd.lib文件拷贝到G:\OSG\Build\OpenSceneGraph\3rdParty\lib目录下,将*.h文件拷贝到G:\OSG\Build\OpenSceneGraph\3rdParty\include\curl目录下。
注意:其中libcurl.dll,libcurl.lib是在Release模式下生成的,libcurld.dll,libcurld.lib是在Debug模式下生成的,在后期进行其它模块编译时也是如此,debug模式生成的文件名,比Release多一个字母d。如果在搜索时发现两种模式下生成的文件名相同,则看该文件是在Debug目录中还是在Release目录中,如果是Debug目录,则统一在原名称后加一个d。
2. 编译GEOS:
下载链接:http://trac.osgeo.org/geos/
本人使用的geos-3.5.1,不建议使用3.6.1,因为这里面的有一些类定义的变量在先前版本中是public,可以直接访问,但在这个版本中都成了protected不可访问。(但博客和交流群中很多大牛用3.6.1以上的版本成功了,可自己的却提示不可访问,也可能是其它模块的版本兼容问题吧)。
对于GEOS的编译,有两种方式,一种是使用cmake,一种是使用nmake,详细参考:
https://www.cnblogs.com/airscrat/p/4992570.html
但是使用nmake编译得到的Release版本的geos.dll和geos.lib是有效的,但debug版本的geosd.dll和geosd.lib是无效的,若使用了这两个文件,则在进行osgEarth编译时总是会提示如下错误:
这是由于debug使用了Release版本的lib文件,按网上的方法也无法解决,因为这两个文件确实是使用nmake在debug模式下生成的。网上的的解决方案:https://www.cnblogs.com/lisuyun/p/6410393.html
因此不得不使用cmake方式,先生成项目文件,再在sln工程中编译。
使用cmake编译geos,编译步骤为:
1. 打开cmake,加载geos源码和定位geos的工程存放位置;
2.点击configure,会报错,首先设置CMAKE_INSTALL-PREFIX定位到geos源码文件目录;
3.然后打开链接https://trac.osgeo.org/geos/browser/trunk/cmake/modules
下载GenerateSourceGroups.cmake文件。
4.将下载后的文件放到使用的cmake3.11.0中,我使用cmake的文件路径为G:\OSGCore\Bulid\cmake-3.11.0-win64-x64,则将刚才下载的文件拷贝到G:\OSGCore\Bulid\cmake-3.11.0-win64-x64\share\cmake-3.11.0\Modules文件下。然后点击configure,不报错了,点击generate,生成编译工程文件,然后打开vs2010工程文件,点击批生成,如图
然后点击生成
编译GEOS 64bit, 第一次批生成可能会有两个工程失败,分别是geos_unit和xmltester,所以可以先编译这两个工程,方法是右键工程名-设置为启动项,然后生成以后就会报错,geos_unit工程的报错是sqrt函数重载的问题,修改方法是在参数前面加上(double),就可以识别出具体调用的哪个sqrt函数了;
xmltester工程的报错是round函数找不到标识,修改方法是在该cpp中添加头文件#include
,在round函数前面加上名字空间util::, 只做这一步,虽然暂时可以消除错误,但是在进行编译时出现:
error LNK2019: 无法解析的外部符号 "double __cdecl
geos::util::java_math_round(double)" (?java_math_round@util@geos@@YANN@Z),该符号在函数 "double __cdecl geos::util::round(double)"
(?round@util@geos@@YANN@Z) 中被引用
这时需要把\geos-3.5.1\src\util文件夹下的math.cpp粘贴到\geos-3.5.1\tests\xmltester文件夹下,并且把math.cpp添加到工程xmltester里面就可以了;然后批生成就行了。
5. 编译后需要转移以下文件到G:\OSGCore\Bulid\OpenSceneGraphic\3rdParty\下的对应位置:(第一个是将geos源码目录下的include文件夹下的geos文件夹拷贝到G:\OSGCore\Bulid\OpenSceneGraphic\3rdParty\include文件夹中,第二个是将编译工程文件夹下的include文件下的geos里面的两个.h文件拷贝到前面的G: \OSGCore\Bulid\OpenSceneGraphic\3rdParty\include\geos中,将编译后生成的lib文件拷贝到G:\OSGCore\Bulid\OpenSceneGraphic\3rdParty\lib下,将编译后生成的dll拷贝到G:\OSGCore\Bulid\OpenSceneGraphic\3rdParty\bin下)。如果找到的两个dll文件名称相同,则将debug下的dll的文件的名称后加上d(文件可以在geos编译的工程文件里面找)拷贝结束后的文件夹目录结构:
3. 编译GDAL
gdal 64bit的编译,与GEOS有些类似,但比后者简单,仅使用nmake的方式即可,具体操作方式如下:
1)下载
gdal下载地址:http://trac.osgeo.org/gdal/wiki/DownloadSource
我使用的是gdal2.2.4
2)修改编译文件
解压后的文件中应该有一个nmake.opt文件,在编译之前需要修改nmake.opt中的一些配置。
1、GDAL_HOME = “C:\warmerda\bld”,编译后的生成的头文件、静态库、动态库将会存储到这个路径。我在D盘新建了文件夹gdal2.24,然后修成了D:\gdal2.24。
2、”#WIN64=YES”,编译64位GDAL时,要删除前面的#。
3、 将
改为:
因为编译的时候会报错:
修改之后就不编译ODBC,然后就用不了ODBC,不过关系不大。
3) 编译
a. 进入VS2010 X64 本机工具命令提示符,在菜单栏的Visual Studio 2010文件夹下
b. 使用命令行,进入到源代码目录
c. 依次输入:
nmake -f makefile.vc
nmake /f makefile.vc install
nmake /f makefile.vc devinstal
第一个命令是编译GDAL
第二个、第三个命令是将生成的头文件、静态库、动态库复制到GDAL_HOME目录。如果需要编译debug模式,就将第一个命令改成nmake -fmakefile.vc DEBUG=1
4. libzip
libzip(vs10)需要下载(http://pan.baidu.com/s/1o70sB6E 密码:n9l6),把解压后的头文件放到G:\OSGCore\Bulid\OpenSceneGraphic\3rdParty\include\libzip下,*.lib放到lib文件夹中,*.dll文件放到bin文件夹中。
5. zlib(minizip)
就用3rdParty/lib下面的zlib.lib和zlibD.lib,头文件zlib.h下载后放到include中的zlib文件夹下,下载链接:http://www.winimage.com/zLibDll/minizip.html
6. 编译sqlite
注:sqlite的编译,如果用不到sqlite,则无需加入编译过程,虽然在后面的osgearth
cmake时会提示有sqlite的选项,直接忽略就行。如果需要,可按照以下网上的步骤进行编译
下载链接:http://www.sqlite.org/download.html
编译步骤:
1.首先下载两个压缩包:http://www.sqlite.org/download.html
2.解压后,把sqlite-dll-win64-x64-3220000下的两个文件放到sqlite-amalgamation-3220000解压后的目录下,解压后文件夹重命名为sqlite3。组合成下面所示:
3.可按照下面链接中的方法进行编译:
https://www.cnblogs.com/baipengchao/p/5123346.html
4.按照链接中的方法生成debug 和release版本,分别命名为sqlite3d.lib|sqlite3d.dll,sqlite3.lib|sqlite3.dll
5.把sqlite3.lib 和sqlite3.dll拷贝到
G:\OSGCore\Bulid\OpenSceneGraphic\3rdParty\bin、G:\OSGCore\Bulid\OpenSceneGraphic\3rdParty\lib
7. 其它库的编译
当然还有许多其它库的编译,例如Expat,protobuf,这些一般是用不到。同时这些也不需要编译,只需要进行安装或者下载已编译好的压缩包,把相关文件放到3rdParty的bin,include,lib目录中就可以。
五、编译前配置Cmake生成sln
G:\OSGCore\Bulid\osgearth-osgearth-2.8.0:osgearth源码存放位置
cmake配置
1.配cmake
2.创建64位 cmake 生成工程
具体和OSG编译文档的设置方法相似,在设置cmake的时候点击2010 WIN64即可
3.指定OSG路径:
4.指定3rdParty路径:
5.点击Configure,勾上Advanced,然后依次对CURL;GDAL;GEOS;ZLIB进行处理
其余的见机行事,没有配置文件的,可以直接忽略
注意:这里需要说的是,ZLIB文件在我们使用的cmake版本中可能不是上面的截屏那样的,会出现上图所示四个或者三个,上面那个图是四个,还有一个对应的ZLIB_LIBRARY_RELEASE,那就需要按照下图的修改方法来修改,修改后再重新点击一下Configure,会出现红色错误,但是不用管。 解决方案链接为 http://blog.csdn.net/worrydog/article/details/71438588
六、编译OSGEarth
1、编译过程
1)如果配置完成后,打开G:\OSGCore\OSGEarth文件夹,打开OSGEARTH工程在,注意是否是64位程序。
2)设置ALL_BUILD的include 包含目录和库目录:
编译osgearth的过程中,有几个项目需要设置include包含目录,主要有:
osgEarthFeatures
osgEarthSymbology
osgEarthUtil
Pluginsosgearth_arcgis
Pluginsosgearth_feature_ogr
Pluginsosgearth_feature_tfs
Pluginsosgearth_feature_wfs
Sampleosgearth_featureinfo
如果嫌一个一个配置太麻烦,可以选择菜单栏“视图”—>其它窗口-->属性管理器,只需配置一个All_build的debug或Realse属性,所有的项目工程就都具有了相同的包含目录和库目录
3. 生成-批生成,对All_BUILD进行生成,选择(Debug和Release两个版本),这段编译时间是很长的,估计2个小时(也看个人电脑的性能与配置,我的是一个小时不到)。
注意上述的配置include包含目录文件只是列出了debug的,release的配置方式和debug相同的,重复上述的操作即可
2、编译过程中可能遇到的错误及解决方案
在编译开始后,总会出现一大堆错误,而且大多数错误是类似“error LNK:无法打开外部文件xxxx”或“无法解析外部函数。。。。。被xxxx给占用”。在osgearth整个解决方案的编译过程中,其实最核心的还是Core目录中的osgEarth、osgEarthAnnotaion、osgEarthFeatures、osgEarthSymbology、osgEarthUtil这五个工程的编译,只要这五个的debug和release编译通过了,则基本上整个的sln工程就可以成功。
反过来一般出的错误都是在进行这五个项目编译过程中出现的,一个项目中的debug或release生成的lib文件没有生成成功,导致后续的工程中lib文件无法生成,造成一系列的错误。如下图所示
而这五个项目的又是依次依赖的,这五个生成的先后顺序是osgEarth、osgEarthSymbology 、osgEarthFeatures 、osgEarthAnnotaion、osgEarthUtil。
因为osgEarthUtil需要前三者或四者的lib或dll库,而osgEarthAnnotaion则需要前三者的两个文件,osgEarthFeatures需要前两者的文件,osgEarthSymbology仅需要osgEarth提供的两个文件。因此当出现很多错误时,可以按照上面红字部分的顺序,依次单独编译,从而排查错误所在。依我个人的编译过程来看,只要osgEarth的debug和Release编译成功,osgEarthSymbology一般不会出现错误,而在进行第三个osgEarthFeatures编译时问题可能较多了。
a.在第一次进行osgearth编译时,出现了1万多个错误,都是提示cmath中函数错误:
网上的说法是项目中存在某个math文件与VS系统原库中的math文件名称相同,可以更改自身项目中的该文件名称,如gmath.h。但本项目所有的文件都是osgearth源代码及第三方库源代码中的文件,不能更改名称,后来发现是在osgearth项目中对第三方库的include设置不对。
按照网上的教程,一般都是说在编译curl、geos、gdal等第三方库后,搜索全部的dll,lib,h文件,在osg源目录中新建curl、geos、gdal等文件夹,并在这些文件夹中分别创建include,lib目录,放置各自的h,dll,lib文件,最后在osgearth工程中分别将这些库的include,lib加载 到包含目录和库目录中,例如:
G:\OSGCore\curl\include
G:\OSGCore\geos\include
这种将各个第三方库单独分出来的方式确实有助于后期配置,但会造成osgearth中的某些文件对第三方库的引用路径出错,如#include会提示无法打开export.h文件以及cmath文件中的上述错误。为了避免这种错误,只需将编译后的第三方库中的根目录中的include文件夹下的文件夹拷贝到"G:\OSGCore\Build\OpenSceneGraph\3rdParty\include"中,如将geos根目录下的include中的geos文件夹拷贝到上述路径中。不过对于dll和lib可以不必如此设置,可以在编译后搜索所有的dll文件,放到G:\OSGCore\Build\OpenSceneGraph\3rdParty\bin目录下,lib文件放到G:\OSGCore\Build\OpenSceneGraph\3rdParty\lib目录下,如图所示
b. osgEarth项目编译中,出现的错误之一是找不到TextureBuffer这个头文件
而DrawInstanced.cpp中引用了osg库中的该文件。后来发现造成这个错误的原因是,我最开始进行编译的OSG的版本是3.0.0,而在该OSG的源目录中并没有这个TextureBuffer,查看了OSG3.4.1的版本源代码后发现这个版本中是存在该文件的。因此最后只能使用OSG3.4.1重新编译了OSG,并且换成了64bit的版本,之后就再也没有出现这个错误。
c.前文在编译GEOS中说过,使用nmake编译得到的Release版本的geos.dll和geos.lib是有效的,但debug版本的geosd.dll和geosd.lib是无效的,若使用了这两个文件,则在进行osgEarth编译时总是会提示如下错误:
这是由于debug使用了Release版本的lib文件,按网上的方法也无法解决,因为这两个文件确实是使用nmake在debug模式下生成的。网上的方案:https://www.cnblogs.com/lisuyun/p/6410393.html
因此需要使用cmake方式,先生成项目文件,再在sln工程中编译生成geosd.dll/geosd.lib或geos.dll/geos.lib。
d. 在osgEarth目录中Registry.cpp中会出现MimeTypeExtensionMap与getMimeTypeExtensionMap()不可访问
后来发现是因为原来使用的OSG3.0版本中osgDB::Registry文件中这个类和方法是protected的,不可访问,而新OSG3.4.0中是却是public的,改了版本之后错误消失。
e. 在osgEarthSymbology编译时,会出现关于Geos的错误,如下图所示
这是由于使用的geos版本太新,原来的public类或方法,在新版本中变成了protected无法访问,因此可以更改到旧版本。
参考:https://blog.csdn.net/worrydog/article/details/71512959
f. osgEarthFeatures编译时只遇到了"未定义标识符OGR_G_Area",后来发现在github中下载的osgearth2.8版本中,GeometryUtils.cpp文件第153行的原来的OGR_G_GetArea函数写成了OGR_G_Area,修改后错误消失。
目前只能列举这些,一些错误由于没有备份,忘记了。
3、环境变量设置及测试
软件部署(只是列出了debug,release于debug相同)
osgEarth软件包主要包括五个目录:bin,data,include,lib,src。
1. G:\OSGCore文件夹下建立一个文件夹path;G:\OSGCore\Path,在path下建立上述五个子目录,如下图所示:
2. 组织bin目录,bin主要包含dll和exe,如下表所示:
拷贝第一项:定位G:\OSGCore\Bulid\OpenSceneGraphic\bin,搜索*.dll和*.exe,拷贝到bin
拷贝第二项:定位G:\OSGCore\OSGEarth,,搜索*.dll,拷贝到bin
拷贝第三项:定位G:\OSGCore\OSGEarth,,搜索*.exe,拷贝到bin
拷贝第四项:定位G:\OSGCore\Bulid\OpenSceneGraphic\3rdParty,搜索*.dll,拷贝到bin
3. 组织data目录:
首先把G:\OSGCore\Bulid\OpenSceneGraphic\data下的所有拷贝到data
然后把G:\OSGCore\Bulid\osgearth-osgearth-2.8.0\data下的所有拷贝到data
首先把G:\OSGCore\Bulid\osgearth-osgearth-2.8.0\tests下的所有拷贝到data
4.组织include
首先把G:\OSGCore\Bulid\OpenSceneGraphic\include下的所有拷贝到include
然后把G:\OSGCore\Bulid\osgearth-osgearth-2.8.0\src下的所有拷贝到include,可以把该目录下的.cpp文件删除,保留.h头文件。
5.组织Lib和dll
拷贝第一项:定位G:\OSGCore\Bulid\OpenSceneGraphic\lib,搜索*.lib,拷贝到lib
拷贝第二项:定位G:\OSGCore\OSGEarth\x64\Debug,搜索*.lib,拷贝到lib
拷贝第三项:定位G:\OSGCore\Bulid\OpenSceneGraphic\3rdParty,搜索*.lib,拷贝到lib
把osg环境变量进行一定的修改:
OSG_FILE_PATH:G:\OSGCore\Path\data
PATH:G:\OSGCore\Path\bin
软件测试
打开cmd,输入osgearth_viewer
gdal_tiff.earth观察会不会出现下面的图,出现即表示编译成功