编译用于Android的busybox
使用arm-eabi-gcc编译busybox,设置-I${NDK_USR}/include -L${NDK_USR}/lib,源文件中出现许多subscripted value is neither array nor pointer nor vector语法error,通不过;换arm-linux-androideabi-gcc设置好-I –L后编译,最后链接阶段报打不开或找不到crtbegin_static.o和crtend_android.o错误,但是这两个目标文件在lib中存在。
试图解决此问题,并回答或解释:
crtbegin_static.o和crtend_android.o是否可以通过给ld选项予以解决?
arm-eabi-gcc和arm-linux-androideabi-gcc(jni native used)在EABI标准上的差异?
Toolchain本身生成时(--with-sysroot)选项的差异和用途区别?
编译jni native code和non-jni native code的步骤;
按照后面的文档所述,编译busybox是使用eabi还是androideabi好呢?
Lib.a for busybox是个什么东西?
Busybox自己带crt.o或startup code?
解决途径:
1. We recommend developers to make themselves familiar with JNI concepts. Alsonote thatthe NDK is *not* a good way towrite non-JNI native code for theAndroid platform. ---- extracted from ndk/README.txt
1. Search arm-eabi- & arm-linux-androideabi- PREFIX & --with-sysroot & SYSROOT in Android Makefiles.
2. Read GCC manual – for some options
参考后面资料后继续编译:
在menuconfig中设置使用arm-linux-androideabi-toolchain,设置sysroot为jellybeantop/prebuilts/ndk/android-ndk-r7/platforms/android-14/arch-arm/(注意是usr目录的上级目录),其中为usr/include和usr/lib),此时不再需要-I和-L选项。则去除某些找不到链接项的feature后,可以编译成功,大小为800k左右。
针对编译过程中的语法错误,可以通过查看命令文件名去掉对应目录和名称的feature;针对链接过程中无法解析的符号,主要是libbb中的,可以通过sourceinsight查看源文件搜索出引用的命令,去掉该feature。
将编译出来的busybox可执行文件,adb push到手机/system/bbdir/目录,测试
./busybox --help可用;
使用命令/system/bbdir/busybox –install –s.安装(注意命令中的当前目录),测试ls –al可用,还有彩色高亮显示。测试其余命令,可用。
编译完成后浏览源文件目录,发现lib.a被拷贝到每个源码目录下。
Makefile文件中有nostadlib选项:
LD = $(CC)-nostdlib
Makefile.flags文件中有--sysroot设置和SYSROOT环境变量输出:
ifneq ($(subst "",,$(CONFIG_SYSROOT)),)
CFLAGS += --sysroot=$(CONFIG_SYSROOT)
export SYSROOT=$(CONFIG_SYSROOT)
endif
一些问题的解释:
为什么使用arm-eabi-toolchain会频繁报subscripted value is neither array nor pointer nor vector,下面这段busybox/Makefile中的注释也许能回答.
## TODO:
## gcc version 4.4.0 20090506 (Red Hat 4.4.0-4) (GCC) is a PITA:
## const char *ptr; ... off_t v = *(off_t*)ptr; -> BOOM
## and no easy way to convince it to shut the hell up.
## We have a lot of such things all over the place.
## Classic *(off_t*)(void*)ptr does not work,
## and I am unwilling to do crazy gcc specific ({ void *ppp = ...; })
## stuff in macros. This would obfuscate the code too much.
## Maybe try __attribute__((__may_alias__))?
#CFLAGS += $(call cc-ifversion, -eq, 0404, -fno-strict-aliasing)
链接时很多feature使用的API找不到?
这是因为bionic c库实现的限制: The NDK only provides system headers for a very limited set of native APIs and libraries supported by the Android platform.
-nostdlib和--with-sysroot的作用?
-nostdlib包含-nostartupfiles和-nodefaultlibs两个选项;前者是_start标号所在,可能是crt.o?后者是通常是libgcc(注意这里所说的缺省库标准库不是有些人以讹传讹的C标准库),是实现_init, _fini, __main, _atexit _initarray _finiarray等等这些的编译器标准库.
而-sysroot才是指定target系统标准头文件和库文件目录的选项.
Busybox本身有定制的startup code,且不去使用编译器标准库,故加-nostdlib链接选项. Busybox/Makefile中有$(busybox-init), $(busybox-main)和链接布局描述;而-sysroot选项主要是指定bionic c头文件和库目录上级rootdir[/usr].
--with-sysroot选项的作用
传给GCC的--with-sysroot选项,--sysroot