发这篇博客的起因很简单:我最近在新环境里折腾地形数据处理,需要把 GDAL 3.6.2 完整编译进自己的项目目录,结果发现网上讲源码编译的教程要么版本太老、要么只讲了一半,根本没提依赖库的重要性。折腾了两天,踩了不少坑,最后总算把流程理顺了。这篇就当作一份整理笔记,给同样需要从源码编译安装 gdal3.6.2 库的朋友们抄作业用。
1. 为什么非要源码编译 GDAL 3.6.2 不可
1.1 系统包管理器解决不了的三个痛点
很多人第一反应是:直接 apt install 或者 pip install 多方便,为什么非得自己编译?这个想法没错,但如果你的项目对环境有严格要求,包管理器往往搞不定三件事。
第一是版本控制问题。操作系统自带的 GDAL 版本通常特别保守,比如 Ubuntu 22.04 仓库里的版本卡在 3.4.1,而某些新的栅格驱动、坐标转换算法只有 3.6+ 才有修复。你需要特定版本号,仓库里没有,那就只能自己动手。
第二是编译参数问题。做嵌入式部署或者写 C/C++ 后端服务的人最清楚,默认安装经常缺这个模块少那个驱动,比如想裁剪掉某些不需要的格式,或者说项目里同时引用多个 GDAL 版本,这时候一套带定制编译选项的源码构建就是刚需。
第三是路径隔离问题。我这次就是为了把 GDAL 独立装到 /opt/gdal/3.6.2 下,避免污染系统目录。这样以后想卸载或者切换版本,直接改环境变量就行,干净利落。
1.2 源码编译的核心逻辑:三步走
GDAL 的源码编译本质上就是三步:准备依赖 -> 配置构建参数 -> 编译安装。听起来简单,但每一步都有坑。
先说依赖。GDAL 本身是个庞大的库,底下挂了几十个可选依赖,比如 PROJ 管投影转换、GEOS 管几何拓扑运算、libtiff 管 TIFF 读写、SQLite3 管矢量数据存储。这些依赖直接决定了你编译出来的 GDAL 能支持哪些格式和算法。
再说配置。GDAL 从 3.x 开始已经全面推荐用 CMake 构建,相比老的 autotools 方式,CMake 的检查逻辑更直观,而且能自动处理不少依赖查找。但代价是参数特别多,光是 -D 开头的选项就有上百个,如果不清楚自己需要什么,很容易配出一个既不完整又编译不过的奇怪组合。
最后是安装。这一步比想象中容易出问题,尤其是动态库路径、头文件搜索路径没配好的话,编译倒是通过了,但运行 gdalinfo 直接报 libgdal.so: cannot open shared object file,这也是我这次踩得最深的坑之一,后面细说。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 编译前准备:工具链和依赖库清单
2.1 需要准备的工具链
编译 GDAL 3.6.2 需要一个可用的 C++ 开发环境,这一块每个平台略有差异,但核心就两样:编译器 + 构建工具。
我这次用的是 Linux 环境(Ubuntu 22.04,内核 5.15),所以直接装了整套开发工具包。如果你是 CentOS 或者 RHEL 系的系统,用 yum 也能装到等价的东西。Windows 用户注意,官方支持 MSVC + CMake + vcpkg 的组合,但流程完全不同,本文以 Linux 为主来讲。
先更新系统索引,然后安装 gcc、g++、make、cmake 以及 pkg-config 。如果你本地还没有这些基础工具,运行:
bash复制sudo apt update
sudo apt install -y build-essential cmake pkg-config
需要注意一点,GDAL 3.6.2 对 CMake 版本有最低要求,太老的 CMake 会直接报错不认 CMakeLists.txt。我建议至少装 3.16 以上,实测用 CMake 3.22 编译没有任何问题。
2.2 核心依赖库的作用和安装方法
这一节是源码编译的第一步,也是最容易被跳过但后果最严重的一步。GDAL 编译时如果找不到 PROJ,它不会报致命错误,而是默默编译出一个没有投影支持的精简版 GDAL。等你后面用的时候才发现坐标系全是歪的,那才叫欲哭无泪。
为了保证功能完整,我推荐至少安装下面这些依赖库的 dev 版本:
| 依赖库 | 作用 | 缺失后果 |
|---|---|---|
| zlib | 通用压缩库,几乎一切格式的基础 | 大量驱动无法启用 |
| libtiff | TIFF/GeoTIFF 格式读写 | 无法处理 GeoTIFF,这是遥感最核心的格式 |
| libpng / libjpeg | PNG/JPEG 格式读写 | 常用影像格式无法打开 |
| sqlite3 | 矢量空间数据集底层存储 | GPKG/SQLite 支持失效 |
| PROJ | 坐标参考系统与投影转换 | 地图投影功能不可用 |
| GEOS | 空间几何拓扑运算 | 空间分析能力大幅缺失 |
| libxml2 | XML 解析,GDAL 配置文件依赖 | 部分元数据读取异常 |
| curl | 网络协议访问 | 无法读取在线瓦片和远程文件 |
在 Ubuntu 上是这样批量装的:
bash复制sudo apt install -y zlib1g-dev libtiff-dev libpng-dev libjpeg-dev \
libsqlite3-dev libproj-dev libgeos-dev libxml2-dev libcurl4-openssl-dev
这里特别提一下 PROJ 和 GEOS 。想用完整的高精度坐标转换能力,PROJ 版本至少 7.0 以上,GDAL 3.6.2 在配置时会检查 PROJ 的版本号,过低会直接打警告并禁用相关功能。GEOS 同理,版本太低会影响 Geometry 相关操作的编译。Ubuntu 22.04 仓库里的 PROJ 是 8.2 版本,GEOS 是 3.10 版本,都满足条件,所以直接用系统的 dev 包就行。如果你的系统仓库版本太老,建议还是先手动编译一个新版 PROJ,不要拿来就用。
3. 源码获取与 CMake 构建配置
3.1 获取 GDAL 3.6.2 源码
源码下载比较简单。GDAL 的官方托管在 GitHub 的 OSGeo/gdal 仓库,3.6.2 是 3.6 分支下的一个补丁版本。如果你想稳定复现,推荐直接下载 release 源码包,而不是拉 git 仓库。
bash复制wget https://github.com/OSGeo/gdal/releases/download/v3.6.2/gdal-3.6.2.tar.gz
tar -xzf gdal-3.6.2.tar.gz
cd gdal-3.6.2
下载完先看一眼目录结构。顶层有 CMakeLists.txt,gcore/、ogr/、frmts/ 这些是核心模块,apps/ 是命令行工具源码。确认你的目录里有 CMakeLists.txt 存在,后面所有操作都以这个目录为根。
3.2 看懂 CMake 配置的核心参数
进目录之后,第一件事不是直接 cmake,而是搞清楚配置参数的含义。GDAL 的 CMake 配置和普通库有很大不同,它自带了一套 gdal-config 的替代逻辑,并且大量依赖 find_package 来探测外部库。常用的关键参数有几个。
CMAKE_BUILD_TYPE 决定编译优化等级,默认是空值,我强烈建议设为 Release,否则编译出的库不仅体积大,运行时性能也会差一截。CMAKE_INSTALL_PREFIX 是安装目标路径,这也是实现环境隔离最重要的参数,把它设成独立目录,例如 /opt/gdal/3.6.2。
接下来是 GDAL 的功能开关。GDAL_USE_PROJ、GDAL_USE_GEOS、GDAL_USE_TIFF 这些 GDAL_USE_* 系列参数,控制外部依赖模块的启用与否。如果想禁用某一个驱动,可以设成 OFF,但一般情况下我建议全开,宁可多花点编译时间,也别到用的时候发现少功能。
BUILD_SHARED_LIBS 控制生成动态库还是静态库。做嵌入式或者需要静态链接到自己的程序时,设成 OFF;常规的服务器部署就用 ON,方便多个程序共享同一份库文件。还有就是 GDAL_BUILD_OPTIONAL_APPS,它控制是否编译 gdalinfo、ogr2ogr 这些命令行工具,默认是开启的,如果只是做库依赖可以关掉以加快编译。
3.3 一个可直接复制的生产环境配置范本
我这里给出一个经过实测的配置命令,方便你直接复制使用。假设安装到独立目录 /opt/gdal/3.6.2,启用常见依赖,生成 Release 版本动态库:
bash复制cmake -S . -B build \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=/opt/gdal/3.6.2 \
-DBUILD_SHARED_LIBS=ON \
-DGDAL_USE_PROJ=ON \
-DGDAL_USE_GEOS=ON \
-DGDAL_USE_TIFF=ON \
-DGDAL_USE_PNG=ON \
-DGDAL_USE_JPEG=ON \
-DGDAL_USE_SQLite3=ON \
-DGDAL_USE_CURL=ON \
-DGDAL_USE_XML2=ON
执行的时候,-S . 表示源码根目录是当前目录,-B build 表示构建目录命名为 build,所有编译中间文件都会放在这里,不会污染源码目录。
跑完这一步,CMake 会输出一份配置摘要,里面列出了它能找到的依赖库和版本号,显示为 Found PROJ: /usr/lib/x86_64-linux-gnu/libproj.so 这样的信息。这时候我建议睁大眼睛检查一遍摘要,确认 PROJ、GEOS 这些关键依赖都找到了。如果哪一行显示 not found 且你确实需要它,就回去装好依赖再重新执行这一条命令,不要带着残缺配置进入编译阶段。
4. 编译、安装与 C/C++ 联动
4.1 并行编译技巧与内存控制
配置成功后,进入编译阶段。GDAL 源码体量不小,全量编译会比较耗时,所以一般都用多线程并行。我习惯用 nproc 动态获取 CPU 核心数,然后把编译线程数设为核心数减一,避免系统卡死:
bash复制cmake --build build -j "$(nproc -1)"
如果你是 8 核机器,就相当于用 7 个进程并行编译。看编译日志时,前面会刷出一长串 .cc 文件的编译信息,这不是卡住了,是在正常推进。GDAL 源码比较多,整个编译过程在我的机器上大概需要 8 到 10 分钟,喝杯水的功夫。
内存方面需要特别注意。GDAL 中某些大文件(比如 gdalwarp 相关源码)在编译时需要较大的内存,如果你用 -j16 或更高并行度,很容易 OOM。我实测过 8 核 16G 内存的机器,-j7 没问题;如果是 4 核 8G 内存的老机器,建议用 -j2 保底,无非多等几分钟。
如果编译过程中途失败,不要急着从头再来。CMake 构建支持断点续编,修完报错后再跑同一条命令,它会从失败的位置继续,而不是重新编译所有文件。
4.2 安装路径、头文件与动态库配置
编译通过后,执行安装命令。这一步会把头文件、库文件、命令行工具和 CMake 配置统一放到前面指定的 CMAKE_INSTALL_PREFIX 路径下:
bash复制cmake --install build
安装完成,查看一下目录结构:
bash复制ls /opt/gdal/3.6.2
# bin include lib share
include/ 里是 GDAL 的头文件,lib/ 里是 libgdal.so 动态库和 libgdal.so.3.6.2 版本化文件,bin/ 里是 gdalinfo、ogr2ogr 等命令行工具。此时把头文件路径改成 /opt/gdal/3.6.2/include,库路径改成 /opt/gdal/3.6.2/lib,另外还需要把自己的搜索路径指过去,否则编译器找不到:
bash复制export PATH=/opt/gdal/3.6.2/bin:$PATH
export LD_LIBRARY_PATH=/opt/gdal/3.6.2/lib:$LD_LIBRARY_PATH
export CPLUS_INCLUDE_PATH=/opt/gdal/3.6.2/include
export C_INCLUDE_PATH=/opt/gdal/3.6.2/include
这几个环境变量里,LD_LIBRARY_PATH 是最容易被忽略的。动态库安装到非系统默认目录后,运行程序时加载器并不知道去哪里找 libgdal.so,所以编译时链接正常、运行时却说找不到库,十有八九是没配这一项。生产环境里想长期生效,把这几行加到 /etc/profile.d/gdal.sh 或者自己的 ~/.bashrc 里就行。
4.3 静态库和动态库的选择策略
编译参数里我特意提到了 BUILD_SHARED_LIBS,这里展开讲一下选型逻辑。默认动态库的好处是省空间、更新方便,如果你的机器上可能同时跑多个用到 GDAL 的进程,动态库只需要载入一份副本。但动态库也有经典问题,就是版本地狱,程序依赖的 libgdal.so.3.6.2 一旦被替换成更新的版本,原来编译好的程序可能就链接不上。
如果你要把 GDAL 功能打包进一个独立可执行文件,比如部署到没有 GDAL 环境的裸机上,那静态库是更稳的选择。把 BUILD_SHARED_LIBS=OFF 后编译产物是 libgdal.a,链接时不需要再管动态库搜索路径,也不会出现运行时找不到 so 的问题。代价是最终体积会大不少,而且如果需要改 GDAL 的编译参数或者升级版本,整个程序都要重新编译。
我的建议是:服务端常规部署用动态库,自定义工具链分发或者嵌入式场景用静态库。如果你拿不准,先编动态库,真到部署时再针对性地切静态库,反正源码都在手头,重新编译的成本并不高。
5. 验证安装与高频故障排查
5.1 三步验证安装是否成功
安装完成,环境变量也配好了,接下来就该确认这次编译到底成不成功。我习惯用三步来验证。
第一步,检测版本号是否能正常打印:
bash复制gdalinfo --version
# GDAL 3.6.2, released 2023/02/08
如果输出类似 GDAL 3.6.2 的字符串,说明命令行工具和动态库链路都通了。第二步,用 ogrinfo 和 gdal-config 确认关键功能组件:
bash复制ogrinfo --formats | grep -i "gpkg"
gdal-config --version
gdal-config --libs
执行 ogrinfo --formats 会列出一长串支持的矢量格式,里面能看到 GPKG、ESRI Shapefile 这些关键项。gdal-config --libs 则会输出链接需要的库参数,比如 -L/opt/gdal/3.6.2/lib -lgdal。
第三步也是最直观的方式,直接用真实数据跑一遍。随手找一张 GeoTIFF 影像,执行 gdalinfo sample.tif,能正常输出影像尺寸、波段、投影信息就说明读写链路没有问题。这一步千万不要省,我之前就遇到过版本号能打印、但一读数据就段错误的情况,后来排查发现是 PROJ 版本不匹配导致的。
5.2 编译期高频错误及处理办法
编译期间遇到的问题主要分三类:依赖库找不到、头文件不兼容、CMake 版本太旧。
依赖库找不到的场景,典型报错是 Could NOT find PROJ 或 CMake Error: The following variables are used in this project, but they are set to NOTFOUND。这基本就是没装对应的 dev 包。不用重新下载源码,装好包之后重新执行 cmake -S . -B build 的配置命令,让 CMake 重新探测一次就行。
头文件不兼容的场景,典型报错是某个 .h 文件里提示函数没有声明,或者某个类型没定义。这种情况通常是系统里有多个版本的依赖库,CMake 找到了 A 版本的头文件,但链接时却用了 B 版本的库。排查思路是先 cmake --build build 查看详细日志,找出它具体用了哪个 include 路径,再确认那个路径下的版本号。
CMake 版本问题比较简单,报错里会明确写 CMake 3.16 or higher is required,直接用 sudo apt install cmake 升级,或者去官网下载新版安装。
5.3 运行期动态库的经典处理方案
编译链接都过了,但一跑 gdalinfo --version 就报:
code复制gdalinfo: error while loading shared libraries: libgdal.so.3.6.2: cannot open shared object file: No such file or directory
这个报错的根源就是动态库加载器找不到自定义安装路径下的 so 文件。处理方案有两个,二选一都行。
第一个方案是临时设置 LD_LIBRARY_PATH 环境变量。每次执行前:
bash复制export LD_LIBRARY_PATH=/opt/gdal/3.6.2/lib:$LD_LIBRARY_PATH
第二个方案是把库路径写入系统动态链接配置,让全系统都能识别:
bash复制sudo bash -c 'echo "/opt/gdal/3.6.2/lib" > /etc/ld.so.conf.d/gdal.conf'
sudo ldconfig
执行完再运行 gdalinfo --version 就能正常出结果了。需要注意不要同时把 /opt/gdal/3.6.2/lib 往 /usr/local/lib 里硬放,这会造成版本冲突,后续升级时非常危险。
6. 从源码编译到落地使用的一些经验谈
码到这里,整个源码编译安装的流程基本完整了。最后再分享几条我在实战里积累的小心得。
第一,依赖库版本一定要对齐。GDAL 3.6.2 官方文档里写的兼容范围是推荐值,但系统仓库里的版本经常早于它推荐的值,这时候宁可先从源码编译一个新版 PROJ,也不要凑合着用旧版。我这次就是因为 PROJ 版本偏旧,导致编译出的库在某些坐标系转换时会发生偏移,肉眼不易察觉,但做工程测量时问题就大了。
第二,不要贪图方便把编译好的动态库直接复制到别的机器上。GDAL 的洞很连通,它链接了 libproj、libgeos、libsqlite3,这些动态库在不同机器上的路径和版本很可能不一致,直接拷过去轻则警告重则崩溃,正确做法是在目标机器上重新编译,或者做镜像时把依赖库完整打进去。
第三,保存一份自己的编译配置脚本。如果你以后需要重复编译,或者同事也要用同样版本的 GDAL,把前面那一段 cmake 命令完整保存成 .sh 脚本,比记忆一堆参数靠谱得多。我在实际项目中就把这段脚本放进了仓库的 scripts/ 目录,之后新机器初始化直接跑一遍就能复现环境,效率非常高。
第四,官方迁移到 CMake 之后,旧的 autotools 配置方式虽然还能用,但我不建议新项目继续依赖它。CMake 生成的配置状态文件存放在 build/CMakeCache.txt 里,排查问题的时候可以先到这里面看看到底探测到了哪些依赖、路径是什么,信息量远大于直接看报错提示。
这一套流程跑完之后,GDAL 3.6.2 就能在你的项目里安安静静地工作了。以后换新机器、换新环境,再回去翻翻这篇文章,按着流程一步步走,基本两小时内就能把库从零编译到可正常调用。
