一、前言
在Linux(CentOS)平台上进行软件的编译工作,不仅是一项技术活,更是一项体力活。没有充沛的体力与精力,没有不达目标誓不罢休的精神,当然具备良好的技术能力是最基本的,是决然无法完成编译工作的。
尽管从开始编译,已经过去了两周时间。尽管为了编译最后的库,首先需要编译它的依赖库,结果为编译依赖库,还要编译另外的若干个依赖库。经历了重重的依赖库泥潭,在周末的深夜,坐在计算机面前,心底里知道重要要看到曙光了。当满怀信心的写完make后,结果面对的是一坨坨的错误信息,翻十几屏,甚至几十屏的编译输出结果,没有比这更让人崩溃的了。
想来程序员的冷静与沉默,不是生来就有的,而是在这不计其数的深夜,面对无言的对手,经历了殊死搏斗后,在心里终于升起一丝希望,将要迎接曙光来临时,收到的不是finished,而是fatal error,这样的信息时,又要咬紧牙关,沉下心来,重新携其度娘和谷哥时,心里不由的生出风萧萧兮易水寒的悲凉。
编译GDAL,尤其是要链接各种默认不支持的栅格与矢量格式时,相信有过这种经验的,体会会更加深刻。PDF本来是一种文本格式,但是当在PDF中加入空间信息后,便跨界进入GeoSpatial领域,便有了新(biàn)奇( tài)的GeoSpatial PDF格式。
GDAL要支持GeoSpatial PDF,需要链入第三方的库,目前有三种选择:
1) Poppler; 2) PoDoFo; 3) PDFium
PDFium的编译较为困难,PoDoFo的支持能力稍弱,选择Poppler作为PDF支持库进行编译。
二、编译过程
环境:CentOS 7,GDAL 3.0.1,Poppler 0.80.0
2.1 GCC 9.2.0
之所以要升级GCC,是因为使用老版本的GCC 4.8.5,在编译时会出现std::string_literals错误。
GCC 9.2.0依赖于gmp、mpfr、mpc、isl,其间的相互依赖关系如下图所示。图中各依赖库中上一标号为通过download_prerequisites下载的版本号,下一标号为各依赖库最新的版本号。
可以通过运行:
$ ./contrib/download_prerequisites
来获得以上依赖库,但都不是最新的版本。如果要使用最新的版本需要从相应网站自己下载。
编译GCC
首先可以通过以下命令,了解一下编译GCC的配置选项。
$ ./configure --help
验证编译完的GCC,可以打开一个新的窗口,使用以下命令:
$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/local/libexec/gcc/x86_64-pc-linux-gnu/9.1.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: ../configure --disable-multilib --enable-languages=c,c++ --with-gmp=/usr/local/gmp-6.1.2 --with-mpfr=/usr/local/mpfr-4.0.2 --with-mpc=/usr/local/mpc-1.1.0
Thread model: posix
gcc version 9.1.0 (GCC)
2.2 CMake-3.15.2
在编译Poppler时,需要使用新版的cmake。
2.2 FreeType-2.10.1
编译FontConfig,需要首先编译FontType。
$ sed -ri "s:.*(AUX_MODULES.*valid):\1:" modules.cfg &&
sed -r "s:.*(#.*SUBPIXEL_RENDERING) .*:\1:" \
-i include/freetype/config/ftoption.h &&
./configure --prefix=/usr --enable-freetype-config --disable-static &&
Make
$make install
2.3 FontConfig-2.13.92
编译Poppler,需要依赖于FontConfig。
下载FontConfig
HTTP:https://www.freedesktop.org/software/fontconfig/release/fontconfig-2.13.92.tar.bz2
删除src/fcobjshash.h,确保重新生成
$ rm -f src/fcobjshash.h
配置,编译
./configure --prefix=/usr \
--sysconfdir=/etc \
--localstatedir=/var \
--disable-docs \
--docdir=/usr/share/doc/fontconfig-2.13.1 &&
make
安装
$ sudo make install
2.4 安装openjpeg-turbo-devel
尽管在下面Poppler的链接中,对于libjpeg-turbo库的依赖中说是推荐(Recommended),没说是必须的(Required),但是如果没有安装openjpeg库,在cmake poppler时,会提示出错。
$ sudo yum install libjpeg-turbo-devel
2.5 Poppler 0.80.0
$ xz -d poppler-0.80.0.tar.xz
编译
mkdir build &&
cd build &&
cmake -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=/usr \
-DTESTDATADIR=$PWD/testfiles \
-DENABLE_UNSTABLE_API_ABI_HEADERS=ON \
.. &&
make
注意:以上是参考链接给出的编译选项。在编译时,需要加上CMAKE_C_COMPILER与CMAKE_CXX_COMPILER选项,指向在2.1中编译生成的gcc与g++所在的路径。
参考:
1) cannot get compiled because of std:string_literfals error
...using the gcc 4.8 libstdc++ which is probably too old. ...
...use at least 3 features: one is C++ 11, another one id C++14, ...
2.6 编译Proj4
编译GDAL所必须的库。
Proj4需要用到sqlite3。在编译Proj4之前需要编译或安装sqlite3。
如果是安装的sqlite,则编译Proj4没有什么特别之处,常规的步骤。
$./configure
$ make -j8
$ sudo make install
如果是使用自己编译的sqlite3,则可能要在configure中配置SQLITE3_CFLAGS与SQLTIE3_LIBS
$ ./configure SQLITE3_CFLAGS='-I/usr/local/include' SQLITE3_LIBS='-L/usr/local/lib'
注意:如果要自己编译sqlite,要设置SQLITE_ENABLE_COLUMN_METADATA开关。否则,在后面编译GDAL时,会出现undefined reference ’sqlite3_column_origin_name‘ 与 undefined reference to 'sqlite3_column_table_name‘的错误,导致编译失败!
2.7 编译GEOS
毕竟是要编译GDAL库,编译出的GDAL库,如果连空间运算都不支持,有些说不过去。
下载GEOS库。
$ ./configure
$ make -j8
$ sudo make install
2.8 编译GDAL 3.0.1
2.8.1 ./configure
$ export PKG_CONFIG_PATH=/usr/local/lib64/pkgconfig:$PKG_CONFIG_PATH
$ source /etc/profile
$ pkg-config --print-provides --cflags --libs poppler
$ ./configure --with-geos --with-poppler=yes
问题1:fatal error: poppler/Object.h: No such file or directory.
问题2:Error.h: 31:10: fatal error: poppler-config.h: No such file or directory
2.8.2 make [-j8]
$make -j8
问题1:fatal error: poppler/splash/SplashBitmap.h: No such file or directory
问题2:error: undefined reference to sqlite3_column_origin_name
问题3:error: undefined reference to sqlite3_column_table_name
2.8.3 make install
$ sudo make install
2.8.4 验证
$ cd /usr/local/bin
$ ls -l gdal*
-rwxr-xr-x. 1 root root 138064 Aug 30 08:34 gdaladdo
-rwxr-xr-x. 1 root root 46808 Aug 30 08:34 gdalbuildvrt
-rwxr-xr-x. 1 root root 1555 Aug 30 08:34 gdal-config
-rwxr-xr-x. 1 root root 150800 Aug 30 08:34 gdal_contour
-rwxr-xr-x. 1 root root 48112 Aug 30 08:34 gdaldem
-rwxr-xr-x. 1 root root 119336 Aug 30 08:34 gdalenhance
-rwxr-xr-x. 1 root root 44960 Aug 30 08:34 gdal_grid
-rwxr-xr-x. 1 root root 47704 Aug 30 08:34 gdalinfo
-rwxr-xr-x. 1 root root 151280 Aug 30 08:34 gdallocationinfo
-rwxr-xr-x. 1 root root 90280 Aug 30 08:34 gdalmanage
-rwxr-xr-x. 1 root root 50328 Aug 30 08:34 gdal_rasterize
-rwxr-xr-x. 1 root root 61992 Aug 30 08:34 gdalserver
-rwxr-xr-x. 1 root root 71496 Aug 30 08:34 gdalsrsinfo
-rwxr-xr-x. 1 root root 148712 Aug 30 08:34 gdaltindex
-rwxr-xr-x. 1 root root 66088 Aug 30 08:34 gdaltransform
-rwxr-xr-x. 1 root root 114160 Aug 30 08:34 gdal_translate
-rwxr-xr-x. 1 root root 152440 Aug 30 08:34 gdalwarp
$ gdalinfo --version
GDAL 3.0.1, released 2019/06/28
$ gdalinfo --formats | grep PDF
PDF -raster,vector- (rw+vs): Geospatial PDF
读取PDF文件。
$ gdalinfo 44121-2018-829-2018-06-26B.pdf
Driver: PDF/Geospatial PDF
Files: 44121-2018-829-2018-06-26B.pdf
Size is 6212, 4540
Metadata:
CREATION_DATE=D:20180627083644+08'00'
PRODUCER=iText® 5.4.5 ©2000-2013 1T3XT BVBA (AGPL-version)
Corner Coordinates:
Upper Left ( 0.0, 0.0)
Lower Left ( 0.0, 4540.0)
Upper Right ( 6212.0, 0.0)
Lower Right ( 6212.0, 4540.0)
Center ( 3106.0, 2270.0)
Band 1 Block=6212x1 Type=Byte, ColorInterp=Red
Band 2 Block=6212x1 Type=Byte, ColorInterp=Green
Band 3 Block=6212x1 Type=Byte, ColorInterp=Blue