尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

GDAL源码编译完全指南:从CMake配置到裁剪定制

GDAL源码编译完全指南:从CMake配置到裁剪定制 简介这是一套面向GIS开发者的GDALOGR预编译开发包省去从源码编译的繁琐流程适合需要快速集成栅格与矢量数据处理能力的C/C或Python项目可用于遥感影像读取、地图格式转换、投影变换、几何运算等场景。压缩包共1751个文件容量24.49MB以h头文件、cpp源文件、obj目标文件为主同时包含dll、lib运行库及in、am、html等辅助配置与文档目录结构完整能够直接链接使用。包内整合了GDAL、OGR、GEOS与PROJ等关键底层库支持TIFF、Shapefile、GeoJSON、KML、PostGIS等常见格式的读写与坐标系统转换。已有252人学习下载适合缺乏编译环境或希望节省搭建时间的GIS数据开发人员可快速投入实际开发与数据分析。 做GIS开发的手里没一份能用的GDAL/OGR库很多活都干不利索。这组库在地理空间数据处理领域地位太稳了栅格、矢量、投影转换、格式转换、空间分析几乎无处不在地被引用。但问题恰恰出在这它太能干了功能多、依赖也多很多人拿到手的第一反应不是怎么用而是怎么把它编译出来。这篇博文不打算写那些“下载即所得”的假教程而是把“以编译可以直接用”这件事说透——你既可以直接获取一份编译好的二进制库快速接入项目也可以从源码自己编译一份定制版本。两条路我都会讲重点放在源码编译这条主线上因为这是你以后遇到“某某驱动没编进去”“体积太大想裁剪”“运行时库不匹配”这类问题时的根本解法。适合C开发者、GIS后端工程师以及所有被GDAL卡过编译的同行参考。1. 先搞清楚你需要的到底是“编译”还是“配置”很多人一上来就搜“GDAL编译”但其实他心里的需求是“拿一份能用的库”。这是两码事方向不对后面全是弯路。1.1 GDAL和OGR的关系为什么总是成对出现GDALGeospatial Data Abstraction Library最早只做栅格数据处理遥感影像、DEM这些OGR是后来合并进来的矢量模块处理Shapefile、GeoJSON、PostGIS这些矢量数据源。合并之后名义上还是一个库只是模块分工不同。所以你看到的头文件、链接库往往都叫gdal矢量功能也默认在同一个库里面。理解这个背景很重要。因为编译时你并不需要分别编译GDAL和OGR两个库而是编译一份GDAL矢量能力自然就带上了。社区里很多老教程还停留在“先编GDAL再编OGR”的思路那是远古时代的产物现在早就不用这么折腾了。1.2 为什么有现成的安装包还要自己编译这是最核心的问题。官方和第三方确实提供编译好的二进制包GISInternals上有打包好的Windows版本分MSVC版本、x86/x64、debug/release很全。OSGeo4W提供Windows下的安装管理器装完就能用。Linux发行版仓库里也有apt install libgdal-dev 就能一键装好。vcpkg和conda也有现成的port和包。听起来已经很省事了但你还是会遇到不得不自己编译的情况。我列几个真实场景第一MSVC运行时库不匹配。你项目用的是MT静态运行时下回来的预编译包是MD动态运行时链接能过跑起来各种崩溃。第二需要的驱动没编进库里。比如你要读写某个冷门格式预编译包默认没开这个驱动。第三库版本和你的依赖链冲突。项目里已经用了特定版本的PROJ、GEOS、SQLite3预编译包的版本对不上只能自己编译来对齐版本。第四体积敏感比如嵌入式或者系统集成场景希望裁掉用不到的驱动把DLL从几百MB缩到几十MB。这些需求只有源码编译能满足。所以我的建议是如果是快速验证直接拿现成的如果是交付项目或长期维护自己编译一次后面省心很多。2. 选型预编译包、包管理器、源码编译怎么取舍编译方案不只有一种每一步的选择都直接影响你后面要踩多少坑。我把主流方案放在一起对比一下。方案优点缺点适合场景官方/GISInternals预编译包开箱即用无需动编译环境版本固定、驱动固定、MSVC运行时可能不匹配快速原型验证vcpkg安装依赖自动拉取、版本可指定、和CMake集成顺畅下载慢、默认配置可能不全、定制驱动要改portWindows下C项目conda安装与Python生态契合好gdal和rasterio等配套对原生C项目集成不友好Python数据分析源码编译完全可控、可裁剪、可定制耗时长、依赖配置麻烦、首次编译容易劝退正式项目、交付部署2.1 我的推荐先走源码编译但别从零开始如果让我给一个务实的路径我会说第一次接触GDAL先不要急着从GitHub拉最新代码然后陷入依赖地狱。正确的做法是用vcpkg或者官方GitHub Release提供的源码包。我推荐的方式是先在本地装一个vcpkg用vcpkg install gdal走通一遍看看依赖关系长什么样然后删掉再从源码自己编译一次。这样既了解了编译的全貌又不会因为第一次就面对所有依赖而直接放弃。vcpkg帮你把依赖搞清楚之后你自己编译时心里会有底得多。2.2 选择源码版本的注意事项GDAL从3.0开始构建系统从autoconf切换到了CMake。这是一个分水岭。网上很多教程还在讲./configure --with-XXX那是对应2.x老版本的。如果你用新版源码按老教程操作第一步就废了。我建议直接使用当前主流的3.x版本用CMake方式构建。原因很简单CMake对Windows、Linux、macOS都友好配置文件直观更容易和下游项目集成。而且新版CMake配置支持自动检测依赖的能力强了很多省心。3. 编译前的准备工作把环境理顺源码编译GDAL90%的问题出在环境没准备好。我见过太多人编译失败都是因为编译器不对、依赖库版本混乱、路径里有中文或空格。这些基础问题不解决后面每一步都会给你颜色看。3.1 工具链与源码准备Windows下我用的是Visual Studio 2019或2022配合最新版CMake。注意两点VS安装时一定要勾选“使用C的桌面开发”工作负载否则没有MSVC编译器。CMake在官网下载Windows安装包安装时勾选“将CMake加入系统PATH”。源码从GitHub的OSGeo/gdal仓库拉取。有些教程会让你从官网下载源码zip包也可以但GitHub仓库方便你之后用git管理而且能随时切换tag。建议直接用git clone然后切到你需要的release tag比如release/3.8.0。3.2 依赖库策略需要全部手动编译吗这是新手最容易慌的地方。GDAL依赖很多库PROJ投影、GEOS几何操作、SQLite3属性存储、libtiff、libpng、libjpeg、curl等等。难道全都要手动编译不需要。GDAL的CMake配置有非常强的自动探测能力它会去系统里找这些依赖库找到就用找不到就自动禁用对应的驱动和功能。所以策略分两类你只是想要一个能用的GDAL不用管依赖让CMake自动探测缺啥禁啥。编译出来的库功能少一些但常见格式读写没问题。你需要完整投影功能和矢量数据能力一般项目都想要优先准备PROJ、GEOS、SQLite3三个核心依赖。考虑到手动编译PROJ和GEOS又是一大坨工作我建议用vcpkg把这三个依赖装上也可以顺便装完整的依赖集vcpkg install proj geos sqlite3 tiff libpng libjpeg curl装好之后记下vcpkg的安装路径通常类似 C:/dev/vcpkg/installed/x64-windows。后面CMake配置时要把这个路径传给CMAKE_PREFIX_PATH。3.3 Linux下的差异Linux下编译会稍微省心一点因为包管理器能装到大部分依赖。以Ubuntu/Debian为例sudo apt install build-essential cmake libproj-dev libgeos-dev libsqlite3-dev libtiff-dev libpng-dev libjpeg-dev libcurl4-openssl-dev然后源码编译流程和Windows类似只是生成的是libgdal.so而不是DLL。编译命令本身没有本质区别用CMake那一套就行了。4. 实操CMake配置与编译全流程环境准备好之后就可以正式编译了。我先给出一套可以直接用于Windows的完整命令然后逐步解释关键参数。4.1 从源码到“可以直接用”的完整命令# 1. 拉取源码 git clone https://github.com/OSGeo/gdal.git cd gdal git checkout release/3.8.0 # 2. 创建构建目录 mkdir build cd build # 3. CMake配置 cmake .. -G Visual Studio 17 2022 -A x64 ^ -DCMAKE_BUILD_TYPERelease ^ -DCMAKE_PREFIX_PATHC:/dev/vcpkg/installed/x64-windows ^ -DGDAL_BUILD_OPTIONAL_APPSOFF ^ -DGDAL_USE_GEOSON ^ -DGDAL_USE_PROJON ^ -DGDAL_USE_SQLITE3ON ^ -DGDAL_USE_TIFFON ^ -DGDAL_USE_CURLON ^ -DBUILD_SHARED_LIBSON # 4. 编译Release 配置 cmake --build . --config Release -j8 # 5. 安装到指定目录 cmake --install . --prefix C:/dev/gdal-installed这几条命令执行完之后C:/dev/gdal-installed下就会出现include、bin、lib三个目录这就是一份可以直接用的GDAL开发套件。lib里有gdal.lib导入库bin里有gdal.dll和proj相关的DLLinclude里有gdal_priv.h这些头文件。拿到这个目录你就能在任意CMake工程里通过find_package(GDAL)来引用或者直接用cl /I加头文件路径、链接gdal.lib的方式接入项目。4.2 关键参数为什么这么配CMake参数看着唬人其实每个都对应一个具体痛点。-DCMAKE_BUILD_TYPERelease这个不加有时会默认出Debug版本导致后面链接进release工程时一堆LNK2038运行时库不匹配的报错。Windows下MSVC对Debug和Release的边界拿捏很严格一开始就选定成Release后面少很多麻烦。-DCMAKE_PREFIX_PATH指定的是依赖库的搜索路径。CMake找PROJ、GEOS这些依赖时要靠这个路径去定位它们的config文件。不设置的话CMake就得靠系统环境变量PATH慢慢找找不到就静默禁用对应驱动。这一步配置不准确出来的库就是“缺胳膊少腿”的。-DGDAL_BUILD_OPTIONAL_APPSOFF的作用是不编译gdalinfo、ogr2ogr这些命令行工具。很多人觉得命令行工具多有用但编译它们纯属浪费时间而且它们会拖慢整体编译。如果你的目标是给项目提供库文件这个参数建议关掉。想要命令行工具另一个渠道是去装OSGeo4W。-DGDAL_USE_GEOSON、-DGDAL_USE_PROJON这类参数显式启用了核心模块。把常用的置为ONCMake如果找到了对应依赖就会编进去找不到会报错而不是默默禁用这样你能第一时间发现依赖问题而不是等用到某个功能时才一脸茫然。-DBUILD_SHARED_LIBSON生成动态库OFF则是静态库。项目部署建议用动态库体积可控、更新方便如果你追求单文件发布那就用静态库但静态库方式下还要手动链接一堆系统库比如ws2_32、dbghelp、winmm那会是一个新的折腾列表。我建议选ON除非你的项目对发布载荷有极端要求。4.3 编译过程中会发生什么cmake --build执行后MSBuild会开始编成千上万个源文件。这时候没什么需要干预的但我给你打个预防针第一次全量编译耗时通常在30分钟到2小时之间取决于机器性能。编译过程中如果某个源文件疯狂报错而且错误都出现在gdal开头的头文件里八九不离十是某些“特性开关”出了问题。举个例子当你遇到类似“无法打开包括文件: cpl_config.h”的报错时说明CMake配置阶段没有正确生成配置文件。解决方法是回到build目录重新执行cmake ..观察输出是否正常别直接去跟源码较劲。编译结束后在build目录下的lib/Release里会生成gdal.dll和gdal.lib在apps/Release里可能会看到gdalinfo.exe之类的工具如果你没关的话。但注意这不是最终的成果最好执行一下cmake --install它会统一把文件整理到指定安装目录避免DLL、头文件散落各处。5. 常见编译错误与排查记录编译GDAL踩坑太常见了我把自己遇到的、还有社群里高频出现的问题整理成了一张速查表直接对照处理。典型报错出现原因解决方案CMake Error: Could not find PROJCMAKE_PREFIX_PATH没指向依赖安装目录检查vcpkg/系统依赖路径并重新配置error C2039: “XXX”: 不是“std”的成员编译器标准过低新版GDAL用到C17新特性在CMake里加-DCMAKE_CXX_STANDARD17同时确认VS版本在2019以上LNK2038: 运行时库不匹配Debug和Release混用或MT/MD混用全部统一为ReleaseMD检查依赖库的编译配置fatal error LNK1104: 无法打开文件gdal.lib库搜索路径没配置或lib名带d后缀debug版为gdald.lib确认lib文件名在工程属性中添加正确的依赖路径编译时每个cpp都报cpl_config.h找不到配置文件没生成重新执行cmake查看日志中是否提示缺少平台相关头文件gdalinfo能运行但打开Shapefile返回NULL缺少驱动或中文路径问题用GetDriverCount()确认库是否编入了OGR驱动路径不要带中文5.1 最容易被忽略的链接问题编译本身成功了不代表你下游项目能顺利链接。有一个问题极其常见你会得到一个gdal.lib但它依赖的DLL是带版本号的比如libgdal-4.dll。如果你在VS工程里手动链接gdal.lib运行时系统找不到libgdal-4.dll程序就会启动失败。解决办法是把编译产物的bin目录C:/dev/gdal-installed/bin加到系统PATH或者直接把DLL拷贝到你的exe旁边。如果你用CMake的find_package(GDAL)它会自动处理运行时路径手动配置的时候这一坑最容易踩。另外LNK2038和LNK4098这类错误经常被人忽视。LNK2038是运行时库不匹配LNK4098是LIBCMT与LIBCMTD冲突。这俩都属于“库的编译配置和你的项目不一致”。排查思路就一句话把整个依赖链的MT/MD、Debug/Release全部对齐不要混搭。5.2 编译成功之后怎么确认“可以直接用”编完了别急着欢呼先做一个五秒钟验证。新建一个项目或者直接用命令行编译一个测试程序#include gdal_priv.h #include cstdio int main() { GDALAllRegister(); GDALDataset* ds (GDALDataset*)GDALOpenEx(test.shp, GDAL_OF_VECTOR, nullptr, nullptr, nullptr); if (ds) { printf(打开成功图层数量: %d\n, ds-GetLayerCount()); GDALClose(ds); } else { printf(打开失败\n); } return 0; }能打开一个Shapefile文件并正确输出图层数说明你的GDALOGR库可以正常使用。如果这里失败多半是驱动没有编进去或者PROJ数据处理有问题去检查CMake配置阶段的依赖探测输出。6. 裁库与定制一份真正合适的编译版本编过一遍之后你就有了“定制能力”。这块我单独说一下因为它是编译GDAL最有价值的地方。6.1 按需裁剪驱动GDAL整个库很大里面上百个驱动你的项目可能只需要其中十几种。在CMake配置阶段关闭不需要的驱动能显著缩小编译时间和库体积。操作方式是设置对应的GDAL_USE_XXX或GDAL_ENABLE_DRIVER_XXX例如-DGDAL_USE_JPEGOFF -DGDAL_USE_PNGOFF -DGDAL_ENABLE_DRIVER_GTiffON -DGDAL_ENABLE_DRIVER_GeoJSONON -DGDAL_ENABLE_DRIVER_ShapefileON我的经验是裁剪之后DLL体积从300MB级别降到50MB级别完全可能编译时间也能砍半。但别为了极致体积把不该关的驱动关了比如Shapefile、GeoJSON、GTiff这几个常用驱动建议无论如何都保留。6.2 静态库的特别提醒如果你选择了BUILD_SHARED_LIBSOFF那么lib目录下会生成gdal.lib静态库和gdal_i.lib这两个东西。静态库模式下你不需要在部署时附带一堆DLL但你在编译你自己的工程时可能需要额外链接一些系统库。我踩过几次坑现在通常直接用动态库省心。静态库适合那种“只有一个exe到处都是”的部署方式代价是你每次改GDAL配置都要重新全量编译迭代效率会低一些。7. 编译之后的几个实用小技巧上面几条参数配置就是最常见的使用路径。但我自己实际操作中还有几个小技巧顺手分享给你。第一CMake的CMAKE_PREFIX_PATH支持一次传多个路径用分号分隔。如果你的PROJ、GEOS、SQLite3是分开装的可以都写进来CMake会挨个搜索。我一开始不知道这个项目需要不同依赖时反复改路径后来发现全写上去就行。第二编译完的install目录整体拷贝到其他电脑上只要系统里有对应的VC运行库或者你选择静态运行库编译就能直接使用。有了这个基础你完全可以把这当作团队内部的“预编译包”分发地址。第三对Python开发者来说编译好的GDAL不一定非得自己再用C调用。可以用pip install GDAL装Python绑定或者直接用rasterio这些上层封装。但底层C库版本和Python绑定版本不一致时很容易出现“某种格式能读出但另一种格式出错”的诡异问题。这时候还是自己编译一份统一版本靠谱得多。编译GDAL这件事第一次确实有点折磨人主要是依赖配合的问题。但只要你把CMake配置思路理顺了后续重新编译一个新版本会非常快。这套流程跑通之后你对GDAL内部结构的理解也会上一个台阶遇到奇奇怪怪的数据格式问题至少知道该去查哪一层。本文还有配套的精品资源点击获取
返回列表