2014年11月10日 星期一

[轉] android 編譯C程序 在android下可執行

Android編譯環境本身比較複雜,且不像普通的編譯環境:只有頂層目錄下才有Makefile文件,而其他的每個component都使用統一標準Android.mk. Android.mk文件本身是比較簡單的,不過它並不是我們熟悉的Makefile,而是經過了Android自身編譯系統的很多處理,因此要真正理清楚其中的聯繫還比較複雜,不過這種方式的好處在於,編寫一個新的Android.mk來給Android增加一個新的Component會比較簡單。 編譯Java程序可以直接採用Eclipse的集成環境來完成,這裡就不重複了。我們主要針對C/C++來說明,下面通過一個小例子來說明,如何在Android 中增加一個C程序的Hello World:
1. 在$(YOUR_ANDROID)/ development 目錄下創建hello目錄,其中$(YOUR_ANDROID)指Android源代碼所在的目錄。
- # mkdir $(YOUR_ANDROID)/development/hello
2. 在$(YOUR_ANDROID)/external/hello/目錄編寫hello.c文件,hello.c的內容當然就是經典的HelloWorld程序:
#include <stdio.h>
int main(int argc, char **argv)
{
    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_MODULE_TAGS := optional
LOCAL_SRC_FILES:= \
    hello.c
LOCAL_MODULE := helloworld
include $(BUILD_EXECUTABLE)

 Android.mk的例外一種寫法也可以
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

LOCAL_STATIC_LIBRARIES := libcutils libc
LOCAL_MODULE := helloworld
LOCAL_MODULE_TAGS := eng

LOCAL_FORCE_STATIC_EXECUTABLE := true
LOCAL_SRC_FILES:= \
        hello.c

LOCAL_C_INCLUDES := bionic/libc/bionic

ifeq ($(HAVE_SELINUX),true)
LOCAL_CFLAGS += -DHAVE_SELINUX
LOCAL_SHARED_LIBRARIES += libselinux
LOCAL_C_INCLUDES += external/libselinux/include
endif

include $(BUILD_EXECUTABLE)


注意上面LOCAL_SRC_FILES用來指定源文件;,LOCAL_MODULE指定要編譯的模塊的名字,下一步驟編譯時就要用到;include $(BUILD_EXECUTABLE)表示要編譯成一個可執行文件,如果想編譯成動態庫則可用BUILD_SHARED_LIBRARY,這些可以在$(YOUR_ANDROID)/build/core/config.mk查到。
4. 回到Android源代碼頂層目錄進行編譯:
# cd $(YOUR_ANDROID) && make helloworld
注意make helloworld中的目標名helloworld就是上面Android.mk文件中由LOCAL_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目錄
啟動Android模擬器,用如下命令將文件push到Android模擬器上:
    注意:  要把SDK目錄裡的tools目錄放到PATH環境變量中.
adb shell mkdir /dev/sample
adb push hello /dev/sample/hello
adb shell chmod 777 /dev/sample/hello
先創建 /dev/sample目錄,再將編譯好的hello上傳上去,最後將hello改成可執行的。
再進入命令行模式,進入Android的shell環境:
adb shell
#cd /dev/sample
#./hello

沒有留言:

張貼留言