在编译并使用基于android的htop-2.0.2过程中(引用一),发现查看进程使用文件句柄(快捷键'l',实际调用命令lsof)信息一直为空白,经研究发现原来android的lsof其实是包含在toolbox中的子功能,其功能很单一不支持命令行参数,现单独编译源代码生成程序供htop调用。
一、编译方式
1、在android框架中编译
在github上有项目(引用二),是基于4.86在lollipop下的工程,不做过多解释
2、使用ndk(r10e、api21)进行编译
(1) 先下载源代码(引用三),目前的最新版是4.89
(2) 配置编译脚本
export PATH=/home/test/android-ndk-r10e/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin:$PATH
SYSROOT=/home/test/android-ndk-r10e/platforms/android-21/arch-arm/
export LSOF_CC="arm-linux-androideabi-gcc --sysroot=$SYSROOT"
export LSOF_HOST=arm-linux-androideabi
export LSOF_CFGF='-O -DHAS_STRFTIME -DHASNORPC_H -DGLIBCV'
./Configure -n linux
make
更多配置参数可查阅00XCONFIG文件中说明。
(3) 修改编译错误
a) lsof.h:229:12: error: conflicting types for '__errno'
找到lsof.h的229行,屏蔽"extern int errno;"
b) misc.o:misc.c:function safestrprt: error: undefined reference to 'mblen'
找到machine.h的458行,屏蔽"#define HASWIDECHAR 1"
(4) 修改运行错误
运行时错误"only position independent executables (PIE) are supported."
将编译脚本LSOF_CC修改为"arm-linux-androideabi-gcc --sysroot=$SYSROOT -fPIE -pie"
(5) 生成静态链接版本
lsof的配置只支持动态链接方式,但可以在按非PIE方式(跳过上面第4点)编译成功的前提下,执行如下的命令可以生成静态链接版本(引用四)。
$LSOF_CC -o lsof -static dfile.o dmnt.o dnode.o dproc.o dsock.o dstore.o arg.o main.o misc.o node.o print.o proc.o store.o usage.o util.o -L./lib -llsof
二、附htop-2.0.2和ncurses-6.0的编译脚本
1、htop
export PATH=/home/test/android-ndk-r10e/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin:$PATH
SYSROOT=/home/test/android-ndk-r10e/platforms/android-21/arch-arm/
./configure \
CC=arm-linux-androideabi-gcc \
--prefix=$PWD/system \
--bindir=$PWD/system/bin \
CFLAGS=" -I$PWD/../ncurses-6.0/system/include -I$PWD/../ncurses-6.0/system/include/ncurses --sysroot=$SYSROOT -fPIE -pie" \
LDFLAGS=" -L$PWD/../ncurses-6.0/system/lib" \
--host=arm-linux-androideabi \
--disable-unicode
make
make install
2、ncurses
export PATH=/home/test/android-ndk-r10e/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin:$PATH
SYSROOT=/home/test/android-ndk-r10e/platforms/android-21/arch-arm/
./configure \
CC=arm-linux-androideabi-gcc \
--prefix=$PWD/system \
CFLAGS=" -I../ncurses -I../progs --sysroot=$SYSROOT" \
--host=arm-linux-androideabi \
--with-shared \
make
make install
三、扩展话题
在使用ndk进行交叉编译(非ndk-build方式)的时候需要写编译脚本,这个有一定的重复工作(如ndk路径、sysroot参数、编译器配置等等)。发现有人已经把这个重复工作整合成编译工具(引用五),只需要在工程目录下运行工具脚本即可完成前期配置工作。
四、相关引用
1、http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=29570002&id=5746172
2、https://github.com/cfig/android_tools
3、http://archive.ubuntu.com/ubuntu/pool/main/l/lsof/
4、http://blog.lilydjwg.me/2014/3/8/lsof-for-android-compiled.43363.html
5、https://z3ntu.github.io/2015/12/12/Cross-compiling-native-linux-applications-for-android.html