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。