Windows下用mingw32编译GDAL 1.11.5完整指南与踩坑实录
2026/9/8 8:22:44 网站建设 项目流程

简介:这是基于MSYS2与MinGW32环境预编译的GDAL 1.11.5开发包,专为Windows下使用Qt(MinGW版)的开发者准备,解决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 Studio

Windows下编译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与sqlite

GDAL不是个“光杆司令”,编译时依赖好几个底层库。1.11.5年代,最核心的几个依赖是:

  • proj(PROJ.4):负责投影转换和坐标系定义,老版本叫proj4。
  • geos:提供矢量几何操作,比如空间关系判断、缓冲区计算。
  • sqlite3:OGR的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之前,我建议你花十分钟做三件事,能省下后面一大半的排查时间:

  1. 确认终端的类型是“MSYS2 MinGW 32-bit”,可以用gcc -v查看gcc版本,确认是i686目标而不是x86_64。
  2. 确认依赖库的pkg-config文件是否可见,在bash里执行pkg-config --list-all | grep proj之类,看看proj、geos、sqlite3是否都在。
  3. 确认源码包完整性,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/gdal

3.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后缀的whl;Python 3.11环境,就找cp311后缀的whl。安装命令很简单:

pip install gdal==3.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 gdal==3.6.2

如果当前Python版本没有对应的wheel,pip会尝试从源码编译,这时又会回到“地狱模式”——需要本机装好完整的编译工具链和GDAL依赖。所以我强烈建议:能用wheel就用wheel,不要主动去走编译路线。

4.2 pip安装遇到“ERROR: Failed building wheel”怎么办

尽管wheel很香,但总有极端情况:比如你用了一个很新的Python版本,而GDAL官方还没有跟进发布对应版本的wheel,或者网络源里缺失某个平台的后缀,pip就会尝试从源码构建。然后大概率会跳出这个经典报错:

ERROR: Failed building wheel for gdal

这个报错翻译成人话就是:“本环境没有现成的编译产物,需要现场编译,但你的环境缺工具/依赖。”

排查顺序按优先级来:

  1. 先确认是不是版本不对:pip debug --verbose查看当前Python解释器支持的wheel标签,再对照PyPI上gdal的可用文件,找一个配得上的版本。
  2. 检查本机是否有VS Build Tools或MinGW工具链,Python的setuptools在Windows下默认会尝试找MSVC编译器,找不到就报错。如果你不想装大几GB的VS,可以考虑用conda替代:
    conda install -c conda-forge gdal
    conda-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(r"C:\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/pkgconfig
g++: error: unrecognized command line option '-std=c++11'gcc版本过旧升级mingw-w64-i686-gcc
undefined 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,入口点找不到,直接崩。

排查思路很简单,但很考验耐心:

  1. ldd gdalinfo.exe查看它依赖的dll列表和搜索路径。
  2. which proj.dllwhere proj.dll看你当前PATH下到底哪个proj被加载。
  3. 把安装目录下的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本身,而在底层依赖库版本,这一点想通了,后面的路就好走很多。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询