Android.mk規範詳解
本文轉自:http://blog.ednchina.com/laizibin315/1895365/message.aspx
Android.mk檔案是在使用NDK編譯C代碼時必須的檔案,Android.mk檔案中描述了哪些C檔案將被編譯且指明了如何編譯。掌握Android.mk檔案的編寫主要是掌握其裡頭將要使用的一些關鍵字,先來看一個簡單的例子,這個例子在NDK包的D:/android-ndk-r3/apps/hello-jni/project/jni目錄下:
Android.mk中的內容如下:
---------------------------------------------------------
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := hello-jni
LOCAL_SRC_FILES := hello-jni.c
include $(BUILD_SHARED_LIBRARY)
-----------------------------------------------------------
LOCAL_PATH 是描述所有要編譯的C檔案所在的根目錄,這邊的賦值為$(call my-dir),代表根目錄即為Android.mk所在的目錄。
include $(CLEAR_VARS) 代表在使用NDK編譯工具時對編譯環境中所用到的全域變數清零,如LOCAL_MODULE,LOCAL_SRC_FILES等,因為在一次NDK編譯過程中可能會多次調用Android.mk檔案,中間用到的全域變數可能是變化的。關於這個問題看了下面比較複雜的例子可能就明白了。
LOCAL_MODULE 是最後產生庫時的名字的一部分,給其加上首碼lib和尾碼.so就是產生的共用庫的名字libhello-jni.so。
LOCAL_SRC_FILES 指明要被編譯的c檔案的檔案名稱
include $(BUILD_SHARED_LIBRARY) 指明NDK編譯時間將產生一些共用庫
這個Android.mk設定對應的jni檔案夾下的內容為如:
其hello-jni.c中的代碼如下:
#include <string.h>
#include <jni.h>
/* This is a trivial JNI example where we use a native method
* to return a new VM String. See the corresponding Java source
* file located at:
*
* apps/samples/hello-jni/project/src/com/example/HelloJni/HelloJni.java
*/
jstring
Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,
jobject thiz )
{
return (*env)->NewStringUTF(env, "Hello from JNI !");
}
關於如何使用NDK進行編譯,可以查看我的部落格“NDK底層開發環境的搭建”
關於hello-jni.c中的代碼如何編寫,可以查看附件中的“JNI詳解.pdf”檔案。
我們再來看一個複雜點的例子,下面這個例子中在使用NDK編譯的過程中將會先產生一個靜態庫:libsum-jni.a,這個靜態庫將被進一步編譯中調用一起產生共用庫:libhello-jni.so
-----------------------------------------------------------------------------
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := sum-jni
LOCAL_SRC_FILES := sum-jni.c
include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := hello-jni
LOCAL_SRC_FILES := hello-jni.c
LOCAL_STATIC_LIBRARIES := sum-jni
include $(BUILD_SHARED_LIBRARY)
-------------------------------------------------------------------------------------
這個Android.mk檔案中我們可以看到include $(CLEAR_VARS)被使用了兩次,這使得NDK編譯過程中前後使用到的全域變數的值不會互相影響。
include $(BUILD_STATIC_LIBRARY) 指明將sum-jni.c檔案編譯成靜態庫
libsum-jni.a
LOCAL_STATIC_LIBRARIES := sum-jni 指明在第二部編譯過程中調用第一步編譯過程中產生的靜態庫libsum-jni.a,並結合hello-jni.c檔案編譯成共用庫libhello-jni.so
這個Android.mk設定對應的jni檔案夾下的內容為如:
hello-jni.c中的代碼:
#include "sum-jni.h"
#include <string.h>
#include <jni.h>
/* This is a trivial JNI example where we use a native method
* to return a new VM String. See the corresponding Java source
* file located at:
*
* apps/samples/hello-jni/project/src/com/example/HelloJni/HelloJni.java
*/
jstring
Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,
jobject this )
{
return (*env)->NewStringUTF(env, "My name is Zibin Lai.");
}
jint
Java_com_example_hellojni_HelloJni_Jsum(JNIEnv* env, jobject this,jint a,jint b)
{
return sum(a,b);
}
sum-jni.c的代碼:
int sum(int a,int b)
{
return a+b;
}
最後看一個例子是多個C檔案編譯的Android.mk設定:
--------------------------------------------------------------------------------
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := sum-jni
LOCAL_SRC_FILES := sum-jni.c
include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := hello-jni
LOCAL_SRC_FILES := hello-jni.c /
compare-jni.c /
sort/sort.c /
LOCAL_STATIC_LIBRARIES := sum-jni
include $(BUILD_SHARED_LIBRARY)
-----------------------------------------------------------------------------------
我們可以看到第二個LOCAL_SRC_FILES的參數賦值比以上的多了一些檔案的名字,且在這個賦值過程還可以帶上路徑。
這個Android.mk設定對應的jni檔案夾下的內容為如: