此页面介绍了 ndk-build
使用的 Android.mk
构建文件语法。
概述
Android.mk
文件位于项目的 jni/
目录的子目录中,并向构建系统描述您的源文件和共享库。它实际上是一个微小的 GNU makefile 片段,构建系统会解析一次或多次。Android.mk
文件对于定义 Application.mk
、构建系统和您的环境变量未定义的项目范围设置很有用。它还可以为特定模块覆盖项目范围设置。
Android.mk
的语法允许您将源文件分组到模块中。模块可以是静态库、共享库或独立可执行文件。您可以在每个 Android.mk
文件中定义一个或多个模块,并且可以在多个模块中使用同一个源文件。构建系统仅将共享库放入您的应用包中。此外,静态库可以生成共享库。
除了打包库外,构建系统还为您处理各种其他细节。例如,您无需在 Android.mk
文件中列出头文件或生成的之间的显式依赖关系。NDK 构建系统会自动为您计算这些关系。因此,您应该能够在不修改 Android.mk
文件的情况下,从将来 NDK 版本中的新工具链/平台支持中获益。
此文件的语法与 Android 开放源代码项目 分发的 Android.mk
文件中使用的语法非常接近。虽然使用它们的构建系统实现不同,但它们的相似性是旨在简化应用开发者重用外部库源代码的刻意设计决策。
基本知识
在详细介绍语法之前,了解 Android.mk
文件的内容的基本知识很有用。本节使用 Hello-JNI 示例中的 Android.mk
文件为此目的,解释文件中每行代码的作用。
Android.mk
文件必须首先定义 LOCAL_PATH
变量
LOCAL_PATH := $(call my-dir)
此变量指示源文件在开发树中的位置。这里,构建系统提供的宏函数 my-dir
返回当前目录的路径(包含 Android.mk
文件本身的目录)。
下一行声明 CLEAR_VARS
变量,其值为构建系统提供的。
include $(CLEAR_VARS)
CLEAR_VARS
变量指向一个特殊的 GNU Makefile,该文件会为您清除许多 LOCAL_XXX
变量,例如 LOCAL_MODULE
、LOCAL_SRC_FILES
和 LOCAL_STATIC_LIBRARIES
。请注意,它不会清除 LOCAL_PATH
。此变量必须保留其值,因为系统在单个 GNU Make 执行上下文中解析所有构建控制文件,所有变量都是全局的。您必须在描述每个模块之前(重新)声明此变量。
接下来,LOCAL_MODULE
变量存储要构建的模块的名称。在应用程序中,每个模块使用此变量一次。
LOCAL_MODULE := hello-jni
每个模块名称必须是唯一的,并且不能包含任何空格。构建系统在生成最终的共享库文件时,会自动将适当的前缀和后缀添加到分配给 LOCAL_MODULE
的名称。例如,上面显示的示例会导致生成名为 libhello-jni.so
的库。
下一行列出了源文件,用空格分隔多个文件。
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 定义的包含变量
本节讨论构建系统在解析 Android.mk
文件之前定义的 GNU Make 变量。在某些情况下,NDK 可能会多次解析 Android.mk
文件,每次解析时对其中一些变量使用不同的定义。
CLEAR_VARS
此变量指向一个构建脚本,该脚本将取消定义下面“开发人员定义的变量”部分中列出的几乎所有 LOCAL_XXX
变量。使用此变量在描述新模块之前包含此脚本。使用它的语法为
include $(CLEAR_VARS)
BUILD_EXECUTABLE
此变量指向一个构建脚本,该脚本收集您在 LOCAL_XXX
变量中提供的有关模块的所有信息,并确定如何从您列出的源代码构建目标可执行文件。请注意,使用此脚本需要您至少已经为 LOCAL_MODULE
和 LOCAL_SRC_FILES
分配了值(有关这些变量的更多信息,请参阅 模块描述变量)。
使用此变量的语法为
include $(BUILD_EXECUTABLE)
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
一次,APP_ABI
通常在您的 Application.mk
文件中定义。如果 APP_ABI
为 all
,则构建系统会为 NDK 支持的每个 ABI 解析 Android.mk
一次。本节介绍构建系统每次解析 Android.mk
时定义的变量。
TARGET_ARCH
构建系统在解析此 Android.mk
文件时所针对的 CPU 系列。此变量将是以下之一:arm
、arm64
、x86
或 x86_64
。
TARGET_PLATFORM
构建系统在解析此 Android.mk
文件时所针对的 Android API 级别编号。例如,Android 5.1 系统映像对应于 Android API 级别 22:android-22
。有关平台名称和对应 Android 系统映像的完整列表,请参阅 原生 API。以下示例显示了使用此变量的语法
ifeq ($(TARGET_PLATFORM),android-22)
# ... do something ...
endif
TARGET_ARCH_ABI
构建系统在解析此 Android.mk
文件时所针对的 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 和相关兼容性问题的更多详细信息,请参阅 Android ABI。
将来新的目标 ABI 将具有不同的值。
TARGET_ABI
目标 Android API 级别和 ABI 的串联。当您想要针对真实设备的特定目标系统映像进行测试时,它特别有用。例如,要检查在 Android API 级别 22 上运行的 64 位 ARM 设备
ifeq ($(TARGET_ABI),android-22-arm64-v8a)
# ... do something ...
endif
模块描述变量
本节中的变量向构建系统描述您的模块。每个模块描述都应遵循以下基本流程。
- 使用
CLEAR_VARS
变量初始化或取消定义与模块关联的变量。 - 为用于描述模块的变量分配值。
- 使用
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
文件更便携。
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++ 和汇编)时将其添加到包含搜索路径中。例如
LOCAL_C_INCLUDES := sources/foo
或者
LOCAL_C_INCLUDES := $(LOCAL_PATH)/<subdirectory>/foo
在通过 LOCAL_CFLAGS
或 LOCAL_CPPFLAGS
设置任何相应的包含标志之前,定义此变量。
构建系统还在使用 ndk-gdb 启动原生调试时自动使用 LOCAL_C_INCLUDES
路径。
LOCAL_ASFLAGS
构建 .s
或 .S
文件时传递给 Clang 的标志。
LOCAL_ASMFLAGS
构建 .asm
文件时传递给 yasm 的标志。
LOCAL_CFLAGS
构建 C、C++ 和某些汇编(.s
和 .S
,但不包括 .asm
)源文件时传递给 Clang 的标志。这种能力对于指定额外的宏定义或编译选项很有用。使用 LOCAL_CPPFLAGS
指定仅适用于 C++ 的标志。使用 LOCAL_CONLYFLAGS
指定仅适用于 C 的标志。
尽量不要在您的 Android.mk
文件中更改优化/调试级别。构建系统可以使用 Application.mk
文件中的相关信息自动处理此设置。这样做允许构建系统生成在调试过程中使用的有用数据文件。
可以通过编写以下内容来指定额外的包含路径
LOCAL_CFLAGS += -I<path>,
但是,最好为此目的使用 LOCAL_C_INCLUDES
,因为这样做还可以使用 ndk-gdb 可用于原生调试的路径。
LOCAL_CONLYFLAGS
编译 C 源代码时传递给 Clang 的标志。与 LOCAL_CFLAGS
不同,LOCAL_CONLYFLAGS
在编译 C++ 或汇编源代码时不会传递给 Clang。
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 版本中链接的公开系统库的列表,请参阅 原生 API。
LOCAL_LDFLAGS
构建系统在构建您的共享库或可执行文件时使用的其他链接器标志列表。例如,要使用 ARM/X86 上的 ld.bfd
链接器
LOCAL_LDFLAGS += -fuse-ld=bfd
LOCAL_ALLOW_UNDEFINED_SYMBOLS
默认情况下,当构建系统在尝试构建共享时遇到未定义的引用时,它会抛出未定义符号错误。此错误可以帮助您发现源代码中的错误。
要禁用此检查,请将此变量设置为 true
。请注意,此设置可能会导致共享库在运行时加载。
LOCAL_ARM_MODE
默认情况下,构建系统以拇指模式生成 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
LOCAL_ARM_NEON
此变量仅在您针对 armeabi-v7a
ABI 时才重要。它允许在您的 C 和 C++ 源代码中使用 ARM 高级 SIMD(NEON)编译器内联函数,以及在汇编文件中使用 NEON 指令。
请注意,并非所有基于 ARMv7 的 CPU 都支持 NEON 指令集扩展。因此,您必须执行运行时检测才能在运行时安全地使用此代码。有关更多信息,请参阅 Neon 支持 和 CPU 功能。
或者,您可以使用 .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
,它们依赖于 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
,而 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 包含路径。在某些情况下,它很有用,例如,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
。这样做会生成一个**精简档案**,这是一个库文件,它不包含对象文件,而是只包含指向它通常包含的实际对象的路径。
这有助于减少构建输出的大小。缺点是此类库**不能**移动到其他位置(它们内部的所有路径都是相对的)。
有效值为 true
、false
或空。可以在您的 Application.mk
文件中通过 APP_THIN_ARCHIVE
变量设置默认值。
LOCAL_FILTER_ASM
将此变量定义为一个 shell 命令,构建系统将使用该命令来过滤从您为 LOCAL_SRC_FILES
指定的文件中提取或生成的汇编文件。定义此变量会导致以下情况发生
- 构建系统从任何 C 或 C++ 源文件生成一个临时汇编文件,而不是将它们编译成目标文件。
- 构建系统在任何临时汇编文件和在
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 提供的功能宏
本节介绍 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
,因为这是它最近的包含指向的位置。
可以通过将其他包含内容放在 Android.mk
文件中的所有其他内容之后来避免此问题。例如
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
文件。