
简介这是基于MSYS2与MinGW32环境预编译的GDAL 1.11.5开发包专为Windows下使用QtMinGW版的开发者准备解决GDAL自行编译耗时长、依赖复杂的问题。包内含编译好的动态库、静态库、头文件和坐标系统参数数据解压后将bin目录加入系统环境变量再在.pro文件中完成链接配置即可直接调用GDAL接口进行栅格/矢量读写、投影转换与格式处理省去从源码编译的漫长等待。资源共149个文件以63个C/C头文件、28个CSV坐标投影参数文件、22个命令行工具exe为主体另含dll、a库及少量xml、wkt等辅助文件压缩包约74.73MB其中头文件提供编程接口声明CSV文件为地图投影和坐标转换提供参数支持结构清晰便于集成。目前已有778人学习下载适合熟悉Qt开发但不想折腾编译链的初中级开发者。作者另附排错博客针对程序异常结束给出具体排查思路能帮助使用者快速解决环境配置中的常见问题。 写这篇的起因很实际——最近在Windows下折腾一套老的地理数据处理流程项目指定要用GDAL 1.11.5 mingw32的组合跑编译和二次开发。这套搭配放到今天听起来确实有点“上古”但真上手后发现老版本自有老版本的价值而且mingw32下的编译坑是真不少网上资料又散、又旧很多帖子都是2014、2015年的按图索骥踩了一路雷。我把整个从环境准备、源码编译到Python调用的一整套流程和踩坑记录整理出来给后面需要在Windows上用mingw32编译GDAL旧版、或者想搞清楚GDAL与Python版本对应关系的朋友做个参考。GDAL这个名字在地理信息系统和遥感领域基本绕不开。它全称是Geospatial Data Abstraction Library专门处理栅格和矢量地理数据格式的读写与转换。大到卫星影像、数字高程模型小到一份Shapefile、GeoJSON底层几乎都在和GDAL打交道。Python生态里的rasterio、geopandas之所以能“优雅”地读取地理数据底层靠的也是GDAL/OGR这套C/C库。而mingw32则是Windows上的一套GNU编译器工具链用来把GDAL这种以C为主的源码在Windows下编译成原生可执行文件和动态链接库不依赖微软的Visual Studio。1. 为什么还折腾GDAL 1.11.5与mingw32的组合1.1 1.11.5这个版本的特殊之处GDAL 1.11.5发布于2015年中属于1.x系列的晚期维护版本。这个版本最大的特点是稳定和“古董级兼容”。1.x系列和2.x、3.x在API设计上有一个明显的分水岭2.0开始引入了统一的栅格和矢量数据模型很多内部结构重写了而3.0更是把C接口翻了个底朝天。如果你负责维护的是老项目、老插件、老生产环境代码里到处是GDAL 1.x时代的函数调用习惯那么升级到3.x不亚于一次小规模重构。我当时接到这个需求的核心原因就是这个——一批老算法模块基于GDAL 1.11.5的API写的短时间不可能全部重写只能在原有版本基础上做维护和功能扩展。这个场景在测绘、国土、农业遥感这些行业里非常常见底层库一旦“稳定运行了很多年”就没人敢动了。1.2 为什么偏偏是mingw32而不是Visual StudioWindows下编译C项目主流无非两条路微软自家的MSVC或者MinGW系列Minimum GNU for Windows。mingw32通常指针对32位Windows目标的GNU编译器链而mingw-w64这个项目则同时支持32位和64位目标。GDAL 1.11.5那个年代官方预编译的Windows安装包大多是32位MSVC的组合如果你要用MinGW工具链自己编译就得自己动手。选mingw32还有一个现实原因某些老的第三方依赖库和插件只提供了32位MinGW编译版本或者是老项目里约定俗成的构建方式就是“mingw32老版本GDAL”。这套环境虽然老但它在特定行业流程里是能跑的贸然切换工具链可能连依赖库都得全部重来风险远大于收益。说白了在新版本层出不穷的今天折腾GDAL 1.11.5和mingw32不是图新鲜而是为了在存量系统里续命。你要是遇到同样的情况最好的心态是“理解它、编译它、扩展它”。2. 编译环境准备MSYS2与依赖库的版本纠缠2.1 快速认识MSYS2与MinGW-w64要在Windows下用MinGW工具链编译GDAL强烈建议装MSYS2而不是直接下载个老旧的MinGW安装包。MSYS2是一个软件发行平台和构建环境它提供了一套类Linux的shell基于mintty和bash并且通过自带的pacman包管理器来安装各种开发库和编译器。好处是依赖关系自动处理版本也比较新。安装完MSYS2后打开“MSYS2 MinGW 32-bit”终端注意选择32位终端——毕竟标题是mingw32目标就是32位环境。先用pacman更新一下系统并安装基础编译工具链pacman -Syu pacman -S mingw-w64-i686-gcc mingw-w64-i686-pkg-config make这里有个关键点mingw-w64-i686-前缀代表32位编译器工具链如果你装成mingw-w64-x86_64开头的默认就是64位编译出来的GDAL没法直接当mingw32版本用。我当时第一次就栽在这里装成了64位工具链configure时倒是顺利但生成dll后放到项目里直接报“bad image format”。2.2 依赖库的版本纠缠proj、geos与sqliteGDAL不是个“光杆司令”编译时依赖好几个底层库。1.11.5年代最核心的几个依赖是projPROJ.4负责投影转换和坐标系定义老版本叫proj4。geos提供矢量几何操作比如空间关系判断、缓冲区计算。sqlite3OGR的SQLite/GPKG驱动需要它。libpng/jpeg/tiff栅格格式的图片支持。curl网络访问、WMS/WFS等在线数据源的驱动支持。在MSYS2里安装这些库命令很简单pacman -S mingw-w64-i686-proj mingw-w64-i686-geos mingw-w64-i686-sqlite3 pacman -S mingw-w64-i686-libpng mingw-w64-i686-libtiff mingw-w64-i686-libjpeg-turbo pacman -S mingw-w64-i686-curl但这里有个“版本纠缠”的大坑MSYS2软件源里的库版本永远是最新的而GDAL 1.11.5是2015年发布的拿2020年之后甚至近几年的proj、geos去配老GDAL大概率会报各种API不兼容的编译错误。例如新版本proj库头文件里的函数签名变了老GDAL源码调用的老接口根本找不到。我当时处理的思路是不追求过新也不强行找老版本号而是看configure阶段的具体报错缺哪个接口就针对性处理。如果不想费这个劲你也可以在configure时直接禁用相关驱动--without-proj那种但那样GDAL的坐标系变换功能就废了实用性大打折扣。如果你有确定的老业务依赖建议用Docker/CentOS 6/7这类老系统里编译好再拷dll出来而如果在Windows纯环境下尽量让MSYS2的库版本“够用就行”别刻意全升级到最新。2.3 编译前必须确认的三件事正式开始configure之前我建议你花十分钟做三件事能省下后面一大半的排查时间确认终端的类型是“MSYS2 MinGW 32-bit”可以用gcc -v查看gcc版本确认是i686目标而不是x86_64。确认依赖库的pkg-config文件是否可见在bash里执行pkg-config --list-all | grep proj之类看看proj、geos、sqlite3是否都在。确认源码包完整性MD5校验一下GDAL 1.11.5的tar.gz避免下载过程中文件损坏。我当时忽略了第2点结果configure时提示找不到proj库折腾半天发现是PKG_CONFIG_PATH没设置好。在MSYS2的32位环境下通常需要这样设置export PKG_CONFIG_PATH/mingw32/lib/pkgconfig设置完之后pkg-config --modversion proj能正确输出版本号configure才能顺利找到库。3. 源码编译GDAL 1.11.5的核心流程3.1 configure阶段的参数选择GDAL源码包解压后进入根目录经典的构建三步走configure、make、make install。configure阶段是核心中的核心参数直接决定最终版功能开关。以下是我实际使用的configure命令并附了参数解释./configure \ --prefix/home/user/gdal-1.11.5-build \ --with-python \ --with-proj/mingw32 \ --with-geos/mingw32/bin/geos-config \ --with-sqlite3/mingw32 \ --with-curl/mingw32/bin/curl-config \ --with-libtiff/mingw32 \ --with-geotiff/mingw32 \ --with-jpeg/mingw32 \ --with-png/mingw32 \ --without-pg \ --without-mysql \ --without-odbc \ --without-grass \ --without-libkml几个说明--with-python编译生成Python绑定模块。如果你计划用Python调用GDAL这步要加。--prefix指定安装目录尽量别用系统默认的/usr/local免得污染MSYS2环境。--without-*按需裁掉不需要的数据库驱动和重依赖。老机器的编译时间有限裁剪能显著提速。--with-proj指定到/mingw32因为MSYS2安装的proj库就在这个前缀下。configure跑完以后看一眼输出的总结信息重点确认proj、geos、curl都是“yes”状态不要用“no”掩盖掉。如果某个依赖显示“no”回去检查pkg-config路径或者对应的-dev包有没有装全。3.2 make与安装的细节configure通过后直接执行make -j4-j参数指定并行编译任务数如果你的机器内存足够8GB以上用4或8都能显著缩短编译时间。GDAL 1.11.5全量编译大概在10到20分钟取决于机器性能和驱动开关。编译过程中最容易出现的问题是“未定义的引用”和“头文件找不到”。前者一般是库版本API不匹配后者一般是依赖库没装全。比如geos版本过高GDAL 1.11.5源码里geos_c.h的某些接口调用方式不兼容就会出现类似gdalwarp.cpp: undefined reference to GEOSBuffer_r(...)这种报错没有多少捷径只有一个笨办法去源码里查这个函数调用的特征和头文件里定义的特征做对比必要时在源码里做一个兼容层。我当时处理geos相关的两个函数时因为只是老API改名直接在头文件里加了宏替换两行搞定#define GEOSBuffer_r(handle, geom, width, quadsegs) GEOSBuffer_r(handle, geom, width, quadsegs, 0)注意这只是示意实际替换必须根据你安装的geos头文件版本写法来。make结束且没有致命错误后接着make install安装完成后把安装目录下的bin文件夹加入PATH并在系统环境变量里设置GDAL_DATA指向安装目录下的share/gdal否则运行GDAL命令时可能因为找不到数据集定义文件而报错export PATH/home/user/gdal-1.11.5-build/bin:$PATH export GDAL_DATA/home/user/gdal-1.11.5-build/share/gdal3.3 验证编译成果用gdalinfo说话安装完成后的第一件事跑一个最基础的验证命令gdalinfo --version正常情况下会输出类似GDAL 1.11.5, released 2015/06/23接着用一张tif或img影像测试一下真实读取能力gdalinfo sample.tif如果能看到影像的尺寸、波段数、投影信息列表说明这套mingw32下的自编译GDAL基本是可用的。如果这里报错“Unable to open file”优先查GDAL_DATA路径是否正确而不是怀疑库本身。我建议在这个阶段顺手跑一个格式转换测试比如把一个tif转成vrt再转回tif能验证栅格读写链路是完整的gdal_translate -of VRT sample.tif sample.vrt gdal_translate -of GTiff sample.vrt sample_out.tif转换成功且sample_out.tif文件大小不为0就可以进入Python绑定的环节了。4. 现代场景下的Python安装GDAL路径4.1 官方wheel从cp313到cp37的版本对应说到Python安装GDAL我注意到现在搜索指数最高的是“gdal 3.10.1 cp313 cp313 win_amd64.whl”这类词条。这其实是现代Python环境下安装GDAL最幸福的方式——直接用pip安装预编译好的wheel包完全不用自己编译。wheel文件名里的“cp313”代表CPython 3.13版本“win_amd64”代表Windows 64位平台。GDAL的官方wheel版本和Python版本有严格的对应关系不能乱装。比如你在Python 3.13环境里安装就找cp313后缀的whlPython 3.11环境就找cp311后缀的whl。安装命令很简单pip install gdal3.10.1如果当前环境的Python版本和3.13不一致pip会自动降级或报错这种时候就要去PyPI或者官方镜像站查一下当前Python版本对应的GDAL版本列表。如果你是在老Python环境比如Python 3.7、3.8还需要安装老一点的GDAL版本比如3.4.x、3.2.x。这里给一张常见的对应表供参考GDAL版本支持的主要Python版本说明3.10.13.9-3.13当前较新版本功能全面3.6.23.7-3.11兼容性较好3.4.33.7-3.10老项目常用2.4.42.7、3.4-3.8最后支持Python 2的版本之一如果懒得查表在pip安装时可以直接让pip自己解析pip install gdal3.6.2如果当前Python版本没有对应的wheelpip会尝试从源码编译这时又会回到“地狱模式”——需要本机装好完整的编译工具链和GDAL依赖。所以我强烈建议能用wheel就用wheel不要主动去走编译路线。4.2 pip安装遇到“ERROR: Failed building wheel”怎么办尽管wheel很香但总有极端情况比如你用了一个很新的Python版本而GDAL官方还没有跟进发布对应版本的wheel或者网络源里缺失某个平台的后缀pip就会尝试从源码构建。然后大概率会跳出这个经典报错ERROR: Failed building wheel for gdal这个报错翻译成人话就是“本环境没有现成的编译产物需要现场编译但你的环境缺工具/依赖。”排查顺序按优先级来先确认是不是版本不对pip debug --verbose查看当前Python解释器支持的wheel标签再对照PyPI上gdal的可用文件找一个配得上的版本。检查本机是否有VS Build Tools或MinGW工具链Python的setuptools在Windows下默认会尝试找MSVC编译器找不到就报错。如果你不想装大几GB的VS可以考虑用conda替代conda install -c conda-forge gdalconda-forge上的GDAL也是预编译好的能省去大量烦恼。如果一定要编译那就得先确保本机有完整的编译环境和GDAL依赖库这基本等于重复前面第2和第3章的流程唯一差别是还要额外装Python开发头文件。4.3 Python调用GDAL时的运行时dll问题即使gdal的whl安装成功了Python里面import也可能“翻车”from osgeo import gdal常见的报错是ImportError: DLL load failed: The specified module could not be found.这个错误十有八九是GDAL依赖的底层dll不在系统搜索路径里。你想想看GDAL是个C库它运行时需要proj、geos、sqlite等动态库但是wheel包只打包了GDAL自身的dll底层依赖库并不会一起带上。解决办法一把依赖库的路径加入PATH环境变量。如果你是用conda安装的那conda环境里的Library/bin目录下一般已经有这些dll了手动把该目录加到PATH即可。解决办法二在Python代码里显式添加搜索路径。在import osgeo之前用os.add_dll_directory()把dll所在目录注册进去Python 3.8支持例如import os os.add_dll_directory(rC:\Program Files\GDAL) from osgeo import gdal这条行为在Win10/11下特别重要。老教程里常见的“直接改系统PATH”也不是不能用但需要重启终端才会生效而add_dll_directory是即时生效的排障效率高很多。还有一个技巧装完gdal whl后用python -c from osgeo import gdal; print(gdal.__version__)先验证基础可用性。如果这一句能过再跑后续代码能避免把“安装没问题”和“业务代码问题”搅在一起。5. 常见问题与排查技巧实录5.1 编译期报错速查表报错信息原因处理方式configure: error: PROJ not foundpkg-config路径不对设置PKG_CONFIG_PATH/mingw32/lib/pkgconfigg: error: unrecognized command line option -stdc11gcc版本过旧升级mingw-w64-i686-gccundefined reference toGEOSBuffer_rgeos新API不兼容检查geos头文件做宏兼容替换cannot find -lproj缺少proj库pacman安装proj并确认32位版gdal-config not foundmake install未执行或prefix未加入PATH执行make install检查PATH这张表看着简单但每一条背后都是我实实在在走过的坑。尤其是PROJ not found一开始总怀疑是依赖没装结果根本不是缺库就是pkg-config路径没指过去。5.2 运行时dll不匹配的经典案例有一次我编译完了GDAL直接调gdalinfo测试结果报了一个很诡异的错误The procedure entry point ... could not be located in the dynamic link library。这个错误的意思是系统加载某个dll时找不到需要的函数入口点。根源几乎都是“多个版本的dll混用”。比如你MSYS2环境里proj的版本和最终GDAL链接时用的proj版本不一致运行时系统加载到了另一个目录下的老proj.dll入口点找不到直接崩。排查思路很简单但很考验耐心用ldd gdalinfo.exe查看它依赖的dll列表和搜索路径。用which proj.dll或where proj.dll看你当前PATH下到底哪个proj被加载。把安装目录下的bin设为PATH最前保证优先加载自己编译时对应的那套dll。这个案例最能解释为什么我前面强调“尽量把依赖都装在一个前缀下/mingw32”因为只要依赖库来源统一运行时冲突概率就小得多。5.3 我的避坑心得如果只能分享三条经验我会说第一别硬凑版本号。GDAL老版本和依赖库之间没有“一定行”的组合表最重要的技能是看懂configure和编译报错信息针对性地调。每次报错都是一次学习机会。第二能用二进制的绝不自己编译。如果只是Python调用优先conda-forge或者pip官方wheel只有做C二次开发、需要自定义编译开关时才值得走源码编译这条路。GDAL 1.11.5这种老版本之所以要自己编译纯粹是因为那个年代没有这么好的预编译生态。第三环境变量是魔鬼。GDAL_DATA、PATH、PROJ_LIB这三个变量占据了我排查GDAL问题的大半时间。每次在新环境里部署先把这三个变量的值搞清楚再跑程序。我个人在实际项目里总结出来的习惯是先写一个环境检查的小脚本把GDAL版本、PROJ版本、数据目录、dll搜索路径一口气打印出来后面所有问题排查都先过一遍这个脚本省掉大量重复劳动。最后再分享一点关于后续扩展的想法——编完GDAL 1.11.5和mingw32这套环境后如果你有权限升级依赖可以试试在同一套MSYS2环境里把proj、geos升级到当时的次新版本看GDAL的驱动和坐标系能力有什么变化。老版本GDAL对某些新格式支持有限很多时候问题不在GDAL本身而在底层依赖库版本这一点想通了后面的路就好走很多。本文还有配套的精品资源点击获取