首页 / 资讯中心 / 文章详情

GDAL 1.11.5源码编译实战:mingw32环境完整指南

GDAL 1.11.5源码编译实战:mingw32环境完整指南 ★ FEATURED ARTICLE
简介面向 Windows 平台 QT MinGW 开发者提供的 GDAL 1.11.5 预编译资源包基于 msys2 与 mingw32 编译省去了源码编译的漫长等待与依赖配置。解压后将 bin 目录加入系统环境变量再于 .pro 文件中完成 GDAL 相关配置即可在 QT 工程中直接调用动态库与接口适合需要在桌面应用中快速集成栅格/矢量读取、坐标系转换等能力的开发者。压缩包共 149 个文件约 74.73MB63 个头文件用于二次开发导入库和 dll 提供链接与运行支持22 个 exe 为命令行工具可直接用于数据检查与格式转换CSV、wkt 等文件内置坐标参考、椭球与投影参数XML、gfs、dxf、dgn 等则覆盖常见 GIS 数据格式描述整体结构清晰完整。目前已有 778 人学习下载资源还附带了 QT 下程序异常结束的排查思路能帮助开发者在 QT(MINGW) 环境中更高效地完成 GDAL 部署与地理数据处理功能的落地。 前阵子帮一个老项目做环境重建Windows 7的工控机上跑着GDAL 1.11.5原来编译的人早不在了Makefile散落在三个目录里。折腾了整整两个晚上才把这套老掉牙的GDAL 1.11.5在mingw32环境下从源码到命令行工具完整跑通。这过程踩的坑比这五年加起来的都多。我估计不少朋友迟早要碰这种老版本迁移或者历史项目环境重装的活干脆把这套东西捋清楚写出来。1. 为什么2026年还要折腾GDAL 1.11.5 mingw32背景与选型逻辑先说结论如果你是从零开始的新项目直接上GDAL 3.x官方Windows安装包别往下看了。这篇文章是给那些被历史包袱绑住的人准备的——老系统的接口协议只兼容旧版GDAL行为、遗留C代码里直接调用了1.x独有的内部API、或者甲方指定必须在某个老旧运行环境里保持版本不变。我这次接触的项目属于第二种。业务代码里用到了GDAL 1.11.5中一个在后续版本被移除的内部数据结构具体名字不说了免得大家跟着踩升级GDAL意味着重写几百行代码得不偿失。所以唯一的出路就是在新机器上重新把1.11.5编译出来。为什么选mingw32而不是MSVC三个原因项目原本就是MinGW工具链编译的链接的是libgdal.a这种静态库和MinGW运行时换MSVC意味着所有依赖库全部重编工作量和风险完全失控。老旧机器上装完整版Visual Studio本身就很折腾MinGW解压即用适合现场救援。后续维护的人大概率是Linux背景用GCC系工具链更顺手。需要提醒的是mingw32指的主要是32位编译目标。我这次的目标机虽然是64位CPU但系统是老版Windows 7 32位所以只能编32位版本。mingw-w64项目本身也提供32位目标的编译器通常前缀是i686-w64-mingw32这个细节后面编译参数里会体现。2. 环境准备工具链版本、依赖库取舍与目录规划2.1 工具链版本别用太新的GCC教训第一条mingw32环境下的GCC版本不要追新。GDAL 1.11.5是2015年的代码用的是C03标准而新版GCC9.x以上默认启用了更严格的编译检查老代码里一堆隐式转换、废弃API调用会直接变成错误或铺天盖地的警告。我测试了三个组合GCC版本结果GCC 5.3.0官方MinGW-W64项目早期版编译顺利基本无痛GCC 8.1.0有少量错误手工改代码可过GCC 12.x报错数量爆炸果断放弃最后锁定了MinGW-W64项目提供的gcc 5.3.0i686架构版本。这个版本和GDAL 1.11.5基本是同时代的产物兼容性最好。你在SourceForge的MinGW-W64目录下能找到压缩包解压后把bin目录加到PATH即可。注意网上还有另一种MinGW发行版叫MinGW.org它只提供32位的gcc版本停在4.8.1太老了反而有问题。建议直接用MinGW-W64的i686-5.3.0版本。2.2 依赖库能免则免能内建就别外链GDAL 1.11.5的configure脚本支持很多可选依赖库比如GeoTIFF、libpng、libjpeg、PROJ、GEOS等。在mingw32环境下这些库的Windows预编译版本很难找齐而且版本不匹配的话编译时让你欲哭无泪。我的策略是把能内建的内建configure参数里用internal把用不到的外链直接禁用--without-*只保留了必须用到的外部依赖实际操作时我只额外准备了两个外部库zlib和libtiff。zlib在MinGW-W64的发行包里自带一份直接指向它的路径就行。libtiff如果不想折腾GDAL也能用内部版本。我为了保持和原项目一致选择了外链libtiff这里多花了一些时间。如果你不确定哪些依赖可以禁用参考我这次的configure参数./configure \ --prefix/c/gdal-1.11.5-mingw32 \ --hosti686-w64-mingw32 \ --buildi686-pc-mingw32 \ --with-libz/c/mingw32/i686-w64-mingw32 \ --with-pnginternal \ --with-jpeginternal \ --with-gifinternal \ --with-libtiff/c/libtiff-mingw32 \ --with-geotiffinternal \ --with-geosno \ --with-projno \ --with-curlno \ --with-pythonno \ --with-expatno \ --with-xercesno \ --with-netcdfno \ --with-hdf4no \ --with-hdf5no \ --with-mysqlno \ --with-pgno \ --with-odbcno \ --with-sqlite3no \ --without-ogdi \ --without-gta \ --without-pcraster \ --without-cfitsio \ --without-openjpeg \ --without-pcre看着一堆no其实逻辑很清晰先按原项目用到的格式清单过一遍只保留必要项其他统统关掉。GDAL 1.11.5本身对很多可选库的依赖不是强制的关掉之后只是少了一些驱动支持不影响核心栅格/矢量读写功能。2.3 目录规划统一前缀方便后续链接因为我需要同时编译GDAL C库和命令行工具而且还要供老项目链接所以目录规划很重要。我的建议是源码目录C:/work/gdal-1.11.5安装目录C:/gdal-1.11.5-mingw32外部依赖目录C:/mingw32和C:/libtiff-mingw32这样配置时--prefix指向一个干净目录后续项目只需要把这个目录的include、lib、bin加入对应路径即可。我见过一些人直接把GDAL装到MinGW的目录里短期省事长期混乱不推荐。3. configure make 完整编译实录3.1 第一步配置configure脚本GDAL不需要单独的autoheader/aclocal步骤源码包自带了configure脚本直接用bash执行即可。这里有个重要细节必须用MinGW的bashMSYS环境来运行configure而不是Windows的CMD。因为configure脚本内部用到了大量Unix工具sed、awk、grep等CMD下跑不动。我使用的是MSYS2环境但MSYS2默认带的工具链是64位的所以需要在MSYS2的shell中明确指定32位环境变量export PATH/c/mingw32/bin:$PATH export CPPFLAGS-I/c/mingw32/i686-w64-mingw32/include export LDFLAGS-L/c/mingw32/i686-w64-mingw32/lib然后运行configure命令。3.2节的配置参数直接粘贴执行即可。configure运行时间大约3分钟会打印大量检测信息。关键看最后几行确认GDAL is now configured for那一节里C compiler和C compiler都指向了i686-w64-mingw32-gcc。如果configure报错说找不到C编译器先检查PATH里有没有g和gcc。MinGW-W64的bin目录下这两个文件的名分别是i686-w64-mingw32-gcc.exe和i686-w64-mingw32-g.exe有些地方也提供不带前缀的gcc.exe和g.exe但建议用带前缀的避免和系统其他编译器混淆。3.2 第二步make编译及常见报错处理configure通过之后直接make -j4这里建议不要用-j8之类的太高的并行数。GDAL这个老版本代码在并行编译时偶尔会有头文件依赖不完整的问题-j4比较稳我试过-j2更稳但慢。编译过程大约20分钟32位机器。我这里遇到过一次报错内容大致是gdalwarp.cpp: In function void* GDALWarpInit... gdalwarp.cpp: xxx: error: cannot convert int* to long*...这是我前面说过的老代码与GCC版本冲突问题。因为已经锁定了GCC 5.3.0理论上不该出现。后来查明是CPPFLAGS里-m32参数影响到了自定义类型的对齐把CFLAGS里多余的-march参数去掉就好了。如果你的代码不一样大概率也会撞上类似问题——解决办法不是盲目改代码而是先对照GCC版本再检查编译参数最后才动源码。编译结束后执行make install安装过程把头文件、库文件、可执行文件放到/c/gdal-1.11.5-mingw32目录下。完成后检查一下ls /c/gdal-1.11.5-mingw32/bin应该能看到gdalinfo.exe、ogr2ogr.exe、gdal_translate.exe等工具。同时lib目录下应该有libgdal.a静态库、libgdal.dll.a导入库和gdal111.dll动态库。4. 链接报错的集中排查老版本遇上新工具链的典型问题这是整个过程中最痛苦的环节我遇到过三类链接错误附上根因和方案。4.1 头文件里使用了strcasecmp和strncasecmpGDAL 1.11.5的源码里有地方用了POSIX风格的strcasecmp这在Linux上没问题但MinGW环境没有实现到链接时才报undefined reference to strcasecmp。解决办法在GDAL的port目录下它自带了一个cpl_config.h里面通过宏映射了strcasecmp到stricmp。如果configure没有正确识别MinGW系统这个宏不会生效。你可以手动在编译命令里加上-Dstrcasecmpstricmp -Dstrncasecmpstrnicmp或者在cpl_config.h里找到/* #undef HAVE_STRCASECMP */这一行改成#define HAVE_STRCASECMP 1同时加入映射宏。我是直接在命令行参数里加的省得改源码。4.2libgdal.dll.a和gdal111.dll的导入导出符号问题如果最终项目要动态链接gdal111.dll链接器需要导入库。GDAL的Makefile在make install时生成的导入库是libgdal.dll.a放在/c/gdal-1.11.5-mingw32/lib下。但项目可能在编写时用的是-lgdal这种写法链接器会在默认目录找libgdal.a。如果只有libgdal.dll.a而没有libgdal.a链接时优先找到了libgdal.a但它的符号表是从静态库导出的和动态库里的符号不一致导致部分符号找不到。我的做法是静态链接直接指向libgdal.a动态链接直接用libgdal.dll.a改名或拷贝成libgdal.a。为了省事我把动态库对应的导入库拷一份为libgdal.a这一招在别的依赖库里也通用。4.3__imp__前缀导致Python绑定链接失败即使在configure里设了--with-pythonnoGDAL捆绑的SWIG接口脚本仍可能被编译并且在链接时抛出一堆__imp_*相关的未定义符号。这个现象是因为MSVC风格的导入库符号和MinGW风格的命名差异。GDAL 1.11.5的SWIG接口默认针对MSVC做了修饰MinGW下会有冲突。最省心的办法如果不需要Python绑定我这次不需要老项目是C调用直接在编译时把SWIG生成的部分排除掉。编辑源码根目录的GNUmakefile找到与swig相关的target注释掉或者最后阶段不执行make swig。如果必须用Python绑定那需要单独编译SWIG的C源码建议完全脱离GDAL主流程、单独编一个闭源的封装库工作量不小。5. 编译完成后的使用实测命令行工具和C调用5.1 命令行工具快速验证安装完成后的第一件事跑一下/c/gdal-1.11.5-mingw32/bin/gdalinfo --version正常输出GDAL 1.11.5, released 2015/04/29注意在32位环境下如果要处理超大栅格超过4GB32位进程会受2GB或4GB地址空间限制容易报内存不足。实测时我处理一个3.8GB的GeoTIFF就崩了好在项目场景是几十MB到几百MB的影像没太大影响。如果你也有大文件需求务必提前做好分块方案别迷信老版本能硬扛。然后跑一个真实文件测试/c/gdal-1.11.5-mingw32/bin/gdalinfo C:/data/test.tif关注输出里的Driver: GTiff/GeoTIFF、Size is、Coordinate System is这几行确认依赖库libtiff/zlib都正常加载了。5.2 C项目集成老项目链接这版GDAL时编译器参数需要这样写i686-w64-mingw32-g main.cpp \ -I/c/gdal-1.11.5-mingw32/include \ -L/c/gdal-1.11.5-mingw32/lib \ -lgdal \ -o app.exe运行时记得把C:/gdal-1.11.5-mingw32/bin/gdal111.dll复制到可执行文件旁边或者加到系统PATH里。我见过不少人在开发机上跑得好好的部署到现场就报缺少DLL就是这个原因。GDAL环境初始化和清理还是老一套#include gdal_priv.h #include cpl_conv.h int main() { GDALAllRegister(); GDALDataset* ds (GDALDataset*)GDALOpen(C:/data/test.tif, GA_ReadOnly); if (ds) { int cols ds-GetRasterXSize(); int rows ds-GetRasterYSize(); // 业务逻辑 GDALClose(ds); } GDALDestroyDriverManager(); return 0; }老项目只要接口没变这块基本无痛迁移。补充一点GDAL 1.11.5的C接口文档网上已经不好找了离线文档在源码包的doc目录下建议保留一份后续查函数原型比翻网页快得多。5.3 驱动列表确认要确认到底哪些格式被编译进了库用gdalinfo --formats我这次启用精简配置后能看到的有GTiffGeoTIFF栅格HFAErdas ImagineENVIENVI .hdr LabelledAAIGridArc/Info ASCII GridCSV逗号分隔矢量ESRI Shapefile矢量KMLKeyhole Markup LanguageGeoJSON读新版才支持写依赖外部库的JPEG、PNG、GIF也都在。如果你发现某些格式缺失回到configure参数重新检查对应依赖即可。6. 如果重来一次版本选择、避免踩坑的替代方案编译成功后我冷静下来总结如果换一个思路完全能省下至少一个晚上的时间。6.1 优先用发行版预编译包GDAL官方维护了Windows二进制包我在网上搜索GDAL相关热词时也看到很多人直接用gdal 3.10.1 cp313 cp313 win_amd64.whl这类Python wheel安装GDAL。对于大多数人来说这才是正道。如果是被老版本绑死也有第三方项目提供了历史版本的预编译DLL和import库比如GISInternals能直接下载到GDAL 1.11.x的mingw版本。只是这些第三方包的编译器版本可能和你项目不完全一致在链接纯C接口时通常没问题C内部ABI就要看运气了。我当时为什么没用这招因为内网环境不能随意下载第三方包而且C需要一直链的动态库必须和项目原来的参数保持一致担心预编译包缺少某些驱动所以只能完整编译。走廊如果你也是这个处境我觉得先试试预编译包、再决定是否从源码编是更合理的顺序。6.2 Python安装GDAL的注意事项顺带聊一下Python安装GDAL。热词里出现gdal 3.10.1 cp313 cp313 win_amd64.whl这其实是PyPI上GDAL的轮子服务于Python 3.13和Windows 64位环境。如果你需要用Python调用老版本GDAL要注意两点GDAL 1.11.5对应的SWIG绑定只支持Python 2.x和早期Python 3.x现代Python 3.10基本上编不过去所以不要指望pip install gdal1.11.5在2026年的环境还能跑。如果只是做数据处理建议直接用现代的rasterio或osgeoGDAL 3.x它们内部封装了新版GDALAPI设计更现代性能更好。对了我这次整个编译过程完全没有涉及Python就是因为知道这块在老版本上是无底洞。6.3 两个极小但极关键的提醒MSYS环境变量不要污染configure。如果系统里还有MSYS自带的某些库configure可能把它们当成依赖导致Makefile里出现错误路径。最稳妥的做法在一个干净的MSYS shell里只把MinGW-W64的bin和必要的依赖include/lib加入PATH其他全不保留。32位地址空间和GDAL的缓存设置。GDAL 1.11.5的GDAL_CACHEMAX环境变量控制内部缓存块大小默认很小。在32位进程里不要设置超过1000MB不然内存分配失败会导致程序闪退。我一般设成256MB。这次折腾完之后我把整个编译环境打包成了7z存档放在服务器上备份。下次如果再有机器要重装环境直接解压、改一下路径就能用不用再花第二个晚上。如果你手头也有这种老版本GDAL的编译任务建议你也这么做——毕竟这套东西编一次少一次谁知道明年编译器又会变得多严格。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?
咨询建站