相關參考
Asen_十足壞蛋的GDAL for Android 從編譯到讀寫shp
預先說明
- gdal 版本為2.3.1 編譯的so版本為arm-v7a
- 操作系統為在Virtual Box 6.0上安裝的ubuntu-16.04.1-desktop-amd64.iso 版本
- 本次編譯中依賴的第三方庫編譯包括proj、geos、expat、kml、json-c、sqlite
準備工作
- Virtual Box 虛擬機
- Ubuntu 16.04 LTS
- NDK R10e
- 下載地址
https://developer.android.google.cn/ndk/downloads/older_releases.html
不同的NDK版本可能編譯會有問題,主要在于stl庫
- Gdal 2.3.1
- libcurl (網絡通信庫,解決wms等文件的讀寫問題)
- geos 庫(幾何算法庫)
- expat (xml解析庫,GML、GPX文件讀取)
- KML庫
編譯環境搭建
- 安裝swig、ant、jdk
sudo apt-get install swig
sudo apt-get install ant
sudo apt-get install openjdk-8-jdk
注:
- swig的主要作用是將c++的申明文件自動生成c文件調用并且生成對應的java文件
- openjdk-8-jdk 用于java文件的編譯
- NDK 環境配置
- 將NDK下載解壓,并設置NDK_HOME的環境變量
export NDK_HOME=/home/lanmo/android-ndk-r10e
export PATH=$NDK_HOME:$PATH
- 交叉環境構建
由于NDK默認是有很多版本的構建的,如果不指定構建版本,需要做很多配置工作才可完成,構建交叉工具鏈的目的就是為了編譯各種開源庫的便利。
創建make_toolchain.sh 腳本并將一下內容復制到文件中保存,執行腳本,執行完成之后會在用戶的根目錄下生成一個android-toolchain的文件夾,內部有arm和arm64兩個文件夾
export NDK_HOME=/home/lanmo/android-ndk-r10e
platform=android-21
shmake=$NDK_HOME/build/tools/make-standalone-toolchain.sh
archs=(
'arm'
'arm64'
)
toolchains=(
'arm-linux-androideabi-4.9'
'aarch64-linux-android-4.9'
)
echo $NDK_HOME
num=${#archs[@]}
for ((i=0;i<$num;i++))
do
sh $shmake --arch=${archs[i]} --platform=$platform --install-dir=$HOME/Android/android-toolchain/${archs[i]} --toolchain=${toolchains[i]}
done
配置交叉編譯的環境變量(此處先以arm進行編譯,可自行更改為android-toolchain中的其他文件夾):
export TOOLCHAIN_HOME=/home/lanmo/Android/android-toolchain/arm
export PATH=$TOOLCHAIN_HOME/bin:$PATH
export LIBS="-lstdc++ -liconv -lgnustl_shared"
export CC=arm-linux-androideabi-gcc
export CXX=arm-linux-androideabi-g++
export CXXFLAGS="-march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16"
export CFLAGS="-march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16"
export LDFLAGS="-march=armv7-a -Wl,--fix-cortex-a8"
常用android庫編譯
大部分的android庫的編譯都可以使用以下步驟來完成(主要測試有sqlite、geos、curl、proj、expat)庫,其他的如libspatialite、freexl 由于沒有對android的交叉編譯環境設置,配置會出錯
- 1、進入源碼目錄,執行configure
LIBS="-lsupc++ -lstdc++" ./configure --host=arm-linux-androideabi --enable-shared=yes
- 執行make
make
- 執行make install
sudo make install
注:直接執行會報以下錯誤
很多人遇到這個錯誤的時候會將配置改成以下方式
--prefix=某個目錄
LIBS="-lsupc++ -lstdc++" ./configure --host=arm-linux-androideabi --enable-shared=yes
但是使用此方法的缺點非常明顯,GDAL庫不能識別這些庫的目錄,在gdal的configure 中需要一個個去指定路徑,如--with-geos=/home/lanmo/Android/lib/geos/lib/pkg-config/geos-config
這種方法也不是特別靠譜,不是所有的路徑都可以正確的識別到。因此此方法行不通。
sudo make install
出現錯誤的原因是root是系統的環境,而交叉編譯使用的是用戶的環境,我們要安裝的路徑應該是用戶的路徑,所以會導致識別不了用戶的環境變量導致安裝出錯。
//正確的解決辦法
$ sudo passwd
Password: <--- 輸入安裝時那個用戶的密碼
Enter new UNIX password: <--- 新的Root用戶密碼
Retype new UNIX password: <--- 重復新的Root用戶密碼
passwd:已成功更新密碼
這樣就可以通過su切換成功了之后直接調用make install
即可,安裝后的路徑為
注:
通過該方法一次編譯成功的有proj、geos、expat、json-c、sqlite
對于kml需要指定curl的頭文件和lib的路徑
LIBS="-lsupc++ -lstdc++" ./configure --host=arm-linux-androideabi --enable-shared=yes --with-expat-include-dir=/home/lanmo/Android/lib/expat/include --with-expat-lib-dir=/home/lanmo/Android/lib/expat/lib --prefix=/home/lanmo/Android/lib/kml
gdal so編譯
- 進入gdal的解壓路徑,執行 configure命令
CFLAGS="-mthumb" CXXFLAGS="-mthumb" LIBS="-lsupc++ -lstdc++" ./configure --host=arm-linux-androideabi --prefix=/home/lanmo/Android/lib/gdal --with-threads --with-ogr --with-geos --with-libz=internal --with-curl --with-sqlite3 --with-static-proj4 --with-expat --with-libkml
執行 configure命令之后可以看到:
其中sqlite,expat、kml、proj都是已經編輯進去了。
- 進行編譯并安裝,安裝的路徑在上面的--prefix=后面配置
make
make install
- 生成java文件和需要的c、c++文件
cd swig
make ANDROID=yes
cd java
make ANDROID=yes
在編譯java中的命令時,會出現如下錯誤:
imageimage
處理方法:刪掉報錯類中報錯的地方,重新make ANDROID=yes。
編譯Android能直接鏈接的so文件(使用NDK鏈接的方式供JAVA調用)
mkdir jni
cd /home/lanmo/gdal_2.3.1/jni
# copy library bin and wrappers:
cp /home/lanmo/Android/lib/gdal/lib/libgdal.so ./
#copy wrappers
cp /home/lanmo/gdal-2.3.1/swig/java/*_wrap.cpp ./
cp /home/lanmo/gdal-2.3.1/swig/java/gdalconst_wrap.c ./
# copy headers
cp -r /home/lanmo/gdal-2.3.1/swig/java/org ../jniwrap/
cp /home/lanmo/gdal-2.3.1/swig/java/gdal.jar ../jniwrap/
注:此步驟根據實際情況修改
- 創建Android.mk文件,并寫入下面的內容
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := gdalalljni
LOCAL_SRC_FILES := gdal_wrap.cpp gdalconst_wrap.c ogr_wrap.cpp osr_wrap.cpp
LOCAL_C_INCLUDES := /home/lanmo/Android/lib/gdal/include /home/lanmo/Android/lib/proj/include
#LOCAL_SHARED_LIBRARIES LOCAL_LDLIBS
LOCAL_LDLIBS := -L$(LOCAL_PATH) -lgdal
include $(BUILD_SHARED_LIBRARY)
- 創建Application.mk文件,并寫入下面的內容
APP_STL := gnustl_static
APP_CFLAGS := Android.mk
APP_ABI := armeabi-v7a
APP_PLATFORM := android-21
-
編譯成功
image.png