1. 程式人生 > 實用技巧 >linux下編譯GDAL3.x(整合Proj和Geos等)

linux下編譯GDAL3.x(整合Proj和Geos等)

目錄

1、準備工作

  • 1、安裝 gccvcpkg 等。

  • 2、下載最新的 GDAL 原始碼。

  • 3、使用 vcpkg 安裝第三方庫。

    ./vcpkg install tiff
    install sqlite3[tool]
    ./vcpkg install geos
    ./vcpkg install curl
    ./vcpkg install liblzma
    ./vcpkg install hdf5
    ./vcpkg install libwebp
    ./vcpkg install zstd
    ./vcpkg install openjpeg
    

2、生成 Makefile

進入 GDAL 原始碼目錄下,使用 configure 指令碼生成 Makefile 檔案。

 LIBRARY_PATH=/home/x/code/vcpkg/installed/x64-linux/lib \
 CPPFLAGS="-I/home/x/code/vcpkg/installed/x64-linux/include" \
 LDFLAGS="-s -L/home/x/code/vcpkg/installed/x64-linux/lib" \
 LIBS="-lpthread -ldl" HDF5_LIBS="-hdf5 -lszip" \
 ./configure \
 --prefix=/home/x/code/output --disable-rpath \
 --with-libtiff=internal --with-libz=internal \
 --with-curl=/home/x/code/vcpkg/installed/x64-linux \
 --with-sqlite3=/home/x/code/vcpkg/installed/x64-linux \
 --with-proj=/home/x/code/vcpkg/installed/x64-linux \
 --with-proj-extra-lib-for-test="-ltiff -ljpeg -llzma -lz" \
 --with-liblzma=/home/x/code/vcpkg/installed/x64-linux \
 --with-zstd=yes --with-png=internal --with-geotiff=internal \
 --with-jpeg=internal \
 --with-gif=internal \
 --with-hdf5=/home/x/code/vcpkg/installed/x64-linux \
 --with-openjpeg=yes --with-geos=yes \
 --with-webp=/home/x/code/vcpkg/installed/x64-linux --with-qhull=internal

1、報錯 "checking for sqlite3_open in -lsqlite3 ... no"

通過檢視 config.log 發現 checking for sqlite3_open in -lsqlite3 的時候沒有連結 pthreaddl庫(找不到 pthread_xxxxx 以及 dlcopen 等函式的定義) 導致的錯誤。

執行configure的時候新增環境變數LIBS="-lpthread -ldl" 來傳入額外的庫。

檢視 configure 檔案,找到 24944$as_echo_n "checking for sqlite3_open in -lsqlite3... " >&6; } 發現上面有一行 LIBS="" 這樣導致傳入的 LIBS 被清空,註釋掉這一行繼續。

2、 checking for proj_create_from_wkt in -lproj 未通過

還是檢視 config.log 檔案,找到相關行的輸出,發現是沒有連結 tiff(以及jpeglzma等)庫,導致的找不到相關函式的定義。

執行configure指令碼的時候,新增--with-proj-extra-lib-for-test="-ltiff -ljpeg -llzma -lz"選項即可。

3、checking for H5Fopen in -lhdf5... no

完整報錯資訊如下:

 checking for H5Fopen in -lhdf5... no
 
 configure:33439: error: HDF5 support requested with arg /home/x/code/vcpkg/installed/x64-linux, but no hdf5 lib found
 
 configure:33395: checking for H5Fopen in -lhdf5
configure:33420: gcc -o conftest -DHAVE_AVX_AT_COMPILE_TIME -DHAVE_SSSE3_AT_COMPILE_TIME -DHAVE_SSE_AT_COMPILE_TIME -g -O2 -I/home/x/code/vcpkg/installed/x64-linux/include -s -L/home/x/code/vcpkg/installed/x64-linux/lib conftest.c -lhdf5 -lhdf5 -L/home/x/code/vcpkg/installed/x64-linux/lib -L/home/x/code/vcpkg/installed/x64-linux -L/home/x/code/vcpkg/installed/x64-linux/lib -ljpeg -lzstd -L/home/x/code/vcpkg/installed/x64-linux/lib -lproj -ltiff -ljpeg -llzma -lz -L/home/x/code/vcpkg/installed/x64-linux/lib -lsqlite3 -lpthread -lm -lrt -ldl -lpthread -ldl -lhdf5 >&5
/home/x/code/vcpkg/installed/x64-linux/lib/libhdf5.a(H5Z.c.o): In function `H5Z__init_package':
H5Z.c:(.text+0x6a1): undefined reference to `SZ_encoder_enabled'
/home/x/code/vcpkg/installed/x64-linux/lib/libhdf5.a(H5Zszip.c.o): In function `H5Z_filter_szip':
H5Zszip.c:(.text+0xe4): undefined reference to `SZ_BufftoBuffDecompress'
H5Zszip.c:(.text+0x195): undefined reference to `SZ_BufftoBuffCompress'

這些找不到的,需要連結 libszip 。於是新增 HDF5_LIBS 選項,結果還是不行。

找打 configure 檔案,找到 33401 行(大概這個位置,搜尋HDF5就是) LIBS="-lhdf5 $LIBS"(搜尋 but no hdf5 lib found 往上面一點點找),修改為 LIBS="-lhdf5 -lszip $LIBS",重新執行。

4、configure 完成,輸出 geos 等為 no

這裡是沒有識別出 geos 等庫,導致沒有引用到。這裡的原因也不好找,直接開啟configure指令碼檔案,找到對 GEOS 庫進行檢查的位置,在後面新增下面程式碼

HAVE_GEOS="yes"
HAVE_GEOS_RESULT="yes"
GEOS_LIBS="-lgeos -lgeos_c ${LIBS}"

其它的庫(如 curl 等)也可以進行同樣的操作。

LZMA		LIBLZMA_SETTING="yes"


curl		CURL_SETTING=yes
			CURL_INC=
			CURL_LIB="-lcurl $LIBS"
			
openjepg	HAVE_OPENJPEG="yes"
			OPENJPEG_LIBS="-lopenjp2 ${LIBS}"
			OPT_GDAL_FORMATS="openjpeg $OPT_GDAL_FORMATS"

3、編譯

上面正常生成 Makefile 之後,執行 make -j4 進行編譯。

1、編譯錯誤 libproj.a: error adding symbols: Bad value

這裡詳細的報錯資訊沒有記錄下來,但是不影響這裡記錄解決辦法。

GCC 提示recompile with -fPIC,需要對 libproj使用 -fPIC選項進行重新編譯。這裡我是自己編譯的libproj,直接在執行 cmake 生成 Makefile 的時候,新增-DCMAKE_C_FLAGS=-fPIC -DCMAKE_CXX_FLAGS=-fPIC 選項重新生成,重新編譯之後替換即可。

2、找不到curl_xxxGEOSxxxx等定義

部分報錯資訊如下:

/bin/sh /home/x/code/gdal/gdal/libtool --mode=link --silent g++ -s -L/home/x/code/vcpkg/installed/x64-linux/lib gdaladdo.lo  /home/x/code/gdal/gdal/libgdal.la -o gdaladdo
/home/x/code/gdal/gdal/.libs/libgdal.so: undefined reference to `curl_multi_info_read'
/home/x/code/gdal/gdal/.libs/libgdal.so: undefined reference to `GEOSOverlaps_r'
/home/x/code/gdal/gdal/.libs/libgdal.so: undefined reference to `GEOSTouches_r'
/home/x/code/gdal/gdal/.libs/libgdal.so: undefined reference to `curl_mime_name'
/home/x/code/gdal/gdal/.libs/libgdal.so: undefined reference to `GEOSPolygonize_r'
/home/x/code/gdal/gdal/.libs/libgdal.so: undefined reference to `GEOSGetCentroid_r'

這是因為沒有連結libgeos_c.alibgeos.alibcurl.a等庫的原因。

開啟 apps/GNUMakefile 檔案,在前面新增一行

CONFIG_LIBS =   -L/home/x/code/vcpkg/installed/x64-linux/lib -lgeos_c -lgeos -lcurl \
                -lssl -lcrypto -lszip -pthread

3、 undefined reference to `GDALVersionInfo'

做上面修改後,繼續執行 make ,再次報錯,部分報錯資訊如下:

/bin/sh /home/x/code/gdal/gdal/libtool --mode=link --silent g++ -s -L/home/x/code/vcpkg/installed/x64-linux/lib gdaladdo.lo  -L/home/x/code/vcpkg/installed/x64-linux/lib -lgeos_c -lgeos -lcurl -lssl -lcrypto -lszip -pthread -o gdaladdo
.libs/gdaladdo.o: In function `main':
/home/x/code/gdal/gdal/apps/gdaladdo.cpp:117: undefined reference to `GDALVersionInfo'
/home/x/code/gdal/gdal/apps/gdaladdo.cpp:126: undefined reference to `GDALAllRegister'
/home/x/code/gdal/gdal/apps/gdaladdo.cpp:128: undefined reference to `GDALGeneralCmdLineProcessor'
/home/x/code/gdal/gdal/apps/gdaladdo.cpp:139: undefined reference to `GDALTermProgress'
/home/x/code/gdal/gdal/apps/gdaladdo.cpp:195: undefined reference to `CPLRealloc'
/home/x/code/gdal/gdal/apps/gdaladdo.cpp:244: undefined reference to `CPLPushErrorHandler'

這裡是因為沒有連結 libgdal 的原因,修改上面新增的那句為

CONFIG_LIBS =   -L$(GDAL_ROOT)/.libs -lgdal -L/home/x/code/vcpkg/installed/x64-linux/lib \
                -lgeos_c -lgeos -lcurl \
                -lssl -lcrypto -lszip -pthread

4、hidden symbol `curl_multi_info_read' in ...

報錯資訊如下:

.libs/gdalinfo: hidden symbol `curl_multi_info_read' in /home/x/code/vcpkg/installed/x64-linux/lib/libcurl.a(multi.c.o) is referenced by DSO

這個問題是因為 libcurl.a 裡面的 curl_multi_info_read 是個隱藏符號(符號可見性問題),重新編譯下curl 即可。

修改 vcpkg/buildtrees/curl/src/url-7_68_0-cd669cc759/include/curl/curl.h 檔案,在 定義 CURL_EXTERN 相關程式碼的後面,加上

#undef CURL_EXTERN
#define CURL_EXTERN __attribute__ ((visibility("default"))) 

然後在 vcpkg/buildtrees/curl/x64-linux-rel 執行 vcpkg/downloads/tools/ninja-1.10.0-linux/ninja all
編譯完成後,把 當前 lib 目錄下的 libcurl.a 覆蓋 vcpkg/installed/x64-linux/lib/libcurl.a

然後重新執行 make 編譯即可。

參考: