简介:这份资源是作者在 Windows 下用 msys2 + mingw64 方式预先编译好的 GDAL 1.11.5 库,面向使用 Qt(MinGW 版)进行 C++ 地理信息开发的工程师与学习者,解决自行编译 GDAL 耗时长、依赖配置繁琐的问题。压缩包共 149 个文件,约 70.71MB,包含 63 个 h 头文件、22 个 exe 工具、28 个 csv 坐标与投影数据、8 个 gfs、6 个 wkt 及若干 svg、dxf、dgn、xml、xsd 等,另有 libgdal.a、libgdal.dll.a 等静态与导入库,覆盖编译、链接与运行所需的核心组件。解压后将 bin 目录加入系统环境变量,并在 .pro 文件中配置 GDAL 路径即可直接调用,无需重复编译。目前已有 1520 人学习下载,适合希望快速在 Qt 项目中集成 GDAL 读写栅格与矢量数据的开发者,若遇到程序异常结束,可参考作者提供的排错博客定位问题。
1. 为什么今天还有人折腾 mingw64 编译的 GDAL 1.11.5
如果你手上有一个十多年前的 C++ 桌面项目,依赖链里锁死了 GDAL 1.11.5,而构建环境又是 Windows 上的 MinGW-w64,那你大概率已经体会过那种「包管理器里全是新版、旧版源码一编译就炸」的窒息感。mingw64 编译的 GDAL 1.11.5 这件事,本质上不是怀旧,而是被现实逼出来的:老项目要复现、老插件要兼容、老数据格式要读写,而系统里能用的编译器只有 MinGW-w64。它解决的核心问题是——在没有 Visual Studio 授权、也不想引入 MSVC 运行时的前提下,产出一套能在 Windows 上被老代码直接链接的 GDAL 动态库和命令行工具。适合谁?适合那些维护遗留 GIS 桌面端、做遥感数据批处理、或者要给老 Qt 工程补地理能力的工程师。这一章先把「为什么是 1.11.5、为什么是 MinGW-w64」讲清楚,后面再动手。
GDAL 1.11.5 属于 1.x 时代的末期版本,API 相对稳定,很多老代码直接依赖GDALAllRegister、OGRRegisterAll这类全局注册函数,以及CPLSetConfigOption的旧行为。新版 GDAL 3.x 改了坐标轴顺序、改了驱动注册方式,老代码迁过去往往要动几十处。MinGW-w64 则是 Windows 上少有的、能同时提供 32/64 位、且不依赖 MSVC 运行时的 GCC 工具链。两者结合,能让你在一台干净的 Windows 机器上,用纯开源工具链把 GDAL 1.11.5 编出来,产出的 DLL 可以直接丢给老程序用。代价是:依赖库要自己编,configure 脚本对 MinGW 的支持有坑,链接顺序稍错就报一堆 undefined reference。下面按「准备依赖 → 配置编译 → 排错 → 进阶」的顺序走一遍。
2. 编译前的依赖准备:MinGW-w64 环境与第三方库怎么选
2.1 工具链版本与 MSYS2 环境搭建
MinGW-w64 本身只是一套头文件和库,真正干活的是 GCC。我一般用 MSYS2 来管理,因为它能同时装mingw-w64-x86_64-gcc和mingw-w64-i686-gcc,切换架构只改一个环境变量。注意:不要用 MSYS 自带的/usr/bin/gcc,那是给 MSYS 运行时用的,编出来的 DLL 依赖msys-2.0.dll,丢到普通 Windows 程序里跑不起来。必须用mingw64或mingw32子系统里的 GCC。
# 在 MSYS2 的 mingw64 shell 里执行 # 确认当前编译器是 MinGW-w64 而不是 MSYS 的 which gcc # 期望输出:/mingw64/bin/gcc gcc --version # 期望看到类似 x86_64-w64-mingw32 的目标三元组 # 安装基础构建工具 pacman -S --needed base-devel mingw-w64-x86_64-toolchain逻辑说明:which gcc是第一个分水岭,如果输出/usr/bin/gcc,说明你开错了 shell,后面所有库都会带 MSYS 依赖。pacman -S base-devel提供 make、pkg-config 等工具,GDAL 的 configure 脚本会调用它们。参数上,--needed避免重复安装,mingw-w64-x86_64-toolchain是元包,包含 gcc、g++、binutils。如果你要编 32 位,把x86_64换成i686,并在mingw32shell 里操作。
2.2 GDAL 1.11.5 的依赖库清单与编译顺序
GDAL 1.11.5 的依赖分两类:必需的和可选的。必需的是 PROJ.4(投影转换)、libtiff、libjpeg、libpng、zlib。可选但常用的有 libgeotiff、libcurl、sqlite3、expat。MinGW-w64 下最稳的做法是:先用 MSYS2 的包管理器装预编译版,再手动编 PROJ.4 和 libgeotiff,因为这两个版本匹配要求严。
| 依赖库 | 作用 | 推荐来源 | 版本约束 |
|---|---|---|---|
| zlib | 压缩 | MSYS2 包 | 1.2.x 以上 |
| libjpeg | JPEG 读写 | MSYS2 包 | 8d 或 9 |
| libpng | PNG 读写 | MSYS2 包 | 1.6.x |
| libtiff | TIFF 读写 | MSYS2 包 | 4.0.x |
| PROJ.4 | 投影 | 源码编译 | 4.8.0 或 4.9.x |
| libgeotiff | GeoTIFF | 源码编译 | 1.4.x |
| sqlite3 | SQLite 驱动 | MSYS2 包 | 3.x |
| expat | XML 解析 | MSYS2 包 | 2.x |
# 用 MSYS2 装大部分依赖 pacman -S --needed \ mingw-w64-x86_64-zlib \ mingw-w64-x86_64-libjpeg-turbo \ mingw-w64-x86_64-libpng \ mingw-w64-x86_64-libtiff \ mingw-w64-x86_64-sqlite3 \ mingw-w64-x86_64-expat # 手动编 PROJ.4(GDAL 1.11.5 对 5.x 的 API 不兼容,必须用 4.x) cd /d/build tar xzf proj-4.9.3.tar.gz cd proj-4.9.3 ./configure --prefix=/mingw64 --disable-static make -j4 && make install逻辑说明:MSYS2 的包默认装到/mingw64,头文件在/mingw64/include,库在/mingw64/lib,GDAL 的 configure 能自动找到。PROJ.4 必须用 4.x,因为 GDAL 1.11.5 调用的是pj_init_plus这类旧接口,PROJ 5 之后改了 API,链接会报 undefined reference。--disable-static只产动态库,减少体积。make -j4的并行数按 CPU 核心数调,一般设为核心数或核心数+1。
2.3 环境变量与 pkg-config 路径确认
编 GDAL 之前,必须让pkg-config能找到所有依赖的.pc文件。MSYS2 的包会自动装到/mingw64/lib/pkgconfig,但手动编的 PROJ.4 如果 prefix 设错,就会漏掉。
# 确认 pkg-config 搜索路径 echo $PKG_CONFIG_PATH # 如果为空,手动加上 export PKG_CONFIG_PATH=/mingw64/lib/pkgconfig:/mingw64/share/pkgconfig # 逐个验证依赖是否可见 for lib in zlib libjpeg libpng libtiff-4 sqlite3 expat proj; do echo -n "$lib: " pkg-config --modversion $lib 2>/dev/null || echo "NOT FOUND" done逻辑说明:PKG_CONFIG_PATH是 configure 脚本找依赖的唯一线索,漏一个就会导致对应驱动被禁用。pkg-config --modversion返回版本号说明可见,返回 NOT FOUND 就要检查是不是装到了/usr而不是/mingw64。注意 libtiff 的 pc 文件名是libtiff-4,不是libtiff,写错会误判。这一步做完,依赖就齐了。
3. 配置与编译 GDAL 1.11.5:configure 参数与 make 实操
3.1 configure 关键参数逐项拆解
GDAL 1.11.5 的 configure 脚本对 MinGW 的支持不算完美,默认会尝试用 MSVC 风格的路径,必须显式指定--host和--build。下面是我验证过能跑通的一套参数。
cd /d/build/gdal-1.11.5 ./configure \ --host=x86_64-w64-mingw32 \ --build=x86_64-w64-mingw32 \ --prefix=/mingw64 \ --disable-static \ --enable-shared \ --with-proj=/mingw64 \ --with-libtiff=internal \ --with-geotiff=internal \ --with-jpeg=internal \ --with-png=internal \ --with-zlib=internal \ --with-sqlite3=/mingw64 \ --with-expat=/mingw64 \ --without-curl \ --without-python \ --without-java \ --without-perl逻辑说明:--host和--build都设成x86_64-w64-mingw32,告诉 configure 这是交叉编译场景,避免它去探测 MSVC。--disable-static --enable-shared只产 DLL,老程序链接动态库更方便。--with-libtiff=internal等用内置版本,是因为 MinGW 下外部 libtiff 的链接顺序容易出问题,内置版虽然旧但稳定。--without-curl关掉网络驱动,减少依赖;--without-python/java/perl关掉语言绑定,除非你确实需要。--with-proj和--with-sqlite3指向/mingw64,让 configure 去那里找头文件和库。
3.2 make 阶段的并行与错误定位
configure 成功后,make 阶段最常见的错误是链接时找不到符号,或者某个驱动编译失败。建议先单线程跑一遍,确认无误再用并行。
# 先单线程编译,方便定位第一个错误 make 2>&1 | tee build.log # 如果成功,再清理后用并行加速 make clean make -j8 2>&1 | tee build_parallel.log # 安装到 prefix make install逻辑说明:tee build.log把输出同时写到屏幕和文件,出错时可以直接搜error:。单线程能保证错误顺序和源码顺序一致,并行时多个驱动的错误会混在一起。make -j8的 8 是并行任务数,按 CPU 核心数设,太多会爆内存。安装后,DLL 在/mingw64/bin,头文件在/mingw64/include,导入库在/mingw64/lib。验证一下:
# 检查产出的 DLL 是否依赖 MSYS 运行时 ldd /mingw64/bin/libgdal-1.dll | grep -i msys # 期望:没有任何输出 # 检查 gdalinfo 能否运行 /mingw64/bin/gdalinfo --version # 期望输出:GDAL 1.11.5, released 2016/01/26逻辑说明:ldd | grep msys是判断 DLL 是否「干净」的关键,有输出说明链接到了 MSYS 运行时,丢到普通 Windows 程序里会加载失败。gdalinfo --version能跑通,说明基本功能正常。如果报缺少某个 DLL,用ldd逐个查依赖,把缺失的 DLL 从/mingw64/bin拷到同目录。
3.3 验证编译结果:用 gdalinfo 读写一个 GeoTIFF
编译完不算完,得实际读写一个文件,确认驱动真的可用。
# 生成一个测试 GeoTIFF(用 gdal_translate 从内置格式转) gdal_translate -of GTiff \ -a_srs EPSG:4326 \ -a_ullr 100 40 110 30 \ /mingw64/share/gdal/meanvar.dat \ test.tif # 查看信息 gdalinfo test.tif # 转成 PNG 验证格式转换链 gdal_translate -of PNG test.tif test.png逻辑说明:-a_srs EPSG:4326指定地理坐标系,-a_ullr指定左上右下角坐标,这两个参数能验证投影和坐标写入是否正常。meanvar.dat是 GDAL 自带的示例数据,路径在 share/gdal 下。gdalinfo输出里要能看到Driver: GTiff/GeoTIFF、Coordinate System is:和Origin等信息。转 PNG 成功说明 JPEG/PNG 驱动也链接正常。如果某一步报「not recognized as a supported file format」,说明对应驱动没编进去,回 configure 检查--with-xxx参数。
4. 避坑与排查:MinGW-w64 编 GDAL 1.11.5 的 5 个血泪坑
4.1 坑一:链接报大量 undefined reference to__imp_xxx
现象:make 到最后链接libgdal-1.dll时,报几十个undefined reference to '__imp_pj_init_plus'或__imp_TIFFOpen。原因:MinGW-w64 下,如果头文件里声明了__declspec(dllimport),但链接时没找到对应的导入库,就会报__imp_前缀的符号缺失。解决:确认--with-proj和--with-libtiff指向的目录下有.dll.a或.a导入库,且LDFLAGS里加了-L/mingw64/lib。如果是内置库,检查--with-libtiff=internal是否真的生效,configure 输出里搜checking for TIFFOpen看结果。
4.2 坑二:configure 误判平台,生成 MSVC 风格的 Makefile
现象:configure 输出里出现checking for MSVC... yes,然后 make 报cl不是内部命令。原因:MinGW-w64 的 GCC 在某些 MSYS2 配置下会被 configure 误认为 MSVC 兼容环境。解决:显式传--host=x86_64-w64-mingw32 --build=x86_64-w64-mingw32,并在 configure 前unset CC CXX,让脚本自己找x86_64-w64-mingw32-gcc。如果还不行,加CC=x86_64-w64-mingw32-gcc CXX=x86_64-w64-mingw32-g++到 configure 命令行。
4.3 坑三:PROJ.4 版本不匹配导致投影驱动失效
现象:编译通过,但gdalinfo读带投影的文件时报ERROR 1: PROJ: pj_init_plus failed。原因:GDAL 1.11.5 链接的是 PROJ 5.x,API 不兼容。解决:卸载 PROJ 5+,重新编 PROJ 4.9.3,--prefix=/mingw64,然后make clean重编 GDAL。验证方法:pkg-config --modversion proj必须返回 4.x。如果系统里同时有多个 PROJ,用--with-proj=/path/to/proj4显式指定。
4.4 坑四:DLL 依赖 msys-2.0.dll,脱离 MSYS2 环境无法运行
现象:在 MSYS2 shell 里gdalinfo正常,但把 DLL 拷到普通 Windows 程序目录后,程序启动报「找不到 msys-2.0.dll」。原因:编译时用了/usr/bin/gcc而不是/mingw64/bin/gcc,或者某个依赖库是 MSYS 版。解决:ldd libgdal-1.dll | grep msys找出带 MSYS 依赖的库,重新用 MinGW-w64 版替换。所有依赖必须来自/mingw64,不能来自/usr。检查PATH,确保/mingw64/bin在/usr/bin前面。
4.5 坑五:make install 后头文件路径带 MSYS 前缀,老程序找不到
现象:老程序 include<gdal.h>时报找不到文件,或者链接时找不到libgdal-1.dll.a。原因:--prefix设成了/mingw64,但老程序的构建系统期望的是 Windows 风格路径C:/msys64/mingw64。解决:要么在 configure 时用--prefix=C:/msys64/mingw64,要么在老程序里加-I/mingw64/include -L/mingw64/lib。注意 MinGW-w64 的 GCC 能识别/mingw64这种路径,但 MSVC 或其他构建工具不一定,跨工具链时统一用 Windows 风格路径更稳。
5. 进阶技巧:把 GDAL 1.11.5 做成可分发的绿色包
5.1 用 objdump 和 ldd 做依赖裁剪
编完的 GDAL 目录里有一堆 DLL,但老程序可能只用其中几个驱动。我一般用objdump -p看导入表,把没用的依赖去掉。
# 列出 libgdal-1.dll 的直接依赖 objdump -p /mingw64/bin/libgdal-1.dll | grep "DLL Name" # 用 ldd 递归看完整依赖树 ldd /mingw64/bin/libgdal-1.dll # 把需要的 DLL 拷到一个独立目录 mkdir -p /d/gdal_dist/bin cp /mingw64/bin/libgdal-1.dll /d/gdal_dist/bin/ cp /mingw64/bin/gdal1115.dll /d/gdal_dist/bin/ 2>/dev/null # 按 objdump 结果逐个拷依赖逻辑说明:objdump -p输出的是 PE 导入表,比ldd更准,因为它不依赖运行时。gdal1115.dll是 GDAL 1.11.5 在 MinGW 下的实际 DLL 名,不同编译配置可能不同,用ls /mingw64/bin/*gdal*确认。裁剪时注意:PROJ.4 的数据文件(proj_def.dat、epsg等)也要拷,否则投影转换会失败。数据文件在/mingw64/share/proj。
5.2 设置 GDAL_DATA 和 PROJ_LIB 环境变量
GDAL 运行时需要知道数据文件在哪,否则很多驱动会静默失败。
# 在程序启动脚本里设置 export GDAL_DATA=/d/gdal_dist/share/gdal export PROJ_LIB=/d/gdal_dist/share/proj # 验证 gdalinfo --formats | head -20 # 如果 GDAL_DATA 没设对,会报 "Unable to open gdal_datum.csv"逻辑说明:GDAL_DATA指向gdal_datum.csv、pcs.csv等坐标数据,PROJ_LIB指向 PROJ.4 的投影定义。这两个变量不设,gdalinfo可能能跑,但gdalwarp会失败。在 Windows 程序里,可以用SetEnvironmentVariable在启动时设置,或者写一个.bat包装脚本。注意路径用正斜杠或双反斜杠,单反斜杠会被当转义符。
5.3 用 CMake 的 find_package 对接老工程
如果老工程用 CMake,可以写一个FindGDAL.cmake让它找到这套 MinGW 编的 GDAL。
# FindGDAL.cmake 片段 find_path(GDAL_INCLUDE_DIR gdal.h PATHS /mingw64/include PATH_SUFFIXES gdal) find_library(GDAL_LIBRARY NAMES gdal-1 gdal PATHS /mingw64/lib) if(GDAL_INCLUDE_DIR AND GDAL_LIBRARY) set(GDAL_FOUND TRUE) set(GDAL_INCLUDE_DIRS ${GDAL_INCLUDE_DIR}) set(GDAL_LIBRARIES ${GDAL_LIBRARY}) endif()逻辑说明:find_path的PATH_SUFFIXES gdal是因为 GDAL 1.11.5 的头文件在include/gdal/下,不是直接放include/。find_library的NAMES gdal-1 gdal按顺序找,MinGW 下通常是libgdal-1.dll.a。找到后,老工程里target_link_libraries(myapp ${GDAL_LIBRARIES})就能链接。注意 CMake 的find_package默认搜系统路径,要加CMAKE_PREFIX_PATH=/mingw64才能找到这套。
5.4 一个我踩过的坑:别在 PATH 里混多个 GDAL
最后说个我自己的教训。有次机器上同时装了 QGIS 自带的 GDAL 3.x 和这套 1.11.5,PATH 里 QGIS 在前,结果老程序加载的是 3.x 的 DLL,一读文件就崩。排查了半天才发现是 DLL 搜索顺序问题。后来我养成习惯:给老程序单独写一个启动脚本,把PATH设成只有/d/gdal_dist/bin,再启动。Windows 的 DLL 搜索顺序是「程序目录 → 系统目录 → PATH」,所以最稳的做法是把所有依赖 DLL 和 exe 放同一个目录,不依赖 PATH。这个习惯帮我省了很多「玄学崩溃」的排查时间。希望帮到你。
本文还有配套的精品资源,点击获取