将gdal源码转化为VS工程编译过程记录

作者:朱金灿

来源:http://blog.csdn.net/clever101

 

      为什么要用VS工程的方式来编译gdal库?主要还是为了调试方便,虽然理论上使用命令行方式生成库也能调试,详见:GDAL库调试(包括跨语言调试),但是我把gdal库的pdb文件、ilk文件都拷贝到输出目录依然无法调试,使用windbg进行调试,感觉繁琐了点,还有开发组的其他成员还不会用windbg这玩意,于是开始折腾将gdal源码转化为VS工程。

 

       结果一折腾之下,发现自己仿佛掉进无穷深的坑,可能就是俗称的dll地狱吧,终于在今天折腾完。下面就详细说说这一过程:

 

       第一步:使用makegdal_gen.bat生成一个VS2008工程makegdal90.vcproj,makegdal_gen.bat的具体用法见参考文献一,这里不作详述。可能有读者认为这样生成不是VS工程吗?实际上这并不是我想要可以调试的dll工程,而是一个Make工程,这个Make工程实际上调用的还是nmake的命令行,具体看下图:


        第二步就是要把make工程转化为dll工程,转化的过程很简单,用记事本将makegdal90.vcproj打开,找到Configurations节点,具体如下:

	<Configurations>
		<Configuration
			Name="Debug|Win32"
			OutputDirectory="$(ConfigurationName)"
			IntermediateDirectory="$(ConfigurationName)"
			ConfigurationType="0"
			>
			<Tool
				Name="VCNMakeTool"
				BuildCommandLine="cd $(ProjectDir) && nmake -f makefile.vc MSVC_VER=1400 DEBUG=1"
				ReBuildCommandLine="cd $(ProjectDir) && nmake -f makefile.vc MSVC_VER=1400 DEBUG=1 clean && nmake -f makefile.vc MSVC_VER=1400 DEBUG=1"
				CleanCommandLine="cd $(ProjectDir) && nmake -f makefile.vc MSVC_VER=1400 DEBUG=1 clean"
				Output="gdal17.dll"
				PreprocessorDefinitions=""
				IncludeSearchPath=""
				ForcedIncludes=""
				AssemblySearchPath=""
				ForcedUsingAssemblies=""
				CompileAsManaged=""
			/>
		</Configuration>
		<Configuration
			Name="Release|Win32"
			OutputDirectory="$(ConfigurationName)"
			IntermediateDirectory="$(ConfigurationName)"
			ConfigurationType="0"
			>
			<Tool
				Name="VCNMakeTool"
				BuildCommandLine="cd $(ProjectDir) && nmake -f makefile.vc MSVC_VER=1400 && nmake -f makefile.vc MSVC_VER=1400 install"
				ReBuildCommandLine="cd $(ProjectDir) && nmake -f makefile.vc MSVC_VER=1400 clean && nmake -f makefile.vc MSVC_VER=1400 && nmake -f makefile.vc MSVC_VER=1400 install"
				CleanCommandLine="cd $(ProjectDir) && nmake -f makefile.vc MSVC_VER=1400 clean"
				Output="gdal17.dll"
				PreprocessorDefinitions=""
				IncludeSearchPath=""
				ForcedIncludes=""
				AssemblySearchPath=""
				ForcedUsingAssemblies=""
				CompileAsManaged=""
			/>
		</Configuration>
	</Configurations>

替换为如下内容:

	<Configurations>
		<Configuration
			Name="Debug|Win32"
			OutputDirectory="........Outdirdebug"
			IntermediateDirectory="........Intdir$(ConfigurationName)$(ProjectName)"
			ConfigurationType="2"
			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaultsUpgradeFromVC71.vsprops"
			CharacterSet="2"
			>
			<Tool
				Name="VCPreBuildEventTool"
			/>
			<Tool
				Name="VCCustomBuildTool"
			/>
			<Tool
				Name="VCXMLDataGeneratorTool"
			/>
			<Tool
				Name="VCWebServiceProxyGeneratorTool"
			/>
			<Tool
				Name="VCMIDLTool"
			/>
			<Tool
				Name="VCCLCompilerTool"
				Optimization="0"
				AdditionalIncludeDirectories=""
				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;GDAL_EXPORTS"
				IgnoreStandardIncludePath="false"
				MinimalRebuild="true"
				BasicRuntimeChecks="3"
				RuntimeLibrary="3"
				UsePrecompiledHeader="0"
				WarningLevel="3"
				Detect64BitPortabilityProblems="true"
				DebugInformationFormat="3"
				DisableSpecificWarnings="4251"
				ForcedIncludeFiles=""
			/>
			<Tool
				Name="VCManagedResourceCompilerTool"
			/>
			<Tool
				Name="VCResourceCompilerTool"
			/>
			<Tool
				Name="VCPreLinkEventTool"
			/>
			<Tool
				Name="VCLinkerTool"
				AdditionalDependencies=""
				OutputFile="$(OutDir)/gdal-vc9.dll"
				LinkIncremental="2"
				AdditionalLibraryDirectories=""
				IgnoreAllDefaultLibraries="false"
				IgnoreDefaultLibraryNames="msvcrt.lib"
				ForceSymbolReferences=""
				GenerateDebugInformation="true"
				ProgramDatabaseFile="$(OutDir)/gdal.pdb"
				SubSystem="1"
				RandomizedBaseAddress="1"
				DataExecutionPrevention="0"
				ImportLibrary="$(OutDir)/gdal-vc9.lib"
				TargetMachine="1"
			/>
			<Tool
				Name="VCALinkTool"
			/>
			<Tool
				Name="VCManifestTool"
			/>
			<Tool
				Name="VCXDCMakeTool"
			/>
			<Tool
				Name="VCBscMakeTool"
			/>
			<Tool
				Name="VCFxCopTool"
			/>
			<Tool
				Name="VCAppVerifierTool"
			/>
			<Tool
				Name="VCPostBuildEventTool"
				CommandLine=""
			/>
		</Configuration>
		<Configuration
			Name="Release|Win32"
			OutputDirectory="........outdir
elease"
			IntermediateDirectory="........Intdir$(ConfigurationName)$(ProjectName)"
			ConfigurationType="2"
			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaultsUpgradeFromVC71.vsprops"
			CharacterSet="2"
			>
			<Tool
				Name="VCPreBuildEventTool"
			/>
			<Tool
				Name="VCCustomBuildTool"
			/>
			<Tool
				Name="VCXMLDataGeneratorTool"
			/>
			<Tool
				Name="VCWebServiceProxyGeneratorTool"
			/>
			<Tool
				Name="VCMIDLTool"
			/>
			<Tool
				Name="VCCLCompilerTool"
				AdditionalIncludeDirectories=""
				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;GDAL_EXPORTS"
				RuntimeLibrary="2"
				UsePrecompiledHeader="0"
				WarningLevel="3"
				Detect64BitPortabilityProblems="true"
				DebugInformationFormat="0"
				DisableSpecificWarnings="4251"
			/>
			<Tool
				Name="VCManagedResourceCompilerTool"
			/>
			<Tool
				Name="VCResourceCompilerTool"
			/>
			<Tool
				Name="VCPreLinkEventTool"
			/>
			<Tool
				Name="VCLinkerTool"
				AdditionalDependencies=""
				OutputFile="$(OutDir)/gdal-vc9.dll"
				LinkIncremental="1"
				AdditionalLibraryDirectories=""
				IgnoreDefaultLibraryNames=""
				ForceSymbolReferences=""
				GenerateDebugInformation="false"
				SubSystem="2"
				OptimizeReferences="2"
				EnableCOMDATFolding="2"
				RandomizedBaseAddress="1"
				DataExecutionPrevention="0"
				ImportLibrary="$(OutDir)/gdal-vc8.lib"
				TargetMachine="1"
			/>
			<Tool
				Name="VCALinkTool"
			/>
			<Tool
				Name="VCManifestTool"
			/>
			<Tool
				Name="VCXDCMakeTool"
			/>
			<Tool
				Name="VCBscMakeTool"
			/>
			<Tool
				Name="VCFxCopTool"
			/>
			<Tool
				Name="VCAppVerifierTool"
			/>
			<Tool
				Name="VCPostBuildEventTool"
				CommandLine=""
			/>
		</Configuration>
	</Configurations>

这样你就将一个make工程转化为一个win32 dll工程。

 

        第三步添加附加头文件路径、预处理器和附加库。事实上这一步最为繁琐。先说说添加头文件路径,因为gdal库涉及到众多的格式,只要你数下frmts目录以及ogrogrsf_frmts目录下有多少个子文件夹就可以知道gdal支持多少种栅格格式和矢量格式(我的感觉是gdal库就像一座桥梁,把众多的图形图像库联结在一起),也就是说要把这么多格式的路径都添加进头文件路径。手动添加肯定是不行的,我写了一个JS文件通过遍历文件路径进行添加。然后开始添加预处理器,预处理器的作用主要有两方面,一是控制gdal库支持哪些格式,比如添加了FRMT_gtiff预处理器表示支持geotiff格式,想知道哪些栅格格式对应哪些预处理器,请看GDALAllRegister函数源码,对于支持哪些矢量格式,比如添加SHAPE_ENABLED表示支持shp格式,想知道哪些矢量格式对应哪些预处理器,请看OGRRegisterAll函数源码,二是控制是否添加附加库,比如添加HAVE_LIBJPEG表示有额外的jpeg库。我添加了下面这些预处理器:

HAVE_XERCES
FRMT_ceos
FRMT_aigrid
FRMT_elas
FRMT_hfa
FRMT_gtiff
FRMT_sdts
FRMT_raw
FRMT_gxf
FRMT_ceos2
FRMT_png
FRMT_dted
FRMT_mem
FRMT_jdem
FRMT_gif
FRMT_envisat
FRMT_aaigrid
FRMT_usgsdem
FRMT_l1b
FRMT_vrt
FRMT_xpm
FRMT_bmp
FRMT_jpeg
SHAPELIB_DLLEXPORT
ZIP_SUPPORT
SHAPE_ENABLED
TAB_ENABLED
NTF_ENABLED
SDTS_ENABLED
TIGER_ENABLED
S57_ENABLED
DGN_ENABLED
VRT_ENABLED
AVCBIN_ENABLED
REC_ENABLED
MEM_ENABLED
_CRT_SECURE_NO_DEPRECATE
BUILD_AS_DLL
USE_CPL
HAVE_GEOS
BIGTIFF_SUPPORT
PROJ_STATIC
COMPILATION_ALLOWED
HAVE_EXPAT
JAS_WIN_MSVC_BUILD
USE_IN_GDAL
OGR_ENABLED
LIBHDF_EXPORTS
HAVE_LIBJPEG
HAVE_LIBZ
HDF5CPP_USEDLL
_HDF5USEDLL_
BUILDING_LIBCURL
HAVE_CURL

       既然gdal库支持那么多格式,是不是我们都应该把每种格式的源码都编译一遍呢?回答是否定的,理由很简单,有些格式很生僻,其数据很可能你一辈子都没见过,那你编译它做什么,因此你完全可以在工程文件里果断地将一些你不想支持的格式的源码移除掉。尽管如此,我们需要的第三方库还是很多的。下面是我们需要的第三方库一览表:

第三方库名及版本

备注

Expat v2.1.0_vc9

xml格式解析库,主要为支持kml格式提供支持。

zlib v1.2.3

开源压缩库,为很多第三方库提供支持。

geos v3.3.5

开源空间分析库

xerces v3.1.1

xml文件解析库

sqlite v3071401

开源数据库,可作为ogr库的空间数据库支持

OpenDWG

用于支持Autocad的dwg格式,值得注意的是OpenDWG是一个cad商业联盟为解析dwg格式而联合推出的一个解析库,其库需要购买,其源码并不公开,它并不是一个库,而是一系列库的集合,具体如下

TD_Gs.lib

TD_Db.lib

TD_DbRoot.lib

TD_Ge.lib

TD_Root.lib

TD_AcisBuilder.lib

TD_Gi.lib

TD_Alloc.lib

TD_ExamplesCommon.lib

TD_SpatialIndex.lib。

libwebp v0.2.0

貌似是支持一种网络图片格式webp。

Openjpeg v2.0.0-win32-x86lib

用于支持jpeg200格式

pthreads v2_9_1

跨平台线程库

Libkml v1.3.0

用于支持kml格式

Jasper v1.900.1

用于支持Jasper格式

Curl v7.32.0

文件传输库,貌似为了支持GIS的WMS服务,在windows平台上需要win socket支持,具体需要ws2_32.lib、wsock32.lib、Wldap32.lib这三个库支持。

libiconv v1.11.1

跨平台文本编码转换库

proj v4.8

投影转换库

hdfeos 2_18

用于支持hdf格式

hdf5 v1.8.8

用于支持hdf5格式

hdf v4.2.6

用于支持hdf5格式

libj2k

用于支持jpeg2000格式,不知和openjpeg有何区别。

jpeg v8d

用于支持jpeg库

minizip

支持kml格式的附加库

uriparser

支持kml格式的附加库



参考文献:

 

1. GDAL源码剖析(二)之编译说明






原文地址:https://www.cnblogs.com/lanzhi/p/6470468.html