VS2019下OSG 3.6.5与osgEarth三方库配置与编译 简介面向使用 Visual Studio 2019 开发 OSG3.6.5 与 OSGEarth2.10 三维地球应用的 C 开发者这套预编译 64 位第三方库用于减少逐项编译依赖、处理链接错误和配置环境的时间适合需要快速建立可编译工程的中级学习者。压缩包约 2000 个文件、整体 137.76MB以 1351 个头文件、56 个静态库和 4 个动态库为主并配有 cmake 配置、inc 模块文件及少量 C/C 源码与辅助页面覆盖声明、链接库和构建配置等环节。目前已有 626 人学习下载。包内依赖按模块整理读者可在 VS2019 工程中直接引用头文件与库目录用于复现编译环境、定位第三方库缺失、核对库文件结构也能作为整理本地依赖与排查版本不匹配问题的参考。1. 别急着运行 CMake先搞清 3rdParty.zip 里装的是什么在 VS2019 上编译 OSG 3.6.5真正卡住的往往不是引擎本身而是那二十几个第三方库zlib、libpng、libjpeg、libtiff、freetype、curl、GDAL、PROJ、sqlite3、expat、libxml2 等等。每个库都自己编译一遍配置一次或两次就能花掉一整天版本之间还互相冲突。这份预编译好的 3rdParty.zip 解决的正是这件事它按 VS2019 的 v142 工具集和 x64 位把 OSG 3.6.5 与 OSGEarth 需要的三方库编译好了include、lib、bin 成套提供你只需要在 CMake 里把路径指过去。它适合两类人一是想跳过依赖编译问题、直接生成引擎的二是已经编译失败过一次、需要一份版本能对得上的参照物来反查自己哪里配置错了。2. 拆包先看三层目录工具集标签、位数与 CMake 变量的对应关系2.1 解压后先确认三件事拿到手的包目录组织常见两种形态。一种是平铺的顶层直接就是include、lib、bin三个目录另一种按工具集和平台分了层形如x64/v142/include、x64/v142/lib。这两种布局决定了你后面CMAKE_PREFIX_PATH到底该指到哪一层指错一级CMake 就会安静地少找到一半库最后表现为插件被跳过而不是报错。先花两分钟确认目录不要省略# 1) 看顶层结构include / lib / bin 是否成套还是按工具集分了层 Get-ChildItem D:\OSG\3rdParty | Select-Object Name, Mode # 2) 往下探两层确认 v142 这一级在哪v142 对应 VS2019v143 对应 VS2022 Get-ChildItem D:\OSG\3rdParty -Directory -Recurse -Depth 2 | Select-Object FullName # 3) 抽查关键头文件是否齐全缺哪个后面就会缺哪个插件 zlib.h,png.h,jpeglib.h,tiffio.h,ft2build.h,gdal.h,proj.h,sqlite3.h,curl/curl.h | ForEach-Object { [pscustomobject]{ Header $_; Exists Test-Path D:\OSG\3rdParty\x64\v142\include\$_ } }第三段里的Test-Path路径按你实际层级改。这一步的价值在于OSG 的 CMake 在找不到某个依赖时默认行为是把这个依赖对应的功能关掉然后继续编译。也就是说你可能得到一份“编译成功但缺 gdal 驱动、缺 curl 插件”的产物等到运行时加载 .earth 文件才报错。提前查一遍头文件比事后排查省事得多。接着看lib目录里的文件名。这里要注意 Debug 和 Release 是分开放的还是同名的。常见的三种情况只有 Release 库文件名不带后缀Release 和 Debug 分两个子目录lib和lib/debug或者 Debug 库带d后缀zlibd.lib、libpng16d.lib。这一点直接决定你后面能不能同时生成 Debug 和 Release 两套也是第五章第一个问题会涉及的根源。2.2 OSG 的 CMake 在 Windows 上是怎么找这些库的OSG 源码根目录下有个CMakeModules目录里面是一批FindXXX.cmake比如 FindZLIB、FindPNG、FindJPEG、FindTIFF、FindFreetype、FindCURL、FindGDAL、FindSqlite3、FindEXPAT、FindLibXml2。这些脚本在 Windows 上遵循 CMake 的标准查找顺序先看缓存变量有没有被手动指定再看CMAKE_PREFIX_PATH最后才在系统默认路径里查找。关键在于查找规则find_path会在候选前缀下拼/includefind_library会拼/lib。所以只要把CMAKE_PREFIX_PATH指向同时含include和lib的那一层父目录大部分依赖就能被自动找到。提示CMAKE_PREFIX_PATH要指到这两个目录的父目录不要指到include或者lib本身。指错了不会报“路径不存在”只会找不到排查起来很费时间。另外部分版本的 OSG 在 CMakeLists 里还会认一个ACTUAL_3RDPARTY_DIR缓存项作用是一次性把所有依赖的搜索根目录换掉。你可以在 OSG 源码根目录搜一下这个名字Select-String -Path D:\OSG\src\OpenSceneGraph-3.6.5\CMakeLists.txt -Pattern 3RDPARTY_DIR搜得到就顺手传搜不到就老老实实用CMAKE_PREFIX_PATH加逐个变量指定这两条路都能走通。2.3 一张变量对照表把路径固定下来如果三方库目录层级规整CMAKE_PREFIX_PATH一条就够了。但如果包里混了多个版本的同名库或者某个库的头文件被放在奇怪的位置GDAL 和 freetype 经常这样就得逐个固定路径。下表是我常用的对应关系变量名是 OSG 的 Find 模块实际读取的那几个依赖头文件变量库变量目录里常见的文件名zlibZLIB_INCLUDE_DIRZLIB_LIBRARYzlib.lib或zlibstatic.liblibpngPNG_PNG_INCLUDE_DIRPNG_LIBRARYlibpng16.liblibjpegJPEG_INCLUDE_DIRJPEG_LIBRARYjpeg.lib、libjpeg.liblibtiffTIFF_INCLUDE_DIRTIFF_LIBRARYlibtiff.lib、tiff.libfreetypeFREETYPE_INCLUDE_DIRSFREETYPE_LIBRARYfreetype.libcurlCURL_INCLUDE_DIRCURL_LIBRARYlibcurl.lib、libcurl_imp.libGDALGDAL_INCLUDE_DIRGDAL_LIBRARYgdal.libPROJPROJ_INCLUDE_DIRPROJ_LIBRARYproj.libsqlite3SQLITE3_INCLUDE_DIRSQLITE3_LIBRARYsqlite3.libexpatEXPAT_INCLUDE_DIREXPAT_LIBRARYexpat.lib、libexpat.lib对应的固定写法可以把这一段放到一个单独的.cmake文件里用-C预置进缓存也可以直接拼进命令行。我用后者多一点因为出问题时命令行就在历史记录里不用再回头翻文件# 假设 TP 指向 x64/v142 这一层 set(TP D:/OSG/3rdParty/x64/v142) set(ZLIB_INCLUDE_DIR ${TP}/include CACHE PATH zlib headers) set(ZLIB_LIBRARY ${TP}/lib/zlib.lib CACHE FILEPATH zlib import lib) set(PNG_PNG_INCLUDE_DIR ${TP}/include CACHE PATH libpng headers) set(PNG_LIBRARY ${TP}/lib/libpng16.lib CACHE FILEPATH libpng import lib) # 其余照抄把 lib 文件名换成你目录里真实存在的那个不要凭记忆写文件名一定要按目录里实际存在的内容填写。三方库打包方式差异很大同一个库在这份包里叫libcurl.lib在另一份里可能叫libcurl_imp.lib写错一个字符CMake 就当成没找到。3. 编译 OSG 3.6.5从 CMake 配置到 install 产物的完整链路3.1 源码、三方库、构建目录的摆放约定目录结构如果不整理好后面会出现两类很难查的问题一是install目录被上一次失败构建的残渣污染新产物和老产物混在一起二是构建目录放在源码目录里清理时删不干净。我的习惯是四个目录完全分开D:\OSG\ ├─ 3rdParty\ 预编译三方库解压后不再改动 ├─ src\ │ ├─ OpenSceneGraph-3.6.5\ │ └─ osgEarth\ ├─ build\ │ ├─ osg365\ CMake 的二进制目录 │ └─ osgearth\ └─ install\ OSG 和 osgEarth 共用一个安装前缀源码、构建、安装三者分离的好处很直接--target INSTALL是覆盖写install目录可以随时整个删掉重来而源码和三方库保持原样构建目录出问题删掉重建代价只有一次 CMake 配置的时间。另外提醒一句整条路径尽量全 ASCII、不要空格、不要太深。这不是迷信第五章最后一节会讲为什么。3.2 一份可直接抄的配置命令逐行解释开关VS2019 对应的生成器名是Visual Studio 16 2019平台用-A x64指定。下面这条命令是我在 x64 环境下反复用过的版本cmake -S D:\OSG\src\OpenSceneGraph-3.6.5 -B D:\OSG\build\osg365 -G Visual Studio 16 2019 -A x64 -DCMAKE_INSTALL_PREFIXD:/OSG/install -DCMAKE_PREFIX_PATHD:/OSG/3rdParty/x64/v142 -DBUILD_OSG_APPLICATIONSON -DBUILD_OSG_EXAMPLESOFF -DBUILD_DOCUMENTATIONOFF -DDYNAMIC_OPENSCENEGRAPHON -DDYNAMIC_OPENTHREADSON -DOPENGL_PROFILEGL3 -DCMAKE_DEBUG_POSTFIXd逐项说明一下为什么这么设CMAKE_INSTALL_PREFIX统一指向D:/OSG/install是为了让后面 osgEarth 用find_package直接找到 OSG不用再配第二套路径。CMAKE_PREFIX_PATH指到x64/v142这一层理由在 2.2 说过。DYNAMIC_OPENSCENEGRAPH和DYNAMIC_OPENTHREADS设成 ON 是生成 DLL 而不是静态库。写业务代码时这一点很关键DLL 模式下插件osgdb_png.dll这类才有意义静态链接时插件机制基本失效读到非原生格式就报“找不到合适的读取器”。OPENGL_PROFILE设GL3是给 osgEarth 3.x 用的。默认值一般是更老的配置画能画出来但某些着色器路径会退化帧率也上不去排查这类问题很容易变成无休止的调试过程。如果你只是纯粹跑 OSG 不做地球保持默认也不是不行。CMAKE_DEBUG_POSTFIXd会让 Debug 版的库和 DLL 带d后缀比如 Release 是osg.dll、Debug 是osgd.dll插件同理。这个名字后面在第五章排查“插件加载不上”时还会遇到。配置完成后重点看 CMake 输出里那一段依赖汇总。正常情况你能看到逐行列出 zlib、png、jpeg、tiff、freetype、curl、gdal、sqlite 的“找到/未找到”。出现Could NOT find的项先在 2.3 的表里固定对应变量再重新配置。不要带着缺项往下编译编译是通过了运行时就要遇到问题。3.3 编译、安装、产物自检# 只编 Release目标直接打 INSTALL省一步手动拷贝 cmake --build D:\OSG\build\osg365 --config Release --target INSTALL -- /m:8/m:8是传给 MSBuild 的并行度按你的物理核数调整一般设成核数或核数的一半。内存小的机器把并行度调低些否则链接阶段容易因为内存不足出现莫名其妙的失败。编译完成后不要直接开始写代码先做一次产物盘点$root D:\OSG\install 主 DLL 数量 : (Get-ChildItem $root\bin -Filter *.dll -File).Count 插件数量 : (Get-ChildItem $root\bin\osgPlugins-3.6.5 -Filter *.dll -File).Count 导入库样例 : Get-ChildItem $root\lib -Filter *.lib | Select-Object -First 8 Name 版本头文件 : (Test-Path $root\include\osg\Version)三个判断标准bin下的主 DLL 应该有十几个以上osg、osgDB、osgUtil、osgViewer、osgGA、osgText、osgSim 等各自一个插件目录里的 DLL 通常有几十个如果只有个位数基本可以确定是三方库没找全对应的读写插件被跳过编译了include\osg\Version必须存在缺了说明安装步骤根本没跑完你拿到的是一个半成品。4. 编译 OSGEarth版本匹配、依赖裁剪与插件目录4.1 osgEarth 与 OSG、GDAL、PROJ 之间的版本匹配osgEarth 3.x 对 OSG 的主次版本是有硬性检查的写在根目录的 CMakeLists 里。别凭印象判断直接搜Select-String -Path D:\OSG\src\osgEarth\CMakeLists.txt -Pattern OSG_VERSION|MIN_OSG|OSGEARTH_VERSION|CXX_STANDARD这条命令会同时告诉你三件事它要求的 OSG 最低版本、osgEarth 自己的版本号、以及 C 标准3.x 一般是 C11部分分支要求 C14。版本对不上时 CMake 会在配置阶段直接拒绝这个失败反而是好事比运行时崩溃好排查一万倍。真正容易出问题的是 GDAL 和 PROJ 这一对。GDAL 3.x 之后坐标系相关功能全部交给 PROJ 6 处理运行时需要proj.db这个数据文件而 GDAL 2.x 时代的二进制包根本不带这个东西。osgEarth 的 gdal 驱动是通过 GDAL 间接调用 PROJ 的所以一旦 PROJ 的运行环境没配好症状不是“编译失败”而是“能启动、能画球、一加载带投影的影像就报错或者位置偏到别处”。这也解释了为什么这份预编译三方库的价值主要在这里GDAL 和 PROJ 的版本必须相互匹配自己单独升级其中一个大概率会掉进 API 变更的坑里。我的建议是保持包内原有组合不替换真需要新版 GDAL 就整体重编一套不要只替换其中一半。GEOS 属于可选依赖不装不影响主流程但涉及缓冲区、相交判断这类几何运算时没有它就跑不了。是否启用看你的业务场景纯做影像贴图和地形渲染的项目可以不装省一点体积和出错面。4.2 配置命令与必须显式指定的几个变量# 先确认 OSG 的 config 文件到底安装在哪个子目录不同分支位置不完全一样 Get-ChildItem D:\OSG\install -Recurse -Filter OpenSceneGraphConfig.cmake | Select-Object FullName拿到真实路径后再配置cmake -S D:\OSG\src\osgEarth -B D:\OSG\build\osgearth -G Visual Studio 16 2019 -A x64 -DCMAKE_INSTALL_PREFIXD:/OSG/install -DCMAKE_PREFIX_PATHD:/OSG/install;D:/OSG/3rdParty/x64/v142 -DOpenSceneGraph_DIRD:/OSG/install/lib/cmake/OpenSceneGraph -DBUILD_OSGEARTH_EXAMPLESOFF -DOSGEARTH_BUILD_TESTSOFFCMAKE_PREFIX_PATH里同时放了两个前缀install用来找 OSG 自己3rdParty用来找 GDAL、PROJ、curl。osgEarth 找 OSG 走的是 config 模式读OpenSceneGraphConfig.cmake找其他依赖还是 module 模式所以两个前缀都得给。OpenSceneGraph_DIR必须明确指定到 config 文件所在目录不要指望 CMake 自己猜。常见的失败信息是Could not find a package configuration file provided by OpenSceneGraph看到这句就回头执行上面那条Get-ChildItem把真实路径填进去。BUILD_OSGEARTH_EXAMPLES关掉是省时间示例工程几十个每个都要链接一遍编一次多花十几分钟而你验证功能只需要osgearth_viewer这一个工具。等主流程稳定了想跑示例再单独打开。4.3 插件目录与运行时 DLL 的部署方式osgEarth 装完之后bin下会多出一个插件目录不同分支的命名不完全一致有叫osgEarthPlugins的也有直接并入osgPlugins-3.6.5的。不要凭记忆找直接列Get-ChildItem D:\OSG\install\bin -Directory | Select-Object Name Get-ChildItem D:\ p a hrefhttps://download.csdn.net/download/AAALB/89539472 stylecolor:#ec7500;font-size:14px; 本文还有配套的精品资源点击获取 /a img altmenu-r.4af5f7ec.gif srchttps://csdnimg.cn/release/wenkucmsfe/public/img/menu-r.4af5f7ec.gif stylewidth:16px;margin-left:4px;vertical-align:text-bottom;cursor:text; /p