首页 > 代码库 > Compile a native C Android application
Compile a native C Android application
原文: Compile a native C Android application
翻译: Zhiwei.Li
通过上网搜索,你可以发现很多种编译Android native应用的方法.我想说的是,不同的控制台应用, 守护程序(daemon), C/C++库,等等.这些程序在你自己的计算机上
编译没有任何问题.
为了给Android编译程序,你需要ARM工具链(toolchain). 我发现有两种主张,分别是使用Android Prebuild toolchain和CodeSourcery
1)Android Prebuild toolchain
Android没有使用传统的libc库.相反,它用了Bionic库,一个由Google开发的,用在Android移动软件平台上的轻量级的libc
Bionic被裁剪到只支持 Android系统. 请看 六百万美元的c程序库
2)CodeSourcery
CodeSourcery是ARM的合作伙伴. 专门为ARM处理器开发增强GUN工具链的,并提供验证过的GNU工具链.这些工具链有很多不同的版本.
对于Android平台,需要 arm-none-linux-gnueabi, 而 arm-none-eabi是没有glibc包含在里面的,主要面向那些编译完整的native库和应用(比如FreeRTOS)
译者注: arm-none-eabi就是用来编译裸机程序的,请参考 最简单的ARM裸机程序
我个人的观点,如果白手起家开始创建一个Android的应用程序,你应该选择Bionic.
但是如果你选择从你的PC环境移植一个库到Android,你应该选择CodeSourcery
如果你使用到线程或者C++异常,Bionic库也不能完全支持它们(实际上,它根本就不支持异常)
agcc.pl是Andrew Ross开发的一个脚本,让你以一种很简单的方法来自动包含常用的库,使用Android的ARM工具链gcc
某种程度上,他像makefile
第1种方法 使用Makefile和Android NDK
AR = arm-linux-androideabi-arAS = arm-linux-androideabi-asCC = arm-linux-androideabi-gccCXX = arm-linux-androideabi-g++LD = arm-linux-androideabi-ld.goldNDK_KIT = /home/tim/android-ndk-r10bPLATF_KIT = platforms/android-9ARM_INC = $(NDK_KIT)/$(PLATF_KIT)/arch-arm/usr/includeARM_LIB = $(NDK_KIT)/$(PLATF_KIT)/arch-arm/usr/libOBJS = hello.oEXES = hellohello : hello.o $(LD) --dynamic-linker=/system/bin/linker -nostdlib -rpath-link=$(ARM_LIB) $(ARM_LIB)/crtbegin_dynamic.o -L$(ARM_LIB) -lc -o hello hello.ohello.o: hello.c $(CC) -I $(ARM_INC) -c hello.cclean: rm -f $(OBJS) $(EXES)
源代码
#include <stdio.h>int main(int argc, char* argv[]){ printf("Hello Android\n"); return 0;}
设置环境变量 envsetup.sh
export PATH=$PATH:/home/tim/android-ndk-r10b/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/bin
最后,运行 make 就可以了
关于 -rpath-link选项,请参考 gcc链接选项
第二种简单方法,使用shell脚本
#!/bin/shOS=‘linux‘ANDROIDSDK=‘android-14‘PROGDIR=‘/home/tim/android-ndk-r10b/‘PROGDIR=`cd $PROGDIR && pwd`ARMEABIGCC=$PROGDIR/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gccARMEABILIB=$PROGDIR/platforms/$ANDROIDSDK/arch-arm/usr/libARMEABIINC=$PROGDIR/platforms/$ANDROIDSDK/arch-arm/usr/includeARMEABICRT="$ARMEABILIB/crtbegin_dynamic.o $ARMEABILIB/crtend_android.o"LINKER=/system/bin/linkerecho "GCC:"$ARMEABIGCC "LIB:"$ARMEABILIB "LINKER":$LINKER "PARAMS:"$@echo "CRT:"$ARMEABICRT$ARMEABIGCC $@ -Wl,-rpath-link=$ARMEABILIB,-dynamic-linker=$LINKER -L$ARMEABILIB $ARMEABICRT -I$ARMEABIINC -nostdlib -lc
保存为b
./b hello.c -o hello
就可以了
实际就是运行命令
/home/tim/android-ndk-r10b/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc -Wl,-rpath-link=/home/tim/android-ndk-r10b/platforms/android-16/arch-arm/usr/lib,-dynamic-linker=/system/bin/linker -L/home/tim/android-ndk-r10b/platforms/android-16/arch-arm/usr/lib /home/tim/android-ndk-r10b/platforms/android-16/arch-arm/usr/lib/crtbegin_dynamic.o /home/tim/android-ndk-r10b/platforms/android-16/arch-arm/usr/lib/crtend_android.o -I/home/tim/android-ndk-r10b/platforms/android-16/arch-arm/usr/include -nostdlib -lc hello.c -o hello
crtbegin_dynamic.o 和 crtend_android.o必须配对使用
第三种方法,用–sysroot也是可以的
#!/bin/shNDK=/home/tim/android-ndk-r8eSYSROOT=$NDK/platforms/android-9/arch-armCC="$NDK/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc --sysroot=$SYSROOT"CFLAGS=‘-march=armv7-a -mfloat-abi=softfp -mfpu=neon‘LDFLAGS=‘-Wl,--fix-cortex-a8‘$CC $@
http://www.srombauts.fr/2011/03/06/standalone-toolchain/
#include <stdio.h>#include <android/log.h>#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "hello-ndk", __VA_ARGS__))int main(void){ printf("Hello from NDKn"); LOGI("Hello from NDK"); return 0;}
果然厉害,上面这段代码都可以这样编译
./b9 -l log nl.c -o hn
用Makefile也能搞
CC = arm-linux-androideabi-gccCFLAGS = -Wall -gLDFLAGS = -llogSRC =http://www.mamicode.com/hello-ndk.c>编译so库也是可以,厉害
CC = arm-linux-androideabi-gccCFLAGS = -Wall -gLDFLAGS = -llog -sharedSRC =http://www.mamicode.com/hello-ndk.c>还可以直接运行 gcc
/home/tim/android-ndk-r10/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc --sysroot=/home/tim/android-ndk-r10/platforms/android-3/arch-arm -lc -lm -g main.c -o mm第4种方法,用ndk-build
创建工程目录hello,然后在其下创建子目录jni
然后在jni下创建两个文件,一个是hello.c,另外一个是Android.mk,内容如下LOCAL_PATH:= $(call my-dir)include $(CLEAR_VARS)LOCAL_SRC_FILES:=hello.cLOCAL_MODULE := helloworldLOCAL_MODULE_TAGS := optionalinclude $(BUILD_EXECUTABLE)其中 LOCAL_MODULE_TAGS := optional 这行可以不要
进入到hello目录下,运行下面的命令
# export NDK_PROJECT_PATH=`pwd`# ndk-buildCompile thumb : helloworld <= hello.c Executable : helloworld Install : helloworld => libs/armeabi/helloworldCompile a native C Android application