1、准備工作
-
1、安裝
gcc
、vcpkg
等。 -
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
使用vcpkg
編譯出來的都是靜態庫,如果機器上默認的庫目錄已經有了對應的版本,下面指定鏈接庫的時候就不要使用 -Lxxxx -lyyy
的方式,而應該直接使用/xx/vcpkg/installed/x64-linux/lib/libxxxx.a
庫完整路徑的方式,否則可能鏈接的不是你想要的那一個。
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
的時候沒有鏈接 pthread
和dl
庫(找不到 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
(以及jpeg
、lzma
等)庫,導致的找不到相關函數的定義。
執行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"
這里有可能編譯的gdal鏈接是系統庫目錄下 libcurl.so 而不是 vcpkg 安裝的 libcurl.a
可以直接打開 GDALmake.opt 文件,將里面對應的位置 $(CURL_LIB) 修改為
/home/x/code/vcpkg/installed/x64-linux/lib/libcurl.a
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_xxx
、GEOSxxxx
等定義
部分報錯信息如下:
/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.a
、libgeos.a
、libcurl.a
等庫的原因。
打開 apps/GNUMakefile
文件,在前面添加一行
CONFIG_LIBS = -L/home/x/code/vcpkg/installed/x64-linux/lib -lgeos_c -lgeos -lcurl \
-lssl -lcrypto -lszip -pthread
這里也可以通過修改GDALmake.opt
文件來達到目的,我修改過的 LIBS
變量如下:、
LIBS = $(SDE_LIB) -lcrypto -L/home/x/code/vcpkg/installed/x64-linux/lib -lwebp \
-L/home/x/code/vcpkg/installed/x64-linux/lib -lhdf5 -lopenjp2 \
-lzstd -L/home/x/code/vcpkg/installed/x64-linux/lib \
-lproj -ltiff -ljpeg -llzma -lz \
/home/x/code/vcpkg/installed/x64-linux/lib/libgeos_c.a \
/home/x/code/vcpkg/installed/x64-linux/lib/libgeos.a \
/home/x/code/vcpkg/installed/x64-linux/lib/libcurl.a \
/home/x/code/vcpkg/installed/x64-linux/lib/libssl.a \
/home/x/code/vcpkg/installed/x64-linux/lib/libcrypto.a \
/home/x/code/vcpkg/installed/x64-linux/lib/libszip.a \
/home/x/code/vcpkg/installed/x64-linux/lib/libsqlite3.a \
$(KAK_LIBS) $(DWG_LIBS) \
$(MRSID_LIBS) $(MRSID_LIDAR_LIBS) $(ECW_LIBS) $(INGRES_LIB) \
$(PCIDSK_LIB) $(RASDAMAN_LIB) $(SOSI_LIB) \
$(OPENCL_LIB) $(JVM_LIB) $(LIBICONV) $(FGDB_LIB) $(LIBXML2_LIB) \
$(MONGODB_LIB) $(MONGOCXXV3_LIBS) $(JNI_LIB) $(HDFS_LIB) \
-lpthread -lm -lrt -ldl -lpthread -ldl
部分指定了完整路徑的庫,是因為本地系統路徑下有對應的.so
,所以導致默認先去鏈接了.so
文件,導致編譯出來的libgdal.so
會有一些符號是為包含在其中的(需要從相關庫導入),所以直接指定靜態庫完整路徑,將這些符號的定義都鏈接到輸出的 libgdal.so
里面去。
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
編譯即可。
參考:
-
(attribute((visibility("visibility_type"))) variable attribute)[http://www.keil.com/support/man/docs/armcc/armcc_chr1359124983511.htm]