1. 程式人生 > >Android.mk檔案語法詳述

Android.mk檔案語法詳述

介紹:
------------

這篇文件是用來描述你的C或C++原始檔中Android.mk編譯檔案的語法的,為了理解她們我們需要您先看完
docs/OVERVIEW.html(http://hualang.iteye.com/blog/1135105)檔案來了解它的作用

概覽:
------------
Android.mk檔案是用來描述build system(編譯系統)的,更準確的說:

--該檔案是一個微型的GNU Makefile片段,將由build system解析一次或者多次。這樣,您就可以儘量減少您宣告的變數,並且不要以為在解析過程中沒有任何定義。

--這個檔案但語法是用來允許你將原始檔組織成模組,這個模組中含有:

  -一個靜態庫(.a檔案)
  -一個動態庫(.so檔案)
  只有動態庫才會被安裝/複製到你的應用程式包,儘管靜態庫可以被用來生成動態庫。你可以在每個模組中  都定義一個Android.mk檔案,你也可以讓多個模組共用一個Android.mk檔案。

--build system可以為你處理許多細節,例如:你不許要在Android.mk檔案中列出標頭檔案或者其他的依賴關係,這些NDK的build system會自動為你計算並處理。

這也意味著,當更新到新版本的NDK的時候,你應該得益於新的toolchain/platform的支援,而無需修改你的Android.mk檔案。

注意:這些語法非常接近於分佈在完整的開源的Android原始碼中的Android.mk檔案,儘管是build system實現的,但是它們的用法是不同的。這樣故意設計的決定是為了讓應用程式開發者重用“外部”庫的原始碼更容易。


簡單例項:
-------------
再詳細講解語法之前,讓我們先看看一個簡單的例子"hello JNI",它在apps/hello-jni/project下

--'src'目錄下用於存放java原始檔
--‘jni’目錄下用於存放本地原始檔,例如"jni/hello-jni.c"

這個原始檔實現了一個簡單的共享庫(shared library):實現了一個本地方法,為VM應用程式返回一個字串。

--‘jni/Android.mk’檔案描述瞭如何生成一個共享庫,它的內容是:
-----------------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:=$(call my-dir)

Android.mk檔案必須以LOCAL_PATH變數開始,它用於在樹中定位檔案。在這個例子中,巨集功能'my-dir'是由build system提供的,用於返回當前目錄路徑(包括Android.mk檔案本身)

include $(CLEAR_VARS)

CLEAR_VARS變數是由build system提供的,並且指明瞭一個GNU makefile檔案,這個功能會清理掉所有以LOCAL_開頭的內容(例如LOCAL_MODULE,LOCAL_SRC_FILES,LOCAL_STATIC_LIBRARIES等),除了LOCAL_PATH,這句話是必須的,因為如果所有的變數都是全域性變數的話,所有的可控的編譯檔案都需要在一個單獨的GNU中被解析並執行

LOCAL_MODULE :=hello-jni

LOCAL_MODULE變數必須被定義,用來區分Android.mk中的每一個模組。檔名必須是唯一的,不能有空格。注意,這裡編譯器會為你自動加上一些字首和字尾,來保證檔案是一致的,比如:這裡表明一個動態連線庫模組被命名為"hello-jni",但是最後會生成為"libhello-jni.so"檔案。但是在Java中裝載這個庫的時候還是使用"hello-jni"名稱。當然如果我們使用"IMPORTANT NOTE:",編譯系統就不會為你加上字首,但是為了支援Android平臺原始碼中的Android.mk檔案,也同樣會生成libhello-jni.so這樣的檔案。

重要提示:如果你將你的模組命名為'libfoo',編譯系統將不會將字首'lib'加上去,並且也會生成libfoo.so檔案。

LOCAL_SRC_FILES := hello-jni.c

LOCAL_SRC_FILES變數被需包括一個C和C++原始檔的列表,這些會編譯並聚合到一個模組中。
注意:這裡並不需要你列出標頭檔案和被包含的檔案,因為編譯系統會自動為你計算相關的屬性,原始碼中的列表會直接傳遞給編譯器。

C++預設檔案的副檔名是“.cpp”,我們可以通過定義一個LOCAL_DEFAULT_CPP_EXTENSION變數來定義一個不同的C檔案。不要忘記在初始化前面的“.”點(也就是說".cpp"可以正常工作,但是cpp不能正常工作)

include $(BUILD_SHARED_LIBRARY)
BUILD_SHARED_LIBRARY這個變數是由系統提供的,並且指定給GNU Makefile的指令碼,它可以收集所有你定義的"include $(CLEAR_VARS)"中以LOCAL_開頭的變數,並且決定哪些要被編譯,哪些應該做的更加準確。編譯生成的是以"lib<module_name>.so"的檔案,這個就是共享庫了。我們同樣也可以使用BUILD_STATIC_LIBRARY編譯系統便會生成一個以"lib<module_name>.a"的檔案來供動態庫呼叫。

在samples目錄下有很多複雜的例子,那裡的Android.mk檔案可以供我們參考

參考:
-----------------------
這是個變數的列表,你可以依賴或者定義它們到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)
----------------------------

我們繼續:

NDK提供的變數:
在您的Android.mk檔案被解析之前這些GNU Make變數由編譯系統定義,注意,在某些情況下,NDK可能被解析幾次,每次以不同的變數的定義解析的

CLEAR_VARS
CLEAR_VARS這個變數由系統提供,功能是清理掉所有以LOCAL_開頭的內容,再開始一個新的模組之前,你必須包括這段指令碼

include ($CLEAR_VARS)

BUILD_SHARED_LIBRARY

在編譯指令碼中收集所有以LOCAL_開頭的資訊並且決定從列出的原始碼中編譯一個目標共享庫。注意,你必須定義了LOCAL_MODULE和LOCAL_SRC_FILES變數,使用它的時候,可以這樣定義

include $(BUILD_SHARED_LIBRARY)

注意,我們會生成一個以lib<module_name>.so為名的檔案

BUILD_STATIC_LIBRARY

用來構建一個靜態庫,該靜態庫將不會被拷貝到你的project/packages下,但是可以被用於動態庫
(看下面的LOCAL_STATIC_LIBRARY和LOCAL_WHOLE_STATIC_LIBRARY介紹)

例如:
include $(BUILD_STATIC_LIBRARY)

注意,這將生成一個lib<module_name>.a為名字的模組

PREBUILD_SHARED_LIBRARY
在編譯指令碼中用於指定一個預先編譯的動態庫,不像BUILD_SHARED_LIBRARY和BUILD_STATIC_LIBRARY,LOCAL_SRC_FILES的預先共享庫必須是一個單獨的路徑(如:foo/libfoo.so),而不是原始檔。

你可以在另一個模組中引用預編譯的庫(參見docs/pribuilds.html)

PRIBUILD_STATIC_LIBRARY
這個變數類似於PREBUILD_SHARED_LIBRARY,但是是針對靜態庫的,(詳見docs/prebuilds.html)

TARGET_ARCH
TARGET_ARCH指框架中CPU的名字已經被Android開原始碼明確指出了,這裡的arm包含了任何ARM-獨立結構的架構,以及每個獨立的CPU版本

TARGET_PLATFORM
Android平臺的名字在Android.mk中被解析,比如"android-3"對應Android 1.5系統映象,對於平臺的名稱對應Android系統的列表,請看docs/STABLE-APIS.html

TARGET_ARCH_ABI
在Android.mk中被解析時指CPU+ABI的名字。

目前支援的兩個值
armeabi for ARMv5TE
armeabi-v7a

注意,到Android NDK 1.6_r1,這個值被簡化為"arm"。然而,這個值被重定義可以更好的匹配Android平臺內部使用的是什麼

更多的資訊可以參見docs/CPU-ARCH-ABIS.html

未來的NDK版本中得到支援,它們會有一個不同的名字,注意所有基於ARM的ABI都會有一個"TARGET_ARCH"被定義給arm,但也有可能有不同的"TARGET_ARCH_ABI"

TARGET_ABI

目標平臺和ABI的連結,這裡要定義$(TARGET_PLATFORM)-$(TARGET_ARCH_ABI)它們都非常有用,特別是當你想測試一下具體的系統映象在一個真實裝置環境的時候

預設地,這個是"android-3-armeabi"

(到Android NDK 16_R1版本,使用"android-3-arm"作為預設)

NDK提供的巨集功能
--------------------------------
以下是使用GNU make的巨集功能,必須通過使用"$(call <function>)",返回一個文字資訊。

my-dir

返回最後包含的makefile的路徑,這通常是當前Android.mk所在目錄的路徑,在Android.mk開始之前定義
LOCAL——PATH是很有用的。

在Android.mk檔案的開始位置定義
LOCAL_PATH :=$(call my-dir)

...宣告一個模組
include $(LOCAL_PATH)/foo/Android.mk

LOCAL_PATH :=($call my-dir)

...宣告另一個模組
這裡的問題是第二次呼叫"my-dir"定義LOCAL_PATH替換$PATH為$PATH/foo,由於在此之前執行過。

對於這個原因,最好是將額外的其他所有東西都在Android.mk中包含進來

LOCAL_PATH :=$(call my-dir)

...宣告一個模組

LOCAL_PATH :=$(call my-dir)
...宣告另一個模組

#在Android.mk的最後額外包括進來
include $(LOCAL_PATH)/foo/Android.mk

如果這樣不方便的話,儲存第一個my-dir呼叫的值到另一個變數中,例如

MY_LOCAL_PATH :=$(call my-dir)
LOCAL_PATH :=$(MY_LOCAL_PATH)
...宣告一個模組

include $(LOCAL_PATH)/foo/Android.mk
LOCAL_PATH :=$(MY_LOCAL_PATH)
...宣告另一個模組

all-subdir-makefiles
返回一個Android.mk檔案所在位置的列表,以及當前的my-dir的路徑。比如
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包含進來。

此功能可以用於提供深層巢狀的原始碼目錄build system的層次結構。請注意,預設情況下,NDK只會尋找
sources/*Android.mk

this-makefile
返回當前makefile的路徑(也就是那個功能被呼叫了)

parent-makefile
返回makefile的包含樹,也就是包含Makefile當前的檔案

grand-parent-makefile
你猜?

import-module
一個允許你通過名字找到幷包含另一個模組的的Android.mk的功能,例如

$(call import-module,<name>)

這將會找到通過NDK_MODULE_PATH環境變數引用的模組<name>的目錄列表,並且將其自動包含到
Android.mk中

詳細資訊請參閱:docs/IMPORT-MODULE.html

模組變數描述:
----------------------------------
下面的這些變數是用來描述怎樣用你的模組來編譯系統的。你可以定義它們中的一些比如
"include $(CLEAR_VARS)"和"include $(BUILD_XXX)",正如前面所寫的,$(CLEAR_VARS)是一個可以取消定義/清楚所有變數的指令碼。

LOCAL_PATH
這個變數是用來給出當前檔案的路徑。您比系再您的Android.mk開始位置定義:
LOCAL_PATH :=$(call my-dir)
注意,這個變數是不被$(CLEAR_VARS)清除的,其他的都要被清除(我們可以定義幾個模組到一個檔案中)

LOCAL_MODULE
這個是你模組的名稱,它在你的所有模組中名稱必須是唯一的,並且不能包含空格。你必須在包含任何
$(BUILD-XXX)指令碼之前定義它。

預設情況下,模組的名稱決定了生成的檔案的名稱,例如lib<foo>.so,它是foo模組的名字。

相關推薦

Android.mk檔案語法詳述

介紹:------------這篇文件是用來描述你的C或C++原始檔中Android.mk編譯檔案的語法的,為了理解她們我們需要您先看完docs/OVERVIEW.html(http://hualang.iteye.com/blog/1135105)檔案來了解它的作用概覽:

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檔案語法規範及使用

1.概述Android.mk編譯檔案是用來向Android NDK描述你的C,C++原始碼檔案的。具體來說:該檔案是GNU Makefile的一小部分,會被編譯系統解析一次或更多次的build系統。因此,您應儘量減少您宣告的變數,不要認為某些變數在解析過程中不會被定義。這

安卓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檔案語法規範——深入瞭解android平臺的jni

Android.mk是Android提供的一種makefile檔案,用來指定諸如編譯生成so庫名、引用的標頭檔案目錄、需要編譯的.c/.cpp檔案和.a靜態庫檔案等。要掌握jni,就必須熟練掌握Android.mk的語法規範。 一、Android.mk檔案的用途一個andr

android.mk檔案語法總結

LOCAL_PATH := $(call my-dir)//指定本地路徑,通常是android.mk檔案所在路徑     include $(CLEAR_VARS)//這兩行必須要     LOCAL_MODULE    := OgreGLES2Sample//指定模組名,

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.mk 檔案語法大全

講解如下:LOCAL_PATH := $(call my-dir) 每個Android.mk檔案必須以定義LOCAL_PATH為開始。它用於在開發tree中查詢原始檔。巨集my-dir 則由Build System提供。返回包含Android.mk的目錄路徑。include $(CLEAR_VARS)CLE

Android .mk檔案語法解析

下面是MTK-AndroidFM模組Android .mk程式碼內容: 1 ifeq ($(MTK_FM_SUPPORT),yes) 2 LOCAL_PATH:= $(call my-dir) 3 include $(CLEAR_VARS) 4 LOCAL_MODULE_T

編寫Android.mk檔案備錄

前言:     由於目前供職於機器人公司,從事基於android系統的軟體開發,因此常常需要進行原始碼編譯(當然也可以基於機器人的sdk和android studio環境進行開發)。   進行原始碼編譯,少不了編寫Android.mk檔案。通常類比前人的Android.mk檔案修修改

Android Studio使用自定義的Android.mk檔案編譯ffmpegyuv-bgr

概述 最近做專案的時候,領導安排一個任務,讓測試一下,用ffmpeg中的yuv轉bgr函式的速度。之前編譯so庫大部分都是用eclipse,本次博主花了兩天時間,在Android studio上編譯並執行,在此做一下記錄。 設定Android Studio ndk 1、開啟setings

LOCAL_MODULE_TAGS--------在Android.mk檔案裡的配置項------------

ZZZZ: http://blog.csdn.net/talking12391239/article/details/10904653 要了解Android編譯選項eng、user和userdebug的區別,需先了解下LOCAL_MODULE_TAGS這一Android.m

Makefile & Android.mk檔案

1. 列印輸出:$(warning xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx)或者$(error xxxxx) 列印輸出變數的值:$(warning  $(LOCAL_SHARED_LIBRARIES)) 2. LOCAL_CFLAGS

androd.mk 檔案語法規範

http://blog.163.com/[email protected]/blog/static/70234777201102611363180/ Android.mk檔案語法規範 序言: ------------- 此文件旨在描述Android.

Android5.1 內建第三方APK及Android.mk檔案編寫(以在amlogic5.1公版系統內建百度輸入法為例)

Android.mk檔案用來向編譯系統描述如何編譯你的原始碼。在編譯整個工程的情況下,系統所找到的所有的Android.mk將會先存入subdir_makefiles變數中,隨後一次性一次性include進整個編譯檔案中。 示例 Android.mk內容:

專案中在Android.mk檔案中根據專案名稱選擇不同的AndroidManifest.xml檔案 && 如何使用系統設定的日期顯示格式

專案中根據專案名稱選擇不同的AndroidManifest.xml檔案 MY_PROJECT_NAME := $(subst full_,,$(TARGET_PRODUCT)) ifeq ($(strip $(MY_PROJECT_NAME)), xxxxxx)# xxxx

ndk開發中的Android.mk檔案與Application.mk詳解及例項

Android.mk檔案的作用: An Android.mk file is written to describe your sources to the build system. 中文意思是:寫一個Android.mk檔案是為了向生成系統描述你的原始碼。

解讀Android.mk檔案

一、介紹 本文章會介紹構建 Android.mk檔案的構建過程;Android.mk檔案會將我們的 C 和 C++ 檔案描述為 Android NDK 二、概述 Android.mk檔案是描述原始檔在構建系統的作用,更具體來說: 這個Andro