GDAL 1.11.5 mingw32 编译指南:从环境配置到链接排错
简介本资源为在Windows平台下基于msys2与MinGW32方式编译完成的GDAL 1.11.5开发库面向使用QtMinGW进行地理空间数据处理开发的程序员可省去自行编译的繁琐过程。解压后只需将bin目录加入系统环境变量并在.pro文件中配置GDAL路径即可直接调用适用于遥感影像读取、矢量数据转换、坐标投影等GIS开发场景。压缩包共149个文件约74.73MB包含63个C/C头文件、22个可执行工具、28个CSV坐标与基准数据、若干WKT、XSD、XML等投影与模式定义文件以及静态库、动态库和gdal-config配置脚本覆盖开发与运行所需的核心组件。目前已有779人学习下载。资源附带常见程序异常结束的排查思路指引帮助开发者快速定位环境配置问题降低入门与调试成本。1. GDAL 1.11.5 配 mingw32老版本工具链为什么还有人死磕如果你手头有一个 2015 年前后启动的 GIS 桌面项目或者维护着一套跑在 Windows XP/7 工控机上的地图切片工具那你大概率绕不开 GDAL 1.11.5 这个版本。它发布于 GDAL 1.11 系列末期是最后一个对 mingw32 支持相对完整、且不强制依赖 C11 的稳定版本。很多老项目的构建脚本里写死了gdal111的库名升级到 2.x 之后 API 断裂、依赖链爆炸于是“用 mingw32 重新编一个 1.11.5”成了每年都要翻出来折腾一次的任务。这篇文章不讲 GDAL 是什么也不讲 GIS 基础。我假设你已经有一个必须在 32 位 Windows 上跑、必须用 mingw32 工具链、且必须链接 GDAL 1.11.5 的场景。我会把从环境准备、configure 参数、编译排错到产物验证的完整路径拆开重点放在那些官方文档不会写、但实际编译时一定会撞上的坑。如果你只是想找个现成的 DLL 用gisinternals 这类站点确实提供过编译好的包但版本和编译器匹配问题会让你在链接阶段付出代价——自己编一次反而更省时间。2. mingw32 工具链选型与 GDAL 1.11.5 源码准备2.1 为什么是 mingw32 而不是 mingw-w64标题里写的是 mingw32不是 mingw-w64。这两个东西经常被混为一谈但在 GDAL 1.11.5 这个年代它们的行为差异很大。mingw32 通常指 32 位目标、使用 msvcrt.dll 作为 C 运行时的老式 MinGW 工具链典型代表是 MinGW.org 的 GCC 4.8.x 系列。mingw-w64 则是另一套项目支持 32/64 位目标运行时可以选择 msvcrt 或 ucrt。GDAL 1.11.5 的源码里大量使用了#ifdef __MINGW32__这样的宏判断这些判断最初是针对 MinGW.org 工具链写的。如果你用 mingw-w64 的 32 位模式去编宏定义虽然也能命中但某些头文件路径和库命名规则不一致会在 configure 阶段就报错。我一般会直接锁定 MinGW.org 的 GCC 4.8.1 或 4.9.3这两个版本在 SourceForge 上还能找到完整的 32 位安装包。安装时注意勾选mingw32-base、mingw32-gcc-g、msys-base这三项。msys 提供 bash 环境和 make没有它你没法跑 configure 脚本。装完之后把C:\MinGW\bin和C:\MinGW\msys\1.0\bin都加进 PATH但要注意顺序msys 的 bin 放在前面否则你会用到 Windows 自带的 find.exe 而不是 msys 的 findconfigure 脚本会莫名其妙失败。2.2 源码包获取与依赖库清单GDAL 1.11.5 的源码可以从 OSGeo 的下载归档里找到文件名通常是gdal-1.11.5.tar.gz。解压到一个不含空格和中文的路径比如C:\build\gdal-1.11.5。不要放在C:\Program Files下面configure 脚本对空格路径的处理一直有问题。GDAL 本身依赖几个第三方库但 1.11.5 对它们的依赖是可选式的。最小可编译配置只需要 zlib 和 libtiff如果你要读写 PNG 或 JPEG再加 libpng 和 libjpeg。这些库在 mingw32 下有两种获取方式一是用 msys 的 pacman 装预编译包二是自己从源码编。我建议 zlib 和 libtiff 自己编因为预编译包的路径和 GDAL configure 的默认搜索路径经常对不上。自己编 zlib 的流程很简单解压后进目录执行make -f win32/Makefile.gcc然后把zlib1.dll、libz.a、zlib.h、zconf.h分别拷到 MinGW 的 bin、lib、include 目录。libtiff 稍微麻烦一点它依赖 zlib 和 libjpegconfigure 的时候要显式指定--with-zlib-include-dir和--with-jpeg-include-dir。如果你暂时不需要 TIFF 支持可以在 GDAL 的 configure 里加--without-libtiff先编一个最小版本跑通流程。提示所有依赖库都编成静态库.a比动态库省事因为最终链接时不用操心 DLL 的搜索路径。但如果你要生成一个供其他程序调用的 GDAL DLL那就得把依赖也编成 DLL否则符号冲突会让你调很久。3. configure 参数逐项拆解与编译命令3.1 最小可编译的 configure 命令进入 msys 终端cd 到 GDAL 源码目录执行下面这条命令。这是我反复验证过的最小配置能编出一个支持 GeoTIFF、PNG、JPEG 的 32 位 GDAL 1.11.5。./configure \ --hosti686-pc-mingw32 \ --prefix/c/gdal-build \ --with-threads \ --without-libtool \ --with-pnginternal \ --with-jpeginternal \ --with-libtiffinternal \ --with-geotiffinternal \ --without-python \ --without-curl \ --without-sqlite3 \ --without-expat \ CFLAGS-O2 -m32 \ CXXFLAGS-O2 -m32 \ LDFLAGS-m32逐项说明--hosti686-pc-mingw32告诉 configure 目标平台是 32 位 Windows这个三元组必须写对否则生成的 Makefile 会用错误的库命名规则。--prefix指定安装路径用 msys 风格的/c/gdal-build而不是C:\gdal-build。--with-threads启用多线程支持GDAL 的某些驱动在单线程下会退化成阻塞模式。--without-libtool是个关键参数。libtool 在 mingw32 下经常生成错误的 .la 文件导致链接阶段找不到依赖。关掉它之后GDAL 会直接用 gcc 生成 DLL 和导入库反而更干净。--with-pnginternal表示使用 GDAL 源码树里自带的 libpng 副本而不是外部库。1.11.5 的 internal 版本虽然老但胜在路径可控不会出现头文件版本不匹配的问题。同理jpeg、libtiff、geotiff 都用 internal。--without-python必须加。GDAL 1.11.5 的 Python 绑定在 mingw32 下几乎编不过swig 生成的代码和 Python 头文件的兼容性很差。如果你确实需要 Python 绑定建议单独用 pip 装一个对应版本的 GDAL wheel不要在这个编译流程里折腾。3.2 编译与安装命令configure 跑完之后检查输出末尾有没有GDAL is now configured for i686-pc-mingw32这行字。如果有就可以开始编译了。make -j4 make install-j4是并行编译的核数根据你机器的 CPU 调整。GDAL 1.11.5 的代码量不小单线程编可能要二十分钟以上。编译过程中最常见的错误是某个 internal 库的头文件找不到比如png.h或tiffio.h。这通常是因为 configure 阶段没有正确识别 internal 库的路径。解决办法是手动在 CFLAGS 里加上-I./frmts/png/libpng这样的路径具体路径根据报错信息里的文件名去源码树里找。make install会把gdal111.dll、libgdal.a、头文件和工具程序拷到/c/gdal-build下面。检查一下bin目录里有没有gdalinfo.exelib目录里有没有libgdal.a和gdal111.lib如果你需要 MSVC 兼容的导入库。如果没有.lib文件可以用dlltool从.def文件生成命令是dlltool -d gdal111.def -l gdal111.lib。注意make install之后不要急着删源码目录。后续如果你要调试某个驱动的行为或者需要重新生成 .def 文件源码目录里的中间产物还有用。4. 编译期与链接期的避坑排查4.1 现象configure 报错 “C compiler cannot create executables”原因msys 的 PATH 顺序不对或者 MinGW 的 gcc 没有正确安装。有时候是因为TMP或TEMP环境变量指向了一个不存在的目录configure 在测试编译时无法写临时文件。解决在 msys 终端里执行which gcc确认输出是/c/MinGW/bin/gcc而不是 msys 自带的某个版本。然后检查echo $TEMP如果是空或者指向不存在的路径手动设成/tmp。再跑一次 configure基本就能过。4.2 现象编译到 ogr 目录时报 “undefined reference to__imp_WSAGetLastError”原因GDAL 1.11.5 的 OGR 部分用到了 Winsock 的 API但 Makefile 里没有自动链接-lws2_32。这在 mingw32 下是常见问题因为 msvcrt 不会隐式带入 Winsock 库。解决在 configure 的 LDFLAGS 里加上-lws2_32或者在 make 的时候手动指定LIBS-lws2_32。如果已经 configure 过了可以直接编辑GDALmake.opt文件找到LIBS那一行把-lws2_32追加进去然后重新 make。4.3 现象生成的 gdal111.dll 在目标机器上加载失败报 “找不到 msvcr100.dll”原因你的 mingw32 工具链链接了 msvcr100.dllVisual Studio 2010 的运行时而不是 msvcrt.dll。这通常是因为你用的 MinGW 发行版自带了某个版本的 msvcr 导入库。解决用 Dependency Walker 或objdump -p gdal111.dll | findstr DLL Name查看实际依赖。如果确实依赖 msvcr100.dll要么在目标机器上装对应的 VC 运行时要么换一个纯 msvcrt 的 MinGW 工具链重新编译。我一般会在 configure 时加LDFLAGS-static-libgcc -static-libstdc把 GCC 的运行时也静态链进去减少对目标机器环境的依赖。4.4 现象gdalinfo --version输出正常但打开 GeoTIFF 时报 “not recognized as a supported file format”原因GeoTIFF 驱动没有正确注册。GDAL 1.11.5 的驱动注册是静态的如果 configure 时--with-geotiffinternal没有生效编译出来的 DLL 里就不会包含 GeoTIFF 驱动。解决检查 configure 输出里有没有GeoTIFF support: yes。如果没有说明 internal geotiff 的路径没被识别。手动在frmts/gtiff/libtiff和frmts/gtiff/geotiff目录下确认源码文件存在然后在GDALmake.opt里把GDAL_FORMATS那一行的gtiff加回去重新 make。4.5 现象链接自己的程序时提示 “cannot find -lgdal111”原因库文件名不对。mingw32 下 GDAL 生成的导入库通常叫libgdal.a或gdal111.lib而不是libgdal111.a。-lgdal111会让链接器去找libgdal111.a自然找不到。解决用-lgdal代替-lgdal111或者直接把libgdal.a的完整路径写进链接命令。如果你用的是 MSVC 风格的.lib文件那就在链接器选项里写gdal111.lib的完整路径不要用-l前缀。5. 产物验证与在 mingw32 项目中的集成方式编完之后第一件事是验证 DLL 能不能正常工作。在 msys 终端里执行/c/gdal-build/bin/gdalinfo.exe --version /c/gdal-build/bin/gdalinfo.exe --formats第一条命令应该输出GDAL 1.11.5, released 2015/09/16之类的版本信息。第二条命令会列出所有已编译进去的驱动格式检查一下 GeoTIFF、PNG、JPEG 是否在列表里。如果格式列表是空的说明驱动注册有问题回到 4.4 节排查。接下来用一个真实的 GeoTIFF 文件测试读写/c/gdal-build/bin/gdalinfo.exe test.tif如果能看到坐标系、波段数、尺寸等信息说明核心功能正常。再试一下格式转换/c/gdal-build/bin/gdal_translate.exe -of PNG test.tif test.png这一步会同时调用 GeoTIFF 读取和 PNG 写入两个驱动能过就说明驱动链没问题。在自己的 mingw32 项目里集成时Makefile 里需要加三个东西头文件路径-I/c/gdal-build/include库路径-L/c/gdal-build/lib以及链接选项-lgdal -lws2_32。如果你的项目是 C 的还要加-lstdc。运行时把gdal111.dll和它的依赖 DLL比如zlib1.dll、libtiff.dll放到 exe 同目录或者加到 PATH 里。提示如果你要把 GDAL 静态链进自己的程序用libgdal.a而不是 DLL。但静态链接时要注意符号冲突特别是 zlib 和 libtiff 的符号如果和你项目里已有的库重名链接器会报重复定义。解决办法是在链接选项里加-Wl,--allow-multiple-definition但这是最后手段优先考虑用动态库。6. 用 gdal-config 脚本简化跨项目引用编完 GDAL 之后make install会在bin目录下生成一个gdal-config脚本。这个脚本在 Linux 下很常用但在 mingw32 环境里经常被忽略。它可以根据参数输出编译和链接所需的标志省去你手动拼路径的麻烦。/c/gdal-build/bin/gdal-config --cflags /c/gdal-build/bin/gdal-config --libs /c/gdal-build/bin/gdal-config --version第一条输出-I/c/gdal-build/include第二条输出-L/c/gdal-build/lib -lgdal第三条输出1.11.5。你可以在 Makefile 里这样用GDAL_CFLAGS : $(shell /c/gdal-build/bin/gdal-config --cflags) GDAL_LIBS : $(shell /c/gdal-build/bin/gdal-config --libs) myapp.exe: myapp.o i686-pc-mingw32-g -o $ $^ $(GDAL_LIBS) -lws2_32这样写的好处是如果以后你换了 GDAL 的安装路径只需要改gdal-config的位置不用动 Makefile 里的每一处路径。但要注意mingw32 下的gdal-config脚本是用 sh 写的在 msys 终端里能跑在 Windows 的 cmd 里跑不了。如果你的构建系统是 cmd 批处理那就得手动解析这个脚本的输出或者干脆把路径写死。还有一个技巧如果你需要把 GDAL 的头文件路径暴露给一个用 CMake 构建的项目可以在 CMakeLists.txt 里用execute_process调用gdal-config把输出赋给变量。这样 CMake 和 Makefile 两套构建系统就能共享同一个 GDAL 安装。我自己的习惯是每次编完 GDAL 之后先把gdal-config --cflags和--libs的输出记在一个文本文件里放在项目根目录。下次再编的时候直接对照这个文件检查 configure 参数有没有漏。这个习惯帮我省了很多次“明明上次能编过这次怎么不行”的排查时间。希望帮到你。本文还有配套的精品资源点击获取