Android 编译 — Android.mk语法(Android compiler — android.mk syntax)

android系统源码编译步骤
1.source build/envsetup.sh && lunch xxx 或者 . ./build/envsetup.sh && lunch xxx 。执行envsetup.sh脚本之后,envsetup.sh中的变量成了全局变量,而其中的函数也可以直接在当前终端命令行中使用。

常用函数解析

  • lunch :选择要编译的目标产品和版本
  • croot:切换到源码的顶层目录
  • m: 从顶层目录build整个系统
  • mm: 构建当前目录下所有的模块,但不包括它们的依赖
  • mmm: 构建指定目录下所有的模块,但不包括它们的依赖
  • mma: 构建当前目录下所有的模块以及它们所依赖的模块
  • mmma: 构建指定目录下所有的模块以及它们所依赖的模块

android.mk的使用实例和函数解释

mk 语法允许将 Source 打包成一个模块,模块又分为:

动态库:可以被 install/copy 到应用程序包(apk)
静态库:可以被链接入动态库
一个 mk 中能定义一个或者多个模块,也可以将同一份 Source 加入到多个模块中。

动态库:可以被 install/copy 到应用程序包(apk)
静态库:可以被链接入动态库
一个 mk 中能定义一个或者多个模块,也可以将同一份 Source 加入到多个模块中。

简单例子展示

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := hello
LOCAL_SRC_FILES := hello.c
include $(BUILD_SHARED_LIBRARY)

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := hello
LOCAL_SRC_FILES := hello.c
include $(BUILD_SHARED_LIBRARY)

  • LOCAL_PATH := $(call my-dir)
    mk文件须由 LOCAL_PATH 开始,用于在开发系统源码tree中查找源文件,宏 my-dir 则由 Build System 提供,返回包含 Android.mk 的目录路径。
  • include $(CLEAR_VARS)
    CLEAR_VARS变量是编译系统提供的,并指向一个指定的 GNU Makefile,由它负责清理很多LOCAL_xxx。用于清理变量,重置编译环境,因为所有的编译控制文件由同一个GNU Makefile解析和执行,其变量是全局的,所以清理后才能避免相互影响。
  • LOCAL_MODULE := hello
    模块的名称,必须定义,名字要唯一不能带空格。Build System 会自动添加适当的前缀和后缀。
  • LOCAL_SRC_FILES := hello.c
    列出需要编译的c/c++文件。
  • include $(BUILD_SHARED_LIBRARY)
    BUILD_SHARED_LIBRARY 是 Build System 提供的一个变量,指向一个 GNU Makefile 脚本。

BUILD_STATIC_LIBRARY:编译为静态库
BUILD_SHARED_LIBRARY:编译为动态库
BUILD_EXECUTABLE:编译为Native C可执行程序

  • BUILD_STATIC_LIBRARY:编译为静态库
  • BUILD_SHARED_LIBRARY:编译为动态库
  • BUILD_EXECUTABLE:编译为Native C可执行程序
  • LOCAL_MODULE_TAGS := optional
    指定在什么类型的版本下编译,通常有user/debug/eng 或者 optional(在所有版本下都会编译)
  • LOCAL_PRIVATE_PLATFORM_APIS := true
    使用SDK中隐藏的API参与编译
  • LOCAL_SDK_VERSION := current
    设置参与编译SDK版本,(若是在 Android.mk 中添加该选项,则编译时会忽略源码隐藏的API,故在使用源码的 hide api 后会导致编译失败)

internal api
翻译为内部API,理解为供sdk内部使用的API。这类接口最初打算就是不对外公开的
hide api
在源码中看到使用@hide 标记的方法或类,就是hide的。这类接口本意是要公开,但是当前阶段仍然不稳定或未开发完成。所以暂时不推荐开发者调用。但可以使用
普通api
第三方app也可以使用的api

  • internal api
    翻译为内部API,理解为供sdk内部使用的API。这类接口最初打算就是不对外公开的
  • hide api
    在源码中看到使用@hide 标记的方法或类,就是hide的。这类接口本意是要公开,但是当前阶段仍然不稳定或未开发完成。所以暂时不推荐开发者调用。但可以使用
  • 普通api
    第三方app也可以使用的api
  • LOCAL_CERTIFICATE := platform
    指定用什么方式签名
  • LOCAL_USE_AAPT2 := true
    aapt 是Android Asset Packaging Tool的缩写,是编译和打包资源的工具。appt2是appt的升级版。
  • LOCAL_JNI_SHARED_LIBRARIES := libbluetooth
    参与编译的共享库
  • LOCAL_JAVA_LIBRARIES := javax
    指定依赖的共享java类库,这个是编译时依赖,最终不会打包
  • LOCAL_STATIC_JAVA_LIBRARIES

LOCAL_STATIC_JAVA_LIBRARIES :=
com.android.vcard
指定依赖的静态java类库,最终会打包到apk里面。

LOCAL_STATIC_JAVA_LIBRARIES :=
com.android.vcard
指定依赖的静态java类库,最终会打包到apk里面。

  • LOCAL_STATIC_ANDROID_LIBRARIES

LOCAL_STATIC_ANDROID_LIBRARIES :=
androidx.appcompat_appcompat
androidx.fragment_fragment
声明要调用 android 的包

LOCAL_STATIC_ANDROID_LIBRARIES :=
androidx.appcompat_appcompat
androidx.fragment_fragment
声明要调用 android 的包

  • LOCAL_PROGUARD_FLAG_FILES := proguard.flags
    添加混淆规则配置文件参与编译。

android.mk的使用实例

  • 编译有源码的apk
LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)
# 源文件,可包含java、aidl文件 LOCAL_SRC_FILES += src/com/goodocom/gocsdk/IGocsdkCallback.aidl
LOCAL_SRC_FILES := $(call all-java-files-under, src)

# resource资源文件
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
# AndroidManifest.xml文件 LOCAL_MANIFEST_FILE := $(LOCAL_PATH)/AndroidManifest.xml

# 是否启用AAPT2 是编译和打包资源的工具 LOCAL_MODULE_PATH apk存放路径
LOCAL_USE_AAPT2 := true
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_PATH := $(TARGET_OUT)/app
LOCAL_PROGUARD_FLAG_FILES := proguard.flags
# APK的签名方式
LOCAL_CERTIFICATE := platform
# 目标APK文件名称
LOCAL_PACKAGE_NAME := QualBT
# 是否启用odex优化
LOCAL_DEX_PREOPT := false
# SDK版本
LOCAL_SDK_VERSION := current
# 依赖的静态库 so库是已经存在的,不需要重新编译 
#LOCAL_PREBUILT_JNI_LIBS :=libs/armeabi/libserial_port.so

# 私有路径 /system/priv_app  LOCAL_PRIVILEGED_MODULE := true

# 依赖的android静态库
LOCAL_STATIC_ANDROID_LIBRARIES := \
	androidx.appcompat_appcompat \
	androidx.fragment_fragment

# 构建APK
include $(BUILD_PACKAGE)
  • 编译无源码的apk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE := btTw
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := $(LOCAL_MODULE).apk
LOCAL_MODULE_CLASS := APPS
LOCAL_CERTIFICATE := platform

#out\target\product\qssi\system\app
LOCAL_MODULE_PATH := $(TARGET_OUT)/app
include $(BUILD_PREBUILT)

预置的android.mk

  • 预置jar
LOCAL_PATH:= $(call my-dir)

# 预置
include $(CLEAR_VARS)
LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := zxing:libs/core.jar \
                                        gson:libs/gson-2.8.0.jar \
                                        android-support-v7:libs/android-support-v7-recyclerview.jar 
include $(BUILD_MULTI_PREBUILT)

# 引用
include $(CLEAR_VARS)
......
LOCAL_STATIC_JAVA_LIBRARIES += zxing
LOCAL_STATIC_JAVA_LIBRARIES += gson
LOCAL_STATIC_JAVA_LIBRARIES += android-support-v7
......
include $(BUILD_PACKAGE)

*预置so

LOCAL_PATH:= $(call my-dir)

# 预置
include $(CLEAR_VARS)
LOCAL_MODULE := mylib2
LOCAL_SRC_FILES_32 := lib/armeabi-v7a/mylib2.so
LOCAL_SRC_FILES_64 := lib/arm64-v8a/mylib2.so
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
LOCAL_MODULE_SUFFIX := .so
LOCAL_PROPRIETARY_MODULE := true
LOCAL_MULTILIB := both
include $(BUILD_PREBUILT)

......
# 引用
include $(CLEAR_VARS)
LOCAL_SHARED_LIBRARIES += mylib2
include $(BUILD_PACKAGE)
......

*预置apk

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

# 模块名称
LOCAL_MODULE := NewGallery2
# 要覆盖掉的模块名称
LOCAL_OVERRIDES_PACKAGES := Gallery Gallery3D GalleryNew3D Gallery2 DreamGallery2
# 模块类型为APPS
LOCAL_MODULE_CLASS := APPS
# 允许使用系统隐藏接口
LOCAL_PRIVATE_PLATFORM_APIS := true
# 签名,如无需重签名,则直接设置为PRESIGNED使用已有签名;需要重签,则设置为对应签名的值。
LOCAL_CERTIFICATE := platform
# 目标编译后的输出目录
LOCAL_MODULE_PATH := $(TARGET_OUT)/priv-app
# APK文件
LOCAL_SRC_FILES := apk/NewGallery2.apk
# APK预置的so
ifeq ($(strip $(TARGET_ARCH)), arm64)
    LOCAL_PREBUILT_JNI_LIBS := libs/arm64-v8a/libjni_jpeg.so
else ifeq ($(strip $(TARGET_ARCH)), x86_64)
    LOCAL_PREBUILT_JNI_LIBS := libs/x86_64/libjni_jpeg.so
else ifeq ($(strip $(TARGET_ARCH)),arm)
    LOCAL_PREBUILT_JNI_LIBS := libs/armeabi-v7a/libjni_jpeg.so
else
    LOCAL_PREBUILT_JNI_LIBS := libs/x86/libjni_jpeg.so
endif
include $(BUILD_PREBUILT)

参考文献

Android.mk例子
Android.mk例子

————————

< strong > Android system source code compilation steps < / strong >
1.source build/envsetup.sh && amp; Lunch XXX or. / build / envsetup.sh & amp& amp; lunch xxx 。 After executing the envsetup.sh script, the variables in envsetup.sh become global variables, and the functions can also be used directly in the command line of the current terminal.

< strong > common function analysis < / strong >

  • Lunch: select the target product and version to compile
  • Croot: switch to the top-level directory of the source code
  • m: Build the whole system from the top-level directory
  • Mm: build all modules in the current directory, but not their dependencies
  • Mmm: build all modules in the specified directory, but not their dependencies
  • MMA: build all modules in the current directory and the modules they depend on
  • Mmma: build all modules in the specified directory and the modules they depend on

Use examples and function explanations of android.mk

< strong > MK syntax allows source to be packaged into a module, which is divided into: < / strong >

Dynamic library: it can be installed / copied to the application package (APK)
Static library: can be linked into dynamic library
One or more modules can be defined in a MK, or the same source can be added to multiple modules.

Dynamic library: it can be installed / copied to the application package (APK)
Static library: can be linked into dynamic library
One or more modules can be defined in a MK, or the same source can be added to multiple modules.

< strong > simple example presentation < / strong >

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := hello
LOCAL_SRC_FILES := hello.c
include $(BUILD_SHARED_LIBRARY)

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := hello
LOCAL_SRC_FILES := hello.c
include $(BUILD_SHARED_LIBRARY)

  • LOCAL_PATH := $(call my-dir)
    mk文件须由 LOCAL_PATH 开始,用于在开发系统源码tree中查找源文件,宏 my-dir 则由 Build System 提供,返回包含 Android.mk 的目录路径。
  • include $(CLEAR_VARS)
    CLEAR_ Vars variable is provided by the compilation system and points to a specified GNU Makefile, which is responsible for cleaning up many local files_ xxx。 It is used to clean up variables and reset the compilation environment. Because all compilation control files are parsed and executed by the same GNU Makefile, their variables are global, so mutual influence can be avoided after cleaning.
  • LOCAL_ MODULE := hello
    The name of the module must be defined. The name must be unique and cannot contain spaces. Build system will automatically add appropriate prefixes and suffixes.
  • LOCAL_SRC_FILES := hello.c
    列出需要编译的c/c++文件。
  • include $(BUILD_SHARED_LIBRARY)
    BUILD_SHARED_LIBRARY 是 Build System 提供的一个变量,指向一个 GNU Makefile 脚本。

BUILD_ STATIC_ Library: compile to static library
BUILD_ SHARED_ Library: compile as a dynamic library
BUILD_ Executable: compiled as a native C executable

  • BUILD_STATIC_LIBRARY:编译为静态库
  • BUILD_SHARED_LIBRARY:编译为动态库
  • BUILD_EXECUTABLE:编译为Native C可执行程序
  • LOCAL_MODULE_TAGS := optional
    指定在什么类型的版本下编译,通常有user/debug/eng 或者 optional(在所有版本下都会编译)
  • LOCAL_PRIVATE_PLATFORM_APIS := true
    使用SDK中隐藏的API参与编译
  • LOCAL_ SDK_ VERSION := current
    Set the SDK version involved in compiling. (if this option is added to android.mk, the hidden API of the source code will be ignored during compilation, so the compilation will fail after using the hide API of the source code)

internal api
Translated into internal API, understood as API for internal use in SDK. Such interfaces were originally intended not to be exposed to the public
hide api
See the method or class marked with @ hide in the source code, that is, hide. This kind of interface is intended to be open, but the current stage is still unstable or undeveloped. Therefore, it is not recommended for developers to call. But you can use
General API
Third party apps can also use APIs

  • internal api
    Translated into internal API, understood as API for internal use in SDK. Such interfaces were originally intended not to be exposed to the public
  • hide api
    See the method or class marked with @ hide in the source code, that is, hide. This kind of interface is intended to be open, but the current stage is still unstable or undeveloped. Therefore, it is not recommended for developers to call. But you can use
  • General API
    Third party apps can also use APIs
  • LOCAL_CERTIFICATE := platform
    指定用什么方式签名
  • LOCAL_USE_AAPT2 := true
    aapt 是Android Asset Packaging Tool的缩写,是编译和打包资源的工具。appt2是appt的升级版。
  • LOCAL_JNI_SHARED_LIBRARIES := libbluetooth
    参与编译的共享库
  • LOCAL_ JAVA_ LIBRARIES := javax
    Specify the dependent shared Java class library. This is a compile time dependency and will not be packaged in the end
  • LOCAL_STATIC_JAVA_LIBRARIES

LOCAL_ STATIC_ JAVA_ LIBRARIES :=
com.android.vcard
The static Java class library that specifies the dependency will eventually be packaged into APK.

LOCAL_ STATIC_ JAVA_ LIBRARIES :=
com.android.vcard
The static Java class library that specifies the dependency will eventually be packaged into APK.

  • LOCAL_STATIC_ANDROID_LIBRARIES

LOCAL_STATIC_ANDROID_LIBRARIES :=
androidx.appcompat_appcompat
androidx.fragment_fragment
声明要调用 android 的包

LOCAL_STATIC_ANDROID_LIBRARIES :=
androidx.appcompat_appcompat
androidx.fragment_fragment
声明要调用 android 的包

  • LOCAL_PROGUARD_FLAG_FILES := proguard.flags
    添加混淆规则配置文件参与编译。

android.mk的使用实例

  • Compile APK with source code
LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)
# 源文件,可包含java、aidl文件 LOCAL_SRC_FILES += src/com/goodocom/gocsdk/IGocsdkCallback.aidl
LOCAL_SRC_FILES := $(call all-java-files-under, src)

# resource资源文件
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
# AndroidManifest.xml文件 LOCAL_MANIFEST_FILE := $(LOCAL_PATH)/AndroidManifest.xml

# 是否启用AAPT2 是编译和打包资源的工具 LOCAL_MODULE_PATH apk存放路径
LOCAL_USE_AAPT2 := true
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_PATH := $(TARGET_OUT)/app
LOCAL_PROGUARD_FLAG_FILES := proguard.flags
# APK的签名方式
LOCAL_CERTIFICATE := platform
# 目标APK文件名称
LOCAL_PACKAGE_NAME := QualBT
# 是否启用odex优化
LOCAL_DEX_PREOPT := false
# SDK版本
LOCAL_SDK_VERSION := current
# 依赖的静态库 so库是已经存在的,不需要重新编译 
#LOCAL_PREBUILT_JNI_LIBS :=libs/armeabi/libserial_port.so

# 私有路径 /system/priv_app  LOCAL_PRIVILEGED_MODULE := true

# 依赖的android静态库
LOCAL_STATIC_ANDROID_LIBRARIES := \
	androidx.appcompat_appcompat \
	androidx.fragment_fragment

# 构建APK
include $(BUILD_PACKAGE)
  • Compiling APK without source code
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE := btTw
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := $(LOCAL_MODULE).apk
LOCAL_MODULE_CLASS := APPS
LOCAL_CERTIFICATE := platform

#out\target\product\qssi\system\app
LOCAL_MODULE_PATH := $(TARGET_OUT)/app
include $(BUILD_PREBUILT)

预置的android.mk

  • 预置jar
LOCAL_PATH:= $(call my-dir)

# 预置
include $(CLEAR_VARS)
LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := zxing:libs/core.jar \
                                        gson:libs/gson-2.8.0.jar \
                                        android-support-v7:libs/android-support-v7-recyclerview.jar 
include $(BUILD_MULTI_PREBUILT)

# 引用
include $(CLEAR_VARS)
......
LOCAL_STATIC_JAVA_LIBRARIES += zxing
LOCAL_STATIC_JAVA_LIBRARIES += gson
LOCAL_STATIC_JAVA_LIBRARIES += android-support-v7
......
include $(BUILD_PACKAGE)

*Preset so

LOCAL_PATH:= $(call my-dir)

# 预置
include $(CLEAR_VARS)
LOCAL_MODULE := mylib2
LOCAL_SRC_FILES_32 := lib/armeabi-v7a/mylib2.so
LOCAL_SRC_FILES_64 := lib/arm64-v8a/mylib2.so
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
LOCAL_MODULE_SUFFIX := .so
LOCAL_PROPRIETARY_MODULE := true
LOCAL_MULTILIB := both
include $(BUILD_PREBUILT)

......
# 引用
include $(CLEAR_VARS)
LOCAL_SHARED_LIBRARIES += mylib2
include $(BUILD_PACKAGE)
......

*Preset apk

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

# 模块名称
LOCAL_MODULE := NewGallery2
# 要覆盖掉的模块名称
LOCAL_OVERRIDES_PACKAGES := Gallery Gallery3D GalleryNew3D Gallery2 DreamGallery2
# 模块类型为APPS
LOCAL_MODULE_CLASS := APPS
# 允许使用系统隐藏接口
LOCAL_PRIVATE_PLATFORM_APIS := true
# 签名,如无需重签名,则直接设置为PRESIGNED使用已有签名;需要重签,则设置为对应签名的值。
LOCAL_CERTIFICATE := platform
# 目标编译后的输出目录
LOCAL_MODULE_PATH := $(TARGET_OUT)/priv-app
# APK文件
LOCAL_SRC_FILES := apk/NewGallery2.apk
# APK预置的so
ifeq ($(strip $(TARGET_ARCH)), arm64)
    LOCAL_PREBUILT_JNI_LIBS := libs/arm64-v8a/libjni_jpeg.so
else ifeq ($(strip $(TARGET_ARCH)), x86_64)
    LOCAL_PREBUILT_JNI_LIBS := libs/x86_64/libjni_jpeg.so
else ifeq ($(strip $(TARGET_ARCH)),arm)
    LOCAL_PREBUILT_JNI_LIBS := libs/armeabi-v7a/libjni_jpeg.so
else
    LOCAL_PREBUILT_JNI_LIBS := libs/x86/libjni_jpeg.so
endif
include $(BUILD_PREBUILT)

reference

Android.mk例子
Android.mk例子