news 2026/9/8 7:33:24

Windows上mingw64编译GDAL 1.11.5:老版本依赖的完整方案

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Windows上mingw64编译GDAL 1.11.5:老版本依赖的完整方案

简介:基于MSYS2与MinGW64编译完成的GDAL 1.11.5开发包,供Qt(MinGW版)环境下的C++开发者直接使用,解决GIS工程中GDAL库编译繁琐的问题。压缩包共149个文件,约70.71MB,以头文件、静态链接库、可执行工具和坐标参数CSV为主:头文件与静态库用于Qt项目链接调用,CSV提供投影、基准面与椭球参数,exe支持命令行格式转换。包内另有dll、ini等配套文件,解压后将bin目录加入环境变量,并在.pro中配置include和lib路径即可接入,若程序异常退出可参考作者排错博文快速定位。目前已有1514人学习下载,适合需要快速集成GDAL地理数据处理能力的MinGW64使用者。 说实话,如果只是想在Windows上用GDAL处理数据,我完全不建议去折腾编译——pip install gdal或者直接拉一个OSGeo4W安装包,几分钟就能开干。但如果你遇到的是下面这些场景:老项目锁定在GDAL 1.x系列、Qt用了MinGW工具链导致MSVC库没法混用、或者需要给一个叫libgdal-1.dll的旧库做兼容性封装,那"mingw64编译的GDAL 1.11.5"几乎就是唯一解。

GDAL 1.11.5是1.x系列的收官版本,在2016年底发布之后,整个1.x分支就停更了。按理说这种老版本早该被2.x、3.x替代,但地理空间领域的老代码生命力超出想象。我自己就接过一个维护需求:对方的GIS平台从32位迁移到64位,原来的GDAL预编译包是x86的,一连串依赖全部作废,最后只能自己动手在mingw64环境下从源码完整编一套。这篇就顺着这条线,把整个过程的决策逻辑、编译流程、踩坑点和集成方法写清楚,给后面要干同样事的人省点时间。

1. 为什么要折腾GDAL 1.11.5这种"老古董"

1.1 GDAL 1.11.5的特殊定位

GDAL 1.x和现在主流的2.x、3.x,在很多核心API上并不是无缝兼容的。1.11.5的代码主体是C++98风格,很多老项目里大量使用GDALOpen这种C接口配合C++封装来做二次开发,函数签名、错误处理、甚至数据模型都和后来的版本有明显差异。

尤其要注意的是,2.x引入的GDALOpenEx、统一栅格/矢量API,以及3.x对多线程模型的强化,让老代码在升级时不是改两个函数名那么简单。很多生产系统里基于1.x做的格式插件、内存数据管理逻辑,换到新版本后行为直接变了。所以一些对稳定性要求极高、又不想投入人力做迁移测试的团队,宁可在新环境里继续用1.11.5,也不愿意冒升级风险。

1.2 什么场景会把人逼到源码编译这一步

我自己遇到过的真实需求有几类,你可以对号入座:

  • 老项目的构建环境从32位迁移到64位,原来下载的预编译GDAL只有x86版,或者x64版对应的依赖库版本和项目不匹配。
  • 项目用了MinGW分支的Qt做桌面端开发,GIS核心模块需要链接GDAL。这时候MSVC编译的GDAL就非常尴尬,因为GCC和MSVC的导入库、运行时库、异常处理模型都不一致,硬链接的结果通常是编译报错,或者编译过了运行起来出诡异崩溃。
  • 第三方库或插件明确依赖GDAL 1.11.5的导出符号和ABI,比如某些老版本的QGIS插件、收费GIS模块。
  • 自己维护的发行套件里捆绑了特定版本的GDAL,为了保持所有环境行为一致,不允许随便换版本。

这一类需求基本都能在社区里搜到同类提问,结论都是一样的:用mingw64自己编,而不是找现成包。

1.3 为什么选择mingw64而不是MSVC的nmake方案

GDAL官方在Windows平台上的构建方案,最早是给MSVC准备的,源码目录里就有nmake.opt和说明文档。但GDAL 1.x整体构建体系是Unix风格:configure脚本、Makefilegcc/g++这一整套。用MSVC去编也不是不行,但要额外处理很多环境变量和外部依赖,而且最终产物是.lib导入库,跟GCC系工具链基本绝缘。

mingw64则完全踩在GCC生态上:生成的libgdal.dll.a导入库可以直接让MinGW的GCC用,Qt的MinGW版本、Code::Blocks自带的编译器、MSYS2里的各种开源库都能无缝衔接。说白了,选择mingw64不是因为它比MSVC更好,而是因为你的下游工具链是GCC系,GDAL必须用同一套编译器来编译,这是最容易被忽略的一环。

2. 搭建mingw64环境:依赖库选型决定后面的坑

2.1 MSYS2与mingw64工具链

在Windows上获得mingw64工具链,最省事的方式是安装MSYS2。安装包从官网下载,默认装到C:\msys64。装完后不要直接用Windows的cmd去编译,GDAL 1.x的configure是shell脚本,需要在MSYS2提供的MinGW64环境里运行。

打开"MSYS2 MinGW x64"终端,先做一轮更新和工具链安装:

pacman -Syu pacman -S --needed base-devel mingw-w64-x86_64-toolchain

base-devel会带来patch、make等基础工具,mingw-w64-x86_64-toolchain则是完整的GCC工具链。注意必须是在MinGW64终端里,因为只有这个终端的PATH默认包含了/mingw64/bin,configure脚本才能顺利找到gcc和make。

2.2 依赖库:哪些必须、哪些可以砍

编译GDAL之前,最难的不是主程序编译,而是决定依赖库怎么配。依赖库选型直接决定你后面要踩多少坑,我给你一个实际测试过的最小配置参考:

依赖库是否必须作用备注
zlib必须TIFF/PNG等格式的压缩数据支持建议用pacman装mingw64版本
libtiff强烈建议GeoTIFF读写核心没有它GDAL的栅格能力直接瘫痪
libpng建议PNG格式支持处理遥感图像时很常用
libjpeg-turbo建议JPEG格式支持同上
proj视需求坐标投影转换GDAL 1.11.5需要老版本proj 4.9.x,新版proj没有proj_api.h,这个是最大的坑
geos可选空间拓扑运算不需要OpenGIS几何运算就关闭
curl可选WMS/WCS等远程数据源配置麻烦,新项目基本用不上
sqlite3可选GPKG等格式支持不需要可以关

安装常用依赖库的命令:

pacman -S mingw-w64-x86_64-zlib \ mingw-w64-x86_64-libtiff \ mingw-w64-x86_64-libpng \ mingw-w64-x86_64-libjpeg-turbo \ mingw-w64-x86_64-expat

这里有一个必须提前知道的常识:所有依赖库都必须用mingw64版本,不能用MSVC编译出来的版本。MSVC的.lib导入库在GCC面前就是一堆无法解析的符号,就算把DLL硬塞给编译器,也会在链接阶段报出漫山遍野的undefined reference

2.3 源码包的正确获取方式

GDAL 1.11.5源码从官网历史版本目录就能拿到,文件名是gdal-1.11.5.tar.gz,大概几十MB,解压到任意工作目录,比如/c/src/gdal-1.11.5

我的建议是解压到C:\src这种短路径下,尽量别放在C:\Program Files或带中文的目录里。GDAL 1.x的configure脚本对路径里的空格特别敏感,轻则检查不到依赖库,重则直接生成错误的Makefile,这类问题排查起来非常折磨人。

3. configure与make:GDAL 1.11.5核心编译流程

3.1 理解老的构建系统逻辑

GDAL 1.x的源码根目录里,你会看到两个体系并存:nmake.optnmakefile是给MSVC用的,configureGNUmakefile则是给Unix/MinGW环境用的。mingw64走的完全是后者。

configure脚本会做环境探测,检查系统架构、编译器、依赖库头文件和库文件位置,把结果写入生成的GDALmake.optcpl_config.h。整个流程一旦出错,不要急着重新跑,先把最新报错信息定位到具体是哪个依赖检查环节失败,这比无限重试有用得多。

3.2 configure配置项:每个参数的实际含义

我实际使用的configure命令大致如下,拆开讲解:

cd /c/src/gdal-1.11.5 ./configure --prefix=/c/gdal-win64 \ --with-curl=no \ --with-geos=no \ --with-proj=/c/proj-4.9.3-win64 \ --with-python=no \ --without-libtool
  • --prefix=/c/gdal-win64:安装路径,根据前面说的避开空格原则设置。
  • --with-curl=no:明确关闭远程数据源驱动,避免configure去系统里反复查找curl库。如果你确实需要WMS等远程服务,就另外用pacman装上mingw-w64-x86_64-curl,再改成--with-curl=yes
  • --with-geos=no:没有安装GEOS就关掉。GDAL 1.x对GEOS的依赖不只是头文件,还涉及OGR几何函数的运行时交互,没有把握不要开。
  • --with-proj=/c/proj-4.9.3-win64:这里指向的是你额外编译安装的PROJ 4.9.x目录。如果你不需要坐标转换,可以改成--with-proj=no,但GIS项目基本绕不开投影,我建议还是老老实实把老proj编出来。
  • --with-python=no:关掉Python绑定,因为我们只需要C/C++库。OpenGDA官方对Python绑定的依赖比较啰嗦,开了反而容易因为distutils版本问题卡住。
  • --without-libtool:GDAL 1.x默认有可能尝试走libtool构建路径,在MinGW环境下有时会生成动态库失败。不用libtool可以少一层麻烦,不过也可能导致产物只有静态库,具体看你需要的链接方式。

3.3 make、安装与产物验证

configure通过后,直接编译:

make -j4

-j4是四线程并行,新手不建议给太高,因为如果某个编译单元报错,多线程的报错输出会混在一起,很难定位。等第一次编译成功之后,再考虑并行加速。

整个编译时间取决于机器性能,老机器可能二十分钟,新机器几分钟就能跑完。编译完成后执行:

make install

安装后的目录结构大致是这样:

  • include/:gdal.h、gdal_priv.h、ogr_api.h、cpl_conv.h等头文件。
  • lib/libgdal.a静态库和libgdal.dll.a导入库。
  • bin/gdalinfo.exegdal_translate.exeogrinfo.exe等命令行工具,以及GDAL主动态库和依赖库。

验证一下基本功能:

/c/gdal-win64/bin/gdalinfo --version /c/gdal-win64/bin/gdalinfo --formats

只要能看到GDAL 1.11.5, released 2016/...和一大票格式驱动列表,核心编译就算完成了。

4. 编译中高频踩坑:proj头文件、混用产物、gcc版本

4.1 proj 6.0以上移除了proj_api.h,GDAL 1.11.5直接编译失败

这是整个GDAL 1.x在mingw64下编译遇到最多的问题。PROJ库在6.0.0版本把老式的proj_api.h头文件和pj_init这套API全部移除了,只保留基于PROJ类和proj.h的新接口。

GDAL 1.11.5的代码里,凡是用到坐标投影的模块都依赖proj_api.h。如果你从MSYS2的源直接安装新版proj,configure阶段也许能检测到libproj库,但编译到对应文件时会直接报:

fatal error: proj_api.h: No such file or directory

解决办法有两个:

  • 推荐:下载PROJ 4.9.3源码,用同样的mingw64工具链编译并安装到独立目录,比如/c/proj-4.9.3-win64,然后传给GDAL的--with-proj参数。
  • 省事:--with-proj=no,牺牲所有投影转换能力。

如果你做的是正儿八经的GIS开发,我强烈建议别在图省事之后后悔。坐标转换在GDAL里牵扯太广,很多格式驱动写进元数据时也会调用投影接口,关掉proj会损失大量功能。

4.2 依赖库混用MSVC产物,引发的连锁反应

有人会想,proj库我直接找一个MSVC编译好的DLL来凑合用,反正都是Windows。这个想法我劝你趁早打消。

MSVC和MinGW的导入库格式不同,pe导出符号机制也存在差异。MinGW的gcc链接器看到MSVC生成的.lib,通常会报:

undefined reference to `__imp_pj_init'

这种以__imp_开头的未定义符号,就是GCC无法理解MSVC导入库的典型表现。就算个别库用dlltool能把DLL转成.a导入库,ABI层面的C语言结构体对齐、__cdecl调用约定等细节也容易埋雷。实践原则只有一条:GDAL的每一个依赖库都必须用mingw64编译,不要混用任何MSVC产物。

4.3 过新的gcc版本对老代码不友好

MSYS2仓库里的mingw64工具链更新速度很快,如果你装到了gcc 12甚至更高的版本,编译GDAL 1.11.5时可能会碰到老代码在严格编译器下报错的情况。常见症状是某些默认警告被当成错误,比如-Werror开启后,老代码里的类型转换或未使用参数直接中断编译。

遇到这种情况,可以在configure时人为放宽编译选项:

./configure --prefix=/c/gdal-win64 \ CFLAGS="-O2 -Wno-error" \ CXXFLAGS="-O2 -Wno-error" \ --with-curl=no \ --with-proj=/c/proj-4.9.3-win64

如果已经编到一半报错,不建议盲目加-fpermissive,那是最后的逃生手段。更理性的做法是回去装一个gcc 9或10的旧版本,确保工具链和源码属于同一个时代。以我给几个项目搭环境的经验看,gcc 10在大多数情况下都能顺利编过1.11.5,gcc 12开始才需要额外处理。

4.4 路径、杀毒软件和其他隐蔽问题

再补充几个经常把人逼疯的细节:

  • 安装路径和源码路径都不能有空格,C:\Program Files这种目录是configure脚本的重灾区。
  • Windows自带的杀毒软件有可能在生成大量DLL时误报,建议把MSYS2目录、源码目录、安装目录都加入白名单。
  • 不要在Windows cmd里直接敲./configure,那不是cmd能解析的脚本,必须在MSYS2 MinGW64终端里运行。
  • 如果你的依赖库是用pacman装在/mingw64下的,configure通常能自动找到;如果是自己编译安装到自定义目录,最好用--with-xxx=/路径明确指定,否则configure检查通过但实际编译时找不到头文件的情况也会出现。

5. 编译产物集成:CMake链接、动态库部署与实际测试

5.1 先做一轮冒烟测试

编译安装完成后,先用命令行工具做基础验证。找一张真实的GeoTIFF测试一下:

export PATH=/c/gdal-win64/bin:$PATH gdalinfo /path/to/your/test.tif

能正确输出影像大小、波段数、投影信息,就说明GDAL核心驱动工作正常。ogrinfo再测一下矢量格式,比如读一个ESRI Shapefile,确认OGR模块也没问题。

测试阶段不要急着用CSV之类的简单格式,能覆盖GeoTIFF和Shapefile这种基础格式就足够暴露大多数问题。

5.2 在CMake工程中集成GDAL

GDAL 1.11.5本身没有内建CMake config文件,所以find_package(GDAL)依赖CMake自带的FindGDAL模块。这个模块老版本的习惯是优先找gdal-config程序。因此在CMake之前,需要把C:\gdal-win64\bin加入PATH,或者设置环境变量GDAL_ROOT,让CMake能找到对应的可执行文件。

一个常规的CMake集成写法:

find_package(GDAL REQUIRED) include_directories(${GDAL_INCLUDE_DIR}) target_link_libraries(myapp PRIVATE ${GDAL_LIBRARY})

如果find_package还是找不到,就直接手动指定路径:

set(GDAL_INCLUDE_DIR "C:/gdal-win64/include") set(GDAL_LIBRARY "C:/gdal-win64/lib/libgdal.dll.a")

需要注意的是,mingw下的GDAL导入库是libgdal.dll.a,不是MSVC习惯的gdal_i.lib。如果你的构建脚本里写的-lgdal,GCC会自动找到libgdal.dll.alibgdal.a,不需要额外改库名。

5.3 写一个最小示例验证链接

写一个读取栅格影像基本信息的C++程序,验证整条编译链是否通畅:

#include "gdal_priv.h" #include <cstdio> int main() { GDALAllRegister(); GDALDataset* ds = static_cast<GDALDataset*>( GDALOpen("C:/data/test.tif", GA_ReadOnly)); if (ds) { std::printf("size: %dx%d, bands: %d\n", ds->GetRasterXSize(), ds->GetRasterYSize(), ds->GetRasterCount()); GDALClose(ds); } else { std::printf("open failed\n"); } return 0; }

编译命令:

g++ -o read_img.exe read_img.cpp \ -I C:/gdal-win64/include \ -L C:/gdal-win64/lib -lgdal

运行前,确保C:\gdal-win64\bin在PATH里,或者把GDAL主动态库和它依赖的proj、tiff等DLL全部拷到exe所在目录。如果运行时提示找不到DLL,先不要怀疑代码,直接在命令行里跑where gdal111.dll看路径是否可达。

我个人在实际排查中最常用也最有效的工具是objdump -p read_img.exe | grep "DLL Name",一条命令就能列出程序依赖的动态库列表,哪个缺失一目了然。

这套编译流程走完,再回头看整个过程,最花时间的其实不是GDAL本身的编译,而是把proj固定在4.9.x这个老版本上,并且确保所有依赖库统一用mingw64编译。只要你记住这个顺序:先统一工具链,再解决依赖库,最后回来编主库,基本能少走一大半弯路。

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/8 7:32:53

Java与JavaScript全方位对比:从运行机制到应用场景的深度解析

很多刚接触编程的朋友都有过这样的困惑&#xff1a;Java和JavaScript&#xff0c;名字这么像&#xff0c;到底是不是一回事&#xff1f;我当年也在这上面栽过跟头——以为学会了Java就顺带懂JavaScript&#xff0c;结果打开前端页面直接懵了。今天就用一篇长文&#xff0c;把这…

作者头像 李华
网站建设 2026/9/8 7:31:22

前端JS在线预览PDF:pdf.js原理与实战踩坑全解析

简介&#xff1a;这是一份基于PDF.js实现浏览器端在线预览PDF的完整前端资源包&#xff0c;面向Web前端开发者和需要快速集成PDF预览功能的技术人员。资源共402个文件&#xff0c;压缩包大小仅3.06MB&#xff0c;核心由JS、HTML、CSS构成可直接运行的示例页面与工具脚本&#x…

作者头像 李华
网站建设 2026/9/8 7:29:56

刚删除的照片怎么找回?8个恢复方案从原理到实操全解析

刚删除的照片怎么找回&#xff1f;这个问题的答案其实不在某个神奇软件里&#xff0c;而在你对“删除”这件事的理解有多深。作为被朋友和读者问过无数次数码恢复问题的人&#xff0c;我见过太多人把一次可以10分钟解决的小意外&#xff0c;拖成花大价钱找数据机构才能解决的大…

作者头像 李华
网站建设 2026/9/8 7:26:31

AI眼镜人脸识别:从Meta专利到端侧实战拆解

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/8 7:26:29

逆变器Class B辐射超标?PV端口共模噪声定位与整改实战

做逆变器硬件最怕的一句话就是&#xff1a;“预测试不过&#xff0c;Class B 辐射超了。” 尤其是那种二三十千瓦的大功率机型&#xff0c;明明传导发射还算干净&#xff0c;结果一上辐射测试&#xff0c;30MHz到80MHz这一段直接给你顶出一个尖包&#xff0c;怎么压都压不下去。…

作者头像 李华
网站建设 2026/9/8 7:26:07

ESP32 AI玩偶音频链路重构:WebSocket二进制帧实现连续对话

WebSocket 二进制音频链路重构&#xff1a;让 ESP32 AI 玩偶从“能对话”走向“连续对话”先说结论&#xff1a;做 AI 硬件玩具&#xff0c;最坑的不是大模型接口调不通&#xff0c;而是“能对话”这三个字背后的链路设计。去年我接手了一个 ESP32 AI 玩偶项目&#xff0c;最初…

作者头像 李华