一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

Android.mk官方說明 中文翻譯

 jiffes 2017-08-10

轉(zhuǎn)載請注明出處:http://blog.csdn.net/qq_15650553/article/details/51548025

譯者注:第一次做這樣的翻譯,自己感覺還是很多不足,有些概念沒有很好的理解,所以翻譯過來的中文可能也會有問題。這篇文章主要是用來記錄自己的學(xué)習(xí)所得。所以網(wǎng)友們?nèi)粢鶕?jù)下面的譯文來學(xué)習(xí),不是不行,但是請謹(jǐn)慎。

這篇文章描述了Android.mk文件的語法,這個文件將android NDK與你的c/c++代碼聯(lián)系到一起。

Overview

這個Android.mk文件存在于你的project下的jni目錄的子目錄中,它向編譯系統(tǒng)描述了你的源碼和共享庫。這個文件是GNU makefile的一個小的片段,編譯系統(tǒng)會讀取它一次或者多次。The Android.mk file is useful for defining project-wide settings that Application.mk, the build system, and your environment variables leave undefined。 It can also override project-wide settings for specific modules.

你可以利用Android.mk的語法將你的源碼分為多個module。一個module可以是一個靜態(tài)庫,或者是一個共享庫,又或者是一個獨(dú)立的可執(zhí)行文件。你可以在每個android.mk文件中定義一個或者多個module,而且你還可以在不同的module中使用相同的源文件。編譯系統(tǒng)只會將共享庫放到你的應(yīng)用的包中。另外,靜態(tài)庫是可以生成共享庫的。

為了打包這些庫,編譯系統(tǒng)為你處理了大量的細(xì)節(jié)。例如,你不必要在android.mk中列出頭文件,也不必列出生成的文件之間的明確的依賴關(guān)系。NDK編譯系統(tǒng)已經(jīng)為你自動的計算好了這些關(guān)系。因此,你應(yīng)該從未來的支持新的toolchain/platform的NDK版本中獲得便利,不用去編輯Android.mk文件。

此android.文件的語法與Android Open Source Project中使用的 Android.mk文件非常接近。While the build system implementation that uses them is different, their similarity is an intentional design decision aimed at making it easier for application developers to reuse source code for external libraries。

Basics

在開始探索Android.mk文件的語法之前,先理解Android.mk的基本組件會非常有用。這章里面使用了Hello-JNI 示例工程里面的Android.mk,并且解釋了這個文件中的每一行所扮演的角色。

一個Android.mk文件必須以定義LOCAL_PATH 開始:

LOCAL_PATH := $(call my-dir)

這個變量指示了源碼文件在development tree中的位置。這里,my-dir這個宏函數(shù)使用編譯系統(tǒng)提供的,返回了當(dāng)前目錄的路徑(這個目錄包含了 Android.mk文件本身)。
接下來的一行定義了CLEAR_VARS 這個變量的是由編譯系統(tǒng)提供的。

include $(CLEAR_VARS)

CLEAR_VARS這個變量指向了一個特殊的 GNU Makefile,這個Makefile會為你清除很多類似于LOCAL_XXX 的變量,例如LOCAL_MODULE,LOCAL_SRC_FILES,以及LOCAL_STATIC_LIBRARIES。注意,這里并沒有清除LOCAL_PATH。這個變量必須保持它的值因為the system parses all build control files in a single GNU Make execution context where all variables are global。你必須在描述每個module之前都要聲明一下這個變量。

然后,LOCAL_MODULE 這個變量用來存你想要編譯的module的名字。在你的應(yīng)用的每個module中都要使用一次這個變量。

LOCAL_MODULE := hello-jni

每個module的名字都必須是唯一的并且不能包含空格。當(dāng)編譯系統(tǒng)生成最終的共享庫時,會自動把你賦予LOCAL_MODULE 的值加上前綴和后綴,例如,上面的例子會生成一個名字為libhello-jni.so的庫。

注意:如果你的module的名字的前綴已經(jīng)加上了lib,編譯系統(tǒng)就不會再為你加前綴了,它會直接以這個module的名字為共享庫的名字,并加上.so的擴(kuò)展名。所以,假如一個源文件的名字本來就叫l(wèi)ibfoo.c,那么產(chǎn)生的共享庫的名字就是libfoo.so。這種特性是為了支持 Android platform sources通過Android.mk產(chǎn)生的共享庫;像這樣的庫的名字都會以lib開頭。

接下來的一行列出源文件,使用空格隔離不同的源文件:

LOCAL_SRC_FILES := hello-jni.c

LOCAL_SRC_FILES 必須包括你想要包含進(jìn)module的c/c++的源文件的列表。

最后一行幫助系統(tǒng)把每件事物聯(lián)系起來。

include $(BUILD_SHARED_LIBRARY)

BUILD_SHARED_LIBRARY 這個變量指向一個GNU Makefile腳本,這個腳本會收集自你定義的從最近的include之后的每個LOCAL_XXX變量的信息。這個腳本確定了build什么東西,以及怎么build.

這里還有更加復(fù)雜的示例代碼,在samples 文件夾里面,這些代碼都包含有帶注釋的Android.mk文件。除此以外,Sample: native-activity 提供了很詳細(xì)的關(guān)于 Android.mk 文件的解釋。最后,Variables and Macros提供了對這章中的變量的更深入的解釋。

Variables and Macros

編譯系統(tǒng)提供了很多可以在 Android.mk 里面使用的變量。大部分變量都是預(yù)先指定好了值。其他的變量的值你來指定。

除了這些變量以外,你還可以定義自己的變量。如果你打算這樣做,記住NDK系統(tǒng)保留了以下變量名:

  • 以LOCAL_開頭的名字,例如LOCAL_MODULE。

  • 以PRIVATE_、NDK_或者APP開頭的。編譯系統(tǒng)在內(nèi)部使用這些變量名。

  • 小寫的變量名,例如my-dir。編譯系統(tǒng)同樣在內(nèi)部使用這些變量名。

如果你想要在 Android.mk中定義自己的變量,我們建議你在名字前面加上MY_ 。

NDK定義的變量

這一章我們討論 GNU Make 變量,這些變量是在編譯系統(tǒng)解析Android.mk 文件之前就定義好了的。在某些情況下,NDK會多次解析你的Android.mk文件,每一次使用不同的定義去解析其中一些變量。

CLEAR_VARS

這個變量指向一個構(gòu)建腳本,這個腳本的作用是清除幾乎所有的在上一章提到的LOCAL_XXX 變量。在描述一個新的module之前使用這個變量去引用這個腳本使用它的語法是:

include $(CLEAR_VARS)

BUILD_SHARED_LIBRARY

這個變量指向了一個腳本,這個腳本會收集你在每個module定義的LOCAL_XXX變量信息,而且這個變量還確定了怎樣使用你的源碼去編譯一個共享庫。注意,使用這個變量需要你至少已經(jīng)定義了LOCAL_MODULE 和LOCAL_SRC_FILES。(如需查看更多信息,參考 Module-Description Variables)

使用這個變量的語法如下:

include $(BUILD_SHARED_LIBRARY)

一個這樣的變量會使編譯系統(tǒng)生成一個以.so結(jié)尾的庫。

BUILD_STATIC_LIBRARY

這個變量是BUILD_SHARED_LIBRARY 的一個變體,是用來生成一個靜態(tài)庫。構(gòu)建系統(tǒng)并不會把靜態(tài)庫包含進(jìn)你的工程里面,但是可以利用靜態(tài)庫生成共享庫(參考 LOCAL_STATIC_LIBRARIES 和 LOCAL_WHOLE_STATIC_LIBRARIES,在下面)。這個變量的語法是:

include $(BUILD_STATIC_LIBRARY)

這樣的一個變量會使編譯系統(tǒng)生成一個以.a結(jié)尾的庫。

PREBUILT_SHARED_LIBRARY

指向一個腳本,這個腳本被用來指定一個預(yù)構(gòu)建的共享庫。與BUILD_SHARED_LIBRARY 和 BUILD_STATIC_LIBRARY 不同,LOCAL_SRC_FILES 的值不能是一個源文件,它必須是一個單獨(dú)的指向預(yù)構(gòu)建的共享庫的路徑,例如foo/libfoo.so。使用這個變量的語法是:

include $(PREBUILT_SHARED_LIBRARY)

你也可以在另一個module里面使用LOCAL_PREBUILTS 變量來引用一個預(yù)構(gòu)建的庫。更多信息查看 Using Prebuilt Libraries。

PREBUILT_STATIC_LIBRARY

與 PREBUILT_SHARED_LIBRARY 相同,只是指向的一個預(yù)構(gòu)建的靜態(tài)庫。更多信息請見 Using Prebuilt Libraries。

TARGET_ARCH

這個變量是目標(biāo)CPU架構(gòu)的名字,就像 Android Open Source Project 里面指定了目標(biāo)CPU架構(gòu)。這個變量用于任意的ARM兼容的構(gòu)建,或者ARM,或者是獨(dú)立于CPU結(jié)構(gòu)的修訂,或者ABI (見下方 TARGET_ARCH_ABI)。

這個變量的值是從你在 Android.mk 文件定義的APP_ABI 中得到的,系統(tǒng)會在解析Android.mk 文件之前讀取APP_ABI 。

TARGET_PLATFORM

這個變量代表系統(tǒng)構(gòu)建的目標(biāo)Android API 的數(shù)字。例如,Android 5.1對應(yīng)Android API 22:android-22。想要知道完整的系統(tǒng)和api對應(yīng)的關(guān)系,請參考 Android NDK Native APIs。下面的例子展示了如何使用這個變量:

TARGET_PLATFORM := android-22

TARGET_ARCH_ABI

當(dāng)編譯系統(tǒng)解析Android.mk文件的時候,這個變量存儲CPU和架構(gòu)的名字。你可以指定一個或者多個下面列出的名字,使用空格分隔兩個名字,Table 1 展示了使用每種CPU和架構(gòu)時ABI的設(shè)置。

Table 1. 對于不用的CPU和架構(gòu),ABI的設(shè)置。

CPU和架構(gòu) 設(shè)置
ARMv5TE armeabi
ARMv7 armeabi-v7a
ARMv8 AArch64 arm64-v8a
i686 x86
x86-64 x86_64
mips32 (r1) mips
mips64 (r6) mips64
All all

下面的例子展示了如何設(shè)置ARMv8 AArch64 為目標(biāo)架構(gòu):

TARGET_ARCH_ABI := arm64-v8a

注意: Android NDK 1.6_r1之前這個這個變量被定義為arm。

如需了解更多關(guān)于架構(gòu)ABIs和相關(guān)問題,參考 ABI Management;

未來出現(xiàn)的新的架構(gòu)ABI會有不同的值。

TARGET_ABI

將API的級別和ABI聯(lián)系在一起,當(dāng)你在真機(jī)上調(diào)試系統(tǒng)的時候特別有用。例如,指定一個64位的搭載Android 22的ARM設(shè)備:

TARGET_ABI := android-22-arm64-v8a

注意: 直到 Android NDK 1.6_r1,默認(rèn)的值是android-3-arm。

Module-Description Variables 描述module的變量

這章的這些變量用于描述你的module用于系統(tǒng)構(gòu)建。每一條module的描述都應(yīng)遵從以下原則:

  1. 如需初始化或者去掉與此module相關(guān)的變量,使用CLEAR_VARS 。
  2. 通過給這些變量賦值的方式來描述module。
  3. 如需設(shè)置NDK使用合適的腳本編譯module,使用BUILD_XXX 。

LOCAL_PATH

這個變量的作用是給出當(dāng)前文件的路徑。你必須在 Android.mk文件的開頭定義它。下面的例子展示了怎樣使用:

LOCAL_PATH := $(call my-dir)

指向CLEAR_VARS的腳本不會清除這個變量。因此,即使你的Android.mk文件里面定義了幾個module,你仍然只需要定義一次這個變量。

LOCAL_MODULE

這個變量存儲你的module的名字。在所有定義的module中這個變量的值必須是唯一的,并且不能包含空格。你必須在包含任何腳本文件之間就要定義它(除了 CLEAR_VARS)。你不必要添加lib前綴或者.so和.a后綴。編譯系統(tǒng)會自動添加前綴和后綴。在 Android.mk和Application.mk文件里面都是通過引用module的名字來表示該module的。(Throughout your Android.mk and Application.mk files, refer to your module by its unmodified name)。例如,下面這句會生成一個名為libfoo.so 的共享庫module:

LOCAL_MODULE := "foo"

如果你希望生成的庫的名字不是lib加上LOCAL_MODULE 的值,你可以使用LOCAL_MODULE_FILENAME 來設(shè)置你想要的名字。

LOCAL_MODULE_FILENAME

這個變量是可選的,允許你通過這個變量來設(shè)置生成的庫的名字而不是采用系統(tǒng)默認(rèn)的名字。例如,你的LOCAL_MODULE 的值是foo,你可以強(qiáng)制讓系統(tǒng)生成的庫的名字為 libnewfoo。下面的一行展示了如何做:

LOCAL_MODULE := foo
LOCAL_MODULE_FILENAME := libnewfoo

如果是生成一個共享庫,那么文件的名字會是 libnewfoo.so。

注意: 你i無法做到修改文件路徑或者后綴名。

LOCAL_SRC_FILES

這個變量包含你想要組成module的源文件的列表。只要列出需要編譯器編譯的源文件就可以了,編譯系統(tǒng)會自動計算出依賴關(guān)系。

注意絕對路徑和相對路徑你都可以使用。

我們建議你避免使用絕對路徑,這樣可以使你的 Android.mk文件更加輕便。

注意: 在構(gòu)建文件里面應(yīng)只使用unix風(fēng)格 的正斜杠(/)。構(gòu)建系統(tǒng)不識別Windows風(fēng)格的反斜杠(\)。

LOCAL_CPP_EXTENSION

你可以使用這個可選的變量來指定你的C++源文件的除了.cpp以外其他的后綴名。例如,下面的例子將后綴名變成了 .cxx (必須包含前面的‘.’):

LOCAL_CPP_EXTENSION := .cxx

自從 NDK r7 以后,你可以使用這個變量指定多個后綴名。例如:

LOCAL_CPP_EXTENSION := .cxx .cpp .cc

LOCAL_CPP_FEATURES

你可以使用這個可選的變量來指明你的代碼依賴于特別的C++特性。它會在構(gòu)建的過程中使用對應(yīng)的編譯器和鏈接器。這個變量還可以定義那些預(yù)構(gòu)建的二進(jìn)制文件所依賴的特性,以幫助最后的鏈接過程變正確。我們建議你使用這個變量而不是使用LOCAL_CPPFLAGS 直接打開frtti 和 fexceptions 特性。使用這個變量可以幫助編譯系統(tǒng)為每個module設(shè)一個單獨(dú)的合適的信號值(flags )。使用 LOCAL_CPPFLAGS 會導(dǎo)致編譯器為所有的module設(shè)置所有的指定的信號值,而不管真正需要的是什么。

例如,指定你的代碼使用RTTI(運(yùn)行時類型信息),寫下:

LOCAL_CPP_FEATURES := rtti

指定你的代碼使用C++異常:

LOCAL_CPP_FEATURES := exceptions

你也可以指定多個值:

LOCAL_CPP_FEATURES := rtti features

值的先后順序并不重要。

LOCAL_C_INCLUDES

你可以使用這個變量去指定NDK編譯代碼(C,C++,匯編)的時候include的路徑。例如:

LOCAL_C_INCLUDES := sources/foo

甚至:

LOCAL_C_INCLUDES := $(LOCAL_PATH)//foo

在使用 LOCAL_CFLAGS 和 LOCAL_CPPFLAGS 設(shè)置include之前就要定義這個變量。

編譯系統(tǒng)還會在使用ndk-gdb調(diào)試作原生的調(diào)試的時候使用LOCAL_C_INCLUDES 定義的路徑。

LOCAL_CFLAGS

這個可選的變量設(shè)置編譯系統(tǒng)在編譯C和C++代碼時需要傳遞的編譯器標(biāo)記(compiler flags)。這個特性在指定額外的宏定義或者編譯選項的時候會非常有用。

盡量不要在Android.mk中更改 optimization/debugging 的級別。編譯系統(tǒng)會自動根據(jù) Application.mk中的相關(guān)信息為你設(shè)置這個變量。使用這種方式編譯系統(tǒng)會生成在調(diào)試時很有用的數(shù)據(jù)文件。

注意: 在android-ndk-1.5_r1中,這個flag值僅用于c文件中,c++文件不行。現(xiàn)在他們適配了完整的Android構(gòu)建系統(tǒng)的特性。(你現(xiàn)在可以使用LOCAL_CPPFLAGS 專門設(shè)置C++文件的flag)。

通過線面這種方式指定額外的include路徑是可能的:

LOCAL_CFLAGS += -I<path>,

相比使用LOCAL_C_INCLUDES ,這樣做更好,因為這樣的話在使用ndk-gdb調(diào)試原生程序的時候也可以使用這些路徑。

LOCAL_CPPFLAGS

這個變量是可選的僅用于編譯C++源文件的時候需要傳遞的編譯器標(biāo)記。LOCAL_CPPFLAGS變量會在編譯器的命令行中出現(xiàn),是在LOCAL_CFLAGS 出現(xiàn)之后。

*注意:* 在android-ndk-1.5_r1中,這個變量同時作用于C和C++源文件。如果要為C和C++都指定編譯器標(biāo)記,使用LOCAL_CFLAGS。

LOCAL_STATIC_LIBRARIES

這個變量指定了當(dāng)前module依賴的靜態(tài)庫。

如果當(dāng)前的module是共享庫或者可執(zhí)行文件,這個變量會強(qiáng)制讓這些庫被連接進(jìn)最后生成的二進(jìn)制文件中。

如果當(dāng)前的module是靜態(tài)庫,這個變量僅表示依賴于當(dāng)前module的其他module也依賴于此變量指定的庫。

LOCAL_SHARED_LIBRARIES

這個變量指定了當(dāng)前module在運(yùn)行時依賴的共享庫。這個變量的信息在鏈接時是必需的,這個變量會將對應(yīng)的信息嵌入到最終生成的文件中。

LOCAL_WHOLE_STATIC_LIBRARIES

這個變量是LOCAL_STATIC_LIBRARIES的一個變種,它表示鏈接器應(yīng)該將相關(guān)聯(lián)的庫認(rèn)為是 whole archives。獲取更多關(guān)于whole archives的信息可以查看GNU 鏈接器的文檔,查看 –whole-archive 標(biāo)記。

當(dāng)幾個靜態(tài)庫中存在循環(huán)的依賴時這個變量非常有用。當(dāng)你使用這個變量構(gòu)建一個共享庫時,這個變量會強(qiáng)制讓編譯系統(tǒng)把所有的object文件從靜態(tài)庫中拷貝到最后的庫中。然后當(dāng)你要生成可執(zhí)行文件時這樣做就不對了。

LOCAL_LDLIBS

這個變量包含了額外的鏈接器標(biāo)記,這些標(biāo)記在構(gòu)建你的共享庫或者可執(zhí)行文件時會使用到。這個變量允許你通過以-l為前綴傳遞你指定的系統(tǒng)中的庫的名字。例如,下面的例子告訴鏈接器生成一個module,這個module在加載的時候鏈接上了 /system/lib/libz.so 。

LOCAL_LDLIBS := -lz

如果要查看可以在NDK中使用的系統(tǒng)庫的列表,查看 Android NDK Native APIs。

注意: 如果你在靜態(tài)庫中定義了這個變量,編譯系統(tǒng)會忽略它,并且ndk-build會打印警告。

LOCAL_LDFLAGS

這個變量表示編譯系統(tǒng)在構(gòu)建共享庫或者可執(zhí)行文件時需要的其他的鏈接器標(biāo)記的列表。下面的例子使用ARM/X86 GCC 4.6+平臺的ld.bfd鏈接器,其中l(wèi)d.gold 是默認(rèn)的:

LOCAL_LDFLAGS += -fuse-ld=bfd

注意: 如果你在靜態(tài)庫中定義了這個變量,編譯系統(tǒng)會忽略它,并且ndk-build會打印警告。

LOCAL_ALLOW_UNDEFINED_SYMBOLS

默認(rèn)的情況是,編譯系統(tǒng)如果在構(gòu)建一個共享庫時發(fā)現(xiàn)了一個未定義的引用時會拋出一個未定義錯誤(undefined symbol error)。這個錯誤在你尋找bug的時候很有用。

若要關(guān)閉這個檢查,設(shè)置這個變量為true即可。注意這樣做可能導(dǎo)致共享庫在運(yùn)行時加載。

注意: 如果你在靜態(tài)庫中定義了這個變量,編譯系統(tǒng)會忽略它,并且ndk-build會打印警告。

LOCAL_ARM_MODE

默認(rèn)地,在thumb 模式下編譯系統(tǒng)會生成ARM架構(gòu)的二進(jìn)制文件,這種模式下的都是16位的,并且會會鏈接thumb/目錄下的STL 庫文件。將這個變量定義為arm 會起強(qiáng)制編譯系統(tǒng)以32位的arm模式生成該module的object 文件。下面展示了怎樣做:

LOCAL_ARM_MODE := arm

你也可以讓編譯系統(tǒng)只針對你指定的文件以arm模式編譯,你需要在源文件的名字上加上.arm的后綴。例如,下面的例子會告訴編譯器總是以arm模式編譯bar.c,但是對于foo.c是根據(jù)LOCAL_ARM_MODE的值來編譯的。

LOCAL_SRC_FILES := foo.c bar.c.arm

注意: 你還可以通過設(shè)置 Application.mk中的 APP_OPTIM來實現(xiàn)生成ARM 的二進(jìn)制文件用來調(diào)試。指定debug 會強(qiáng)制以ARM模式構(gòu)建,因為工具鏈的調(diào)試器不會正確的處理Thumb 模式的代碼。

LOCAL_ARM_NEON

這變量僅在指定為armeabi-v7a ABI的時候有用。這個變量允許你在你的C、C++和匯編里面使用ARM 高級SIMD (NEON) GCC本證函數(shù)。

要注意并不是所以的ARMv7系列的CPU都支持NEON 指令集擴(kuò)展。由于這個原因,你必須在運(yùn)行時檢查,以便于安全地運(yùn)行代碼。更多信息查看NEON Support The cpufeatures Library。

或者,你還可以通過在源文件的名字后面加上.neon的方式讓編譯器針對指定的文件采取neon的支持。在下面的例子中,編譯系統(tǒng)會以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_NO_EXECUTE

Android NDK r4添加了 “NX bit”的安全特性的支持。這個是默認(rèn)開啟的,但是你可以通過設(shè)置這個變量為true來關(guān)閉它。我們不建議你在沒有一個很好的理由的情況下這樣做。

這項特性不會修改ABI,而且只會在ARMv6+的CPU的內(nèi)核中啟用。開啟了這樣特性的機(jī)器代碼會無修改地在運(yùn)行在使用更早的CPU架構(gòu)的設(shè)備上。

更多信息請參考Wikipedia: NX bitThe GNU stack kickstart。

LOCAL_DISABLE_RELRO

默認(rèn)的,NDK利用只讀的重定位地址和GOT保護(hù)。這個變量使運(yùn)行時的鏈接器對重定位后的某些內(nèi)存區(qū)域做出標(biāo)記作為只讀的內(nèi)存,使得某些安全漏洞更加困難(例如GOT重寫)。注意這些保護(hù)只在API 16 以后才具有,當(dāng)API 低于16,這些代碼任然會運(yùn)行,但是沒有內(nèi)存保護(hù)。

這個變量默認(rèn)是打開的,你也可以通過設(shè)置這個變量為true的方式關(guān)閉。沒有一個很好的理由的話我們不建議你這樣做。

更多信息查看 RELRO: RELocation Read-Only Security enhancements in RedHat Enterprise Linux (section 6)

LOCAL_DISABLE_FORMAT_STRING_CHECKS

默認(rèn)的,編譯系統(tǒng)編譯時具有字符串保護(hù)。這樣做會導(dǎo)致一個編譯器的錯誤,如果一個非常量(non-constant )的字符串被用于類似于printf的函數(shù)里面。

這個變量默認(rèn)是打開的,你也可以通過設(shè)置這個變量為true的方式關(guān)閉。沒有一個很好的理由的話我們不建議你這樣做。

LOCAL_EXPORT_CFLAGS

這個變量將一系列本module的 C/C++編譯標(biāo)記添加到通過LOCAL_STATIC_LIBRARIES 和 LOCAL_SHARED_LIBRARIES 來引用本module的那些module的LOCAL_CFLAGS 值里面。

例如,觀察下面這兩個module,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)

這里,編譯系統(tǒng)會在編譯器編譯bar.c的時候傳遞-DFOO=1和 -DBAR=2 給編譯器。編譯系統(tǒng)還會預(yù)先將那些你所引用的module的LOCAL_CFLAGS 的值添加到你現(xiàn)在的module的LOCAL_CFLAGS 里面,這樣你就可以很簡單的重寫它們了。

另外,module之間的關(guān)系是可傳遞的,如果zoo 依賴于 bar,bar依賴于foo,那么zoo也會繼承從foo那里來的標(biāo)記。

最后,編譯系統(tǒng)在本地編譯的時候并沒有使用導(dǎo)出的標(biāo)記(例如編譯一個標(biāo)記被導(dǎo)出的module)。因此,在上面的例子中,編譯foo/foo.c的時候并沒有向編譯器傳遞-DFOO=1 。如果要本地編譯,使用LOCAL_CFLAGS 。
(譯者注:此處的本地編譯(building locally)的概念不是很清楚)

LOCAL_EXPORT_CPPFLAGS

這個變量和 LOCAL_EXPORT_CFLAGS 是一樣的,只是這個變量只適用于C++標(biāo)記。

LOCAL_EXPORT_C_INCLUDES

這個變量和LOCAL_EXPORT_CFLAGS是一樣的,但是用于C的include的路徑。例如,當(dāng)bar.c需要引入foo的頭文件時這個變量就很有用。

LOCAL_EXPORT_LDFLAGS

這個和LOCAL_EXPORT_CFLAGS是一樣的,只是這個用于鏈接器標(biāo)識。

LOCAL_EXPORT_LDLIBS

這個和LOCAL_EXPORT_CFLAGS是一樣的,告訴構(gòu)建系統(tǒng)將指定的系統(tǒng)庫的名字傳遞給編譯器。你需要在你指定的庫的名字前加上 -l。

注意構(gòu)建系統(tǒng)會把鏈接器標(biāo)識導(dǎo)入到你的module的LOCAL_LDLIBS 值里面。這樣做是因為Unix鏈接器的工作方式。

當(dāng)foo是一個靜態(tài)庫并且含有依賴于系統(tǒng)庫的代碼時這個變量很有用。你可以使用LOCAL_EXPORT_LDLIBS 導(dǎo)出這些依賴,例如:

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)

在這個例子里面,構(gòu)建系統(tǒng)會在構(gòu)建libbar.so的時候?qū)?llog加到鏈接器命令的末尾。這樣做告訴了鏈接器:因為 libbar.so依賴于foo,所以它也會依賴于系統(tǒng)的log庫。

LOCAL_SHORT_COMMANDS

當(dāng)你的module里面含有很多源碼或者依賴于靜態(tài)庫或共享庫的時候?qū)⑦@個變量設(shè)置為true。Doing so forces the build system to use @ syntax for archives containing intermediate object files or linking libraries.

這個特性在Windows平臺很有用,因為Windows平臺的命令行最大包含8191個字符,對于復(fù)雜系統(tǒng)顯得太小了。 It also impacts the compilation of individual source files, placing nearly all compiler flags inside list files, too.

注意任何不是true的值都會導(dǎo)致變成默認(rèn)的設(shè)置。你也可以在Application.mk文件里面強(qiáng)制規(guī)定你的工程的所有的module的行為。

我們不建議默認(rèn)開啟這項特性,因為會讓構(gòu)建系統(tǒng)變得更慢。

LOCAL_THIN_ARCHIVE

當(dāng)構(gòu)建靜態(tài)庫的時候設(shè)置這個變量為true。這樣做會生成一個輕的、小的庫文件,這個庫文件一般不包含object文件,僅包含指向這些object文件的路徑。

這樣做對于減小輸出文件的大小很有用。這樣做的一個缺點是這個樣的庫文件不能移動到一個其他的位置(因為庫文件的里的路徑都是相對路徑)。

有效的值有,true,false,或者空格。你可以在 Application.mk 的APP_THIN_ARCHIVE上設(shè)置一個默認(rèn)的值。

注意: 在非靜態(tài)庫或者預(yù)構(gòu)建靜態(tài)庫的時候這個變量是被忽略的。

LOCAL_FILTER_ASM

(不是很理解,待翻譯)
Define this variable as a shell command that the build system will use to filter the assembly files extracted or generated from the files you specified for LOCAL_SRC_FILES.

Defining this variable causes the following things to occur:

The build system generates a temporary assembly file from any C or C++ source file, instead of compiling them into an object file.
The build system executes the shell command in LOCAL_FILTER_ASM on any temporary assembly file and on any assembly file listed in LOCAL_SRC_FILES, thus generating another temporary assembly file.
The build system compiles these filtered assembly files into an object file.
For example:

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” corresponds to the compiler, “2” to the filter, and “3” to the assembler. The filter must be a standalone shell command that takes the name of the input file as its first argument, and the name of the output file as the second one. For example:

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

NDK-provided function macros NDK提供的函數(shù)宏

這個章節(jié)介紹了NDK提供的GNU Make的函數(shù)宏。使用$(call <function>) 來求值,他們會返回文本信息。

my-dir

這個宏返回最近加入的makefile的路徑,一般是當(dāng)前的Android.mk的路徑。 my-dir在你的Android.mk 開頭的LOCAL_PATH 的定義中很有用,例如:

LOCAL_PATH := $(call my-dir)

由于GNU Make 的工作方式,這個宏的返回值是構(gòu)建系統(tǒng)在解析構(gòu)建腳本的時候最后引入的makefile的路徑。由于這個原因,你不應(yīng)該在include其他的文件之后還繼續(xù)使用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的調(diào)用將LOCAL_PATH 的值設(shè)置為了$PATH/foo 而不是$PATH/foo,因為$PATH/foo 才是最近include的路徑。

你可以在Android.mk文件中加入一些額外的includes來避免這個問題。例如:

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

如果這樣做不可行,那么你可以將第一次調(diào)用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 的列表。

你可以使用這個函數(shù)將深沉次的嵌套關(guān)系提供給構(gòu)建系統(tǒng)。默認(rèn)地,NDK只會在含有 Android.mk文件的目錄里面尋找文件。

this-makefile

返回當(dāng)前的makefile文件的路徑()。

parent-makefile

返回當(dāng)前的包含當(dāng)前的makefile的makefile的路徑。

grand-parent-makefile

Returns the path of the grandparent makefile in the inclusion tree (the path of the makefile that included the current one).

import-module

這是一個允許你通過module的名字找到并包含這個module的Android.mk文件。典型的應(yīng)用如下:

$(call import-module,<name>)

在這個例子里面,構(gòu)建系統(tǒng)會根據(jù)NDK_MODULE_PATH這個環(huán)境變量所指示的目錄里面尋找名為 <name> 的module,然后自動為你include對應(yīng)的 Android.mk文件。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    日韩精品一区二区三区四区| 国产精品99一区二区三区| 黄片免费播放一区二区| 日韩欧美国产精品自拍| 小草少妇视频免费看视频| 欧美尤物在线观看西比尔| 日韩成人午夜福利免费视频 | 激情五月激情婷婷丁香| 果冻传媒精选麻豆白晶晶| 日本人妻丰满熟妇久久| 成人国产激情在线视频| 亚洲中文字幕视频在线播放| 99久久婷婷国产亚洲综合精品| 中文字幕乱码一区二区三区四区| 又黄又爽禁片视频在线观看| 国产成人精品资源在线观看| 黄色国产一区二区三区| 99热中文字幕在线精品| 亚洲第一视频少妇人妻系列| 国产精品国产亚洲区久久| 日韩丝袜诱惑一区二区| 亚洲综合香蕉在线视频| 夫妻性生活真人动作视频| 国产91人妻精品一区二区三区| 日韩欧美综合中文字幕| 深夜视频在线观看免费你懂| 国产三级不卡在线观看视频| 日韩成人中文字幕在线一区| 久久综合亚洲精品蜜桃| 亚洲欧洲一区二区中文字幕| 国内精品偷拍视频久久| 欧美三级不卡在线观线看| 中文字幕一区二区三区中文| 台湾综合熟女一区二区| 欧美国产日本免费不卡| 中文字幕日韩无套内射| 五月天综合网五月天综合网| 国产一区二区三区午夜精品 | 大香蕉伊人精品在线观看| 日韩欧美国产精品中文字幕| 日本女人亚洲国产性高潮视频|