Ubuntu上用premake编译GDAL

GDAL的编译脚本呈现出不同平台不同解决方案的百花齐放现状。我是从windows平台开始编译GDAL的,用的自然是nmake。那就是一种每个目录下都需要写makefile文件的构建方法,写的人麻烦,我因为要定制,也是不甚其烦。

基于前文:premake 在64位Ubuntu系统下编译32位GCC程序的基础,我在Ubuntu上构建了premake脚本,可以编译出debug64, debug32, release64和releae32的gdal动态和静态库。由于我所用的gdal是定制版本的,可能有所不同,下面的共参考。

创建一个config.lua脚本文件,内容如下:

 

-- A solution contains projects, and defines the available configurations

solution ("gdal")

configurations {"Debug64","Release64", "Debug32", "Release32"}

location "build"

includedirs

{

   "/usr/src/linux-headers-3.8.0-30-generic/include/config/pci/",

   "/usr/include/x86_64-linux-gnu/c++/4.8"

}



configuration "Debug64"

targetdir "output/linux_debug_x64"

defines

{

   "DEBUG",

   "HAVE_SSE_AT_COMPILE_TIME"

}



flags {"Symbols"}



configuration "Debug32"

targetdir "output/linux_debug_x32"

defines

{

   "DEBUG",

   "HAVE_SSE_AT_COMPILE_TIME"

}



buildoptions {"-m32"}

linkoptions {"-m32"}

flags {"Symbols"}



configuration "Release64"

targetdir "output/linux_release_x64"

defines

{

   "NDEBUG",

   "HAVE_SSE_AT_COMPILE_TIME"

}



flags {"OptimizeSize"}



configuration "Release32"

targetdir "output/linux_release_x32"

defines

{

   "NDEBUG",

   "HAVE_SSE_AT_COMPILE_TIME"

}



buildoptions {"-m32"}

linkoptions {"-m32"}

flags {"OptimizeSize"}



-- project port defines one build target

p = project("port")

basedir(p.name)

location("build/" .. p.name)

kind "SharedLib"

language "C++"

files { p.name .. "/*.h", p.name .. "/*.cpp" }



excludes 

{

   p.name .. "/cpl_vsil_stdout.cpp",

   p.name .. "/cpl_odbc.cpp",

   p.name .. "/cpl_win32ce_api.cpp",

   p.name .. "/cpl_vsil_simple.cpp",

   p.name .. "/cpl_vsil_win32.cpp",

   p.name .. "/cpl_vsil_gzip.cpp",

   p.name .. "/cpl_vsil_buffered_reader.cpp",

   p.name .. "/cpl_minizip_zip",

   p.name .. "/cpl_minizip_zip.cpp",

   p.name .. "/cpl_minizip_unzip.cpp",

   p.name .. "/xmlreformat.cpp",

   p.name .. "/cpl_vsil_tar.cpp",

   p.name .. "/cpl_quad_tree.cpp",

   p.name .. "/cpl_vsil_readahead_reader.cp",

   p.name .. "/cpl_google_oauth2.cpp",

   p.name .. "/cpl_vsil_curl.cpp",

   p.name .. "/cpl_vsil_curl_streaming.cpp",

   p.name .. "/cpl_minizip_ioapi.cpp",

   p.name .. "/cpl_vsil_abstract_archive.cpp",

   p.name .. "/cpl_vsil_cache.cpp",

   p.name .. "/cpl_spawn.cpp"

}



includedirs 

{

   "./port", 

   "./ogr", 

   "./gcore", 

   "./alg",

   "./ogr/ogrsf_frmts",

   "./frmts/zlib"

}



-- project ogr defines one build target

p = project("ogr")

basedir(p.name)

location("build/" .. p.name)

-- build .a here because nmake generats ogr.lib

kind "StaticLib"

language "C++"

files

{

   p.name .. "/*.c",

   p.name .. "/*.cpp"

}



excludes

{

   p.name .. "/ogrlinearring.cpp",

   p.name .. "/ogrutils.cpp",

   p.name .. "/ogr2gmlgeometry.cpp",

   p.name .. "/ogrmultipoint.cpp",

   p.name .. "/ogrmultipolygon.cpp",

   p.name .. "/ogrfeaturestyle.cpp",

   p.name .. "/swq_op_registrar.cpp",

   p.name .. "/ogr_api.cpp",

   p.name .. "/ogrsurface.cpp",

   p.name .. "/ogrfielddefn.cpp",

   p.name .. "/ogr_opt.cpp",

   p.name .. "/ogrmultilinestring.cpp",

   p.name .. "/ogrfeature.cpp",

   p.name .. "/swq.cpp",

   p.name .. "/ogrgeometrycollection.cpp",

   p.name .. "/ogrcurve.cpp",

   p.name .. "/gml2ogrgeometry.cpp",

   p.name .. "/ograssemblepolygon.cpp",

   p.name .. "/ogrfeaturequery.cpp",

   p.name .. "/ogrgeometry.cpp",

   p.name .. "/swq_op_general.cpp",

   p.name .. "/ogrgeometryfactory.cpp",

   p.name .. "/ogrlinestring.cpp",

   p.name .. "/swq_parser.cpp",

   p.name .. "/ogrpolygon.cpp",

   p.name .. "/swq_select.cpp",

   p.name .. "/swq_expr_node.cpp",

   p.name .. "/ogrpoint.cpp",

   p.name .. "/ogrfeaturedefn.cpp",

}



includedirs 

{

   "./port", 

   "./ogr", 

   "./gcore", 

   "./alg",

   "./ogr/ogrsf_frmts",

   "./ogrsf_frmts",

   "./frmts/gtiff/libgeotiff"

}



-- project ogr defines one build target

p = project("gcore")

basedir(p.name)

location("build/" .. p.name)

kind "SharedLib"

language "C++"

files { p.name .. "/*.h", p.name .. "/*.cpp" }



excludes

{

   p.name .. "/gdaljp2metadata.cpp",

   p.name .. "/gdaljp2box.cpp",

   p.name .. "/gdalgmlcoverage.cpp"

}



includedirs 

{

   "./port", 

   "./ogr", 

   "./gcore", 

   "./alg",

   "./ogr/ogrsf_frmts",

   "./ogrsf_frmts",

   "./frmts/gtiff"

}



-- project frmts defines one build target

-- After this last project build is finished, then link all obj and libs to library

p = project("frmts")

basedir(p.name)

location("build/" .. p.name)

kind "SharedLib"

language "C++"

files 

{

   p.name .. "/*.cpp",

   p.name .. "/jpeg/*.cpp",

   p.name .. "/jpeg/*.c",

   p.name .. "/nitf/*.cpp",

   p.name .. "/nitf/*.c",

   p.name .. "/gtiff/*.cpp",

   p.name .. "/gtiff/*.c",

   p.name .. "/gtiff/libtiff/*.c",

   p.name .. "/gtiff/libgeotiff/*.c",

   p.name .. "/jpeg/*.cpp",

   p.name .. "/jpeg/*.c",

   p.name .. "/dted/*.cpp",

   p.name .. "/dted/*.c",

   p.name .. "/zlib/*.cpp",

   p.name .. "/zlib/*.c"

}



excludes

{

   p.name .. "/nitf/rpftocdataset.cpp",

   p.name .. "/nitf/nitfdump.c",

   p.name .. "/dted/dted_test.c",

   p.name .. "/dted/dteddataset.cpp",

   p.name .. "/gtiff/libtiff/tif_print.c",

   p.name .. "/gtiff/libgeotiff/geo_trans.c",

   p.name .. "/zlib/gzio.c"

}



includedirs 

{

   "./port", 

   "./ogr", 

   "./gcore", 

   "./alg",

   "./ogr/ogrsf_frmts",

   "./frmts/zlib",

   "./frmts/jpeg/libjpeg",

   "./frmts/gtiff/libtiff",

   "./frmts/vrt",

   "./frmts/gtiff/libgeotiff",

   "./frmts/jpeg/jpeg-8c"

}



defines

{

   "FRMT_nitf",

   "DFRMT_gtiff",

   "FRMT_jpeg",

   "FRMT_dted",

   "FRMT_zlib"

}



整个设计是用一个solution包含四个project,分别对应GDAL的port, ogr, gcore和frmts目录下的代码。premake会自动为每个项目build出动态或者静态库。但是premake4还没有办法在编译时知道自己的configuration是什么(这个功能要到premake5.0才有)。为了弥补这个缺憾,我写了四个脚本,分别在最后将所有的*.o和*.a文件link成libgdal.so和libgdal.a文件。

 

比如rebuild_linxu_debug_32.sh文件,

 

export CXX=clang++

export CC=clang

rm -rf build

rm -rf output/linux_debug_x32

../../../depfiles/build/linux/premake4 --file=config.lua gmake

cd build

make config=debug32

cd -

$CXX -o output/linux_debug_x32/libgdal.so build/port/obj/Debug32/*.o output/linux_debug_x32/libogr.a build/gcore/obj/Debug32/*.o build/frmts/obj/Debug32/*.o -m32 -shared

ar -rcs output/linux_debug_x32/libgdal.a build/port/obj/Debug32/*.o output/linux_debug_x32/libogr.a build/gcore/obj/Debug32/*.o build/frmts/obj/Debug32/*.o



这里可以看到,我用的是clang编译器,去掉开头两行,就变成了gcc了。其他脚本类似。

 

最后有一个rebuild.sh脚本,编译出所有的版本。

 

rm -rf output

./rebuild_linux_debug_64.sh

./rebuild_linux_release_64.sh

./rebuild_linux_debug_32.sh

./rebuild_linux_release_32.sh

 

 

就在顶层目录下搞定,再也不需要维护那么多makefile了。



 

 

你可能感兴趣的:(ubuntu)