1. 程式人生 > >android.mk語法詳解

android.mk語法詳解

(一)概要

在android系統原始碼中,還是需要在系統環境下編譯的應用程式,都可以見到android.mk的檔案,該檔案就是編譯原始碼所需要的編譯檔案。

下面就來分析下android.mk檔案

該檔案其實是GNU Makefile的一小部分,它用來對Android程式進行編譯Android.mk把原始碼組織成不同的模組,每個模組可以是一個靜態庫也可以是一個動態庫。動態庫才會被拷貝到安裝包中,靜態庫只能用於編譯生成動態庫。同一個Android.mk檔案可以定義多個模組,不同的模組可以共用同一個Android.mk檔案。

一個Android.mk檔案可以編譯多個模組,每個模組屬下列型別之一
  1)APK程式   一般的Android程式,編譯打包生成apk檔案   2)JAVA庫   java類庫,編譯打包生成jar檔案   3)C\C++應用程式  可執行的C\C++應用程式   4)C\C++靜態庫  編譯生成C\C++靜態庫,並打包成.a檔案   5)C\C++共享庫 編譯生成共享庫(動態連結庫),並打包成.so文, 有且只有共享庫才能被安裝/複製到您的應用軟體(APK)包中。 編譯打包的5中方式:
(1)APK程式
  一般的Android程式,編譯打包生成apk檔案
(out/target/product/generic/obj/APPS/XXX_intermediates)
(2)JAVA庫
  java類庫,編譯打包生成jar檔案
(out/target/product/generic/obj/JAVA_LIBRARIES/XXX_intermediates)
(3)C\C++應用程式
 可執行的C\C++應用程式
(out/target/product/generic/obj/EXECUTABLE/XXX_intermediates)
(4)C\C++靜態庫 
編譯生成C\C++靜態庫,並打包成.a檔案
(out/target/product/generic/obj/STATIC_LIBRARY/XXX_static_intermediates)
 (5)C\C++共享庫
編譯生成共享庫(動態連結庫),並打包成.so文, 有且只有共享庫才能被安裝/複製到您的應用軟體(APK)包中。
(out/target/product/generic/obj/SHARED_LIBRARY/XXX_shared_intermediates)

程式碼:
include $(BUILD_PACKAGE)
編譯打包成APK檔案

include $(BUILD_STATIC_JAVA_LIBRARY)
用它來編譯生成JAVA庫(打包成.jar檔案)

include $(BUILD_EXECUTABLE)
編譯C/C++應用程式

include $(BUILD_STATIC_LIBRARY)
用它來編譯生成C\C++靜態庫(打包成.a檔案)

include $(BUILD_SHARED_LIBRARY)
指向一個 GNU Makefile 指令碼(應該就是在 build/core目錄下的 shared_library.mk),用它來編譯生成共享庫(動態連結庫.so)

注意,NDK所使用的Android.mk檔案的語法與Android作業系統的開放原始碼中的Android.mk的語法非常接近,但是

編譯系統實現他們的方式卻是不同的,這是為了方便應用程式開發人員複用以前的程式碼。

(二)簡單示例

jni/Android.mk 檔案是這個模組的編譯指令碼,內容如下:

  1. LOCAL_PATH := $(call my-dir)  
  2. include $(CLEAR_VARS)  
  3. LOCAL_MODULE    := hello-jni  
  4. LOCAL_SRC_FILES := hello-jni.c  
  5. include $(BUILD_SHARED_LIBRARY)  
以上內容解釋如下:

    LOCAL_PATH := $(call my-dir)

每個Android.mk檔案都必須在開頭定義 LOCAL_PATH 變數。這個變數被用來尋找C/C++原始檔。在該例中,my-dir 是一個由編譯系統提供的巨集函式

,用於返回Android.mk所在目錄的路徑。

    include $(CLEAR_VARS)

CLEAR_VARS是編譯系統預定義的一個變數,它指向一個特殊的Makefile,這個Makefile負責清除 LOCAL_xxx 的變數(例如 LOCAL_MODULE, LOCAL_SRC_FILES, LOCAL_STATIC_LIBRARIES 等)但不會清除 LOCAL_PATH。之所以需要清理這些變數是因為所有的編譯控制檔案是在一趟make執行過程中完成的,而所有的變數都是全域性的,會對其他Android.mk檔案產生影響。

    LOCAL_MODULE := hello-jni

LOCAL_MODULE 用來給每個模組定義一個名字,不同模組的名字不能相同,不能有空格。這裡的名字會傳給NDK編譯系統,然後加上lib字首和.so字尾 (例如,變成libhello-jni.so)。注意,如果你在LOCAL_MODULE定義中自己加上了lib字首,則ndk在處理的時候就不會再加上lib字首了(為了相容Android系統的一些原始碼)。

    LOCAL_SRC_FILES := hello-jni.c

在LOCAL_SRC_FILES 變數裡面列舉出對應於同一個模組的、要編譯的那些檔案,這裡不要把標頭檔案加進來,編譯系統可以自動檢測標頭檔案依賴關係。預設情況下,C++原始碼檔案的副檔名應該是cpp,如果想修改的話,將變數LOCAL_CPP_EXTENSION修改為你想要的副檔名,注意句點。例如:LOCAL_CPP_EXTENSION := .cxx

    include $(BUILD_SHARED_LIBRARY)

這個 BUILD_SHARED_LIBRARY也是預定義的變數,也是指向一個Makefile,負責將你在 LOCAL_XXX 等變數中定義資訊收集起來,確定要編譯的檔案,如何編譯。如果要編譯的是靜態庫而不是動態庫,則可以用 BUILD_STATIC_LIBRARY。

(三)自定義變數

 以下是在 Android.mk中依賴或定義的變數列表, 可以定義其他變數為自己使用,但是NDK編譯系統保留下列變數名:  -以 LOCAL_開頭的名字(例如 LOCAL_MODULE)  -以 PRIVATE_, NDK_ 或 APP_開頭的名字(內部使用)  -小寫名字(內部使用,例如‘my-dir’)   如果為了方便在 Android.mk 中定義自己的變數,建議使用 MY_字首,一個小例子MY_SOURCES := foo.c ifneq ($(MY_CONFIG_BAR))  MY_SOURCES += bar.c endif LOCAL_SRC_FILES += $(MY_SOURCES) 注意:‘:=’是賦值的意思;'+='是追加的意思;‘$’表示引用某變數的值。 (四)GNU Make系統變數   這些 GNU Make變數在你的 Android.mk 檔案解析之前,就由編譯系統定義好了。 注意在某些情況下,NDK可能分析 Android.mk 幾次,每一次某些變數的定義會有不同。   (1)CLEAR_VARS:  指向一個編譯指令碼,幾乎所有未定義的 LOCAL_XXX 變數都在"Module-description"節中列出。必須在開始一個新模組之前包含這個指令碼:            include $(CLEAR_VARS),用於重置除LOCAL_PATH變數外的,所有LOCAL_XXX系列變數。   (2)BUILD_SHARED_LIBRARY:  指向編譯指令碼,根據所有的在 LOCAL_XXX 變數把列出的原始碼檔案編譯成一個共享庫。           注意,必須至少在包含這個檔案之前定義 LOCAL_MODULE 和 LOCAL_SRC_FILES。           include $(BUILD_SHARED_LIBRARY) (3) BUILD_STATIC_LIBRARY:  一個BUILD_STATIC_LIBRARY變數用於編譯一個靜態庫。靜態庫不會複製到的APK包中,但是能夠用於編譯共享庫。           示例:include $(BUILD_STATIC_LIBRARY)            注意,這將會生成一個名為 lib$(LOCAL_MODULE).a 的檔案   (4)TARGET_ARCH: 目標 CPU平臺的名字,  和 android 開放原始碼中指定的那樣。如果是arm,表示要生成 ARM 相容的指令,與 CPU架構的修訂版無關。   (5)TARGET_PLATFORM: Android.mk 解析的時候,目標 Android 平臺的名字.詳情可參考/development/ndk/docs/stable- apis.txt.           android-3 -> Official Android 1.5 system images           android-4 -> Official Android 1.6 system images           android-5 -> Official Android 2.0 system images   (6)TARGET_ARCH_ABI:  暫時只支援兩個 value,armeabi 和 armeabi-v7a。在現在的版本中一般把這兩個值簡單的定義為 arm, 通過 android  平臺內部對它重定義來獲得更好的匹配。其他的 ABI 將在以後的 NDK 版本中介紹,它們會有不同的名字。注意雖然所有基於ARM的ABI都會把 'TARGET_ARCH'定義成‘arm’, 但是會有不同的‘TARGET_ARCH_ABI’。  ( 7 ) TARGET_ABI:  目標平臺和 ABI 的組合,它事實上被定義成$(TARGET_PLATFORM)-$(TARGET_ARCH_ABI)  ,在想要在真實的裝置中針對一個特別的目標系統進行測試時,會有用。在預設的情況下,它會是'android-3-arm'。 (五)模組描述變數

下面這些變數用於對模組進行描述,這些變數應該在 include $(CLEAR_VARS) 和 include $(BUILD_XXXX) 之間定義好。

LOCAL_PATH (必須)

這個變量表示當前檔案(一般是Android.mk)所在的路徑,該變數很重要,必須定義(在Android.mk檔案的開頭處定義)。常見寫法如下:

    LOCAL_PATH := $(call my-dir)

巨集函式‘my-dir’,  由編譯系統提供, 用於返回當前路徑(即包含Android.mk file檔案的目錄)。(第7部分會詳細介紹)

該變數不會被 include $(CLEAR_VARS) 清空,所以不論Android.mk定義了幾個模組,一個Android.mk只需要在開頭定義一次即可。

include $(CLEAR_VARS)
CLEAR_VARS是一個GNU Make系統變數指向一個編譯指令碼該指令碼功能為你清除許多 LOCAL_XXX 變數 ( 例如 LOCAL_MODULE , LOCAL_SRC_FILES ,LOCAL_STATIC_LIBRARIES,等等…),除 LOCAL_PATH外。
( android 安裝目錄下的/build/core/config.mk 檔案看到其定義)

LOCAL_MODULE (必須)

該變數定義當前模組的名字,名字必須唯一,不能有空格。這個變數必須在 include $(BUILD_XXX) 之前定義好。預設情況下,這裡的名字會用來得到輸出檔案的名字。例如模組名為foo,則得到的輸出檔案為libfoo.so。但是,如果你要在其他模組的Android.mk檔案或Application.mk中引用這個模組,應該用foo這個模組名,而不要用libfoo.so這個檔名。

LOCAL_MODULE_FILENAME (可選)

該變數可以用來重定義輸出檔案的名字。預設情況下,foo模組得到的靜態庫的名字為 libfoo.a,動態庫的名字為libfoo.so(UNIX規範)。當定義了LOCAL_MODULE_FILENAME之後,輸出檔名就是這個變數指定的名字,例如:

  1. LOCAL_MODULE := foo-version-1  
  2. LOCAL_MODULE_FILENAME := libfoo  
注意: LOCAL_MODULE_FILENAME不支援檔案路徑(所以不能有斜槓),不要寫副檔名(檔案路徑和副檔名是由編譯工具自動加上的)

LOCAL_SRC_FILES (必須)

該變數用來指定該模組對應的原始檔,只把需要傳給編譯器的原始檔名加進LOCAL_SRC_FILES,編譯系統會自動處理標頭檔案依賴。這裡的檔名都是以 LOCAL_PATH 作為當前目錄的(即相對於LOCAL_PATH目錄),例如:

    LOCAL_SRC_FILES := foo.c  \       #如果要換行,用反斜槓

                                           bar.c

LOCAL_SRC_FILES := $(call all-subdir-java-files)  

LOCAL_SRC_FILES := $(call all-java-files-under, src)

LOCAL_MODULE_TAGS :=user eng tests optional  samples  shell_ash  shell_mksh

user: 指該模組只在user版本下才編譯

eng: 指該模組只在eng版本下才編譯

tests: 指該模組只在tests版本下才編譯

optional:指該模組在所有版本下都編譯

LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT)  編譯打包後,指定模組最後的目標存放路徑
TARGET_ROOT_OUT:表示根檔案系統。
TARGET_OUT:表示system檔案系統。
TARGET_OUT_DATA:表示data檔案系統。

LOCAL_CPP_EXTENSION (可選)

用來定義C++程式碼檔案的副檔名。必須以句點開頭(即 “.”),預設值是“.cpp”,可以修改,例如:

    LOCAL_CPP_EXTENSION := .cxx

從 NDK r7 這個版本開始,該變數可以支援多個副檔名了,例如:

    LOCAL_CPP_EXTENSION := .cxx .cpp .cc

LOCAL_CPP_FEATURES (可選)

該變數用來指定C++程式碼所依賴的特殊C++特性。例如,如果要告訴編譯器你的C++程式碼使用了RTTI(RunTime Type Information):

    LOCAL_CPP_FEATURES := rtti

如果要指定你的C++程式碼使用了C++異常,則:

    LOCAL_CPP_FEATURES := exceptions

該變數可以同時指定多個特性。例如:    LOCAL_CPP_FEATURES := rtti features

這個變數的作用就是在編譯模組的時候,開啟相應的編譯器/連結器標誌。對於預編譯的檔案,該變量表明該預編譯的庫依賴了這些特性,從而確保最後的連結工作正確進行。與該變數等價的做法是在LOCAL_CPPFLAGS中寫上 -frtti -fexceptions 等標誌選項。但是,推薦用這裡的方法。

LOCAL_C_INCLUDES

加入需要的標頭檔案搜尋路徑

一個路徑的列表,是NDK根目錄的相對路徑(LOCAL_SRC_FILES中的檔案相對於LOCAL_PATH)。當編譯C/C++、彙編檔案時,這些路徑將被追加到標頭檔案搜尋路徑列表中。例如:

    LOCAL_C_INCLUDES := sources/foo

    或者, LOCAL_C_INCLUDES := $(LOCAL_PATH)/../foo

這裡的搜尋路徑會放在LOCAL_CFLAGS/LOCAL_CPPFALGS等標誌的前面。 當使用ndk-gdb的時候,LOCAL_C_INCLUDES中的路徑也會被用到。

LOCAL_CFLAGS

指定當編譯C/C++原始碼的時候,傳給編譯器的標誌。它一般用來指定其他的編譯選項和巨集定義。

注意:儘量不要在Android.mk中修改優化/除錯等級,因為在Application.mk中定義了相關資訊之後編譯系統會自動處理這些問題。

LOCAL_CXXFLAGS (廢除, LOCAL_CPPFLAGS的別名)

LOCAL_CPPFLAGS (可選)

編譯C++程式碼的時候傳遞給編譯器的選項(編譯C程式碼不會用這裡的選項)。最後得到的命令列選項中,這裡指定的選項在 LOCAL_CFLAGS 指定的選項的後面。

LOCAL_STATIC_LIBRARIES

指定應該連結到當前模組的靜態庫(可指定多個)。當前模組是動態庫時,該選項才有意義。

LOCAL_SHARED_LIBRARIES

指定的是執行時該模組所依賴共享庫(可指定多個)。這些資訊是連結階段必須的。

LOCAL_WHOLE_STATIC_LIBRARIES

它是LOCAL_STATIC_LIBRARIES的變體,用來表示它對應的模組對於linker來說應該是一個“whole archive”(見GNU linker 文件,關於 --whole-archive的資料)。當靜態庫之間有迴圈依賴時,會用到這個選項。注意,當編譯動態庫時,這個選項會強行把所有的物件檔案組裝到一起;不過,在編譯可執行檔案的時候情況不是這樣的。

LOCAL_LDLIBS

用來指定模組編譯時的其餘聯結器標誌。例如:

    LOCAL_LDLIBS := -lz

告訴連結器在載入該共享庫的時候必須連結 /system/lib/libz.so 這個共享庫。

如果想知道Android系統中有哪些共享庫可以連結,參考 Stable APIs

LOCAL_ALLOW_UNDEFINED_SYMBOLS

預設情況下,當編譯一個共享庫的時候,遇到未定義符號引用就會報告一個“undefined symbol”錯誤。這有助於修復你的程式碼中存在的bug。

如果因為某種原因,必須禁止該檢測,可以把這個變數設定為true。注意,編譯出的共享庫有可能在載入的時候就報錯導致程式退出。

LOCAL_ARM_MODE

LOCAL_ARM_NEON

LOCAL_DISABLE_NO_EXECUTE

Android NDK r4增加了對“NX bit“安全特性的支援。它是預設開啟的,如果你確定自己不需要該特性,你可以將它關閉,即:

    LOCAL_DISABLE_NO_EXECUTE := true

該變數不會修改ABI,只會在 ARMv6以上的CPU的核心上啟用。開啟該特性編譯出的程式碼無需修改可執行在老的CPU上(也就是說所有ARM的CPU都能執行)。

參考資訊:

LOCAL_EXPORT_CFLAGS

    這個變數定義一些C/C++編譯器flags。這些flags(標誌)會被追加到使用了這個模組(利用LOCAL_STATIC_LIBRARIES和LOCAL_SHARED_LIBRARIES)的模組的LOCAL_CFLAGS 定義中去。

假如foo模組的宣告如下:

  1. include $(CLEAR_VARS)  
  2. LOCAL_MODULE := foo  
  3. LOCAL_SRC_FILES := foo/foo.c  
  4. LOCAL_EXPORT_CFLAGS := -DFOO=1  
  5. include $(BUILD_STATIC_LIBRARY)  
bar模組依賴foo模組,宣告如下:
  1. include $(CLEAR_VARS)  
  2. LOCAL_MODULE := bar  
  3. LOCAL_SRC_FILES := bar.c  
  4. LOCAL_CFLAGS := -DBAR=2  
  5. LOCAL_STATIC_LIBRARIES := foo  
  6. include $(BUILD_SHARED_LIBRARY)  
因此在編譯bar模組的時候,它的編譯器標誌就是 “-DFOO=1 -DBAR=2”。 匯出的flags 加上本模組的 LOCAL_CFLAGS,成為最後傳給編譯器的flags。這樣修改起來就很容易。這種依賴關係是可傳遞的,例如,如果zoo依賴bar,bar依賴foo,那麼zoo就會同時有bar和foo的匯出flags。

注意,編譯模組自身時,不會使用它所匯出的flags。例如在編譯上面的foo模組時, -DFOO=1 不會傳遞給編譯器。

LOCAL_EXPORT_CPPFLAGS

    與 LOCAL_EXPORT_CFLAGS 相同,是跟C++相關的標誌。

LOCAL_EXPORT_C_INCLUDES

    與 LOCAL_EXPORT_CFLAGS 相同,但是隻用於標頭檔案搜尋路徑。當你的共享庫有多個模組,而且互相之間有標頭檔案依賴時有用。用法詳見 Import Module。

LOCAL_EXPORT_LDLIBS

    與 LOCAL_EXPORT_CFLAGS 相同,但是隻用於聯結器的flag。注意這裡被導人的連結器標誌將追加到模組的 LOCAL_LDLIBS。

    例如當foo模組是一個靜態庫並且程式碼依賴於系統庫時,該變數非常有用。 LOCAL_EXPORT_LDLIBS 可以用於匯出該依賴:

  1. include $(CLEAR_VARS)  
  2. LOCAL_MODULE := foo  
  3. LOCAL_SRC_FILES := foo/foo.c  
  4. LOCAL_EXPORT_LDLIBS := -llog  
  5. include $(BUILD_STATIC_LIBRARY)  
  6. include $(CLEAR_VARS)  
  7. LOCAL_MODULE := bar  
  8. LOCAL_SRC_FILES := bar.c  
  9. LOCAL_STATIC_LIBRARIES := foo  
  10. include $(BUILD_SHARED_LIBRARY)  
此處在編譯bar模組的時候,它的連結器標誌將加上一個 -llog,表示它依賴於系統提供的 liblog.so,因為它依賴 foo 模組。

LOCAL_FILTER_ASM

    這個變數指定一個shell命令,用於過濾LOCAL_SRC_FILES 中列出的彙編檔案或者LOCAL_SRC_FILES列出的檔案所編譯出的彙編檔案。定義該變數後,將導致以下行為:

    1)所有的C/C++原始碼首先翻譯為臨時彙編檔案(如果不定義LOCAL_FILTER_ASM,則C/C++原始碼直接編譯為 obj 檔案)

    2)這些彙編檔案被傳給 LOCAL_FILTER_ASM 所指定的shell命令處理,得到一批新的彙編檔案。

    3)這些新的彙編檔案再被編譯成obj檔案。

換句話說,如果你定義:

  1. LOCAL_SRC_FILES  := foo.c bar.S  
  2. LOCAL_FILTER_ASM := myasmfilter  
則foo.c首先傳給編譯器(gcc),得到 foo.S.orignal,然後這個 foo.S.original 被傳給你指定的過濾器(LOCAL_ASM_FILTER),得到 foo.S,然後再傳給彙編器(例如as),得到 foo.o。 bar.S 直接傳給過濾器得到 bar.S.new,然後再傳給彙編器,得到 bar.o。即在從*.S到*.o的編譯流程中增加了一個過濾的環節。

過濾器必須是獨立的shell命令,輸入檔案作為它的第一個命令列引數,輸出檔案作為第二個命令列引數,例如:

  1.     myasmfilter $OBJS_DIR/foo.S.original $OBJS_DIR/foo.S  
  2.     myasmfilter bar.S $OBJS_DIR/bar.S  

(六)GNU Make‘功能’巨集 GNU Make‘功能’巨集,必須通過使用'$(call  )'來呼叫,呼叫他們將返回文字化的資訊。 (1)my-dir:返回當前 Android.mk 所在的目錄的路徑,相對於 NDK 編譯系統的頂層。這是有用的,在 Android.mk 檔案的開頭如此定義: LOCAL_PATH := $(call my-dir) (2)all-subdir-makefiles: 返回一個位於當前'my-dir'路徑的子目錄中的所有Android.mk的列表。 例如,看下面的目錄層次: sources/foo/Android.mk sources/foo/lib1/Android.mk sources/foo/lib2/Android.mk  如果 sources/foo/Android.mk 包含一行: include $(call all-subdir-makefiles) 那麼它就會自動包含 sources/foo/lib1/Android.mk 和 sources/foo/lib2/Android.mk。 這項功能用於向編譯系統提供深層次巢狀的程式碼目錄層次。 注意,在預設情況下,NDK 將會只搜尋在 sources/*/Android.mk 中的檔案。 (3)this-makefile:  返回當前Makefile 的路徑(即這個函式呼叫的地方) (4)parent-makefile:  返回呼叫樹中父 Makefile 路徑。即包含當前Makefile的Makefile 路徑。 (5)grand-parent-makefile:返回呼叫樹中父Makefile的父Makefile的路徑

(七)參考模板

(1)在android裡在編譯一個java應用時,如果這個應用需要引入一個第三方的jar包,那麼就需要將這個三方的jar包通過mk檔案將其編譯到apk裡,下面是將一個三方的jar包編譯到apk包裡的方法.

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE_TAGS := eng

LOCAL_SRC_FILES := $(call all-subdir-java-files)

#在該模組中使用預編譯好的靜態jar包
LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4  hiconfigserviceapi  hitv

LOCAL_PACKAGE_NAME := HiConfigService

LOCAL_PROGUARD_ENABLED := disabled

LOCAL_CERTIFICATE := platform
#指定編譯該模組為apk
include $(BUILD_PACKAGE)


include $(CLEAR_VARS)
#預編譯靜態jar包。形式為:隨便取的名字 :jar包的真實路徑
LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES :=android-support-v4:libs/android-support-v4.jar\
hiconfigserviceapi:libs/hiconfigserviceapi.jar\
hitv:libs/hitv.jar

include $(BUILD_MULTI_PREBUILT)

重要的語句

LOCAL_STATIC_JAVA_LIBRARIES := googlemap(別名)      


LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := googlemap:libs/armeabi/maps.jar (格式是:別名:JAR路徑)

BUILD_MULTI_PREBUILT

Android提供了Prebuilt編譯方法,兩個檔案prebuilt.mk和multi_prebuilt.mk,對應的方法巨集是BUILD_PREBUILT和 BUILD_MULTI_PREBUILT。

prebuilt.mk就是prebuilt的具體實現,它是針對獨立一個檔案的操作,multi_prebuilt.mk是針對多個檔案的,它對多個檔案進行判斷,然後呼叫prebuilt對獨立一個檔案進行處理。

如果直接用prebuilt.mk的話還是比較麻煩的,得仔細看好需要的巨集,如果使用multi_prebuilt.mk會更方便些,很多它都幫忙處理了。


(2)

做JNI開發,需要把jni編譯生成的so檔案一起打包成apk

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional

LOCAL_SRC_FILES := $(call all-java-files-under, src)

LOCAL_PACKAGE_NAME := TestJNI

#就是把so檔案放到apk檔案裡的libs/armeabi裡
LOCAL_JNI_SHARED_LIBRARIES := libHimediaAnimation

LOCAL_CERTIFICATE := platform


include $(BUILD_PACKAGE)
#為了編譯so檔案
include $(LOCAL_PATH)/jni/Android.mk

重點:

include $(LOCAL_PATH)/jni/Android.mk    編譯生成so檔案在out/target/product/***/system/lib目錄下

然後,LOCAL_JNI_SHARED_LIBRARIES := libHimediaAnimation  引用該目錄下的libHimediaAnimation.so共享檔案

自動拷貝到libs/armeabi裡,隨apk一起打包

在原始碼下,只需要在工程目錄mm,就可以編譯整個JNI工程了。

(3)編譯一個需要platform key簽名的APK 

LOCAL_PACKAGE_NAME := LocalPackage  (apk名)
LOCAL_CERTIFICATE := platform  (後面是簽名檔案的檔名)

關於NDK開發時也使用到了android.mk。基本也一樣。


在android系統原始碼中,根目錄下有個Makefile 檔案,內容為include build/core/main.mk。這是android系統編譯的開始,由此也就開始分析android原始碼的編譯。

上面只是涉及了簡單的android.mk,開發者要怎麼看懂系統中的android.mk,就需要對makefile檔案的語法和規則有個瞭解。

請參考(學習中。。。)

相關推薦

android.mk語法

(一)概要 在android系統原始碼中,還是需要在系統環境下編譯的應用程式,都可以見到android.mk的檔案,該檔案就是編譯原始碼所需要的編譯檔案。 下面就來分析下android.mk檔案 該檔案其實是GNU Makefile的一小部分,它用來對Android程式進

Android.mk用法(一)

       Android.mk是Android提供的一個makefile檔案,可以將原始檔分組為模組。用來引用的標頭檔案目錄、需要編譯的*.c/*.cpp檔案、jni原始檔、指定編譯生成*.so共享庫檔案或者*.a靜態庫檔案,可以定義一個或多個模組,也可以多個模組中使用同

Android.mk 文件語法

too itl 其他 國內 fine 鏈接 sina 流程詳解 img Android.mk 文件語法詳解 轉:http://blog.sina.com.cn/s/blog_602f8770010148ce.html =========================

Android.mk檔案語法

原文地址為:Android.mk 檔案語法詳解 轉:http://blog.sina.com.cn/s/blog_602f8770010148ce.html ===============================================================

Android.mk 檔案語法

===================================================================================== 0. Android.mk簡介: Android.mk檔案用來告知NDK Build 系統關於Sou

安卓Android.mk 檔案語法

0. Android.mk簡介: Android.mk檔案用來告知NDK Build 系統關於Source的資訊。 Android.mk將是GNU Makefile的一部分,且將被Build System解析一次或多次。 所以,請儘量少的在Android.mk中宣告

NDK 編譯和使用靜態庫、動態庫; Android.mk 檔案語法; Android.mk高階寫法

===================================================================================== 0. Android.mk簡介: Android.mk檔案用來告知NDK Build 系統關於Source的資訊。 Andro

Android.mk入門到精通(001)——Android.mk 檔案語法:神文

https://www.cnblogs.com/wainiwann/p/3837936.html 0. Android.mk簡介: Android.mk檔案用來告知NDK Build 系統關於Source的資訊。 Android.mk將是GNU Makefile的一部分,

android init.rc檔案語法

初始化語言包含了四種類型的宣告: Actions(行動)、 Commands(命令)、Services(服務)和Options(選項)。 基本語法規定 1 所有型別的語句都是基於行的,一個語句包含若干個tokens,token之間通過空格字元分隔. 如果一個token中需

008-Hadoop Hive sql語法3-DML 操作:元數據存儲

pan 查詢 寫入 所有 not insert語句 int 寫入文件 文件系統 一、概述 hive不支持用insert語句一條一條的進行插入操作,也不支持update操作。數據是以load的方式加載到建立好的表中。數據一旦導入就不可以修改。 DML包括:INSERT插入

Oracle create tablespace 創建表空間語法

系統回滾段 語法 判斷 臨時 extent 數值 off offline 文件的 CREATE [UNDO] TABLESPACE tablespace_name [DATAFILE datefile_spec1 [,datefile_spec2] ..

mysql-5.7.9 shutdown 語法

resp 登錄 ive conn denied 權限不足 這樣的 fec comm mysql-5.7.9 終於提供shutdown 語法啦:   之前如果想關閉一個mysql數據庫可以通過kill 命令、mysqladmin shutdown 、service mysql

aNDROID之MEDIapLaYER

iap music media 詳解 list oid aid 5% layer %E8%BD%AC%E8%BD%BD%E4%B8%80%E4%B8%AA%E5%9B%BE%E7%89%87%E5%A4%84%E7%90%86%E5%B7%A5%E5%85%B7%E7%B1

[持續交付實踐] pipeline:pipeline 使用之語法

安裝工具 詳細 href 3.0 def 實現 能夠 action roo 一、引言 jenkins pipeline語法的發展如此之快用日新月異來形容也不為過,而目前國內對jenkins pipeline關註的人還非常少,相關的文章更是稀少,唯一看到w3c有篇相關的估計是

Nginx Rewrite語法

服務器端 .html use rgs args port 資源 如果 urn 重寫中用到的指令 if (條件) {} 設定條件,再進行重寫 set #設置變量 return #返回狀態碼 break #跳出rewrite rewrite #重寫 If 語法格式 If

Android RxJava操作符系列: 變換操作符

urn 原因 轉換 需要 生產 依賴 reat 入門 所有 Rxjava,由於其基於事件流的鏈式調用、邏輯簡潔 & 使用簡單的特點,深受各大 Android開發者的歡迎。Github截圖 如果還不了解 RxJava,請看文章:Android:這是一篇 清晰 &

017-Hadoop Hive sql語法7-去重排序、數據傾斜

col 去重排序 sel cluster 可能 更多 分發 指定 clust 一、數據去重排序 1.1、去重   distinct與group by   盡量避免使用distinct進行排重,特別是大表操作,用group by代替   -- 不建議 selec

016-Hadoop Hive sql語法6-job輸入輸出優化、數據剪裁、減少job數、動態分區

分享 hive table 取數 nbsp put union 正在 style 一、job輸入輸出優化 善用muti-insert、union all,不同表的union all相當於multiple inputs,同一個表的union all,相當map一次輸出多條

android:exported 屬性

itl fas 默認 之前 綁定 四大 nbsp ring ins http://blog.csdn.net/watermusicyes/article/details/46460347 昨天在用360掃描應用漏洞時,掃描結果,出來一個android:exported屬性,

(4)Smali系列學習之Smali語法內部類

這一 數字 學習 get 私有方法 如果 單獨 hello 我們 在這一節,我們來介紹一下內部類。對於Java文件中的每一個內部類,都會產生一個單獨的smali文件,比如ActivityThread$1.smali。這些文件的命名規範是如果是匿名內部類,則命名規則是外部類+