Android.mk文件官方使用說明

本頁介紹了 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_MODULELOCAL_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_

NDK 定義的 include 變量

 

本部分探討了編譯系統在解析 Android.mk 文件前定義的 GNU Make 變量。在某些狀況下,NDK 可能會屢次解析 Android.mk 文件,每次使用其中某些變量的不一樣定義。

CLEAR_VARS

此變量指向的編譯腳本用於取消定義下文「開發者定義的變量」部分中列出的幾乎全部 LOCAL_XXX 變量。在描述新模塊以前,請使用此變量來包含此腳本。使用它的語法爲:

include $(CLEAR_VARS)
   
 

BUILD_SHARED_LIBRARY

此變量指向的編譯腳本用於收集您在 LOCAL_XXX 變量中提供的模塊的全部相關信息,以及肯定如何根據您列出的源文件編譯目標共享庫。請注意,使用此腳本要求您至少已經爲 LOCAL_MODULE 和 LOCAL_SRC_FILES 賦值(要詳細瞭解這些變量,請參閱模塊描述變量)。

使用此變量的語法爲:

include $(BUILD_SHARED_LIBRARY)
   
 

共享庫變量會致使編譯系統生成擴展名爲 .so 的庫文件。

BUILD_STATIC_LIBRARY

用於編譯靜態庫的 BUILD_SHARED_LIBRARY 的變體。編譯系統不會將靜態庫複製到您的項目/軟件包中,但可使用靜態庫編譯共享庫(請參閱下文的 LOCAL_STATIC_LIBRARIES 和 LOCAL_WHOLE_STATIC_LIBRARIES)。使用此變量的語法爲:

include $(BUILD_STATIC_LIBRARY)
   
 

靜態庫變量會致使編譯系統生成擴展名爲 .a 的庫。

PREBUILT_SHARED_LIBRARY

指向用於指定預編譯共享庫的編譯腳本。與 BUILD_SHARED_LIBRARY 和 BUILD_STATIC_LIBRARY 的狀況不一樣,這裏的 LOCAL_SRC_FILES 值不能是源文件,而必須是指向預編譯共享庫的一個路徑,例如 foo/libfoo.so。使用此變量的語法爲:

include $(PREBUILT_SHARED_LIBRARY)
   
 

您也可使用 LOCAL_PREBUILTS 變量引用另外一個模塊中的預編譯庫。要詳細瞭解如何使用預編譯庫,請參閱使用預編譯庫

PREBUILT_STATIC_LIBRARY

與 PREBUILT_SHARED_LIBRARY 相同,但用於預編譯靜態庫。要詳細瞭解如何使用預編譯庫,請參閱使用預編譯庫

目標信息變量

 

編譯系統會根據 APP_ABI 變量所指定的每一個 ABI 解析 Android.mk 一次,該變量一般在 Application.mk 文件中定義。若是 APP_ABI 爲 all,則編譯系統會根據 NDK 支持的每一個 ABI 解析 Android.mk 一次。本部分介紹了編譯系統每次解析 Android.mk 時定義的變量。

TARGET_ARCH

編譯系統解析此 Android.mk 文件時面向的 CPU 系列。此變量是 armarm64x86 或 x86_64 之一。

TARGET_PLATFORM

編譯系統解析此 Android.mk 文件時面向的 Android API 級別編號。例如,Android 5.1 系統映像對應於 Android API 級別 22:android-22。如需平臺名稱和對應 Android 系統映像的完整列表,請參閱 Android NDK 原生 API。如下示例演示了使用此變量的語法:

ifeq ($(TARGET_PLATFORM),android-22)
        # ... do something ...
    endif
   
 

TARGET_ARCH_ABI

 

編譯系統解析此 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 將使用不一樣的值。

TARGET_ABI

目標 Android API 級別與 ABI 的鏈接,特別適用於要針對實際設備測試特定目標系統映像的狀況。例如,要檢查搭載 Android API 級別 22 的 64 位 ARM 設備:

ifeq ($(TARGET_ABI),android-22-arm64-v8a)
      # ... do something ...
    endif
   
 

模塊描述變量

 

本部分中的變量會向編譯系統描述您的模塊。每一個模塊描述都應遵照如下基本流程:

  1. 使用 CLEAR_VARS 變量初始化或取消定義與模塊相關的變量。
  2. 爲用於描述模塊的變量賦值。
  3. 使用 BUILD_XXX 變量設置 NDK 編譯系統,使其將適當的編譯腳本用於該模塊。

LOCAL_PATH

此變量用於指定當前文件的路徑。必須在 Android.mk 文件開頭定義此變量。如下示例演示瞭如何定義此變量:

LOCAL_PATH := $(call my-dir)
   
 

CLEAR_VARS 所指向的腳本不會清除此變量。所以,即便 Android.mk 文件描述了多個模塊,您也只需定義它一次。

LOCAL_MODULE

此變量用於存儲模塊名稱。指定的名稱必須惟一,而且不得包含任何空格。必須在包含任何腳本(CLEAR_VARS 的腳本除外)以前定義此變量。無需添加 lib 前綴或者 .so 或 .a 文件擴展名;編譯系統會自動進行這些修改。在整個 Android.mk 和 Application.mk 文件中,請經過未經修改的名稱引用模塊。例如,如下行會致使生成名爲 libfoo.so的共享庫模塊:

LOCAL_MODULE := "foo"
   
 

若是但願生成的模塊使用除「lib + LOCAL_MODULE 的值」之外的名稱,您可以使用 LOCAL_MODULE_FILENAME 變量爲生成的模塊指定本身選擇的名稱。

LOCAL_MODULE_FILENAME

此可選變量使您可以替換編譯系統爲其生成的文件默認使用的名稱。例如,若是 LOCAL_MODULE 的名稱爲 foo,您能夠強制系統將它生成的文件命名爲 libnewfoo。如下示例演示瞭如何完成此操做:

LOCAL_MODULE := foo
    LOCAL_MODULE_FILENAME := libnewfoo
   
 

對於共享庫模塊,此示例將生成一個名爲 libnewfoo.so 的文件。

注意:您沒法替換文件路徑或文件擴展名。

LOCAL_SRC_FILES

此變量包含編譯系統生成模塊時所用的源文件列表。只列出編譯系統實際傳遞到編譯器的文件,由於編譯系統會自動計算全部相關的依賴關係。請注意,您可使用相對(相對於 LOCAL_PATH)和絕對文件路徑。

建議避免使用絕對文件路徑;相對路徑能夠提升 Android.mk 文件的移植性。

注意:務必在編譯文件中使用 Unix 樣式的正斜槓 (/)。編譯系統沒法正確處理 Windows 樣式的反斜槓 (\)。

LOCAL_CPP_EXTENSION

可使用此可選變量爲 C++ 源文件指明 .cpp 之外的文件擴展名。例如,如下行將擴展名更改成 .cxx。(設置必須包含點。)

LOCAL_CPP_EXTENSION := .cxx
   
 

您可使用此變量指定多個擴展名。例如:

LOCAL_CPP_EXTENSION := .cxx .cpp .cc
   
 

LOCAL_CPP_FEATURES

您可以使用此可選變量指明您的代碼依賴於特定 C++ 功能。它會在編譯過程當中啓用正確的編譯器標記和連接器標記。對於預編譯二進制文件,此變量還會聲明二進制文件依賴於哪些功能,從而確保最終連接正常運行。建議您使用此變量,而不要直接在 LOCAL_CPPFLAGS 定義中啓用 -frtti 和 -fexceptions

使用此變量可以讓編譯系統對每一個模塊使用適當的標記。使用 LOCAL_CPPFLAGS 會致使編譯器將全部指定的標記用於全部模塊,而無論實際需求如何。

例如,要指明您的代碼使用 RTTI(運行時類型信息),請輸入:

LOCAL_CPP_FEATURES := rtti
   
 

要指明您的代碼使用 C++ 異常,請輸入:

LOCAL_CPP_FEATURES := exceptions
   
 

您還能夠爲此變量指定多個值。例如:

LOCAL_CPP_FEATURES := rtti features
   
 

描述值的順序可有可無。

LOCAL_C_INCLUDES

可使用此可選變量指定相對於 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 路徑。

LOCAL_CFLAGS

此可選變量用於設置在編譯 C 和 C++ 源文件時編譯系統要傳遞的編譯器標記。這樣,您就能夠指定額外的宏定義或編譯選項。可使用 LOCAL_CPPFLAGS 僅爲 C++ 指定標記。

請勿嘗試在 Android.mk 文件中更改優化/調試級別。編譯系統可使用 [pplication.mk] 文件中的相關信息自動處理此設置。這樣,編譯系統就能夠生成供調試期間使用的有用數據文件。

您可經過輸入如下代碼指定額外的 include 路徑:

LOCAL_CFLAGS += -I<path>,
   
 

可是,最好使用 LOCAL_C_INCLUDES,由於這樣也可使用可用於 ndk-gdb 原生調試的路徑。

LOCAL_CPPFLAGS

只編譯 C++ 源文件時將傳遞的一組可選編譯器標記。它們將出如今編譯器命令行中的 LOCAL_CFLAGS 後面。使用 LOCAL_CFLAGS 爲 C 和 C++ 指定標記。

LOCAL_STATIC_LIBRARIES

此變量用於存儲當前模塊依賴的靜態庫模塊列表。

若是當前模塊是共享庫或可執行文件,此變量將強制這些庫連接到生成的二進制文件。

若是當前模塊是靜態庫,此變量只是指出依賴於當前模塊的其餘模塊也會依賴於列出的庫。

LOCAL_SHARED_LIBRARIES

此變量會列出此模塊在運行時依賴的共享庫模塊。此信息是連接時必需的信息,用於將相應的信息嵌入到生成的文件中。

LOCAL_WHOLE_STATIC_LIBRARIES

此變量是 LOCAL_STATIC_LIBRARIES 的變體,表示連接器應將相關的庫模塊視爲完整歸檔。要詳細瞭解完整歸檔,請參閱 GNU ld 文檔的 --whole-archive 標記部分。

多個靜態庫之間存在循環依賴關係時,此變量頗有用。使用此變量編譯共享庫時,它將強制編譯系統將靜態庫中的全部對象文件添加到最終二進制文件。可是,生成可執行文件時不會發生這種狀況。

LOCAL_LDLIBS

此變量列出了在編譯共享庫或可執行文件時使用的額外連接器標記。利用此變量,您可以使用 -l 前綴傳遞特定系統庫的名稱。例如,如下示例指示連接器生成在加載時連接到 /system/lib/libz.so 的模塊:

LOCAL_LDLIBS := -lz
   
 

如需瞭解此 NDK 版本中能夠連接的公開系統庫列表,請參閱 Android NDK 原生 API

注意:若是爲靜態庫定義此變量,編譯系統會忽略此變量,而且 ndk-build 會顯示一則警告。

LOCAL_LDFLAGS

此變量列出了編譯系統在編譯共享庫或可執行文件時使用的其餘連接器標記。例如,要在 ARM/X86 上使用 ld.bfd 連接器:

LOCAL_LDFLAGS += -fuse-ld=bfd
   
 

注意:若是爲靜態庫定義此變量,編譯系統會忽略此變量,而且 ndk-build 會顯示一則警告。

LOCAL_ALLOW_UNDEFINED_SYMBOLS

默認狀況下,若是編譯系統在嘗試編譯共享庫時遇到未定義的引用,將會拋出「未定義的符號」錯誤。此錯誤可幫助您捕獲源代碼中的錯誤。

要停用此檢查,請將此變量設置爲 true。請注意,此設置可能會致使共享庫在運行時加載。

注意:若是爲靜態庫定義此變量,編譯系統會忽略此變量,而且 ndk-build 會顯示一則警告。

LOCAL_ARM_MODE

默認狀況下,編譯系統會在 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 代碼。

LOCAL_ARM_NEON

此變量僅在以 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 前面。

LOCAL_DISABLE_FORMAT_STRING_CHECKS

默認狀況下,編譯系統會在編譯代碼時保護格式字符串。這樣的話,若是 printf 樣式的函數中使用了很是量格式的字符串,就會強制引起編譯器錯誤。此保護默認啓用,但您也可經過將此變量的值設置爲 true 將其停用。若是沒有必要的緣由,咱們不建議停用。

LOCAL_EXPORT_CFLAGS

此變量用於記錄一組 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_CPPFLAGS

此變量與 LOCAL_EXPORT_CFLAGS 相同,但僅適用於 C++ 標記。

LOCAL_EXPORT_C_INCLUDES

此變量與 LOCAL_EXPORT_CFLAGS 相同,但適用於 C include 路徑。例如,當 bar.c 須要包含模塊 foo 的頭文件時,此變量頗有用。

LOCAL_EXPORT_LDFLAGS

此變量與 LOCAL_EXPORT_CFLAGS 相同,但適用於連接器標記。

LOCAL_EXPORT_LDLIBS

此變量與 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,所以它也依賴於系統日誌記錄庫。

LOCAL_SHORT_COMMANDS

當模塊有不少源文件和/或依賴的靜態或共享庫時,請將此變量設置爲 true。這樣會強制編譯系統將 @ 語法用於包含中間對象文件或連接庫的歸檔。

此功能在 Windows 上可能頗有用,在 Windows 上,命令行最多隻接受 8191 個字符,這對於複雜的項目來講可能太少。它還會影響個別源文件的編譯,並且將幾乎全部編譯器標記都放在列表文件內。

請注意,true 之外的任何值都將恢復爲默認行爲。您也能夠在 Application.mk 文件中定義 APP_SHORT_COMMANDS,以對項目中的全部模塊強制實施此行爲。

不建議默認啓用此功能,由於它會減慢編譯速度。

LOCAL_THIN_ARCHIVE

編譯靜態庫時,請將此變量設置爲 true。這樣會生成一個瘦歸檔,即一個庫文件,其中不含對象文件,而只包含它一般包含的實際對象的文件路徑。

這對於減少編譯輸出的大小很是有用。但缺點是,這樣的庫沒法移至其餘位置(其中的全部路徑都是相對路徑)。

有效值爲 truefalse 或空白。您可在 Application.mk 文件中經過 APP_THIN_ARCHIVE 變量設置默認值。

注意:在非靜態庫模塊或預編譯的靜態庫模塊中,將會忽略此變量。

LOCAL_FILTER_ASM

請將此變量定義爲一個 shell 命令,供編譯系統用於過濾根據您爲 LOCAL_SRC_FILES 指定的文件提取或生成的彙編文件。定義此變量會致使發生如下狀況:

  1. 編譯系統從任何 C 或 C++ 源文件生成臨時彙編文件,而不是將它們編譯到對象文件中。
  2. 編譯系統在任何臨時彙編文件以及 LOCAL_SRC_FILES 中所列任何彙編文件的 LOCAL_FILTER_ASM 中執行 shell 命令,所以會生成另外一個臨時彙編文件。
  3. 編譯系統將這些過濾的彙編文件編譯到對象文件中。

例如:

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 提供的函數宏

 

本部分介紹了 NDK 提供的 GNU Make 函數宏。使用 $(call <function>) 能夠對這些宏進行求值;它們將返回文本信息。

my-dir

這個宏返回最後包含的 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
   
 

all-subdir-makefiles

返回位於當前 my-dir 路徑全部子目錄中的 Android.mk 文件列表。

利用此函數,您能夠爲編譯系統提供深度嵌套的源目錄層次結構。默認狀況下,NDK 只在 Android.mk 文件所在的目錄中查找文件。

this-makefile

返回當前 makefile(編譯系統從中調用函數)的路徑。

parent-makefile

返回包含樹中父 makefile 的路徑(包含當前 makefile 的 makefile 的路徑)。

grand-parent-makefile

返回包含樹中祖父 makefile 的路徑(包含當前父 makefile 的 makefile 的路徑)。

import-module

此函數用於按模塊名稱查找和包含模塊的 Android.mk 文件。典型的示例以下所示:

$(call import-module,<name>)
   
 

在此示例中,編譯系統在 NDK_MODULE_PATH 環境變量所引用的目錄列表中查找具備 <name> 標記的模塊,而且自動包含其 Android.mk 文件。

相關文章
相關標籤/搜索