资讯动态

mingw64 编译 GDAL 1.11.5 包:老项目 Qt 集成与避坑指南

发布时间:2026/10/27 20:50:17 来源:尧图企业网站定制
简介这份资源是作者在 Windows 下用 msys2 配合 mingw64 工具链预先编译好的 GDAL 1.11.5 库面向使用 QtMinGW 版本进行 C 桌面 GIS 开发、又不愿在本地折腾编译环境的开发者可省去从源码配置依赖、处理编译错误的繁琐过程。压缩包共 149 个文件约 70.71MB包含 63 个 C 头文件、22 个可执行程序、28 个 CSV 格式的坐标与投影参数数据以及静态库、导入库、DLL、gdal-config 配置脚本和若干 WKT、XML、XSD 等辅助文件覆盖开发所需的头文件、链接库与运行时数据。已有 1522 人学习下载。解压后将 bin 目录加入系统环境变量并在 .pro 文件中配置 GDAL 路径即可直接调用作者还针对程序异常结束的常见问题给出了排查思路便于读者快速定位运行时库缺失或路径配置错误适合需要稳定 GDAL 开发环境的中级 C 开发者参考使用。1. 老项目卡在 GDAL 1.11.5为什么还要碰这份 mingw64 编译包手上有个 Qt 桌面端的老项目地图数据读写全靠 GDAL版本锁死在 1.11.5换新版接口对不上换编译器又得重编一堆依赖。这种场景下一份已经用 mingw64 编译好的 GDAL 1.11.5 二进制包价值不在于“新”而在于“能直接塞进现有工具链跑起来”。它解决的是老项目维护、遗留系统迁移、教学环境复现这三类人的真实痛点不想从零啃编译脚本只想拿到头文件、库文件和运行时 DLL把工程跑通。这份资源适合谁一是维护 Qt C 老工程的开发者二是需要在 Windows 上快速验证 GDAL 读写逻辑的算法同学三是课程设计里要用 C 调 GDAL 但不想被编译环境劝退的新手。不适合谁指望用最新 EPSG 数据库、最新驱动格式的人1.11.5 的驱动列表和坐标系库都停在那个年代这点后面会反复提。先把“这是什么、边界在哪”说清楚再谈怎么用。2. 拆包看结构mingw64 版 GDAL 的目录与依赖关系2.1 一个合格的 mingw64 GDAL 包应该长什么样拿到压缩包先别急着解压到工程目录找个干净路径展开按目录结构判断这份包是否完整。常见做法是看四类东西include/下的头文件、lib/下的导入库.a或.dll.a、bin/下的运行时 DLL、以及share/gdal/下的数据文件gdal-data、proj相关。缺任何一类后面都会以各种玄学方式翻车。目录/文件作用缺失后的典型症状include/gdal*.h编译期头文件编译报找不到gdal.hlib/libgdal.a或libgdal.dll.a链接期导入库链接报 undefined referencebin/libgdal-1.dll等运行时动态库程序启动即闪退或报缺 DLLshare/gdal/驱动与坐标系数据能打开文件但坐标转换结果离谱mingw64 的坑在于“运行时 DLL 不止一个”。GDAL 自身依赖 zlib、libpng、libjpeg、libtiff、libcurl、sqlite3、expat 等一串库这些要么静态编进libgdal-1.dll要么以独立 DLL 形式躺在bin/里。判断方法很直接用依赖查看工具扫一遍libgdal-1.dll的导入表看它引用了哪些 DLL再对照bin/里有没有。这一步花五分钟能省后面两小时的“为什么我这边能跑你那边不能跑”。2.2 头文件、导入库、DLL 三者的对应关系C 工程接 GDAL 本质是三件事对齐编译时找头文件、链接时找导入库、运行时找 DLL。mingw64 下导入库通常是libgdal.dll.a链接参数写-lgdal链接器会在库搜索路径里找libgdal.dll.a或libgdal.a。如果包里同时有静态库和导入库优先用导入库配 DLL体积小、替换方便只有确定要单文件分发时才考虑静态链接而 GDAL 静态链接的依赖地狱不建议新手碰。Qt 工程里还要注意一点.pro文件的INCLUDEPATH和LIBS是两套路径别只配了头文件路径忘了库路径。下面这段是常见写法路径按你实际解压位置改# 假设 GDAL 解压在 D:/sdk/gdal-1.11.5-mingw64 GDAL_ROOT D:/sdk/gdal-1.11.5-mingw64 INCLUDEPATH $$GDAL_ROOT/include LIBS -L$$GDAL_ROOT/lib -lgdal # 运行时 DLL 不在系统 PATH 时把 bin 目录加进构建输出或部署脚本 # 这里仅作注释提醒qmake 不负责拷贝 DLL逻辑说明INCLUDEPATH让编译器找到gdal.h、ogr_api.h等LIBS的-L指定库目录、-lgdal让链接器找libgdal.dll.a。参数上唯一要改的是GDAL_ROOT其余保持。注意路径里别用反斜杠混写qmake 对\的处理容易出问题统一正斜杠最稳。2.3 用一个小程序验证包是否可用配好工程前先写个最小验证程序别一上来就往大工程里塞。这段代码只做两件事打印 GDAL 版本、注册全部驱动并数一下驱动数量。能跑通说明头文件、链接、DLL、数据目录四件事基本对齐。#include cstdio #include gdal.h int main() { // 打印编译期与运行期版本二者不一致说明 DLL 拿错了 printf(GDAL_VERSION_NUM (compile): %d\n, GDAL_VERSION_NUM); GDALAllRegister(); // 注册所有驱动必须在任何 GDAL 调用前执行 printf(GDALVersionInfo (runtime): %s\n, GDALVersionInfo(RELEASE_NAME)); int count GDALGetDriverCount(); printf(driver count: %d\n, count); GDALDestroyDriverManager(); return 0; }编译命令用 mingw64 的 g把 include 和 lib 路径显式写出来避免依赖环境变量g verify_gdal.cpp -o verify_gdal.exe \ -ID:/sdk/gdal-1.11.5-mingw64/include \ -LD:/sdk/gdal-1.11.5-mingw64/lib -lgdal跑之前把D:/sdk/gdal-1.11.5-mingw64/bin加进当前终端 PATH或者把需要的 DLL 拷到 exe 同目录。输出里compile和runtime版本号必须一致驱动数量一般在 100 以上1.11.5 时代的具体数字随编译选项浮动别拿固定值卡。如果驱动数是 0八成是GDAL_DATA没指对下一节专门说。3. 把 GDAL 接进 Qt 工程路径、链接与运行时三件事3.1 环境变量与数据目录GDAL_DATA 和 PROJ_LIBGDAL 1.11.5 时代坐标系转换还主要靠 PROJ.4数据目录通过GDAL_DATA环境变量定位部分构建还会读PROJ_LIB。这两个变量不设程序不会立刻崩但会在做投影转换、读某些格式时给出莫名其妙的结果属于典型黑匣子问题。常见做法是在程序启动最前面用代码设死别指望用户环境#include cstdlib #include gdal.h int main(int argc, char *argv[]) { // 用相对 exe 的路径部署时把 share/gdal 一起带上 _putenv_s(GDAL_DATA, share/gdal); _putenv_s(PROJ_LIB, share/gdal); GDALAllRegister(); // ... 后续业务代码 return 0; }逻辑说明_putenv_s是 Windows 下设置环境变量的常用写法必须在GDALAllRegister()之前调用因为驱动注册时会读数据目录。参数上路径建议用相对路径配部署脚本绝对路径只适合本机调试。注意share/gdal里应该有gcs.csv、pcs.csv、proj_def.dat这类文件没有就说明包不完整别硬跑。3.2 Qt .pro 与 CMake 两种接法的差异老 Qt 工程多用 qmake新一点的用 CMake两种接法思路一致但写法不同。qmake 前面给过这里补 CMake 版本方便你在混合工程里对照# CMakeLists.txt 片段 set(GDAL_ROOT D:/sdk/gdal-1.11.5-mingw64) find_path(GDAL_INCLUDE_DIR gdal.h PATHS ${GDAL_ROOT}/include NO_DEFAULT_PATH) find_library(GDAL_LIBRARY NAMES gdal libgdal.dll PATHS ${GDAL_ROOT}/lib NO_DEFAULT_PATH) if(NOT GDAL_INCLUDE_DIR OR NOT GDAL_LIBRARY) message(FATAL_ERROR GDAL not found under ${GDAL_ROOT}) endif() target_include_directories(your_target PRIVATE ${GDAL_INCLUDE_DIR}) target_link_libraries(your_target PRIVATE ${GDAL_LIBRARY})逻辑说明NO_DEFAULT_PATH强制只在指定目录找避免系统里另一份 GDAL 混进来——这是 mingw64 环境最常见的“链接到了别的版本”事故来源。find_library的NAMES同时列gdal和libgdal.dll是因为不同打包方式命名不一致。参数上GDAL_ROOT改成你的解压路径即可其余不用动。3.3 运行时 DLL 的部署别让程序在别人机器上闪退本机跑通不等于能交付。mingw64 编译的程序依赖libgcc_s_seh-1.dll、libstdc-6.dll、libwinpthread-1.dll这几个运行时加上 GDAL 自己的一串依赖。交付前用依赖扫描工具把 exe 和libgdal-1.dll的导入表都过一遍把缺的 DLL 全部拷到输出目录。一个可复现的做法是写个部署脚本构建后自动拷贝# deploy.sh在 mingw64 终端里跑 OUTbuild/deploy mkdir -p $OUT cp build/release/your_app.exe $OUT/ cp D:/sdk/gdal-1.11.5-mingw64/bin/*.dll $OUT/ cp -r D:/sdk/gdal-1.11.5-mingw64/share $OUT/ # mingw64 运行时 DLL 从编译器目录取路径按你的安装改 cp /mingw64/bin/libgcc_s_seh-1.dll $OUT/ cp /mingw64/bin/libstdc-6.dll $OUT/ cp /mingw64/bin/libwinpthread-1.dll $OUT/逻辑说明先拷 exe再拷 GDAL 的 DLL 和数据目录最后补编译器运行时。参数上唯一要确认的是 mingw64 安装路径/mingw64/bin是常见布局。注意share目录要整体拷别只挑几个文件驱动依赖的数据文件比你想的多。4. 避坑与排查mingw64 下 GDAL 1.11.5 的五条血泪记录4.1 编译过了链接报一堆 undefined reference现象头文件能找到编译无错链接阶段报undefined reference to GDALAllRegister之类。原因通常是-lgdal写在了源文件前面或者库目录里只有静态库而你没带全依赖。解决把-lgdal放到编译命令末尾链接顺序敏感并确认lib/下确实是libgdal.dll.a若只有libgdal.a需要额外链接 zlib、tiff 等依赖建议换回导入库版本。4.2 程序启动就闪退事件查看器只说缺模块现象双击 exe 无窗口或弹“找不到 libgdal-1.dll”。原因DLL 不在 exe 同目录也不在 PATH。解决把bin/下所有 DLL 拷到 exe 旁边再用依赖扫描工具确认二级依赖也齐。别只拷libgdal-1.dll一个它的依赖缺一个照样起不来。4.3 能打开文件但坐标转换结果差出几百米现象读栅格正常做投影转换后坐标明显偏移。原因GDAL_DATA没设或指向了错误目录PROJ 找不到基准面参数退化成近似转换。解决启动时显式设GDAL_DATA和PROJ_LIB指向包内share/gdal并确认目录里有gcs.csv、proj_def.dat。这是最容易被忽略的一条玄学程度最高。4.4 Qt 工程里混进了系统另一份 GDAL现象本机调试正常换台机器行为不同或版本号打印出来不是 1.11.5。原因PATH 或库搜索路径里有别的 GDAL 抢先被加载。解决CMake 用NO_DEFAULT_PATH锁死路径qmake 里LIBS的-L放最前运行时把包内bin放在 PATH 最前。交付时干脆不依赖 PATH全用同目录 DLL。4.5 中文路径下打开数据集失败现象英文路径正常中文路径GDALOpen返回空。原因1.11.5 时代部分构建对宽字符路径支持不完整底层仍走窄字符接口。解决工程内统一用 UTF-8 转本地编码处理路径或先把文件拷到纯英文临时目录再打开。这条没有优雅解属于版本边界提前在设计上规避比事后修更省事。5. 进阶验证用驱动清单和读写回环确认这份包真能用拿到任何一份预编译 GDAL 包我都会做两件事再决定是否投入工程数驱动、跑读写回环。数驱动看的是功能覆盖面读写回环看的是“能写能读、数据不丢”。先看驱动清单用GDALGetDriverCount配合GDALGetDriver遍历把支持 Create 的驱动单独列出来因为很多包能读不能写#include cstdio #include gdal.h int main() { GDALAllRegister(); int total GDALGetDriverCount(); int writable 0; for (int i 0; i total; i) { GDALDriverH drv GDALGetDriver(i); // 只统计支持创建的驱动判断能否落盘 if (GDALGetMetadataItem(drv, GDAL_DCAP_CREATE, nullptr) ! nullptr) { writable; } } printf(total%d writable%d\n, total, writable); GDALDestroyDriverManager(); return 0; }逻辑说明GDAL_DCAP_CREATE是驱动能力元数据键有值说明支持GDALCreate。参数不用改输出里writable为 0 说明这份包只读做导出功能就得换包。这一步能提前暴露“包不完整”的问题比在业务代码里报错强。读写回环用 GTiff 最省事建一个 256x256 的单波段内存数据集写个渐变值落盘成 tif再重新打开读回第一个像素比对。能写能读且值一致说明驱动、数据目录、DLL 链路全通。这一步我一般写成固定脚本换任何 GDAL 包都先跑一遍跑不过就不往下接。血泪经验是预编译包的问题八成在“缺数据文件”和“DLL 版本错配”这两个用回环测试都能逼出来。最后说个习惯。从那以后我每次接预编译 GDAL 包都强制走一遍“版本打印 → 驱动计数 → 读写回环 → 依赖扫描”四步四步全绿才往工程里接宁可多花二十分钟也不在业务代码里跟玄学闪退纠缠。这份 mingw64 编译的 GDAL 1.11.5 对老项目维护来说够用边界也清楚别指望新格式、新坐标系库把它当稳定底座把数据目录和 DLL 部署做扎实剩下的就是正常 C 调用。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑