ARM环境下编译osg和osgEarth需注意:
1、osg和osgEarth的关系是:osg是一个专门为了三维图像而生的函数库,而osgEarth则是在osg的基础上,更加集中于构建三维下的地球的一个函数库。
2、osg和osgEarth的版本选择很重要!两者的版本号是有相关性的,所以一定要注意你所下载的osg和osgEarth的版本,是否适配。所谓的适配,意思是,在osgEarth中会调用到一系列的osg的函数,但是这些函数,在最新的osg版本中,可能已经被取消了,或者更名了,都有可能。最新的osg是3.6.5版本,但是并不适用于所有的osgEarth的版本,osgEarth我能找到的最新版本是3.1,试了一下,osgEarth3.1和osg3.6.4版本,是无法成功编译的,当然,不能说是不适配,因为在我试的过程中,可能存在别的问题。但我可以肯定的是,osg3.4.0和osgEarth2.8以及osgEarth2.9版本是适配。
3、注意在切换osg版本时,一定要将原版本卸载干净。曾在这儿就吃了亏,一开始选用osg3.6.4版本,后来更换为osg3.4.0版本,当时没清理干净,导致在编译osgEarth时,不断报错,提示xxx:未定义的引用,当时很奇怪,这函数明明是源代码自带的代码中的函数,为什么一直报未定义的引用,这个报错,意思是在在头文件声明了,但是cpp中,或者说编译后的库文件中,未定义。后来我查到,库文件的链接,即LINK不对,指向了osg3.6.4版本,就是没删除干净。要删除干净,就需要搞清楚源代码编译究竟生成了什么,放在了哪里。源代码编译的时候,根据个人习惯,一是可以将依赖的库文件编译后放在一个自定义的位置,比如通过再configure后追加参数,./configure --prefix=/home/osgEarth/
,另一种是放在默认位置,即/usr/local
下,这个看个人习惯,各有各的好处,放在自定义的位置,方便卸载,放在默认位置,不用考虑环境变量的问题。源代码编译后的结果无非三种文件,一种是头文件,即函数的声明,默认放在/usr/local/include
下,一种的可执行文件,默认放在/usr/local/bin
下,一种是库文件,即函数的定义,默认放在/usr/local/lib
或者/usr/local/lib64
下。因此,知道了有什么东西,放在哪,卸载的时候,即手动去删除,务必删除干净。
4、在编译osg代码时,需要指定使用QT5版本,因为现在大部分linux系统下,自带QT4和QT5,所以需要指定位置。在CMakeList.txt文件的IF(OSG_USE_QT AND NOT ANDROID)
的前一行,添加SET(DESIRED_QT_VERSION 5)
。
5、在编译osgEarth时,在2.8版本中,如果不指定使用X11版本,会报错,因此,需要修改CMakeList.txt文件,在首行添加,add_definitions(-std=gnu++11)
或者add_definitions(-std=c++11)
。
6、在osgEarth编译时,为生成可供Qt使用的库文件,修改CMakeList.txt中如下两处,由OFF改为ON。
OPTION(OSGEARTH_QT_BUILD "Enable to use Qt (build Qt-dependent libraries, plugins and examples)" ON)
OPTION(OSGEARTH_QT_BUILD_LEGACY_WIDGETS "Build the legacy Qt widgets" ON)
7、将bin和lib文件夹写入环境变量。编译osg和osgEarth成功之后,在编译的目录下会出现lib和bin两个文件夹(inlcude的文件,已经默认放在了/usr/local/include
下),将这两个单独放置一个妥善位置,建议同osg的DATA文件放一起,方便管理,而后将lib和bin的目录所在地址,写入/etc/profile
,每次修改完这个文件profile后,记得`source /etc/profile``,使其生效。
export PATH=${PATH}:/home/greatwall/osg_install/OpenSceneGraph-build/bin
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/home/greatwall/osg_install/OpenSceneGraph-build/lib
export OSG_FILE_PATH=/home/greatwall/osg_install/OpenSceneGraph-Data
二、库文件依赖的解决
1、依赖问题始终是最棘手的问题,为了解决依赖问题,可以根据osg和osgEarth中的CMakeList中的提示,可以获悉需要什么依赖,以及该库的版本号。我在解决依赖问题的时候,将所有能下到的依赖库的源代码下了下来,自行编译,其实本人觉得,直接编译源代码会简单一些,源代码的编译方法其实相对比较简单,大致上就是两个方法去编译,一个就是看见源代码目录下,有configure文件,就使用./configure
来编译,生成Makefile文件,第二种方法是看见目录下,有CMakeList.txt
文件,就使用cmake CMakeList.txt
去生成Makefile,总之,都是为了生成Makefile文件,然后可以进一步make,sudo make install
。
2、在处理osg和osgEarth中涉及的依赖时,只编译了部分依赖,其实还有一些依赖未解决,但不影响osg和osgEarth编译的成功,不过不解决,会导致后面部分功能无法使用。
3、网上有一个集成依赖库的,OSG配置第三方资源库3rdparty,这个仅适用于windows平台,不适用于linux。
4、osg和osgEarth所涉及的依赖的库文件,他们之间也存在一些依赖关系,所以编译的顺序应该较为严格执行。以下顺序仅供参考。
1) 编译 zlib
2) 编译 png
3) 编译 curl
4) 编译 freetype
5) 编译 gdal(proj->geos->gdal)
6) 编译 jpeg(nasm->libjpeg)
7) 编译 tiff
8) 编译 minizip
9) 编译 sqlite
10) 编译 SDL2
11) 编译 libtool
12) 编译 googletest
13) 编译 protobuf
14) 编译 rocksdb(gflags->rocksdb)
5、在上述库文件的编译过程中,大部分只需要简单的编译。
如,有configure文件时候,使用
./configure
make -j8
sudo make install
有CMakeList.txt时,使用
cmake CMakeList.txt
make -j8
sudo make install
只有下述几个情况比较特殊。
6、在用configure生成Makefile文件时,有时候会报错configure:error: cannot guess build type; you must specify one
,这时候,只需要在configure后添加参数,指定编译所用的引擎即可。./configure --build=arm-linux
。
7、在编译gflags库,默认只生成静态库,而在编译rocksdb时候,需要调用gflags的动态库,需要动态库才行。解决的方法。在cmake生成Makefile时,启用动态库。cmake -DBUILD_SHARED_LIBS=ON -DBUILD_STATIC_LIBS=ON -DINSTALL_HEADERS=ON -DINSTALL_SHARED_LIBS=ON -DINSTALL_STATIC_LIBS=ON
。
8、在编译protobuf库文件时,需要首先运行./autogen.sh
而后才会出现configure文件。
9、每编译完一个库文件,建议在命令行输入一次sudo ldconfig
,更新引用,不然可能会有部分库文件不能马上生效,导致后续相关依赖的库文件编译时报错。
10、如若在库文件编译时,自定义目录,建议将所有目录统一,方便写入环境变量,写入环境变量,则需要使用export,写在/etc/profile
最后面。
三、测试是否成功
1、测试osg,可以在命令行运行osgviewer cow.osg
是否显示一头牛,或者osgversion
,看是否显示版本号。
2、测试osgEarth,可以在命令行运行osgearth_version
,看是否显示版本号。
注意:
- 程序运行使用的Dll必须和编译时候使用的保持一致。
- CMake不同版本可能存在不一致性,所以编译特定版本的osgearth库要查看一下推荐哪个版本的Cmake。