Android.mk 属性解析
LOCAL_PATH:=$(my-dir)
LOCAL_PATH := $(my-dir)
是一个重要的变量赋值语句,用于设置当前 Android.mk
文件所在的目录路径到 LOCAL_PATH
变量中。
具体解释如下:
- 作用:
LOCAL_PATH
是一个特殊的变量,用于表示当前Android.mk
文件所在的目录路径。这个变量通常用于构建规则中的路径操作,例如指定源文件路径、目标文件输出路径等。 - 赋值语句:
LOCAL_PATH := $(my-dir)
表示将变量LOCAL_PATH
的值设置为当前Android.mk
文件所在的目录路径。$(my-dir)
是一个内置函数,用于获取当前Android.mk
文件的目录路径。
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
# 定义模块类型为共享库
LOCAL_MODULE := mylibrary
# 定义要包含的源文件列表
LOCAL_SRC_FILES := file1.cpp file2.cpp
# 包括构建共享库的规则
include $(BUILD_SHARED_LIBRARY)
这个示例中,
LOCAL_PATH := $(call my-dir)
将当前 Android.mk
文件的目录路径赋值给了 LOCAL_PATH
变量。
接着,LOCAL_SRC_FILES
中的源文件路径将相对于 LOCAL_PATH
的值解析,从而构建系统可以正确地找到和编译源文件。
- 注意事项:
LOCAL_PATH
变量通常在Android.mk
文件的开头被设置,以确保后续路径操作可以基于正确的当前目录路径进行。- 使用
$(my-dir)
函数获取当前Android.mk
文件所在的目录路径是一种常见的做法,可以使构建规则更加灵活和可维护。 LOCAL_PATH
的设置对于定义源文件路径、包含其他模块文件、设置目标输出路径等操作非常有用。
include$(CLEAR_VARS)
include $(CLEAR_VARS)
是一个重要的指令,用于清除之前定义的模块变量,以便开始定义新的模块变量。
-
作用:
include $(CLEAR_VARS)
用于清除之前定义的模块变量,包括之前通过LOCAL_MODULE
、LOCAL_SRC_FILES
等方式定义的模块信息。这样做可以确保每个模块的定义是独立的,避免变量重叠或混淆。include $(CLEAR_VARS) # 定义模块类型为共享库 LOCAL_MODULE := mylibrary # 定义要包含的源文件列表 LOCAL_SRC_FILES := file1.cpp file2.cpp # 包括构建共享库的规则 include $(BUILD_SHARED_LIBRARY)
include $(CLEAR_VARS)
用于清除之前定义的模块变量,然后重新定义了一个名为
mylibrary
的共享库模块,并指定了包含的源文件列表。最后,通过
include $(BUILD_SHARED_LIBRARY)
包括了构建共享库的规则,从而完成了对mylibrary
模块的构建和编译。 -
注意事项:
- 在定义每个模块之前,通常会使用
include $(CLEAR_VARS)
来确保模块变量的清洁和隔离。 CLEAR_VARS
是一个预定义的模板文件,用于清除之前定义的模块变量。- 在
Android.mk
文件中,使用include
指令可以将其他模板或规则文件包含进来,以实现模块化的构建和管理。
- 在定义每个模块之前,通常会使用
LOCAL_MODULE_TAGS
LOCAL_MODULE_TAGS
:是用于指定模块标签的变量。模块标签通常用于指示构建系统在构建过程中如何处理特定的模块或库。
- 作用:
LOCAL_MODULE_TAGS
变量用于指定一个或多个模块标签,以控制构建系统对模块的处理方式。这些标签可以影响模块的编译、链接或部署方式。
include $(CLEAR_VARS)
# 定义模块类型为共享库
LOCAL_MODULE := mylibrary
# 定义要包含的源文件列表
LOCAL_SRC_FILES := file1.cpp file2.cpp
# 指定模块标签为 optional
LOCAL_MODULE_TAGS := optional
# 包括构建共享库的规则
include $(BUILD_SHARED_LIBRARY)
在这个示例中,LOCAL_MODULE_TAGS := optional
将模块 mylibrary
标记为可选模块。这种标记可能影响构建系统在处理模块时的行为,例如是否包含在最终输出中。
-
常用标签:
optional
: 表示模块是可选的,可能会影响构建系统在构建过程中的行为,例如在构建不同配置或版本时是否包含在输出中。debug
: 表示模块是调试模块,通常用于指定仅在调试构建中包含的模块。tests
: 表示模块是测试相关的,可能包含单元测试或集成测试相关的模块。
-
注意事项:
LOCAL_MODULE_TAGS
的具体效果取决于构建系统和 Android NDK 版本,不同的标签可能在不同的构建环境中有不同的行为。- 通常情况下,除非需要特定的模块处理行为,否则不需要显式设置
LOCAL_MODULE_TAGS
。
LOCAL_MODULE
LOCAL_MODULE
是用于定义当前模块的名称的变量。这个变量指定了当前模块的名称,该名称在构建过程中用于生成输出文件的文件名或目标名称。
- 作用:
LOCAL_MODULE
变量用于定义当前模块的名称,以便在构建过程中生成对应的输出文件或目标。
include $(CLEAR_VARS)
# 定义模块类型为共享库,并指定模块名称为 mylibrary
LOCAL_MODULE := mylibrary
# 定义要包含的源文件列表
LOCAL_SRC_FILES := file1.cpp file2.cpp
# 包括构建共享库的规则
include $(BUILD_SHARED_LIBRARY)
在这个示例中,LOCAL_MODULE := mylibrary
将当前模块命名为 mylibrary
,并且指定了要包含的源文件列表。当构建此模块时,将生成名为 libmylibrary.so
的共享库文件。
- 注意事项:
LOCAL_MODULE
定义的名称通常是不带文件扩展名的,例如不包括.so
或.a
。- 构建系统将使用
LOCAL_MODULE
定义的名称来生成最终的输出文件名或目标名称,具体生成的文件名取决于模块类型和构建规则。
LOCAL_MODULE_PATH
LOCAL_MODULE_PATH
是用于指定生成的输出文件(例如共享库或可执行文件)存放的路径的变量。
- 作用:
LOCAL_MODULE_PATH
变量用于指定生成的输出文件(例如共享库.so
文件或可执行文件)的存放路径。在构建过程中,生成的输出文件将会被复制到指定的路径中。
include $(CLEAR_VARS)
# 定义模块类型为共享库,并指定模块名称和输出路径
LOCAL_MODULE := mylibrary
LOCAL_SRC_FILES := file1.cpp file2.cpp
# 指定输出路径为 libs/armeabi-v7a/
LOCAL_MODULE_PATH := $(TARGET_OUT)/libs/armeabi-v7a/
# 包括构建共享库的规则
include $(BUILD_SHARED_LIBRARY)
在这个示例中,LOCAL_MODULE_PATH := $(TARGET_OUT)/libs/armeabi-v7a/
将指定生成的共享库文件 libmylibrary.so
被复制到 libs/armeabi-v7a/
目录中。
- 注意事项:
LOCAL_MODULE_PATH
的值通常是一个相对路径或绝对路径,用于指定生成的输出文件的存放位置。$(TARGET_OUT)
是一个预定义的变量,表示 Android NDK 构建系统的输出目录,具体路径取决于目标架构和构建类型(例如libs/armeabi-v7a/
)。- 使用
LOCAL_MODULE_PATH
可以将生成的输出文件放置到特定的目录中,以便后续打包或部署到 Android 设备上。
通常情况下,如果不显式地设置 LOCAL_MODULE_PATH
,构建系统会根据默认规则将生产的目标文件放置到特定的位置。但是通过设置LOCAL_MODEULE_PATH
可以覆盖这些默认设置,从而自定义输出目录。
LOCAL_PACKAGE_NAME
LOCAL_PACKAGE_NAME
并不是一个常见的变量。通常情况下,LOCAL_PACKAGE_NAME
不是用于定义应用程序包名的变量,而是用于定义生成的本地模块(shared library 或可执行文件)的名称。
LOCAL_DEX_PREOPT
LOCAL_DEX_PREOPT
是一个用于控制是否对本地应用程序的 dex 文件进行预优化(pre-optimization)的变量。
预优化是指在应用程序安装过程中,对应用程序的 dex 文件进行预处理,以提高应用程序的启动性能和运行时性能。预优化的过程包括将 dex 文件优化为可执行的机器代码,以便在设备上更快地加载和执行。
include $(CLEAR_VARS)
# 定义本地模块的名称
LOCAL_MODULE := my_app
# 定义源文件路径
LOCAL_SRC_FILES := $(call all-java-files-under, src)
# 指定应用程序的包名
LOCAL_PACKAGE_NAME := com.example.myapp
# 控制是否对 dex 文件进行预优化
LOCAL_DEX_PREOPT := true
include $(BUILD_PACKAGE)
LOCAL_DEX_PREOPT := true
指示 Android NDK 构建系统在构建应用程序时对 dex 文件进行预优化。这意味着在应用程序安装到设备上时,系统会尝试预先优化应用程序的 dex 文件,以提高应用程序的性能。
需要注意的是,LOCAL_DEX_PREOPT
的默认值是 false
,表示不进行预优化。只有在需要提高应用程序性能或需要优化加载速度时,才会将其设置为 true
。
注意事项:
对 dex 文件进行预优化(Pre-optimization)可以提高应用程序的启动性能和运行时性能,但也可能会带来一些潜在的缺点或注意事项,具体取决于应用程序的特性和使用情况:
- 增加安装时间和应用大小:
- 预优化会在应用程序安装过程中进行,可能会增加应用程序的安装时间,特别是对于较大的应用程序。预优化的过程会消耗一定的时间和系统资源。
- 预优化后的 dex 文件可能会增加应用程序的大小,因为优化后的 dex 文件可能比原始的 dex 文件更大。
- 消耗存储空间:
- 预优化会生成优化后的 dex 文件,这些文件会占用设备的存储空间。对于较大的应用程序,优化后的 dex 文件可能会占用大量的存储空间。
- 可能引入兼容性问题:
- 在某些情况下,对 dex 文件进行预优化可能会引入兼容性问题。某些特定的优化操作可能会导致应用程序在某些设备上出现问题或崩溃,尤其是在不同的 Android 版本或硬件上。
- 增加构建时间:
- 预优化会在应用程序构建过程中执行,这可能会增加构建时间。如果频繁地进行预优化,会增加开发和调试的时间成本。
- 不适用于某些应用程序:
- 对于某些应用程序来说,预优化可能并不总是有效或必要的。例如,一些小型应用程序或测试应用程序可能不需要进行预优化,因为优化的收益不值得增加安装和构建的复杂性。
$(warning ...)
$(warning ...)
是一个 Makefile 中的内置函数,用于在执行 Makefile 时输出警告消息到标准输出(stdout)。
$(warning ...)
是 Makefile 中的一个函数,用于发出警告消息。在执行 Makefile 时,如果遇到$(warning ...)
,会在标准输出中输出警告消息。"the value of LOCAL_MODULE is $(LOCAL_MODULE)"
是警告消息的内容。其中$(LOCAL_MODULE)
是一个 Makefile 变量的引用,表示在当前上下文中LOCAL_MODULE
变量的值。
LOCAL_SRC_FILES
LOCAL_SRC_FILES
是一个变量,用于指定当前模块编译所需的源文件列表。这个变量通常用于定义要编译成目标文件或库的源代码文件列表。
LOCAL_PATH := $(call my-dir)
# 定义模块名和类型
LOCAL_MODULE := my_module
LOCAL_MODULE_TAGS := optional
# 定义源文件列表
LOCAL_SRC_FILES := \
source_file1.cpp \
source_file2.cpp \
source_file3.cpp
# 定义头文件搜索路径
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
# 编译为共享库
include $(BUILD_SHARED_LIBRARY)
在上面的示例中:
LOCAL_SRC_FILES
定义了当前模块编译所需的源文件列表,包括source_file1.cpp
,source_file2.cpp
,source_file3.cpp
等。LOCAL_MODULE
定义了当前模块的名称为my_module
。LOCAL_MODULE_TAGS
定义了模块的标签为optional
。LOCAL_C_INCLUDES
定义了头文件搜索路径,这里指定了include
目录下的头文件路径。include $(BUILD_SHARED_LIBRARY)
是用于编译共享库的指令,它会根据前面定义的参数进行编译链接生成目标库。
LOCAL_SRC_FILES := $(notdir $(wildcard $(LOCAL_PATH)/*.apk))
$(LOCAL_PATH)
:这是一个内置变量,表示当前Android.mk
文件所在的目录的路径。$(wildcard $(LOCAL_PATH)/*.apk)
:这是一个 Makefile 函数,用于搜索指定路径下的所有以.apk
结尾的文件,并返回文件列表。$(wildcard ...)
函数会返回符合条件的文件路径列表。$(notdir ...)
:这是一个 Makefile 函数,用于从文件路径中提取文件名部分,去除路径部分。- 所以,
LOCAL_SRC_FILES := $(notdir $(wildcard $(LOCAL_PATH)/*.apk))
的意思是:- 首先使用
$(wildcard $(LOCAL_PATH)/*.apk)
查找当前Android.mk
文件所在目录下所有以.apk
结尾的文件,并得到这些文件的路径列表。 - 然后使用
$(notdir ...)
函数从文件路径列表中提取文件名部分,去除路径部分。 - 最终,将提取出的文件名列表赋值给
LOCAL_SRC_FILES
变量,作为当前模块编译所需的源文件列表。
- 首先使用
例如,如果当前目录下有 app1.apk
, app2.apk
, app3.apk
等文件,那么 LOCAL_SRC_FILES
的值将会是 app1.apk app2.apk app3.apk
,这些文件名将用作当前模块的源文件列表,在编译过程中被包含到生成的目标中。
LOCAL_MODULE_CLASS
LOCAL_MODULE_CLASS
是一个变量,用于指定当前模块的类别或类型。它定义了当前模块的构建行为和属性。
-
STATIC_LIBRARIES
:- 表示当前模块是静态库,会生成一个静态链接库文件(
.a
文件)。 - 静态库文件包含编译后的代码,会被链接到其他可执行程序中。
LOCAL_MODULE_CLASS := STATIC_LIBRARIES
- 表示当前模块是静态库,会生成一个静态链接库文件(
-
SHARED_LIBRARIES
:- 表示当前模块是共享库(动态库),会生成一个共享库文件(
.so
文件)。 - 共享库文件包含编译后的代码,在运行时动态加载到其他程序中。
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
- 表示当前模块是共享库(动态库),会生成一个共享库文件(
-
EXECUTABLES
:- 表示当前模块是可执行程序,会生成一个可执行文件。
- 可执行文件包含编译后的代码,可以直接运行。
LOCAL_MODULE_CLASS := EXECUTABLES
-
JAVA_LIBRARIES
:- 表示当前模块是 Java 库,会生成一个 Jar 文件。
- Java 库文件包含编译后的 Java 类文件和资源文件。
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
-
APPS
:- 表示当前模块是 Android 应用程序,会生成一个 APK 文件。
- APK 文件包含编译后的 Android 应用程序代码、资源和清单文件。
LOCAL_MODULE_CLASS := APPS
-
SCRIPTS
:- 表示当前模块是脚本文件,会直接拷贝到目标位置。
LOCAL_MODULE_CLASS := SCRIPTS
这些是常见的 LOCAL_MODULE_CLASS
值和相应的含义。通过设置 LOCAL_MODULE_CLASS
变量,可以告诉 Android 构建系统如何处理当前模块的源文件,并生成对应的目标文件或输出文件。
LOCAL_MODULE_SUFFIX
LOCAL_MODULE_SUFFIX
是一个变量,用于指定生成的模块文件的后缀名。通常用于给生成的目标文件添加特定的后缀。
-
添加特定后缀名: 可以通过
LOCAL_MODULE_SUFFIX
来为生成的目标文件添加特定的后缀。例如,如果想要生成的目标文件以.so
结尾,可以设置如下:LOCAL_MODULE_SUFFIX := .so
这样,编译系统将会在生成目标文件时,自动为模块名添加
.so
后缀,例如mylib.so
。 -
使用默认后缀名: 在某些情况下,如果希望使用默认的模块后缀名,可以直接使用 Android 构建系统提供的预定义变量,例如
COMMON_ANDROID_PACKAGE_SUFFIX
,它会根据模块类型自动确定合适的后缀名。LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)
这将会根据模块类型自动决定模块文件的后缀名,例如对于共享库(
.so
)、可执行文件(无后缀)、静态库(.a
)或 APK 文件(.apk
)等。
LOCAL_CERTIFICATE
LOCAL_CERTIFICATE
是一个变量,用于指定应用程序或库的签名证书。
LOCAL_CERTIFICATE := platform
: 表示该模块将使用平台签名进行签名。这意味着模块将使用 Android 平台的默认密钥进行签名,这种签名允许模块在 Android 系统的所有应用程序上下文中运行,具有系统级权限和特权。使用此选项需要对 Android 平台具有开发权限。LOCAL_CERTIFICATE := shared
: 表示该模块将使用共享用户证书进行签名。这种签名适用于与其他应用程序共享用户 ID(UID)的模块,允许模块访问相同的应用程序数据。共享用户签名的模块受到一些用户数据的保护,并受到 Android 安全模型的限制。LOCAL_CERTIFICATE := platform_shared
: 表示该模块将使用平台共享证书进行签名。这种签名适用于需要访问 Android 系统资源或共享用户数据的模块,但不具备完全系统级权限的情况。
LOCAL_REQUIRED_MODULES
LOCAL_REQUIRED_MODULES
是一个变量,用于指定当前模块所依赖的其他模块。这个变量通常用于声明当前模块需要链接或依赖的其他模块或库,以确保编译时能够正确解析和链接这些依赖关系。
在 Android 的 Android.mk
或 Android.bp
构建系统中,LOCAL_REQUIRED_MODULES
是一个变量,用于指定当前模块所依赖的其他模块。这个变量通常用于声明当前模块需要链接或依赖的其他模块或库,以确保编译时能够正确解析和链接这些依赖关系。
例如,在 Android.mk
文件中,可以这样使用 LOCAL_REQUIRED_MODULES
:
makefileCopy code# 声明当前模块依赖的其他模块或库
LOCAL_REQUIRED_MODULES := libfoo libbar
这里的 libfoo
和 libbar
是指当前模块需要链接的其他模块或库的名称。这样在编译过程中,构建系统会确保先编译并链接这些依赖的模块,以便正确构建当前模块。
LOCAL_OVERRIDES_PACKAGES
LOCAL_OVERRIDES_PACKAGES
是一个用于指定当前模块覆盖其他模块的列表变量。当某个模块具有与其他模块相同的功能或服务时,可以使用 LOCAL_OVERRIDES_PACKAGES
来指定当前模块覆盖哪些模块。
LOCAL_OVERRIDES_PACKAGES := Camera2 Camera DreamCamera2 SnapdragonCamera Camera0
这里的 LOCAL_OVERRIDES_PACKAGES
指定了当前模块覆盖了列表中列出的多个相机模块,包括 Camera2
、Camera
、DreamCamera2
、SnapdragonCamera
和 Camera0
。这意味着在构建过程中,如果存在多个具有相同功能或服务的相机模块,系统会优先选择当前模块进行覆盖和使用。
使用 LOCAL_OVERRIDES_PACKAGES
可以在构建系统中灵活地管理模块之间的功能重叠和替代关系,确保系统能够正确选择和使用特定的模块实现功能或提供服务。
LOCAL_PRIVILEGED_MODULE
LOCAL_PRIVILEGED_MODULE
是一个变量,用于指定当前模块是否是特权模块(privileged module)。特权模块是指具有系统级权限或系统签名权限的模块,可以访问系统关键资源和执行特定的系统操作。
当设置 LOCAL_PRIVILEGED_MODULE := true
时,表示当前模块是一个特权模块,具有特殊的系统级权限。这意味着该模块在运行时可以执行一些普通应用程序无法执行的操作,例如访问系统的底层服务、修改系统设置或访问系统文件等。
特权模块通常需要使用系统签名(system signature)进行签名,并且可能需要在设备的系统分区上安装和运行。这些模块可以通过 LOCAL_PRIVILEGED_MODULE
变量来标识,构建系统会根据这个标识来确定模块的特权级别,并在编译和部署时做出相应的处理。
小结:
LOCAL_MODULE
:定义模块的名称。LOCAL_SRC_FILES
:指定模块编译时所需的源文件列表。LOCAL_MODULE_PATH
:指定模块输出文件的路径。LOCAL_PACKAGE_NAME
:定义应用程序的包名。LOCAL_MODULE_CLASS
:指定模块的类别,如APPS
。LOCAL_MODULE_SUFFIX
:指定模块输出文件的后缀。LOCAL_CERTIFICATE
:指定模块签名的证书。LOCAL_REQUIRED_MODULES
:指定模块所依赖的其他模块。LOCAL_OVERRIDES_PACKAGES
:指定模块覆盖的其他应用程序包。LOCAL_PRIVILEGED_MODULE
:定义模块是否为特权模块。LOCAL_DEX_PREOPT
:指定是否对 dex 文件进行预优化。include $(CLEAR_VARS)
:清除之前的变量设置,准备用于定义新的模块。