2010年4月28日 星期三

Android 編譯 Native C module

Android編譯環境本身比較複雜,不像普通的編譯環境:
只有頂層目錄下才有Makefile文件,而其他的每個component都使用統一標準的Android.mk。Android.mk文件本身是比較簡單的,不過它並不是我們熟悉的Makefile,而是經過了Android自身build system的很多處理,因此要真正釐清其中的聯繫還蠻複雜的,不過這種方式的好處在於,編寫一個新的Android.mk來給Android增加一個新的Component會比較簡單。

編譯Java程式可以直接採用Eclipse的IDE來完成,這裡就不重複了。
我們主要針對C/C++來說明,下面通過一個小例子來說明,
如何在Android 中增加一個C程式的Hello World:

1. 在$(YOUR_ANDROID)/external 目錄下創建hello目錄,
其中$(YOUR_ANDROID)指的是Android source code所在的目錄。
# mkdir $(YOUR_ANDROID)/external/hello

2. 在$(YOUR_ANDROID)/external/hello/目錄中編寫hello.c文件,
hello.c的內容當然就是經典的HelloWorld程式:

#include stdio.h

int main()
{
printf("Hello World!\n");

return 0;
}



3. 在$(YOUR_ANDROID)/external/hello/目錄編寫Android.mk文件。
這是Android Makefile的標準命名,不要更改。
Android.mk文件的格式和內容可以參考其他已有的Android.mk文件的寫法,
針對helloworld程式的Android.mk文件內容如下:

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)

LOCAL_SRC_FILES:= \

hello.c

LOCAL_MODULE := helloworld

include $(BUILD_EXECUTABLE)


注意上面LOCAL_SRC_FILES用來指定 source file;
LOCAL_MODULE指定要編譯的module的名字,下一步驟編譯時就要用到;
include $(BUILD_EXECUTABLE)表示要編譯成一個可執行文件,
如果想編譯成動態庫則可用 BUILD_SHARED_LIBRARY,
這些可以在 $(YOUR_ANDROID)/build/core/config.mk 查到。

4. 回到Android source code頂層目錄進行編譯:

# cd $(YOUR_ANDROID) && make helloworld

注意make helloworld中的目標名helloworld就是上面Android.mk文件中
由LOCAL_MODULE指定的module名。編譯結果如下:

target thumb C: helloworld <= development/hello/hello.c target Executable: helloworld (out/target/product/generic/obj/EXECUTABLES/helloworld_intermediates/LINKED/helloworld) target Non-prelinked: helloworld (out/target/product/generic/symbols/system/bin/helloworld) target Strip: helloworld (out/target/product/generic/obj/EXECUTABLES/helloworld_intermediates/helloworld) Install: out/target/product/generic/system/bin/helloworld



5.如上面的編譯結果所示,編譯後的可執行文件存放在
out/target/product/generic/system/bin/helloworld
,通過”adb push”將它傳送到模擬器上,
再通過”adb shell”登錄到模擬器終端,就可以執行了


[Reference]
http://www.j2medev.com/android/ShowArticle.asp?ArticleID=5436

沒有留言:

張貼留言