1.Android.mk作用
Android.mk是Android工程管理文件,其作用相当于Linux环境中的Makefile,把你写的源代码编译成库文件或者可执行文件,一个android.mk可以包含多个模块,也即可以编译出多个库文件或者可执行文件。
2.Android.mk的简单案例
android开源代码: /system/libvintf/Android.mk
LOCAL_PATH := $(call my-dir) #源文件在开发树中的位置
include $(CLEAR_VARS) #清除LOCAL_PATH变量之外的LOCAL_XXX变量
LOCAL_MODULE := libvintf_recovery #生成的模块名称
LOCAL_SRC_FILES := VintfObjectRecovery.cpp #需要编译进这个模块的源文件
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include/vintf #头文件
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include #头文件以及头文件中所用到的头文件
LOCAL_CFLAGS := -Wall -Werror #编译源文件时要传递的编译器标志
LOCAL_STATIC_LIBRARIES := \ #编译这个模块所依赖到的静态库
libbase \
libvintf \
libhidl-gen-utils \
libfs_mgr
LOCAL_EXPORT_STATIC_LIBRARY_HEADERS := libhidl-gen-utils
include $(BUILD_STATIC_LIBRARY) #把这个模块编译成静态库
$(call dist-for-goals,dist_files,$(HOST_OUT_EXECUTABLES)/checkvintf)
通过这个简单案例相信你已经初步了解了如何从零开始写一个Android.mk
3.常用语法
语法 | 解释 |
---|---|
call | 调用一个系统提供的宏函数,上面是 my-dir |
$() | 取值 |
:= | 赋值 |
ifeq | 如果相等 |
ifneq | 如果不相等 |
4.常用变量名
4.1 定义当前模块位置
LOCAL_PATH := $(call my-dir)
每个Android.mk文件必须以定义LOCAL_PATH为开始。它用于在开发tree中查找源文件。系统提供的宏函数my-dir返回包含Android.mk所在的目录路径。它不会被 CLEAR_VARS 清除,写法也很固定,即:LOCAL_PATH := $(call my-dir)。
LOCAL_PATH 是表示当前模块位置的变量,my-dir 是由系统提供的宏函数,返回当前文件所在的路径,$(call my-dir) 表示调用这个函数。
4.2 清除LOCAL_XXX变量
include $(CLEAR_VARS)
CLEAR_VARS 变量由系统提供并指向一个指定的GNU Makefile,由它负责清理很多LOCAL_xxx.
例如:LOCAL_MODULE, LOCAL_SRC_FILES, LOCAL_STATIC_LIBRARIES等等。但不清理LOCAL_PATH. 这个清理动作是必须的,因为所有的编译控制文件由同一个GNU Make解析和执行,其变量是全局的。所以清理后才能避免相互影响。
4.3 需要参与编译的源文件
LOCAL_SRC_FILES := VintfObjectRecovery.cpp
LOCAL_SRC_FILES 变量代表需要编译的文件
也有其他的写法:
LOCAL_SRC_FILES := $(call all-subdir-java-files)
all-subdir-java-files 函数返回LOCAL_PATH 子目录的所有java 文件。
但要注意,在文件最后面加上以下语句,指明 LOCAL_PATH 目录。
include $ (call all-makefiles-under,$(LOCAL_PATH))
或者在每个文件路径下都加上 LOCAL_PATH :
LOCAL_SRC_FILES := $(LOCAL_PATH)/VintfObjectRecovery.cpp
4.3.1 几个常用的获取源文件的方法:
LOCAL_SRC_FILES := $(call all-java-files-under, src)
获取指定目录下的所有 Java 文件。
LOCAL_SRC_FILES := $(call all-c-files-under, src)
获取指定目录下的所有 C 语言文件。
LOCAL_SRC_FILES := $(call all-Iaidl-files-under, src)
获取指定目录下的所有 AIDL 文件。
LOCAL_SRC_FILES := $(call all-makefiles-under, folder)
获取指定目录下的所有 Make 文件。
4.4 定义编译生成的模块名称
LOCAL_MODULE := libvintf_recovery
LOCAL_MODULE 变量必须定义且唯一,作为模块的标识,编译系统会自动产生合适的前缀和后缀。
4.5 编译的标签
LOCAL_MODULE_TAGS := optional
常用的有:debug, eng, user,development 或者 optional(默认)。
4.6 签名属性
常用的有:
platform:该 APK 完成一些系统的核心功能。经过对系统中存在的文件夹的访问测试。
shared:该APK需要和 home/contacts 进程共享数据。
media:该APK是 media/download 系统中的一环。
LOCAL_CERTIFICATE := platform
4.7 引用静态jar库
LOCAL_STATIC_JAVA_LIBRARIES := jar1 jar2
jar1、jar2 是第三方 Java 包的别名,需要定义,见后文。
LOCAL_JAVA_LIBRARIES 用于引用动态jar。
4.8 编译成什么
4.8.1 编译成apk
include $(BUILD_PACKAGE)
4.8.2 编译成静态库
include $(BUILD_STATIC_LIBRARY)
4.8.3 编译成动态库
include $(BUILD_SHARED_LIBRARY)
4.8.4 编译成可执行程序
include $(BUILD_EXECUTABLE)
4.8.5 编译成Java静态库
include $(BUILD_STATIC_JAVA_LIBRARY)
4.9 需要进行预编译的库
LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := jar1:path1 \
jar2:path2
jar1、jar2 定义静态库别名,path1、path2 是静态库的路径,注意要一直写到后缀 .jar.
4.10 拷贝到本地编译
include $(BUILD_MULTI_PREBUILT)
将 prebuild 定义的库拷到本地进行编译。
4.11 指定生成目录
LOCAL_MODULE_PATH := $(TARGET_OUT)/
$(TARGET_OUT) 代表 /system
$(TARGET_OUT_DATA_APPS) 代表 data/app 目录
4.12 在什么版本下编译
LOCAL_MODULE_TAGS
user: 指该模块只在user版本下才编译
eng: 指该模块只在eng版本下才编译
tests: 指该模块只在tests版本下才编译
optional:指该模块在所有版本下都编译
4.13 构建成多少位
LOCAL_MULTILIB
both: build both 32-bit and 64-bit
32:build only 32-bit.
64: build only 64-bit.
4.14 预装配置文件 执行
include $(BUILD_PREBUILT)
预装配置文件 执行,就是将要拷贝动态库到指定目录 ,使用此标签;
例如如下代码:
#是将libtsldc.so 预装到(其实就是拷贝到$(TARGET_OUT_VENDOR)/lib下面)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := TS_LDC/C626/tsldc/lib/libtsldc.so
LOCAL_MULTILIB := 32
LOCAL_MODULE := libtsldc
LOCAL_MODULE_SUFFIX := .so
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/lib
include $(BUILD_PREBUILT)
4.15 头文件
LOCAL_INC_FILES
添加自己写的.h 头文件示例如下;LOCAL_INC_FILES := person.h
LOCAL_C_INCLUDES
指定头文件的搜索路径。LOCAL_C_INCLUDES := $(LOCAL_PATH)/include/vintf
4.16 编译器标志
LOCAL_CFLAGS
此可选变量为构建系统设置在构建 C 和 C++ 源文件时要传递的编译器标志。此功能对于指定额外的宏定义或编译选项可能很有用
LOCAL_CPPFLAGS
仅当构建 C++ 源文件时才会传递一组可选的编译器标志。它们将出现在编译器命令行中的 LOCAL_CFLAGS 后面
4.17 编译所需的其他链接器标志列表
LOCAL_LDLIBS
编译所需的其他链接器标志列表。它可让您使用 -l 前缀传递特定系统库的名称.
示例: LOCAL_LDLIBS += -llog -ldl -lz
5.0 致谢
本文参考以下两篇博客: