想用GDAL/OGR功能,折腾了一晚,把步骤记录下来,供以后参考。以下内容是在原文的基础上验证,修改了一些bug。

1 官网下载GDAL源码

可以去官网下载,也可以到下载,后者还提供源码和编译好的文件下载(Debian版本),我用的官网的源码进行的编译。

2 解压源码并安装

可参考https://www.cnblogs.com/charlee44/archive/2017/05/21/6886442.html)。将得到的源码解压:tar -zxvf gdal-3.3.1.tar.gz ,进入解压后的目录,配置安装目录,我配置在/home/zhoujianwen/gdal-3.3.1/build目录下,按照参考说的额,配置安装目录,生成makefile文件,执行命令:

cd gdal-3.3.1/
 sudo mkdir build #建立安装目录
 sudo ./configure --prefix=/home/zjw/gdal-3.3.1/build

问题来了:

checking for PROJ >= 6 library... checking for proj_create_from_wkt in -lproj... no
checking for internal_proj_create_from_wkt in -lproj... no
checking for internal_proj_create_from_wkt in -linternalproj... no
configure: error: PROJ 6 symbols not found

百度搜索,原来GDAL/OGR 3.x版本需要PROJ6的支持,还是得先解决PROJ6的问题。

3 下载编译PROJ6

官网下载PROJ,已经8.x版本了,为求保险兼容,还是选择6.x版本下载吧。(注:对于官网中对于linux debian版本直接安装:sudo apt-get install proj-bin我试了下,没有成功,不知道怎么回事,还是采用源码编译方式。)我下载的6.3.2版本,源码可以用cmake生成编译文件,也可以直接用GUN Make编译,我选用后者。
解压后,进入解压目录,配置安装路径,生成makefile,请参考。

 tar -zxvf proj-8.1.0.tar.gz
 cd proj-8.1.0
 sudo mkdir build #建立安装目录
 sudo ./configure --prefix=/home/zjw/proj-8.1.0/build  #/home/zjw/proj-8.1.0/build目录需要事先建好

问题又来了:

No package 'sqlite3' found

Consider adjusting the PKG_CONFIG_PATH environment variable if you
installed software in a non-standard prefix.

Alternatively, you may set the environment variables SQLITE3_CFLAGS
and SQLITE3_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details.

4 编译安装SQLite3

官网下载 sqlite-autoconf-3360000.tar.gz 解压、进入解压目录、配置安装目录,生成makefile:

tar -zxvf sqlite-autoconf-3360000.tar.gz
cd sqlite-autoconf-3360000/
sudo mkdir build
sudo ./configure --prefix=/home/zjw/sqlite-autoconf-3360000/build

继续编译,安装:

sudo make
sudo make install

/home/zjw/sqlite-autoconf-3360000目录下,会生成bin、include、lib、share四个目录,编译安装成功。终于不用再依赖其他的东西了-_-!!!
在这里插入图片描述

最终安装信息如下:

(base) zjw@node1:~/sqlite-autoconf-3360000$ sudo make install
make[1]: Entering directory '/home/zjw/sqlite-autoconf-3360000'
 /bin/mkdir -p '/home/zjw/sqlite-autoconf-3360000/build/lib'
 /bin/bash ./libtool   --mode=install /usr/bin/install -c   libsqlite3.la '/home/zjw/sqlite-autoconf-3360000/build/lib'
libtool: install: /usr/bin/install -c .libs/libsqlite3.so.0.8.6 /home/zjw/sqlite-autoconf-3360000/build/lib/libsqlite3.so.0.8.6
libtool: install: (cd /home/zjw/sqlite-autoconf-3360000/build/lib && { ln -s -f libsqlite3.so.0.8.6 libsqlite3.so.0 || { rm -f libsqlite3.so.0 && ln -s libsqlite3.so.0.8.6 libsqlite3.so.0; }; })
libtool: install: (cd /home/zjw/sqlite-autoconf-3360000/build/lib && { ln -s -f libsqlite3.so.0.8.6 libsqlite3.so || { rm -f libsqlite3.so && ln -s libsqlite3.so.0.8.6 libsqlite3.so; }; })
libtool: install: /usr/bin/install -c .libs/libsqlite3.lai /home/zjw/sqlite-autoconf-3360000/build/lib/libsqlite3.la
libtool: install: /usr/bin/install -c .libs/libsqlite3.a /home/zjw/sqlite-autoconf-3360000/build/lib/libsqlite3.a
libtool: install: chmod 644 /home/zjw/sqlite-autoconf-3360000/build/lib/libsqlite3.a
libtool: install: ranlib /home/zjw/sqlite-autoconf-3360000/build/lib/libsqlite3.a
libtool: finish: PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin:/sbin" ldconfig -n /home/zjw/sqlite-autoconf-3360000/build/lib
----------------------------------------------------------------------
Libraries have been installed in:
   /home/zjw/sqlite-autoconf-3360000/build/lib

If you ever happen to want to link against installed libraries
in a given directory, LIBDIR, you must either use libtool, and
specify the full pathname of the library, or use the '-LLIBDIR'
flag during linking and do at least one of the following:
   - add LIBDIR to the 'LD_LIBRARY_PATH' environment variable
     during execution
   - add LIBDIR to the 'LD_RUN_PATH' environment variable
     during linking
   - use the '-Wl,-rpath -Wl,LIBDIR' linker flag
   - have your system administrator add LIBDIR to '/etc/ld.so.conf'

See any operating system documentation about shared libraries for
more information, such as the ld(1) and ld.so(8) manual pages.
----------------------------------------------------------------------
 /bin/mkdir -p '/home/zjw/sqlite-autoconf-3360000/build/bin'
  /bin/bash ./libtool   --mode=install /usr/bin/install -c sqlite3 '/home/zjw/sqlite-autoconf-3360000/build/bin'
libtool: install: /usr/bin/install -c sqlite3 /home/zjw/sqlite-autoconf-3360000/build/bin/sqlite3
 /bin/mkdir -p '/home/zjw/sqlite-autoconf-3360000/build/include'
 /usr/bin/install -c -m 644 sqlite3.h sqlite3ext.h '/home/zjw/sqlite-autoconf-3360000/build/include'
 /bin/mkdir -p '/home/zjw/sqlite-autoconf-3360000/build/share/man/man1'
 /usr/bin/install -c -m 644 sqlite3.1 '/home/zjw/sqlite-autoconf-3360000/build/share/man/man1'
 /bin/mkdir -p '/home/zjw/sqlite-autoconf-3360000/build/lib/pkgconfig'
 /usr/bin/install -c -m 644 sqlite3.pc '/home/zjw/sqlite-autoconf-3360000/build/lib/pkgconfig'

环境变量设置

vim ~/.bashrc

添加以下语句
export PATH=/home/zjw/sqlite-autoconf-3360000/build/bin:$PATH
export LD_LIBRARY_PATH=/home/zjw/sqlite-autoconf-3360000/build/lib:$LD_LIBRARY_PATHexport PATH=/home/zjw/sqlite-autoconf-3360000/build/bin:$PATH
export SQLITE3_CFLAGS=/home/zjw/sqlite-autoconf-3360000/build/include
export SQLITE3_LIBS=/home/zjw/sqlite-autoconf-3360000/build/lib 
保存退出

最后永久更新
source ~/.bashrc
echo $PATH
输出
/home/zjw/sqlite-autoconf-3360000/build/bin:/home/zjw/bin:/home/zjw/.local/bin:/home/zjw/anaconda3/bin:/home/zjw/anaconda3/condabin:/home/wml/anaconda3/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/usr/local/go/bin:/usr/local/go/pkg/tool:/home/zjw/sqlite-autoconf-3360000/build/bin:/home/zjw/sqlite-autoconf-3360000/build/bin:/home/zjw/sqlite-autoconf-3360000/build/bin
echo $SQLITE3_CFLAGS
echo $SQLITE3_LIBS
输出
/home/zjw/sqlite-autoconf-3360000/build/include
/home/zjw/sqlite-autoconf-3360000/build/lib

5 继续编译PROJ6

回到proj6解压目录,本以为编译好SQLite3,设置好提示中的PKG_CONFIG_PATH、SQLITE3_CFLAGS、SQLITE3_LIBS、PATH变量,告诉去哪里找头文件,去哪里链接动态库就可以了,但是还是提示错误。(猜想:在命令窗口直接export环境变量只针对当前窗口,是不是放到/etc/profile里面可以解决?没试,可能性也不大感觉,还是按下面步骤做吧。)

sudo ./configure --prefix=/home/zjw/proj-8.1.0/build

提示错误信息
configure: error: Please install sqlite3 binary.

有可能是刚才的 $SQLITE3_LIBS 设置的变量路径无法搜索到库文件,建议更新一下应该就可以跳过 “继续安装依赖:” 这一步。

export SQLITE3_LIBS=/home/zjw/sqlite-autoconf-3360000/build/lib/libsqlite3.la

继续安装依赖:

sudo apt-get install sqlite3

再次执行

```bash
sudo ./configure --prefix=/home/zjw/proj-8.1.0/build
sudo make
sudo make install

成功!!!
在这里插入图片描述

设置环境变量

vim ~/.bashrc
添加
export PATH=/home/zjw/proj-8.1.0/build/bin:$PATH
保存退出

source ~/.bashrc

6 继续编译GDAL

设置PATH将PROJ6的bin目录加入环境变量(这一步不知道需不需要,我是加上了,没试没加的情况,有可能也行,因为后边还要设置依赖的文件目录)、编译依赖文件,即上一步编译的结果。

sudo ./configure --with-proj=/home/zjw/proj-8.1.0/build --prefix=/home/zjw/gdal-3.3.1/build #设置依赖文件及安装目录:注意 --with-proj=/usr/PROJ6很重要,告诉gdal去哪个目录找头文件和库

在这里插入图片描述

sudo make # 比较慢,耐心等待吧

最后显示

echo 'CONFIG_VERSION='`cat ./VERSION`'' >> gdal.pc
echo 'CONFIG_INST_PREFIX=/home/zjw/gdal-3.3.1/build' >> gdal.pc
echo 'CONFIG_INST_LIBS=-L/home/zjw/gdal-3.3.1/build/lib -lgdal' >> gdal.pc
echo 'CONFIG_INST_CFLAGS=-I/home/zjw/gdal-3.3.1/build/include' >> gdal.pc
echo 'CONFIG_INST_DATA=/home/zjw/gdal-3.3.1/build/share/gdal' >> gdal.pc

再执行一次

sudo make install     # 安装

查找一下gdal.pc,默认是在./build/lib/pkgconfig/gdal.pc
查看gdal.pc内容,cat ./build/lib/pkgconfig/gdal.pc

CONFIG_VERSION=3.3.1
CONFIG_INST_PREFIX=/home/zjw/gdal-3.3.1/build
CONFIG_INST_LIBS=-L/home/zjw/gdal-3.3.1/build/lib -lgdal
CONFIG_INST_CFLAGS=-I/home/zjw/gdal-3.3.1/build/include
CONFIG_INST_DATA=/home/zjw/gdal-3.3.1/build/share/gdal
prefix=${CONFIG_INST_PREFIX}
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${exec_prefix}/include
datadir=${CONFIG_INST_DATA}

Name: libgdal
Description: Geospatial Data Abstraction Library
Version: ${CONFIG_VERSION}
Libs: ${CONFIG_INST_LIBS}
Cflags: ${CONFIG_INST_CFLAGS}

复制文件到 /usr/lib/pkgconfig

cp /home/zjw/gdal-3.3.1/build/lib/pkgconfig/gdal.pc  /usr/lib/pkgconfig

把 gdal.pc 文件放到 /usr/lib/pkgconfig路径下
在 linux 下通过 pkg-config 自动获取编译连接路径,可以正常运行了。
试一试看看能否读取路径信息

pkg-config --libs --cflags gdal
显示如下
-I/home/zjw/gdal-3.3.1/build/include -L/home/zjw/gdal-3.3.1/build/lib -lgdal

使用 pkg-config 的 –cflags 参数可以给出在编译时所需要的选项,而 –libs 参数可以给出连接时的选项。例如,假设一个 sample.c 的程序用到了 glib 库,就可以这样编译:

$ gcc -c `pkg-config –cflags glib-2.0` sample.c

然后这样连接:

$ gcc sample.o -o sample `pkg-config –libs glib-2.0`

或者上面两步也可以合并为以下一步:

$ gcc sample.c -o sample `pkg-config –cflags –libs glib-2.0`

关于 pkg-config 认识

pkg-config提供了下面几个功能:

检查库的版本号。如果所需要的库的版本不满足要求,它会打印出错误信息,避免链接错误版本的库文件。
获得编译预处理参数,如宏定义,头文件的位置。
获得链接参数,如库及依赖的其它库的位置,文件名及其它一些连接参数。
自动加入所依赖的其它库的设置。

当然除了在编译时使用pkg-config,还可以使用以下方式操作
gdal设置path搜索路径

vim ~/.bashrc
export PATH=/home/zjw/gdal-3.3.1/build/bin:$PATH
source ~/.bashrc # 编译完马上更新到系统
(base) zjw@node1:~/gdal-3.3.1/build/bin$ gdalinfo --version
GDAL 3.3.1, released 2021/06/28

gdal设置include搜索路径

vim ~/.bashrc
export CPLUS_INCLUDE_PATH=/home/zjw/gdal-3.3.1/build/include    #c++
export C_INCLUDE_PATH=/home/zjw/gdal-3.3.1/build/include		#c

gdal设置静态库搜索路径:

export LIBRARY_PATH=$LIBRARY_PATH:/home/zjw/gdal-3.3.1/build/lib

gdal设置运行时动态库的搜索路径:

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/zjw/gdal-3.3.1/build/lib

永久更新source ~/.bashrc才会生效

echo $CPLUS_INCLUDE_PATH   # /home/zjw/gdal-3.3.1/build/include
echo $C_INCLUDE_PATH # /home/zjw/gdal-3.3.1/build/include
echo $LIBRARY_PATH  # /home/zjw/gdal-3.3.1/build/lib
echo $LD_LIBRARY_PATH # /home/zjw/gdal-3.3.1/build/lib

除了可以使用C++调用之外,还可以使用go,关于go配置请 参阅

至此 gdal 源码编译结束,后面是巩固和复习对 linux 环境变量,include搜索路径,lib库搜索路径的理解

7 环境变量,include搜索路径,lib库搜索路径

库文件在连接(静态库和共享库)和运行(仅限于使用共享库的程序)时被使用,其搜索路径是在系统中进行设置的。一般 Linux 系统把 /lib 和 /usr/lib 两个目录作为默认的库搜索路径,所以使用这两个目录中的库时不需要进行设置搜索路径即可直接使用。对于处于默认库搜索路径之外的库,需要将库的位置添加到库的搜索路径之中。设置库文件的搜索路径有下列两种方式,可任选其一使用:

  1. 在环境变量 LD_LIBRARY_PATH 中指明库的搜索路径。
    vim ~/.bashrc
    添加
    export LD_LIBRARY_PATH=/home/zjw/sqlite-autoconf-3360000/build/lib:$LD_LIBRARY_PATH
    保存
    source ~/.bashrc
    echo $LD_LIBRARY_PATH
    
  2. 在 /etc/ld.so.conf 文件中添加库的搜索路径。
     sudo vim /etc/ld.so.conf 
     添加路径
     /home/zjw/sqlite-autoconf-3360000/build/lib
     保存,此命令激活 /etc/ld.so.cache 文件的更新
     /sbin/ldconfig  
    

将自己可能存放库文件的路径都加入到 /etc/ld.so.conf 中是明智的选择。
添加方法也极其简单,将库文件的绝对路径直接写进去就OK了,一行一个。例如:

/usr/X11R6/lib
/usr/local/lib
/opt/lib

需要注意的是:第二种搜索路径的设置方式对于程序连接时的库(包括共享库和静态库)的定位已经足够了,但是对于使用了共享库的程序的执行还是不够的。这是因为为了加快程序执行时对共享库的定位速度,避免使用搜索路径查找共享库的低效率,所以是直接读取库列表文件 /etc/ld.so.cache 从中进行搜索的。/etc/ld.so.cache 是一个非文本的数据文件,不能直接编辑,它是根据 /etc/ld.so.conf 中设置的搜索路径由 /sbin/ldconfig 命令将这些搜索路径下的共享库文件集中在一起而生成的(ldconfig 命令要以 root 权限执行)。因此,为了保证程序执行时对库的定位,在 /etc/ld.so.conf 中进行了库搜索路径的设置之后,还必须要运行 /sbin/ldconfig 命令更新 /etc/ld.so.cache 文件之后才可以。ldconfig ,简单的说,它的作用就是将 /etc/ld.so.conf 列出的路径下的库文件缓存到/etc/ld.so.cache以供使用。因此当安装完一些库文件(例如刚安装好 glib 或者修改 ld.so.conf 增加新的库路径)后,需要运行一下 /sbin/ldconfig 使所有的库文件都被缓存到 ld.so.cache 中,如果没做,即使库文件明明就在 /usr/lib 下的,也是不会被使用的,结果编译过程中抱错,缺少xxx库,去查看发现明明就在那放着,搞的想大骂 computer 蠢猪一个。 (_

8 参考

[1] linux中make install指定安装目录
[2] make install 时指定安装路径
[3] 理解 Linux中的pkg-config 工具
[4] 系统环境变量设置
[5] pkg-config的用法
[6] 环境变量,include搜索路径,lib库搜索路径

Logo

更多推荐