Compile a native C Android application

http://www.cnblogs.com/GoAhead/p/4186707.htmlhtml

經過上網搜索,你能夠發現不少種編譯Android native應用的方法.我想說的是,不一樣的控制檯應用, 守護程序(daemon), C/C++庫,等等.這些程序在你本身的計算機上
編譯沒有任何問題.linux

爲了給Android編譯程序,你須要ARM工具鏈(toolchain). 我發現有兩種主張,分別是使用Android Prebuild toolchain和CodeSourcery
1)Android Prebuild toolchain
Android沒有使用傳統的libc庫.相反,它用了Bionic庫,一個由Google開發的,用在Android移動軟件平臺上的輕量級的libc
Bionic被裁剪到只支持 Android系統.  請看 六百萬美圓的c程序庫android

2)CodeSourcery
CodeSourcery是ARM的合做夥伴. 專門爲ARM處理器開發加強GUN工具鏈的,並提供驗證過的GNU工具鏈.這些工具鏈有不少不一樣的版本.
對於Android平臺,須要 arm-none-linux-gnueabi, 而 arm-none-eabi是沒有glibc包含在裏面的,主要面向那些編譯完整的native庫和應用(好比FreeRTOS)
譯者注: arm-none-eabi就是用來編譯裸機程序的,請參考 最簡單的ARM裸機程序shell

我我的的觀點,若是白手起家開始建立一個Android的應用程序,你應該選擇Bionic.
可是若是你選擇從你的PC環境移植一個庫到Android,你應該選擇CodeSourcery
若是你使用到線程或者C++異常,Bionic庫也不能徹底支持它們(實際上,它根本就不支持異常)ionic

agcc.pl是Andrew Ross開發的一個腳本,讓你以一種很簡單的方法來自動包含經常使用的庫,使用Android的ARM工具鏈gcc
某種程度上,他像makefileide

第1種方法  使用Makefile和Android NDK工具

AR = arm-linux-androideabi-ar
AS = arm-linux-androideabi-as
CC = arm-linux-androideabi-gcc
CXX = arm-linux-androideabi-g++
LD = arm-linux-androideabi-ld.gold

NDK_KIT = /home/tim/android-ndk-r10b
PLATF_KIT = platforms/android-9

ARM_INC = $(NDK_KIT)/$(PLATF_KIT)/arch-arm/usr/include
ARM_LIB = $(NDK_KIT)/$(PLATF_KIT)/arch-arm/usr/lib

OBJS = hello.o
EXES = hello

hello :  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.o

hello.o: hello.c
	$(CC) -I $(ARM_INC) -c hello.c

clean:
	rm -f $(OBJS) $(EXES)

源代碼ui

#include <stdio.h>

int main(int argc, char* argv[])
{
  printf("Hello Android\n");
  return 0;
}

設置環境變量 envsetup.shidea

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/sh

OS='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-gcc
ARMEABILIB=$PROGDIR/platforms/$ANDROIDSDK/arch-arm/usr/lib
ARMEABIINC=$PROGDIR/platforms/$ANDROIDSDK/arch-arm/usr/include
ARMEABICRT="$ARMEABILIB/crtbegin_dynamic.o $ARMEABILIB/crtend_android.o"

LINKER=/system/bin/linker

echo "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/sh

NDK=/home/tim/android-ndk-r8e
SYSROOT=$NDK/platforms/android-9/arch-arm
CC="$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-gcc
CFLAGS  = -Wall -g
LDFLAGS = -llog
SRC =hello-ndk.c
OBJ =$(SRC:.c=.o)
EXE =hello-ndk

all: $(SRC) $(EXE)

$(EXE): $(OBJ)
    $(CC) -o $@ $^ $(LDFLAGS)

%.o: %.c
    $(CC) -o $@ -c $< $(CFLAGS)

clean:
    rm -f *.o $(EXE)

編譯so庫也是能夠,厲害

CC  = arm-linux-androideabi-gcc
CFLAGS  = -Wall -g
LDFLAGS = -llog -shared
SRC =hello-ndk.c
OBJ =$(SRC:.c=.o)
EXE =libhello-ndk.so

還能夠直接運行 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.c
LOCAL_MODULE := helloworld
LOCAL_MODULE_TAGS := optional
include $(BUILD_EXECUTABLE)

其中 LOCAL_MODULE_TAGS := optional  這行能夠不要

進入到hello目錄下,運行下面的命令

# export NDK_PROJECT_PATH=`pwd`
# ndk-build
Compile thumb  : helloworld <= hello.c Executable     : helloworld Install        : helloworld => libs/armeabi/helloworld
相關文章
相關標籤/搜索