ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Windows下用MinGW64编译GDAL 1.11.5老库实战指南

Windows下用MinGW64编译GDAL 1.11.5老库实战指南 简介这是Windows下采用MSYS2与MinGW64预先编译完成的GDAL 1.11.5开发包专供QtMinGW版本C开发者使用。整个压缩包约70.71MB共149个文件其中包含63个头文件、2个静态库、22个exe工具以及一批坐标系CSV、WKT和XML配置数据覆盖了GDAL常用功能与数据格式支持。将bin目录加入系统环境变量再在.pro文件里指定GDAL路径即可直接链接免去在MinGW环境下从源码编译的麻烦。目前已有1514人学习下载。该包不仅带有可直接调用的运行库还提供了gdal-config等辅助脚本和完整目录结构方便用户按需查看和配置。针对QtMinGW中常见的程序异常结束问题作者在配套博文中给出了具体排错思路下载后遇到问题可对照解决适合希望快速搭建GDAL开发环境的中高级C开发者。 最近接了个内部老项目后端服务要对接一套2015年前后构建的GIS中间件接口里全是GDAL 1.x的API调用。开发机是Windows 10 64位团队同事一开始直接在vscode的mingw64环境里把系统默认的GDAL3.x拉下来编译跑结果一堆核心函数行为对不上——最典型的就是GDALOpen和OGRRegisterAll在3.x里的执行路径跟1.x完全不一样平面坐标的读取结果也有细微偏差。项目卡了两天最后决定一步到位手工把GDAL 1.11.5用mingw64编译一遍在Windows上生成独立的C库。这篇文章就把整个过程完整记录下来包括依赖版本、configure参数、编译坑和最终CMake集成方式给同样被老库困住的朋友一条可以直接抄的路径。1. 为什么在现代化环境里还要折腾GDAL 1.11.51.1 老项目的API兼容性需求GDAL 1.x与2.x、3.x表面上是版本号差异实际上是两代人。GDAL 1.11.5是1.x分支最后一个维护版本2015年6月23日发布。它对应的API形态、头文件组织和数据结构与3.x有大量不兼容。最典型的是OGRFeature、GDALDataset这类对象的生命周期管理在1.11里靠引用计数和GDALClose手工释放3.x虽然保留了GDALClose但内部所有权模型已经变了。还有GDALAllRegister在1.x会一次性注册所有驱动3.x改成了按需注册默认行为完全不同。如果你的业务代码是十年前写的直接用新版GDAL重新编译轻则行为不一致重则内存崩溃这在GIS领域特别常见。不少金融机构、管网、测绘单位到现在还在用1.11不是不想升级是升级成本太高动一条核心查询链路牵扯的都是几十年积累的坐标转换和格式兼容逻辑。所以遇到老系统对接老老实实把对应的老版本GDAL编出来反而是最稳妥的解法。1.2 为什么选mingw64而不是MSVC在Windows上编译一个C库首先面对的就是工具链选择。GDAL官方对Windows主要提供的是MSVC的nmake方案makefile.vc如果团队用的是Visual Studio那当然没问题但很多开源项目团队是vscode或CLion加CMake的组织方式代码里大量使用GCC特性整个项目工具链已经在mingw64上沉淀了两三年。在这种前提下单独为GDAL开一套MSVC工程后续每次编译都要切环境成本极高。mingw64的优势在于它是纯GNU工具链和MSYS2、Cygwin生态完全打通configure脚本可以像在Linux上一样跑依赖库也能直接用pacman装整个编译流程不折腾。缺点就是GDAL官方对mingw的支持没那么精细很多细节要自己处理但这篇文章的价值就是把细节填平。如果你也处在“CMake GCC vscode”这套工作流里选mingw64基本不用纠结。2. 编译前的依赖准备这一半的坑都在这里2.1 用MSYS2当大本营all in oneGDAL属于那种看起来简单实际依赖树很深的库。直接下载一个裸的mingw-w64工具链你会发现后面所有依赖都装不齐。所以第一步是安装MSYS2官方安装包装完打开开始菜单里的“MSYS2 MinGW64”窗口注意一定要选MinGW64这个不是MSYS2 MSYS那个两者的包体系和编译器前缀完全不同。进到MinGW64窗口后先更新包索引和工具链pacman -Syu pacman -S --needed base-devel mingw-w64-x86_64-toolchainmingw-w64-x86_64-toolchain会带gcc、g、gdb、make等全套工具。注意MSYS2 MinGW64环境里的make是GNU make可以直接用不是Visual Studio那个nmake也不是兼容用的mingw32-make。2.2 最容易翻车的PROJ依赖版本GDAL 1.11.5配套的PROJ版本是PROJ 4.x系列4.8到4.9都可以。如果你直接用pacman -S mingw-w64-x86_64-proj装出来大概率是PROJ 6以上甚至9.x。PROJ 6之后API发生了大改最常见的是pj_init_plus直接消失PJ_PROJ4结构体也变了GDAL 1.11.5编译时会在ogrct.cpp这些文件里报一堆undefined reference根本排不完。正确的做法是手动编译一个旧版PROJ。到OSGeo/proj仓库找到4.9.3的tag下载源码在MSYS2 MinGW64窗口里执行curl -L -o proj-4.9.3.tar.gz https://download.osgeo.org/proj/proj-4.9.3.tar.gz tar xzf proj-4.9.3.tar.gz cd proj-4.9.3 ./configure --prefix/c/gdaldeps make -j8 make install这里把PROJ装到/c/gdaldeps也就是C:\gdaldeps避免和MSYS2系统目录混在一起。为什么不用默认的/usr/local因为后续GDAL也要指定前缀把所有自编译依赖统一放一个目录后面排查路径问题会非常省心。GEOS也一样从GEOS 3.4.x源码编到/c/gdaldeps避免和pacman里太新的GEOS冲突。2.3 必装依赖清单与作用解析GDAL的依赖库可以分为三档必选、常用可选、完全可选你编GDAL之前心里得有数。我列一份实操清单mingw-w64-x86_64-zlib几乎每个格式都会用到必装。mingw-w64-x86_64-libtiffTIFF/GeoTIFF读写必装GDAL最核心的栅格格式就是GeoTIFF。mingw-w64-x86_64-libpng、mingw-w64-x86_64-libjpeg-turboPNG和JPEG读写。mingw-w64-x86_64-geos矢量空间运算Union、Intersection那些。mingw-w64-x86_64-sqlite3OGR SQLite驱动和GeoPackage支持。mingw-w64-x86_64-libcurlWMS/WFS在线服务支持用不到可以先去掉。mingw-w64-x86_64-netcdf、mingw-w64-x86_64-hdf5科学数据集格式看项目需求装。对应的pacman安装命令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-geos mingw-w64-x86_64-sqlite3 \ mingw-w64-x86_64-libcurl装完检查一下/mingw64/include下有没有proj_api.h如果有确认版本是不是老的grep PJVERSION /mingw64/include/proj_api.h如果显示6.x以上别指望用它直接走自编译旧版PROJ的路子。依赖库在Windows下编译最怕的就是库搜索路径混乱MSYS2自带的库都在/mingw64下而自编译的PROJ在/c/gdaldeps下混合使用时要通过configure的--with参数明确告诉GDAL去哪找不能指望链接器自己串门。3. 从configure到make的完整编译过程3.1 configure到底在配置什么configure脚本是GDAL源码包自带的自动配置工具作用是把依赖路径、编译参数、可选功能全部探测一遍生成最终的Makefile。GDAL 1.11.5的configure参数不算多但有几个必须显式指定否则它默认去/usr/local找库你的依赖如果装在别处就全歪了。我实际用的命令是./configure --prefix/c/gdallib \ --hostx86_64-w64-mingw32 \ --with-proj/c/gdaldeps \ --with-geos/c/gdaldeps/bin/geos-config \ --with-sqlite3/mingw64 \ --with-libz/mingw64 \ --with-libtiff/mingw64 \ --with-libpng/mingw64 \ --with-libjpeg/mingw64 \ --with-curl/mingw64 \ --with-expat/mingw64 \ --without-python \ --without-java几个正在起作用的关键项--prefix/c/gdallib最终安装目录GDAL头文件和库都会放这里。--hostx86_64-w64-mingw32告诉configure目标平台是64位Windows。这个参数在MSYS2环境下通常能自动识别但显式写出来更保险可以避免configure检测到纯MSYS环境后误判。--with-proj/c/gdaldepsPROJ安装在C:\gdaldeps这里直接指到前缀目录。--with-geos/c/gdaldeps/bin/geos-configgeos-config是GEOS提供的一个脚本输出编译参数GDAL靠它定位GEOS。所以GEOS也要装到/c/gdaldeps下否则它不会出现在/c/gdaldeps/bin。--without-pythonPython绑定单独处理不要让configure去探测SWIG版本否则基本会卡住。3.2 编译执行与产物落盘configure跑完后输出末尾会有大段摘要把“GDAL is now configured”那段仔细看一遍重点确认缺少哪些库比如SQLITE support: no说明sqlite没找到需要回头补。确认没有问题后开始编译make -j8-j8是并行编译的线程数按CPU核数定但别拉满。编译过程中输出会滚动很快一般几分钟到十几分钟不等取决于机器和可选功能的多少。如果某个文件报错先记下报错文件名和行号大部分是头文件路径不对或依赖库版本不匹配往下看第5节的排查方法。编译完成后make install安装完去/c/gdallib检查产物ls -la /c/gdallib/bin ls -la /c/gdallib/lib正常情况下/c/gdallib/bin下会有gdalinfo.exe、ogrinfo.exe、gdal_translate.exe这些命令行工具以及libgdal-1.dll或类似名字取决于libtool生成规则。/c/gdallib/lib下会有libgdal.dll.a、libgdal.a、libgdal.la这些库文件以及gdal_i.h、cpl_config.h等头文件。注意GDAL 1.11.5源码目录里有多个子目录存放头文件比如gcore/、ogr/、port/安装时会合并到/c/gdallib/include。如果你发现某些头文件找不到多半是安装目录没加全检查有没有/c/gdallib/include/gdal_priv.h。3.3 静态库还是动态库一个容易被忽略的选择GDAL 1.11.5在mingw64下默认构建的是动态库生成libgdal-1.dll和导入库libgdal.dll.a。动态库的好处是最终程序体积小多个调用方能共享同一份GDAL内存但DLL必须能在运行时被找到否则程序启动就报libgdal-1.dll not found。如果你的目标是减少部署麻烦希望所有依赖都打进exe那可以在configure时增加--disable-shared --enable-static强制静态编译。代价是链接时所有依赖库的.a文件也必须齐全而且GDAL本身很大静态链接后exe会膨胀到几十兆。我的建议是默认用动态库部署时把libgdal-1.dll和mingw的运行库libgcc_s_seh-1.dll、libstdc-6.dll、libwinpthread-1.dll一起带到目标机器上这几个运行库在/mingw64/bin下可以找到。4. 编译后的验证与VS Code / CMake工程接入4.1 用gdalinfo验证环境编译成功只是开始能不能被别人正常调用是另一回事。先在命令行验证export PATH/c/gdallib/bin:$PATH gdalinfo --version正常会输出GDAL 1.11.5, released 2015/06/23再用一个小GeoTIFF测试读写gdalinfo your_test.tif如果输出能看到Coordinate System is:并正确打印投影参数说明PROJ和GDAL的集成没问题。再测一下矢量驱动ogrinfo --formats | grep -i ESRI Shapefile能看到ESRI Shapefile驱动说明OGR核心和shapefile驱动加载正常。这一步是整个环节里最爽的时刻说明依赖、编译、链接全链路都通了。4.2 CMake接入mingw64编译的GDAL很多人在vscode加mingw64工程里卡在CMake找不到GDAL这一步。GDAL 1.11.5不提供标准的CMake config文件CMake自带的FindGDAL模块实际去寻找的是gdal-config脚本而GDAL 1.11在Windows安装时通常不生成这个脚本。所以推荐直接在CMakeLists.txt里写死路径简单粗暴。cmake_minimum_required(VERSION 3.16) project(gdal_test) set(GDAL_ROOT C:/gdallib) include_directories(${GDAL_ROOT}/include) link_directories(${GDAL_ROOT}/lib) add_executable(test_gdal main.cpp) target_link_libraries(test_gdal gdal)注意target_link_libraries里写的是gdal不用写全名CMake在Windows上会找libgdal.dll.a或gdal.lib。vscode侧面的c_cpp_properties.json里includePath要加上C:/gdallib/include{ configurations: [ { name: Win64-MinGW, includePath: [ ${workspaceFolder}/**, C:/gdallib/include ], defines: [], compilerPath: C:/msys64/mingw64/bin/g.exe, cStandard: c17, cppStandard: c17, intelliSenseMode: windows-gcc-x64 } ], version: 4 }compilerPath要指向你的mingw64的g也就是MSYS2安装目录下的mingw64/bin/g.exe。如果不配置vscode可能默认找Windows SDK的MSVC导致IntelliSense对GDAL头文件报一堆误报。4.3 关于Python绑定说说我的取舍很多读者问GDAL编译出来后能不能直接给Python用。GDAL 1.11.5的Python绑定是依靠SWIG生成代码的SWIG版本有个令人头疼的对应关系GDAL 1.11要求SWIG 1.3.x而现在MSYS2里的SWIG是4.x生成的代码和1.11的C接口根本不兼容。所以自己编译Python绑定的成本很高我建议直接用pip install GDAL1.11.5配上早期Python 3环境或Python 2.7。如果项目必须用Python也可以直接用conda建一个老环境装1.11.5省心很多C这边老老实实用编译出的本地库就够了两边不要混用同一个产物。5. 常见问题与排查技巧实录5.1 三个踩过才知道的坑第一个坑是M_PI未声明。GDAL 1.11.5的老代码在很多地方直接用了M_PIC标准里这个宏本来就不保证存在mingw的GCC默认也不会定义。编译到gdalwarp或ogr某些文件时会报M_PI was not declared in this scope。解决办法是编译时加上全局宏定义在configure环节注入CFLAGS和CXXFLAGSexport CFLAGS-D_USE_MATH_DEFINES export CXXFLAGS-D_USE_MATH_DEFINES ./configure ...Windows系统里_USE_MATH_DEFINES会强制让标准库把M_PI、M_PI_2这些常量暴露出来。第二个坑是PROJ新旧版本错乱。编译过程中如果出现pj_init_plus、pj_transform相关的undefined reference基本就是PROJ版本不对。GDAL 1.11源码里写死了老PROJ的符号遇到新PROJ就崩。这个没有捷径只能老老实实把PROJ 4.9.3编译到独立前缀再用--with-proj指过去。别指望系统里两个PROJ共存能自动选对configure的pkg-config优先搜系统路径很容易选到新版本。第三个坑是运行时DLL找不到。这个发生在目标机器或开发机换路径之后。GDAL本身是动态库mingw的g在链接时会把动态库依赖写入exe的导入表运行时Windows会按PATH顺序搜DLL。如果只把libgdal-1.dll放在exe同目录但它的依赖比如libgcc_s_seh-1.dll、libstdc-6.dll、libproj-0.dll、libsqlite3-0.dll不在PATH里照样启动失败。排查方法是用objdump -p your_exe.exe | grep DLL Name看看它依赖于哪些DLL然后确保这些都在PATH或exe同目录下。5.2 问题速查表现象可能原因解决方案configure提示找不到projPROJ版本过新或路径不对自编译PROJ 4.9.3并指定--with-proj/c/gdaldeps编译报M_PI未声明mingw默认没定义M_PI加-D_USE_MATH_DEFINES链接报undefined reference带pj_前缀PROJ版本不兼容换回PROJ 4.x链接报undefined reference带GEOS前缀GEOS版本不兼容自编译GEOS 3.4.x运行时报libgdal-1.dll not foundDLL搜索路径没配置把/c/gdallib/bin和/mingw64/bin加入PATHIntelliSense对GDAL头文件报错vscode没配mingw编译器在c_cpp_properties.json配置compilerPath为g.execonfigure成功但Python绑定编不出SWIG版本不匹配改用pip安装旧版GDAL这次编译前后折腾了快两天真正消耗时间的不是make而是定位PROJ版本和DLL搜索路径这两个隐性问题。编译老库就是这样——你眼前的东西往往不是真的问题真正卡住你的藏在依赖链深处。如果让我重新来一次我会先把所有老版本依赖PROJ 4.9.3、GEOS 3.4.x统一编译到独立目录再编译GDAL一个下午就能走完全程。另外建议各位先把安装好的C:\gdallib整个目录备份下来下次换机器或者同事需要同样的环境时直接把目录拷过去改下路径就能用不用再从头折腾一遍编译。本文还有配套的精品资源点击获取
返回列表