此页面描述了由 ndk-build
使用的 Android.mk
构建文件的语法。
概述
Android.mk
文件位于项目 jni/
目录的子目录中,它向构建系统描述了您的源代码和共享库。它实际上是一个微小的 GNU makefile 片段,构建系统会解析它一次或多次。Android.mk
文件用于定义 Application.mk
、构建系统和您的环境变量未定义的项目范围设置。它还可以覆盖特定模块的项目范围设置。
Android.mk
的语法允许您将源代码分组到模块中。模块可以是静态库、共享库或独立的可执行文件。您可以在每个 Android.mk
文件中定义一个或多个模块,并且可以在多个模块中使用相同的源文件。构建系统只会将共享库放入您的应用软件包中。此外,静态库可以生成共享库。
除了打包库之外,构建系统还会为您处理各种其他细节。例如,您不需要在 Android.mk
文件中列出头文件或生成文件之间的显式依赖项。NDK 构建系统会自动为您计算这些关系。因此,您应该能够在未来的 NDK 版本中受益于新的工具链/平台支持,而无需修改您的 Android.mk
文件。
此文件的语法与 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
,该变量通常在您的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
不同,编译 C++ 或汇编源代码时不会将 LOCAL_CONLYFLAGS
传递给 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
默认情况下,构建系统以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
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
,而后者又依赖于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
将此变量定义为构建系统将用来过滤从为LOCAL_SRC_FILES
指定的文件中提取或生成的汇编文件的 shell 命令。定义此变量会导致以下情况发生:
- 构建系统从任何 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
文件。