NDK編譯SNMP
目前開發mstar的廠測都是基於recovery的檔案系統來做的,自然所有的庫和檔案都依賴於android的原始檔。
根據專案需求不同,有的專案需要控制或者說是與網路接入裝置通訊。以其中wifi-ap裝置最為典型,我們需要藉助網路管理工具snmp來實現對wifi-ap產品的控制。但是snmp作為一個開源產品,有其自己的編譯邏輯和依賴語言,比如開源產品大多數依賴於gnu-c,而目前android使用的bonic-c,開源產品的編譯規則複雜,在沒有完全弄清楚之前,移植到android的工程量巨大。
根據目前的情況,snmp有native層的開源庫,也有java層的開源庫。但是很不幸,我們的廠測是基於recovery的檔案系統的,自然就是native層的。
問題來了,我怎麼快速的編譯出可以reocvery環境下可以使用的snmp管理工具?
最快的做法是NDK編譯。其實所謂的NDK,也就是使用android的編譯工具鏈,引用Android的庫檔案。
1.準備NDK編譯環境
參考官網文件。下載最新的NDK包,在本次中我使用的是最新的android-ndk-r16b-linux-x86_64.zip。
下載完成,使用unzip解壓。unzip android-ndk-r16b-linux-x86_64.zip,得到android-ndk-r16b目錄。
生成獨立編譯工具包。
進入到android-ndk-r16b/build/tools/,執行如下命令:
./make-standalone-toolchain.sh --platform=android-21 --install-dir=/home/soft7team/sikeyan/ndk/crosstools/ --force
至於對應的引數,可以使用./make-standalone-toolchain.sh --help察看對應的引數。
截至目前,我們的獨立編譯工具包已經生成。
2.在環境變數中引入我們所形成的工具和對應的標頭檔案
export NDKROOT="/home/soft7team/sikeyan/ndk/crosstools"
export PATH=$NDKROOT:$PATH
export SYSROOT=$NDKROOT/sysroot/
export CC="$NDKROOT/bin/arm-linux-androideabi-gcc --sysroot=$SYSROOT"
3.下載最新穩定版的snmp包,net-snmp-5.7.3.tar.gz,並解壓,得到net-snmp-5.7.3。
4.進入到net-snmp-5.7.3,按照開源專案的做法,,先執行configure,生成對應的config.h檔案,然後執行make,make install
以上是大致情況。
為了方便編譯和設定,做了以下指令碼:
#! /bash/sh
export NDKROOT="/home/soft7team/sikeyan/ndk/crosstools"
export PATH=$NDKROOT:$PATH
export SYSROOT=$NDKROOT/sysroot/
export CC="$NDKROOT/bin/arm-linux-androideabi-gcc --sysroot=$SYSROOT"
export AR="/home/soft7team/sikeyan/ndk/arm-linux-androideabi/bin/arm-linux-androideabi-ar"
./configure \
--host=arm \
--prefix=/home/soft7team/sikeyan/ndk/install_dir \
--disable-FEATURE \
--disable-silent-libtool \
--disable-snmpv1 \
--disable-snmpv3 \
--enable-as-needed \
--disable-manuals \
--disable-agent \
--disable-manuals \
--disable-mibs \
--disable-mib-loading \
--disable-scripts \
--disable-mibs \
--disable-mib-loading \
--disable-des \
--disable-privacy \
--disable-md5 \
--disable-developer \
--disable-local-smux \
--disable-debugging \
--disable-snmptrapd-subagent \
--disable-mfd-rewrites \
--disable-embedded-perl \
--disable-fast-install \
--disable-libtool-lock \
--disable-perl-cc-checks \
--disable-shared \
--disable-ipv6 \
--disable-ucd-snmp-compatibility \
--disable-deprecated \
--disable-minimalist \
--disable-testing-code \
--with-endianness=little \
--without-PACKAGE \
--with-endianness=little \
--with-cflags="-s -O2 -D __ANDROID_API__=21 " \
--without-opaque-special-types \
--without-kmem-usage \
--with-persistent-directory="/var/net-snmp" \
--with-copy-persistent-files="no" \
--with-default-snmp-version="2" \
--with-transports="UDP" \
--with-out-transports="UDPIPv6 TCPIPv6 TCP Unix Callback AAL5PVC IPX" \
--with-out-mib-modules="snmpv3mibs ucd_snmp agent_mibs agentx notification target utilities disman/event disman/schedule host mibII/tcpTable mibII/route_write mibII/sysORTable mibII/vacm_vars"
僅供參考。
通過以上方式,基本編譯出我們需要的那些snmpget,snmpset,但是有一些基本編譯錯誤,無法避免。
這幾個錯誤,乍一看,好傢伙,是不是哪裡定義錯誤了,然而不是,是android的bonic本身不支援。
看看這個問題,對於這個問題,只有我們定義
-D__ANDROID_API__=__ANDROID_API_FUTURE__(1000)的時候才可以支援關於net的這些函式。
察看了目前android系統的bonic的原始碼,net的這些函式也是支援的,但是為什麼ndk裡面沒有就不知道原因了。
對了,關於signal那些函式,可以在config.h中開啟或者關閉對應的開關,使用別的函式。
具體的做法參考以下原始碼。
當然,有興趣的人也可以嘗試使用__ANDROID_API_FUTURE__(1000)形成度應的NDK,或者把自己的編譯的系統形成NDK。