本頁介紹了 ndk-build
所使用的 Android.mk
編譯文件的語法。html
Android.mk
文件位於項目 jni/
目錄的子目錄中,用於向編譯系統描述源文件和共享庫。它其實是編譯系統解析一次或屢次的微小 GNU makefile 片斷。Android.mk
文件用於定義 Application.mk
、編譯系統和環境變量所未定義的項目範圍設置。它還可替換特定模塊的項目範圍設置。node
Android.mk
的語法支持將源文件分組爲模塊。模塊是靜態庫、共享庫或獨立的可執行文件。您可在每一個 Android.mk
文件中定義一個或多個模塊,也可在多個模塊中使用同一個源文件。編譯系統只將共享庫放入您的應用軟件包。此外,靜態庫可生成共享庫。android
除了封裝庫以外,編譯系統還可爲您處理各類其餘事項。例如,您無需在 Android.mk
文件中列出頭文件或生成的文件之間的顯式依賴關係。NDK 編譯系統會自動計算這些關係。所以,您應該可以享受到將來 NDK 版本中新工具鏈/平臺支持帶來的益處,而無需處理 Android.mk
文件。shell
此文件的語法與隨整個 Android 開源項目分發的 Android.mk
文件中使用的語法很是接近。雖然使用這些語法的編譯系統實現並不相同,但經過有意將語法設計得類似,可以使應用開發者更輕鬆地將源代碼重複用於外部庫。編程
在詳細瞭解語法以前,最好先了解 Android.mk
文件所含內容的基本信息。爲此,本部分使用 Hello-JNI 示例中的 Android.mk
文件解釋文件中每一行的做用。api
Android.mk
文件必須先定義 LOCAL_PATH
變量:安全
LOCAL_PATH := $(call my-dir)
此變量表示源文件在開發樹中的位置。在這行代碼中,編譯系統提供的宏函數 my-dir
將返回當前目錄(Android.mk
文件自己所在的目錄)的路徑。架構
下一行聲明 CLEAR_VARS
變量,其值由編譯系統提供。app
include $(CLEAR_VARS)
CLEAR_VARS
變量指向一個特殊的 GNU Makefile,後者會清除許多 LOCAL_XXX
變量,例如 LOCAL_MODULE
、LOCAL_SRC_FILES
和 LOCAL_STATIC_LIBRARIES
。請注意,GNU Makefile 不會清除 LOCAL_PATH
。此變量必須保留其值,由於系統在單一 GNU Make 執行環境(其中的全部變量都是全局變量)中解析全部編譯控制文件。在描述每一個模塊以前,必須聲明(從新聲明)此變量。ide
接下來,LOCAL_MODULE
變量存儲您要編譯的模塊的名稱。請在應用的每一個模塊中使用一次此變量。
LOCAL_MODULE := hello-jni
每一個模塊名稱必須惟一,且不含任何空格。編譯系統在生成最終共享庫文件時,會對您分配給 LOCAL_MODULE
的名稱自動添加正確的前綴和後綴。例如,上述示例會生成名爲 libhello-jni.so
的庫。
注意:若是模塊名稱的開頭已是 lib
,則編譯系統不會附加額外的 lib
前綴;而是按原樣採用模塊名稱,並添加 .so
擴展名。所以,好比原來名爲 libfoo.c
的源文件仍會生成名爲 libfoo.so
的共享對象文件。此行爲是爲了支持 Android 平臺源文件根據 Android.mk
文件生成的庫;全部這些庫的名稱都以 lib
開頭。
下一行會列舉源文件,以空格分隔多個文件:
LOCAL_SRC_FILES := hello-jni.c
LOCAL_SRC_FILES
變量必須包含要編譯到模塊中的 C 和/或 C++ 源文件列表。
最後一行幫助系統將全部內容鏈接到一塊兒:
include $(BUILD_SHARED_LIBRARY)
BUILD_SHARED_LIBRARY
變量指向一個 GNU Makefile 腳本,該腳本會收集您自最近 include
以來在 LOCAL_XXX
變量中定義的全部信息。此腳本肯定要編譯的內容以及編譯方式。
示例目錄中有更爲複雜的示例,包括帶有註釋的 Android.mk
文件供您參考。此外,示例:native-activity 詳細介紹了該示例的 Android.mk
文件。最後,變量和宏提供了關於本部分中變量的更多信息。
編譯系統提供了許多可在 Android.mk
文件中使用的變量。其中許多變量已預先賦值。另外一些變量由您賦值。
除了這些變量以外,您還能夠本身定義任意變量。在定義變量時請注意,NDK 編譯系統保留了下列變量名稱:
LOCAL_
開頭的名稱,例如 LOCAL_MODULE
。PRIVATE_
、NDK_
或 APP
開頭的名稱。編譯系統在內部使用這些變量名。my-dir
。編譯系統也是在內部使用這些變量名。若是您爲了方便而須要在 Android.mk
文件中定義本身的變量,建議在名稱前附加 MY_
。
本部分探討了編譯系統在解析 Android.mk
文件前定義的 GNU Make 變量。在某些狀況下,NDK 可能會屢次解析 Android.mk
文件,每次使用其中某些變量的不一樣定義。
此變量指向的編譯腳本用於取消定義下文「開發者定義的變量」部分中列出的幾乎全部 LOCAL_XXX
變量。在描述新模塊以前,請使用此變量來包含此腳本。使用它的語法爲:
include $(CLEAR_VARS)
此變量指向的編譯腳本用於收集您在 LOCAL_XXX
變量中提供的模塊的全部相關信息,以及肯定如何根據您列出的源文件編譯目標共享庫。請注意,使用此腳本要求您至少已經爲 LOCAL_MODULE
和 LOCAL_SRC_FILES
賦值(要詳細瞭解這些變量,請參閱模塊描述變量)。
使用此變量的語法爲:
include $(BUILD_SHARED_LIBRARY)
共享庫變量會致使編譯系統生成擴展名爲 .so
的庫文件。
用於編譯靜態庫的 BUILD_SHARED_LIBRARY
的變體。編譯系統不會將靜態庫複製到您的項目/軟件包中,但可使用靜態庫編譯共享庫(請參閱下文的 LOCAL_STATIC_LIBRARIES
和 LOCAL_WHOLE_STATIC_LIBRARIES
)。使用此變量的語法爲:
include $(BUILD_STATIC_LIBRARY)
靜態庫變量會致使編譯系統生成擴展名爲 .a
的庫。
指向用於指定預編譯共享庫的編譯腳本。與 BUILD_SHARED_LIBRARY
和 BUILD_STATIC_LIBRARY
的狀況不一樣,這裏的 LOCAL_SRC_FILES
值不能是源文件,而必須是指向預編譯共享庫的一個路徑,例如 foo/libfoo.so
。使用此變量的語法爲:
include $(PREBUILT_SHARED_LIBRARY)
您也可使用 LOCAL_PREBUILTS
變量引用另外一個模塊中的預編譯庫。要詳細瞭解如何使用預編譯庫,請參閱使用預編譯庫。
與 PREBUILT_SHARED_LIBRARY
相同,但用於預編譯靜態庫。要詳細瞭解如何使用預編譯庫,請參閱使用預編譯庫。
編譯系統會根據 APP_ABI
變量所指定的每一個 ABI 解析 Android.mk
一次,該變量一般在 Application.mk
文件中定義。若是 APP_ABI
爲 all
,則編譯系統會根據 NDK 支持的每一個 ABI 解析 Android.mk
一次。本部分介紹了編譯系統每次解析 Android.mk
時定義的變量。
編譯系統解析此 Android.mk
文件時面向的 CPU 系列。此變量是 arm
、arm64
、x86
或 x86_64
之一。
編譯系統解析此 Android.mk
文件時面向的 Android API 級別編號。例如,Android 5.1 系統映像對應於 Android API 級別 22:android-22
。如需平臺名稱和對應 Android 系統映像的完整列表,請參閱 Android NDK 原生 API。如下示例演示了使用此變量的語法:
ifeq ($(TARGET_PLATFORM),android-22)
# ... do something ...
endif
編譯系統解析此 Android.mk
文件時面向的 ABI。表 1 顯示用於每一個受支持 CPU 和架構的 ABI 設置。
表 1. 不一樣 CPU 和架構的 ABI 設置。
CPU 和架構 | 設置 |
---|---|
ARMv7 | armeabi-v7a |
ARMv8 AArch64 | arm64-v8a |
i686 | x86 |
x86-64 | x86_64 |
如下示例演示瞭如何檢查 ARMv8 AArch64 是否爲目標 CPU 與 ABI 的組合:
ifeq ($(TARGET_ARCH_ABI),arm64-v8a)
# ... do something ...
endif
要詳細瞭解架構 ABI 和相關兼容性問題,請參閱 ABI 管理。
將來的新目標 ABI 將使用不一樣的值。
目標 Android API 級別與 ABI 的鏈接,特別適用於要針對實際設備測試特定目標系統映像的狀況。例如,要檢查搭載 Android API 級別 22 的 64 位 ARM 設備:
ifeq ($(TARGET_ABI),android-22-arm64-v8a)
# ... do something ...
endif
本部分中的變量會向編譯系統描述您的模塊。每一個模塊描述都應遵照如下基本流程:
CLEAR_VARS
變量初始化或取消定義與模塊相關的變量。BUILD_XXX
變量設置 NDK 編譯系統,使其將適當的編譯腳本用於該模塊。此變量用於指定當前文件的路徑。必須在 Android.mk
文件開頭定義此變量。如下示例演示瞭如何定義此變量:
LOCAL_PATH := $(call my-dir)
CLEAR_VARS
所指向的腳本不會清除此變量。所以,即便 Android.mk
文件描述了多個模塊,您也只需定義它一次。
此變量用於存儲模塊名稱。指定的名稱必須惟一,而且不得包含任何空格。必須在包含任何腳本(CLEAR_VARS
的腳本除外)以前定義此變量。無需添加 lib
前綴或者 .so
或 .a
文件擴展名;編譯系統會自動進行這些修改。在整個 Android.mk
和 Application.mk
文件中,請經過未經修改的名稱引用模塊。例如,如下行會致使生成名爲 libfoo.so
的共享庫模塊:
LOCAL_MODULE := "foo"
若是但願生成的模塊使用除「lib
+ LOCAL_MODULE
的值」之外的名稱,您可以使用 LOCAL_MODULE_FILENAME
變量爲生成的模塊指定本身選擇的名稱。
此可選變量使您可以替換編譯系統爲其生成的文件默認使用的名稱。例如,若是 LOCAL_MODULE
的名稱爲 foo
,您能夠強制系統將它生成的文件命名爲 libnewfoo
。如下示例演示瞭如何完成此操做:
LOCAL_MODULE := foo
LOCAL_MODULE_FILENAME := libnewfoo
對於共享庫模塊,此示例將生成一個名爲 libnewfoo.so
的文件。
注意:您沒法替換文件路徑或文件擴展名。
此變量包含編譯系統生成模塊時所用的源文件列表。只列出編譯系統實際傳遞到編譯器的文件,由於編譯系統會自動計算全部相關的依賴關係。請注意,您可使用相對(相對於 LOCAL_PATH
)和絕對文件路徑。
建議避免使用絕對文件路徑;相對路徑能夠提升 Android.mk
文件的移植性。
注意:務必在編譯文件中使用 Unix 樣式的正斜槓 (/)。編譯系統沒法正確處理 Windows 樣式的反斜槓 (\)。
可使用此可選變量爲 C++ 源文件指明 .cpp
之外的文件擴展名。例如,如下行將擴展名更改成 .cxx
。(設置必須包含點。)
LOCAL_CPP_EXTENSION := .cxx
您可使用此變量指定多個擴展名。例如:
LOCAL_CPP_EXTENSION := .cxx .cpp .cc
您可以使用此可選變量指明您的代碼依賴於特定 C++ 功能。它會在編譯過程當中啓用正確的編譯器標記和連接器標記。對於預編譯二進制文件,此變量還會聲明二進制文件依賴於哪些功能,從而確保最終連接正常運行。建議您使用此變量,而不要直接在 LOCAL_CPPFLAGS
定義中啓用 -frtti
和 -fexceptions
。
使用此變量可以讓編譯系統對每一個模塊使用適當的標記。使用 LOCAL_CPPFLAGS
會致使編譯器將全部指定的標記用於全部模塊,而無論實際需求如何。
例如,要指明您的代碼使用 RTTI(運行時類型信息),請輸入:
LOCAL_CPP_FEATURES := rtti
要指明您的代碼使用 C++ 異常,請輸入:
LOCAL_CPP_FEATURES := exceptions
您還能夠爲此變量指定多個值。例如:
LOCAL_CPP_FEATURES := rtti features
描述值的順序可有可無。
可使用此可選變量指定相對於 NDK root
目錄的路徑列表,以便在編譯全部源文件(C、C++ 和 Assembly)時添加到 include 搜索路徑。例如:
LOCAL_C_INCLUDES := sources/foo
或者甚至:
LOCAL_C_INCLUDES := $(LOCAL_PATH)/<subdirectory>/foo
請在經過 LOCAL_CFLAGS
或 LOCAL_CPPFLAGS
設置任何對應的包含標記前定義此變量。
在使用 ndk-gdb 啓動原生調試時,編譯系統也會自動使用 LOCAL_C_INCLUDES
路徑。
此可選變量用於設置在編譯 C 和 C++ 源文件時編譯系統要傳遞的編譯器標記。這樣,您就能夠指定額外的宏定義或編譯選項。可使用 LOCAL_CPPFLAGS
僅爲 C++ 指定標記。
請勿嘗試在 Android.mk
文件中更改優化/調試級別。編譯系統可使用 [pplication.mk] 文件中的相關信息自動處理此設置。這樣,編譯系統就能夠生成供調試期間使用的有用數據文件。
您可經過輸入如下代碼指定額外的 include 路徑:
LOCAL_CFLAGS += -I<path>,
可是,最好使用 LOCAL_C_INCLUDES
,由於這樣也可使用可用於 ndk-gdb 原生調試的路徑。
只編譯 C++ 源文件時將傳遞的一組可選編譯器標記。它們將出如今編譯器命令行中的 LOCAL_CFLAGS
後面。使用 LOCAL_CFLAGS
爲 C 和 C++ 指定標記。
此變量用於存儲當前模塊依賴的靜態庫模塊列表。
若是當前模塊是共享庫或可執行文件,此變量將強制這些庫連接到生成的二進制文件。
若是當前模塊是靜態庫,此變量只是指出依賴於當前模塊的其餘模塊也會依賴於列出的庫。
此變量會列出此模塊在運行時依賴的共享庫模塊。此信息是連接時必需的信息,用於將相應的信息嵌入到生成的文件中。
此變量是 LOCAL_STATIC_LIBRARIES
的變體,表示連接器應將相關的庫模塊視爲完整歸檔。要詳細瞭解完整歸檔,請參閱 GNU ld 文檔的 --whole-archive
標記部分。
多個靜態庫之間存在循環依賴關係時,此變量頗有用。使用此變量編譯共享庫時,它將強制編譯系統將靜態庫中的全部對象文件添加到最終二進制文件。可是,生成可執行文件時不會發生這種狀況。
此變量列出了在編譯共享庫或可執行文件時使用的額外連接器標記。利用此變量,您可以使用 -l
前綴傳遞特定系統庫的名稱。例如,如下示例指示連接器生成在加載時連接到 /system/lib/libz.so
的模塊:
LOCAL_LDLIBS := -lz
如需瞭解此 NDK 版本中能夠連接的公開系統庫列表,請參閱 Android NDK 原生 API。
注意:若是爲靜態庫定義此變量,編譯系統會忽略此變量,而且 ndk-build
會顯示一則警告。
此變量列出了編譯系統在編譯共享庫或可執行文件時使用的其餘連接器標記。例如,要在 ARM/X86 上使用 ld.bfd
連接器:
LOCAL_LDFLAGS += -fuse-ld=bfd
注意:若是爲靜態庫定義此變量,編譯系統會忽略此變量,而且 ndk-build 會顯示一則警告。
默認狀況下,若是編譯系統在嘗試編譯共享庫時遇到未定義的引用,將會拋出「未定義的符號」錯誤。此錯誤可幫助您捕獲源代碼中的錯誤。
要停用此檢查,請將此變量設置爲 true
。請注意,此設置可能會致使共享庫在運行時加載。
注意:若是爲靜態庫定義此變量,編譯系統會忽略此變量,而且 ndk-build 會顯示一則警告。
默認狀況下,編譯系統會在 thumb 模式下生成 ARM 目標二進制文件,其中每條指令都是 16 位寬,並與 thumb/
目錄中的 STL 庫關聯。將此變量定義爲 arm
會強制編譯系統在 32 位 arm
模式下生成模塊的對象文件。如下示例演示瞭如何執行此操做:
LOCAL_ARM_MODE := arm
您也能夠對源文件名附加 .arm
後綴,指示編譯系統在 arm
模式下僅編譯特定的源文件。例如,如下示例指示編譯系統在 ARM 模式下始終編譯 bar.c
,但根據 LOCAL_ARM_MODE
的值編譯 foo.c
。
LOCAL_SRC_FILES := foo.c bar.c.arm
注意:您也能夠在 Application.mk
文件中將 APP_OPTIM
設置爲 debug
,以強制編譯系統生成 ARM 二進制文件。指定 debug
會強制執行 ARM 編譯,由於工具鏈調試程序沒法正確處理 Thumb 代碼。
此變量僅在以 armeabi-v7a
ABI 爲目標時纔有意義。它容許在 C 和 C++ 源代碼中使用 ARM Advanced SIMD (NEON) 編譯器內建函數,以及在 Assembly 文件中使用 NEON 指令。
請注意,並不是全部基於 ARMv7 的 CPU 都支持 NEON 擴展指令集。所以,必須執行運行時檢測,以便在運行時安全地使用此代碼。詳情請參閱 NEON 支持和 cpufeatures 庫。
此外,您也可使用 .neon
後綴,指定編譯系統僅以 NEON 支持編譯特定源文件。在如下示例中,編譯系統以 Thumb 和 NEON 支持編譯 foo.c
,以 Thumb 支持編譯 bar.c
,並以 ARM 和 NEON 支持編譯 zoo.c
:
LOCAL_SRC_FILES = foo.c.neon bar.c zoo.c.arm.neon
若是同時使用這兩個後綴,則 .arm
必須在 .neon
前面。
默認狀況下,編譯系統會在編譯代碼時保護格式字符串。這樣的話,若是 printf
樣式的函數中使用了很是量格式的字符串,就會強制引起編譯器錯誤。此保護默認啓用,但您也可經過將此變量的值設置爲 true
將其停用。若是沒有必要的緣由,咱們不建議停用。
此變量用於記錄一組 C/C++ 編譯器標記,這些標記將添加到經過 LOCAL_STATIC_LIBRARIES
或 LOCAL_SHARED_LIBRARIES
變量使用此模塊的任何其餘模塊的 LOCAL_CFLAGS
定義中。
例如,假設有下面這一對模塊:foo
和 bar
,bar 依賴於 foo
:
include $(CLEAR_VARS)
LOCAL_MODULE := foo
LOCAL_SRC_FILES := foo/foo.c
LOCAL_EXPORT_CFLAGS := -DFOO=1
include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := bar
LOCAL_SRC_FILES := bar.c
LOCAL_CFLAGS := -DBAR=2
LOCAL_STATIC_LIBRARIES := foo
include $(BUILD_SHARED_LIBRARY)
在此例中,編譯系統在編譯 bar.c
時會向編譯器傳遞 -DFOO=1
和 -DBAR=2
標記。它還會在模塊的 LOCAL_CFLAGS
前面加上導出的標記,以便您輕鬆進行替換。
此外,模塊之間的關係也具備傳遞性:若是 zoo
依賴於 bar
,然後者依賴於 foo
,那麼 zoo
也會繼承從 foo
導出的全部標記。
最後,編譯系統在執行局部編譯時(即,編譯要導出標記的模塊時),不使用導出的標記。所以,在上面的示例中,編譯 foo/foo.c
時不會將 -DFOO=1
傳遞到編譯器。要執行局部編譯,請改用 LOCAL_CFLAGS
。
此變量與 LOCAL_EXPORT_CFLAGS
相同,但僅適用於 C++ 標記。
此變量與 LOCAL_EXPORT_CFLAGS
相同,但適用於 C include 路徑。例如,當 bar.c
須要包含模塊 foo
的頭文件時,此變量頗有用。
此變量與 LOCAL_EXPORT_CFLAGS
相同,但適用於連接器標記。
此變量與 LOCAL_EXPORT_CFLAGS
相同,告訴編譯系統將特定系統庫的名稱傳遞給編譯器。請在您指定的每一個庫名稱前附加 -l
。
請注意,編譯系統會將導入的連接器標記附加到模塊的 LOCAL_LDLIBS
變量值上。其緣由在於 Unix 連接器的工做方式。
當模塊 foo
是靜態庫而且具備依賴於系統庫的代碼時,此變量一般頗有用。而後,您可使用 LOCAL_EXPORT_LDLIBS
導出依賴關係。例如:
include $(CLEAR_VARS)
LOCAL_MODULE := foo
LOCAL_SRC_FILES := foo/foo.c
LOCAL_EXPORT_LDLIBS := -llog
include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := bar
LOCAL_SRC_FILES := bar.c
LOCAL_STATIC_LIBRARIES := foo
include $(BUILD_SHARED_LIBRARY)
在此示例中,編譯系統在編譯 libbar.so
時,在連接器命令的末尾指定了 -llog
。這樣就會告知連接器,因爲 libbar.so
依賴於 foo
,所以它也依賴於系統日誌記錄庫。
當模塊有不少源文件和/或依賴的靜態或共享庫時,請將此變量設置爲 true
。這樣會強制編譯系統將 @
語法用於包含中間對象文件或連接庫的歸檔。
此功能在 Windows 上可能頗有用,在 Windows 上,命令行最多隻接受 8191 個字符,這對於複雜的項目來講可能太少。它還會影響個別源文件的編譯,並且將幾乎全部編譯器標記都放在列表文件內。
請注意,true
之外的任何值都將恢復爲默認行爲。您也能夠在 Application.mk
文件中定義 APP_SHORT_COMMANDS
,以對項目中的全部模塊強制實施此行爲。
不建議默認啓用此功能,由於它會減慢編譯速度。
編譯靜態庫時,請將此變量設置爲 true
。這樣會生成一個瘦歸檔,即一個庫文件,其中不含對象文件,而只包含它一般包含的實際對象的文件路徑。
這對於減少編譯輸出的大小很是有用。但缺點是,這樣的庫沒法移至其餘位置(其中的全部路徑都是相對路徑)。
有效值爲 true
、false
或空白。您可在 Application.mk
文件中經過 APP_THIN_ARCHIVE
變量設置默認值。
注意:在非靜態庫模塊或預編譯的靜態庫模塊中,將會忽略此變量。
請將此變量定義爲一個 shell 命令,供編譯系統用於過濾根據您爲 LOCAL_SRC_FILES
指定的文件提取或生成的彙編文件。定義此變量會致使發生如下狀況:
LOCAL_SRC_FILES
中所列任何彙編文件的 LOCAL_FILTER_ASM
中執行 shell 命令,所以會生成另外一個臨時彙編文件。例如:
LOCAL_SRC_FILES := foo.c bar.S
LOCAL_FILTER_ASM :=
foo.c --1--> $OBJS_DIR/foo.S.original --2--> $OBJS_DIR/foo.S --3--> $OBJS_DIR/foo.o
bar.S --2--> $OBJS_DIR/bar.S --3--> $OBJS_DIR/bar.o
「1」對應於編譯器,「2」對應於過濾器,「3」對應於彙編程序。過濾器必須是一個獨立的 shell 命令,它接受輸入文件名做爲第一個參數,接受輸出文件名做爲第二個參數。例如:
myasmfilter $OBJS_DIR/foo.S.original $OBJS_DIR/foo.S
myasmfilter bar.S $OBJS_DIR/bar.S
本部分介紹了 NDK 提供的 GNU Make 函數宏。使用 $(call <function>)
能夠對這些宏進行求值;它們將返回文本信息。
這個宏返回最後包含的 makefile 的路徑,一般是當前 Android.mk
的目錄。my-dir
可用於在 Android.mk
文件的開頭定義 LOCAL_PATH
。例如:
LOCAL_PATH := $(call my-dir)
因爲 GNU Make 的工做方式,這個宏實際返回的是編譯系統解析編譯腳本時包含的最後一個 makefile 的路徑。所以,包含其餘文件後就不該調用 my-dir
。
例如:
LOCAL_PATH := $(call my-dir)
# ... declare one module
include $(LOCAL_PATH)/foo/`Android.mk`
LOCAL_PATH := $(call my-dir)
# ... declare another module
該示例的問題在於,對 my-dir
的第二次調用將 LOCAL_PATH
定義爲 $PATH/foo
,而不是 $PATH
,由於這是其最近的 include 所指向的位置。
在 Android.mk
文件中的全部其餘內容後添加額外的 include 可避免此問題。例如:
LOCAL_PATH := $(call my-dir)
# ... declare one module
LOCAL_PATH := $(call my-dir)
# ... declare another module
# extra includes at the end of the Android.mk file
include $(LOCAL_PATH)/foo/Android.mk
若是以這種方式構造文件不可行,請將第一個 my-dir
調用的值保存到另外一個變量中。例如:
MY_LOCAL_PATH := $(call my-dir)
LOCAL_PATH := $(MY_LOCAL_PATH)
# ... declare one module
include $(LOCAL_PATH)/foo/`Android.mk`
LOCAL_PATH := $(MY_LOCAL_PATH)
# ... declare another module
返回位於當前 my-dir
路徑全部子目錄中的 Android.mk
文件列表。
利用此函數,您能夠爲編譯系統提供深度嵌套的源目錄層次結構。默認狀況下,NDK 只在 Android.mk
文件所在的目錄中查找文件。
返回當前 makefile(編譯系統從中調用函數)的路徑。
返回包含樹中父 makefile 的路徑(包含當前 makefile 的 makefile 的路徑)。
返回包含樹中祖父 makefile 的路徑(包含當前父 makefile 的 makefile 的路徑)。
此函數用於按模塊名稱查找和包含模塊的 Android.mk
文件。典型的示例以下所示:
$(call import-module,<name>)
在此示例中,編譯系統在 NDK_MODULE_PATH
環境變量所引用的目錄列表中查找具備 <name>
標記的模塊,而且自動包含其 Android.mk
文件。