找回密码
 立即注册
首页 业界区 业界 CMake构建学习笔记25-SpatiaLite库的构建

CMake构建学习笔记25-SpatiaLite库的构建

山芷兰 昨天 11:08
1. 引言

尝试使用CMake构建SpatiaLite及其依赖库,但是没有成功。因为SpatiaLite及其依赖库很多都是老牌的C库,这种库由于年代的原因一般都不提供CMake的构建方式,在Windows下提供的构建方式一般是基于nmake的。这意味着难以实现通过一个配置来实现跨平台构建,不过笔者也没有纠结这个问题,这种问题只能交给时间来解决,比如GDAL、GEOS这样库最开始都是nmake构建,后来陆续都升级为使用CMake构建。在这里就记录一下笔者使用nmake构建SpatiaLite库的过程。
SpatiaLite是一个为SQLite数据库引擎扩展空间数据存储与分析功能的开源库,使其能够支持地理信息系统(GIS)操作。
2. nmake构建

在具体总结SpatiaLite库的构建之前,最好需要了解下Windows下使用namke构建的一般步骤。
在Windows下构建程序最方便的当然是直接使用Visual Studio,通过GUI界面来构建程序。不过GUI方式也有很麻烦的地方,比如CICD需要通过脚本来实现代码到产品的过程,而从终端批处理的方式就是通过nmake来提供的。
2.1 步骤

具体来说,就是在安装Visual Studio之后,开始菜单中打开相应的开发命令行环境。以Visual Studio 2019为例,就是x64 Native Tools Command Prompt for VS 2019工具。这个工具本质上就是一个CMD,只不过已经内置了开发命令行环境,如下所示:
1.png

打开这个VS终端之后,通常输入如下指令来构建程序:
  1. nmake -f makefile.vc
复制代码
这个makefile.vc就是代码项目的主构建脚本,定义了这个项目如何编译、链接。为了找到这个文件,需要先通过CD指令跳转到代码项目包含这个文件的目录下。除了makefile.vc这个文件之外,还可能有nmake.opt这个文件;这是一个自定义的配置文件,用于覆盖默认编译选项(如宏定义、包含路径、库路径、优化选项等)。通常makefile.vc中的内容不用修改,通过修改nmake.opt中的内容来实现自定义配置。
除了上述指令之外,为了区分构建步骤,以下步骤也很常见,例如清理构建过程的文件:
  1. nmake -f makefile.vc clean
复制代码
将构建结果进行安装:
  1. nmake -f makefile.vc install
复制代码
不过clean和install需要看makefile.vc和nmake.opt中是否提供了这个构建目标。如果没有提供,那么上述指令就不起作用。类似的构建还有DEBUG和RELEASE版本,也需要看makefile.vc和nmake.opt中是否存在相关的参数。
2.2 缺点

了解了上述指令之后,大概感觉跟CMake的构建指令差不多。其实差别还是很大的,跟现代构建系统相比,nmake还缺失一个关键的步骤——配置。nmake其实只是一个简单的make系统,对应的就是Linux下的Makefile,可以进行编译、链接,也可以把构建参数提取出来,但是无法动态去生成构建参数。具体来说,nmake的配置参数文件是nmake.opt,但是只有这个文件还不够,还需要根据构建环境不同,动态生成这个nmake.opt文件。
所以使用nmake构建项目的麻烦就在这里,无法根据需要动态地生成项目配置文件,只能手动去修改它。比如在之前的文章《CMake构建学习笔记19-OpenSSL库的构建》中就是如此,也是通过nmake来构建OpenSSL库,但是不能动态生成配置怎么办呢?OpenSSL的维护者引入了perl来解决这个问题。嗯,不得不说,C/C++项目的构建系统太混乱了,简直是各显神通;希望以后的项目都能升级成CMake的构建方式吧,不是CMake有多好,先把构建的行为统一了再说。
3. 构建SpatiaLite

3.1 主项目

在理解了使用nmake构建的一般步骤之后,构建具体的SpatiaLite项目反而比较简单了。从官网上下载最新的5.1.0版本,解压到本地,可以看到SpatiaLite提供了四个版本的构建配置,如下图所示:
2.png

其中:

  • makefile.vc是32位构建配置。
  • makefile64.vc是64位构建配置。
  • makefile_mod.vc是32位模块化构建配置。
  • makefile_mod64.vc是64位模块化构建配置。
这里也可以看到使用nmake构建的缺陷,应对不同的构建需求,需要提供多个配置文件。如果是使用CMake构建,使用一个CMakeList.txt即可。现在一般都是64位系统,选择makefile64.vc和nmake64.opt进行构建。不过为了能正确构建,修改nmake64.opt中的内容如下:
  1. # Directory tree where SpatiaLite will be installed.
  2. INSTDIR=C:\Work\3rdparty
  3. # Uncomment the first for an optimized build, or the second for debug.
  4. OPTFLAGS=        /source-charset:windows-1252 /nologo /Ox /fp:precise /W4 /MD /D_CRT_SECURE_NO_WARNINGS \
  5.                 /DDLL_EXPORT /DYY_NO_UNISTD_H
  6. #OPTFLAGS=        /nologo /Zi /MD /Fdspatialite.pdb /DDLL_EXPORT
  7. # Set the version number for the DLL.  Normally we leave this blank since
  8. # we want software that is dynamically loading the DLL to have no problem
  9. # with version numbers.
  10. VERSION=
复制代码
主要修改了两点:

  • INSTDIR表示构建后安装的目录,按需进行修改。
  • /source-charset:windows-1252是额外增加的编译选项,用于设置代码文件的数据集。
修改makefile64.vc中的内容为:
  1. # $Id: $
  2. #
  3. # NMAKE Makefile to build libspatialite on Windows
  4. #
  5. !INCLUDE nmake64.opt
  6. LIBOBJ = src\gaiaaux\gg_sqlaux.obj src\gaiaaux\gg_utf8.obj \
  7.         src\gaiaexif\gaia_exif.obj src\gaiageo\gg_advanced.obj \
  8.         src\gaiageo\gg_endian.obj src\gaiageo\gg_ewkt.obj \
  9.         src\gaiageo\gg_geodesic.obj src\gaiageo\gg_geoJSON.obj \
  10.         src\gaiageo\gg_geometries.obj src\gaiageo\gg_geoscvt.obj \
  11.         src\gaiageo\gg_gml.obj src\gaiageo\gg_kml.obj \
  12.         src\gaiageo\gg_relations.obj src\gaiageo\gg_shape.obj \
  13.         src\gaiageo\gg_transform.obj src\gaiageo\gg_vanuatu.obj \
  14.         src\gaiageo\gg_wkb.obj src\gaiageo\gg_wkt.obj \
  15.         src\gaiageo\gg_extras.obj src\gaiageo\gg_xml.obj \
  16.         src\gaiageo\gg_voronoj.obj src\gaiageo\gg_matrix.obj \
  17.         src\gaiageo\gg_relations_ext.obj src\gaiageo\gg_rttopo.obj \
  18.         src/connection_cache/alloc_cache.obj src/connection_cache/gg_sequence.obj \
  19.         src\spatialite\mbrcache.obj src\shapefiles\shapefiles.obj \
  20.         src\spatialite\spatialite.obj src\spatialite\virtualdbf.obj \
  21.         src\spatialite\virtualfdo.obj src\spatialite\virtualnetwork.obj \
  22.         src\spatialite\virtualshape.obj src\spatialite\virtualspatialindex.obj \
  23.         src\spatialite\statistics.obj src\spatialite\metatables.obj \
  24.         src\spatialite\virtualXL.obj src\spatialite\extra_tables.obj \
  25.         src\spatialite\virtualxpath.obj src\spatialite\virtualbbox.obj \
  26.         src\spatialite\spatialite_init.obj src\spatialite\se_helpers.obj \
  27.         src\spatialite\srid_aux.obj src\spatialite\table_cloner.obj \
  28.         src\spatialite\virtualelementary.obj src\spatialite\virtualgeojson.obj \
  29.         src\spatialite\virtualrouting.obj src\spatialite\create_routing.obj \
  30.         src\spatialite\dbobj_scopes.obj src\spatialite\pause.obj \
  31.         src\wfs\wfs_in.obj src\srsinit\srs_init.obj src\spatialite\virtualgpkg.obj \
  32.         src\dxf\dxf_parser.obj src\dxf\dxf_loader.obj src\dxf\dxf_writer.obj \
  33.         src\dxf\dxf_load_distinct.obj src\dxf\dxf_load_mixed.obj \
  34.         src\shapefiles\validator.obj src\md5\md5.obj src\md5\gaia_md5.obj \
  35.         src\srsinit\epsg_inlined_00.obj src\srsinit\epsg_inlined_01.obj \
  36.         src\srsinit\epsg_inlined_02.obj src\srsinit\epsg_inlined_03.obj \
  37.         src\srsinit\epsg_inlined_04.obj src\srsinit\epsg_inlined_05.obj \
  38.         src\srsinit\epsg_inlined_06.obj src\srsinit\epsg_inlined_07.obj \
  39.         src\srsinit\epsg_inlined_08.obj src\srsinit\epsg_inlined_09.obj \
  40.         src\srsinit\epsg_inlined_10.obj src\srsinit\epsg_inlined_11.obj \
  41.         src\srsinit\epsg_inlined_12.obj src\srsinit\epsg_inlined_13.obj \
  42.         src\srsinit\epsg_inlined_14.obj src\srsinit\epsg_inlined_15.obj \
  43.         src\srsinit\epsg_inlined_16.obj src\srsinit\epsg_inlined_17.obj \
  44.         src\srsinit\epsg_inlined_18.obj src\srsinit\epsg_inlined_19.obj \
  45.         src\srsinit\epsg_inlined_20.obj src\srsinit\epsg_inlined_21.obj \
  46.         src\srsinit\epsg_inlined_22.obj src\srsinit\epsg_inlined_23.obj \
  47.         src\srsinit\epsg_inlined_24.obj src\srsinit\epsg_inlined_25.obj \
  48.         src\srsinit\epsg_inlined_26.obj src\srsinit\epsg_inlined_27.obj \
  49.         src\srsinit\epsg_inlined_28.obj src\srsinit\epsg_inlined_29.obj \
  50.         src\srsinit\epsg_inlined_30.obj src\srsinit\epsg_inlined_31.obj \
  51.         src\srsinit\epsg_inlined_32.obj src\srsinit\epsg_inlined_33.obj \
  52.         src\srsinit\epsg_inlined_34.obj src\srsinit\epsg_inlined_35.obj \
  53.         src\srsinit\epsg_inlined_36.obj src\srsinit\epsg_inlined_37.obj \
  54.         src\srsinit\epsg_inlined_38.obj src\srsinit\epsg_inlined_39.obj \
  55.         src\srsinit\epsg_inlined_40.obj src\srsinit\epsg_inlined_41.obj \
  56.         src\srsinit\epsg_inlined_42.obj src\srsinit\epsg_inlined_43.obj \
  57.         src\srsinit\epsg_inlined_44.obj src\srsinit\epsg_inlined_45.obj \
  58.         src\srsinit\epsg_inlined_46.obj src\srsinit\epsg_inlined_47.obj \
  59.         src\srsinit\epsg_inlined_48.obj src\srsinit\epsg_inlined_49.obj \
  60.         src\srsinit\epsg_inlined_50.obj src\srsinit\epsg_inlined_51.obj \
  61.         src\srsinit\epsg_inlined_52.obj src\srsinit\epsg_inlined_53.obj \
  62.         src\srsinit\epsg_inlined_54.obj src\srsinit\epsg_inlined_55.obj \
  63.         src\srsinit\epsg_inlined_56.obj src\srsinit\epsg_inlined_57.obj \
  64.         src\srsinit\epsg_inlined_58.obj src\srsinit\epsg_inlined_59.obj \
  65.         src\srsinit\epsg_inlined_60.obj src\srsinit\epsg_inlined_61.obj \
  66.         src\srsinit\epsg_inlined_62.obj src\srsinit\epsg_inlined_63.obj \
  67.         src\srsinit\epsg_inlined_extra.obj src\srsinit\epsg_inlined_prussian.obj \
  68.         src\srsinit\epsg_inlined_wgs84_00.obj src\srsinit\epsg_inlined_wgs84_01.obj \
  69.         src\versioninfo\version.obj src\virtualtext\virtualtext.obj \
  70.         src\cutter\gaia_cutter.obj \
  71.         src\spatialite\virtualknn.obj src\spatialite\virtualknn2.obj \
  72.         src\control_points\gaia_control_points.obj \
  73.         src\control_points\grass_crs3d.obj src\control_points\grass_georef_tps.obj \
  74.         src\control_points\grass_georef.obj src\stored_procedures\stored_procedures.obj \
  75.         src\geopackage\gaia_cvt_gpkg.obj \
  76.         src\geopackage\gpkgAddGeometryColumn.obj \
  77.         src\geopackage\gpkg_add_geometry_triggers.obj \
  78.         src\geopackage\gpkg_add_spatial_index.obj \
  79.         src\geopackage\gpkg_add_tile_triggers.obj \
  80.         src\geopackage\gpkgBinary.obj \
  81.         src\geopackage\gpkgCreateBaseTables.obj \
  82.         src\geopackage\gpkgCreateTilesTable.obj \
  83.         src\geopackage\gpkgCreateTilesZoomLevel.obj \
  84.         src\geopackage\gpkgGetImageType.obj \
  85.         src\geopackage\gpkg_get_normal_row.obj \
  86.         src\geopackage\gpkg_get_normal_zoom.obj \
  87.         src\geopackage\gpkgInsertEpsgSRID.obj \
  88.         src\geopackage\gpkgMakePoint.obj \
  89.         src\topology\gaia_auxnet.obj src\topology\gaia_auxtopo.obj \
  90.         src\topology\gaia_auxtopo_table.obj src\topology\gaia_netstmts.obj \
  91.         src\topology\gaia_network.obj src\topology\gaia_topology.obj \
  92.         src\topology\gaia_topostmts.obj src\topology\lwn_network.obj \
  93.         src\topology\net_callbacks.obj src\topology\topo_callbacks.obj
  94. SPATIALITE_DLL = spatialite$(VERSION).dll
  95. CFLAGS = /nologo -I.\src\headers -I.\src\topology \
  96.         -I. -IC:\Work\3rdparty\include -IC:\Work\3rdparty\include\libxml2 $(OPTFLAGS)
  97. default:        all
  98. all: spatialite.lib spatialite_i.lib
  99. #$(EXIF_LOADER_EXE)
  100. spatialite.lib:        $(LIBOBJ)
  101.         if exist spatialite.lib del spatialite.lib
  102.         lib /out:spatialite.lib $(LIBOBJ)
  103. $(SPATIALITE_DLL):        spatialite_i.lib
  104. spatialite_i.lib:     $(LIBOBJ)
  105.         link /dll /out:$(SPATIALITE_DLL) \
  106.                 /implib:spatialite_i.lib $(LIBOBJ) \
  107.                 C:\Work\3rdparty\lib\proj.lib C:\Work\3rdparty\lib\geos_c.lib \
  108.                 C:\Work\3rdparty\lib\freexl_i.lib C:\Work\3rdparty\lib\iconv.lib \
  109.                 C:\Work\3rdparty\lib\sqlite3.lib C:\Work\3rdparty\lib\zlib.lib \
  110.                 C:\Work\3rdparty\lib\libxml2.lib C:\Work\3rdparty\lib\librttopo.lib
  111.         if exist $(SPATIALITE_DLL).manifest mt -manifest \
  112.                 $(SPATIALITE_DLL).manifest -outputresource:$(SPATIALITE_DLL);2
  113.                
  114. .c.obj:
  115.         $(CC) $(CFLAGS) /c $*.c /Fo$@
  116.        
  117. clean:
  118.         del *.dll
  119.         del *.exp
  120.         del *.manifest
  121.         del *.lib
  122.         del src\connection_cache\*.obj
  123.         del src\cutter\*.obj
  124.         del src\gaiaaux\*.obj
  125.         del src\gaiaexif\*.obj
  126.         del src\gaiageo\*.obj
  127.         del src\shapefiles\*.obj
  128.         del src\spatialite\*.obj
  129.         del src\srsinit\*.obj
  130.         del src\versioninfo\*.obj
  131.         del src\virtualtext\*.obj
  132.         del src\wfs\*.obj
  133.         del src\dxf\*.obj
  134.         del src\md5\*.obj
  135.         del src\topology\*.obj
  136.         del src\stored_procedures\*.obj
  137.         del *.pdb
  138. install: all
  139.         -mkdir $(INSTDIR)
  140.         -mkdir $(INSTDIR)\bin
  141.         -mkdir $(INSTDIR)\lib
  142.         -mkdir $(INSTDIR)\include
  143.         -mkdir $(INSTDIR)\include\spatialite
  144.         copy *.dll $(INSTDIR)\bin
  145.         copy *.lib $(INSTDIR)\lib
  146.         copy src\headers\spatialite.h $(INSTDIR)\include
  147.         copy src\headers\spatialite\*.h $(INSTDIR)\include\spatialite
复制代码
主要修改了以下两点:

  • 修改include文件:
  1. CFLAGS = /nologo -I.\src\headers -I.\src\topology \
  2.         -I. -IC:\Work\3rdparty\include -IC:\Work\3rdparty\include\libxml2 $(OPTFLAGS)
复制代码

  • 修改依赖库文件:
  1. spatialite_i.lib:     $(LIBOBJ)
  2.         link /dll /out:$(SPATIALITE_DLL) \
  3.                 /implib:spatialite_i.lib $(LIBOBJ) \
  4.                 C:\Work\3rdparty\lib\proj.lib C:\Work\3rdparty\lib\geos_c.lib \
  5.                 C:\Work\3rdparty\lib\freexl_i.lib C:\Work\3rdparty\lib\iconv.lib \
  6.                 C:\Work\3rdparty\lib\sqlite3.lib C:\Work\3rdparty\lib\zlib.lib \
  7.                 C:\Work\3rdparty\lib\libxml2.lib C:\Work\3rdparty\lib\librttopo.lib
  8.         if exist $(SPATIALITE_DLL).manifest mt -manifest \
  9.                 $(SPATIALITE_DLL).manifest -outputresource:$(SPATIALITE_DLL);2
复制代码
都修改完成之后,执行:
  1. nmake -f makefile.vc  #构建
  2. nmake -f makefile.vc install  #安装
  3. nmake -f makefile.vc clean        #清理
复制代码
3.2 依赖项

需要注意的是,makefile64.vc中的内容需要根据依赖库的安装地址来进行修改。SpatiaLite的依赖项有:proj、geos、freexl、iconv、sqlite3、zlib、libxml2以及librttopo,这些依赖项都需要提前安装好,笔者是安装到C:\Work\3rdparty目录中。至于具体的构建安装过程,大部分依赖库可参看如下文章:

  • 《CMake构建学习笔记24-使用通用脚本构建PROJ和GEOS》
  • 《CMake构建学习笔记20-iconv库的构建》
  • 《CMake构建学习笔记23-SQLite库的构建》
  • 《CMake构建学习笔记2-zlib库的构建》
  • 《CMake构建学习笔记22-libxml2库的构建》
剩下的就只有freexl和librttopo两个依赖性的构建了,正好这两个也是依赖于nmake构建的库。
3.2.1 构建libexpat

在构建freexl之前,需要先构建libexpat库。libexpat是一个用C语言编写的、开源的、高效的XML解析库,已经支持使用CMake构建。那么可以使用以下脚本:
  1. param(   
  2.     [string]$Name = "libexpat-R_2_7_0",
  3.     [string]$SourceDir = "../Source",
  4.     [string]$Generator,
  5.     [string]$MSBuild,
  6.     [string]$InstallDir,  
  7.     [string]$SymbolDir
  8. )
  9. # 根据 $Name 动态构建路径
  10. $zipFilePath = Join-Path -Path $SourceDir -ChildPath "$Name.zip"
  11. $SourcePath = Join-Path -Path $SourceDir -ChildPath $Name
  12. $BuildDir = Join-Path -Path "." -ChildPath $Name
  13. # 检查是否已经安装(通过目标 DLL)
  14. $TargetDll = "$InstallDir/bin/libexpat.dll"
  15. if (-not $Force -and $TargetDll -and (Test-Path $TargetDll)) {
  16.     Write-Output "Library already installed: $TargetDll"
  17.     exit 0
  18. }
  19. # 确保源码目录存在:解压 ZIP
  20. if (!(Test-Path $SourcePath)) {
  21.     if (!(Test-Path $zipFilePath)) {
  22.         Write-Error "Archive not found: $zipFilePath"
  23.         exit 1
  24.     }
  25.     Write-Output "Extracting $zipFilePath to $SourceDir..."
  26.     Expand-Archive -LiteralPath $zipFilePath -DestinationPath $SourceDir -Force
  27. }
  28. # 如果是强制构建,且构建目录已存在,先删除旧的构建目录(确保干净构建)
  29. if ($Force -and (Test-Path $BuildDir)) {
  30.     Write-Output "Force mode enabled. Removing previous build directory: $BuildDir"
  31.     Remove-Item $BuildDir -Recurse -Force -ErrorAction SilentlyContinue
  32. }
  33. # # 复制符号库
  34. $PdbFiles = @(
  35.      "$BuildDir/RelWithDebInfo/libexpat.pdb"
  36. )
  37. # 额外构建参数
  38. $CMakeCacheVariables = @{
  39.     EXPAT_BUILD_DOCS = "OFF"
  40.     EXPAT_BUILD_EXAMPLES = "OFF"
  41.     EXPAT_BUILD_TESTS = "OFF"
  42. }
  43. # 调用通用 CMake 构建脚本
  44. $cmakeSourcePath = Join-Path -Path $SourcePath -ChildPath "expat"
  45. Write-Output "Starting build for $Name..."
  46. . ./cmake-build.ps1 -SourceLocalPath $cmakeSourcePath `
  47.     -BuildDir $BuildDir `
  48.     -Generator $Generator `
  49.     -InstallDir $InstallDir `
  50.     -SymbolDir $SymbolDir `
  51.     -PdbFiles $PdbFiles `
  52.     -CMakeCacheVariables $CMakeCacheVariables `
  53.     -MultiConfig $true  
  54. if ($LASTEXITCODE -ne 0) {
  55.     Write-Error "Build failed for $Name."
  56.     exit $LASTEXITCODE
  57. }
  58. # 构建成功后,根据 Cleanup 开关决定是否删除
  59. if ($Cleanup) {
  60.     Write-Output "Build succeeded. Cleaning up temporary directories..."
  61.     if (Test-Path $SourcePath) {
  62.         Remove-Item $SourcePath -Recurse -Force -ErrorAction SilentlyContinue
  63.         Write-Output "Removed source directory: $SourcePath"
  64.     }
  65.     if (Test-Path $BuildDir) {
  66.         Remove-Item $BuildDir -Recurse -Force -ErrorAction SilentlyContinue
  67.         Write-Output "Removed build directory: $BuildDir"
  68.     }
  69. }
  70. Write-Output "Build completed for $Name."
复制代码
脚本cmake-build.ps1笔者已经在《CMake构建学习笔记21-通用的CMake构建脚本》这篇文章中介绍过。
3.2.1 freexl构建

freexl是一个开源库,主要用于读取Microsoft Excel的.xls文件格式。构建freexl与前面介绍nmake构建的一般方法基本一致:
  1. nmake -f makefile.vc  #构建
  2. nmake -f makefile.vc install  #安装
  3. nmake -f makefile.vc clean        #清理
复制代码
当然nmake64.opt和makefile64.vc中的内容需要根据自己的情况按需修改。对于nmake64.opt,修改的内容为:
  1. #INSTDIR=C:\OSGeo4W64
  2. INSTDIR=C:\OSGeo4W64
复制代码
而对于makefile64.vc,修改的内容为:
  1. # CFLAGS        =        /nologo -I. -Iheaders -IC:\OSGeo4W64\include $(OPTFLAGS)
  2. CFLAGS        =        /nologo -I. -Iheaders -IC:\Work\3rdparty\include $(OPTFLAGS)
  3. #freexl_i.lib:        $(LIBOBJ)
  4. #        link /debug /dll /out:$(FREEXL_DLL) \
  5. #                /implib:freexl_i.lib $(LIBOBJ) \
  6. #                C:\Work\3rdparty\lib\iconv.lib \
  7. #                C:\Work\3rdparty\lib\libexpat.lib \
  8. #                C:\Work\3rdparty\lib\minizip.lib \
  9. #                C:\Work\3rdparty\lib\zlib.lib
  10. #        if exist $(FREEXL_DLL).manifest mt -manifest \
  11. #                $(FREEXL_DLL).manifest -outputresource:$(FREEXL_DLL);2
  12. freexl_i.lib:        $(LIBOBJ)
  13.         link /debug /dll /out:$(FREEXL_DLL) \
  14.                 /implib:freexl_i.lib $(LIBOBJ) \
  15.                 C:\OSGeo4w64\lib\iconv.lib \
  16.                 C:\OSGeo4W64\lib\libexpat.lib \
  17.                 C:\OSGeo4W64\lib\libminizip.lib \
  18.                 C:\OSGeo4w64\lib\zlib.lib
  19.         if exist $(FREEXL_DLL).manifest mt -manifest \
  20.                 $(FREEXL_DLL).manifest -outputresource:$(FREEXL_DLL);2
复制代码
3.2.1 librttopo构建

librttopo是一个开源的地理空间操作库,是PostGIS项目的一部分,提供了一系列用于处理和分析地理数据的功能,比如几何图形的操作、空间关系判断、坐标转换等。librttopo使用nmake构建有点麻烦,主要原因就是跨平台兼容性有点问题,在Windows下有些文件没有生成导致编译出错。
可以使用这篇文章中提供了一个源代码版本,然后按需修改nmake64.opt:
  1. #INSTDIR=C:\OSGeo4W64
  2. INSTDIR=C:\Work\3rdparty
复制代码
同样修改makefile64.vc:
  1. #CFLAGS        =        /nologo -IC:\OSGeo4W64\include -I. -Iheaders $(OPTFLAGS)
  2. CFLAGS        =        /nologo -IC:\Work\3rdparty\include -I. -Iheaders $(OPTFLAGS)
  3. #librttopo_i.lib:        $(LIBOBJ)
  4. #        link /debug /dll /out:$(LIBRTTOPO_DLL) \
  5. #                /implib:librrttopo_i.lib $(LIBOBJ) \
  6. #                C:\OSGeo4W64\lib\geos_c.lib
  7. #        if exist $(LIBRTTOPO_DLL).manifest mt -manifest \
  8. #                $(LIBRTTOPO_DLL).manifest -outputresource:$(LIBRTTOPO_DLL);2
  9. librttopo_i.lib:        $(LIBOBJ)
  10.         link /debug /dll /out:$(LIBRTTOPO_DLL) \
  11.                 /implib:librrttopo_i.lib $(LIBOBJ) \
  12.                 C:\Work\3rdparty\lib\geos_c.lib
  13.         if exist $(LIBRTTOPO_DLL).manifest mt -manifest \
  14.                 $(LIBRTTOPO_DLL).manifest -outputresource:$(LIBRTTOPO_DLL);2
复制代码
三个nmake构建库修改的配置文件内容大致差不多,都是修改安装目录,修改依赖库include目录,修改链接的库文件,然后执行:
  1. nmake -f makefile.vc  #构建
  2. nmake -f makefile.vc install  #安装
  3. nmake -f makefile.vc clean        #清理
复制代码
4. 问题

如文中所说,这种nmake构建的方式有个很大的问题就是总是需要临时修改nmake64.opt和makefile64.vc来应对不同的环境,这对于使用脚本自动批处理的方式来说不太友好。说白了Windows下所有的逻辑都是基于GUI的,nmake不过是个临时补丁。不过理论上也可以考虑使用环境变量的方式来避免这个问题,就留待后续解决了。

来源:豆瓜网用户自行投稿发布,如果侵权,请联系站长删除

相关推荐

您需要登录后才可以回帖 登录 | 立即注册