首先我们来看一段android.mk文件
LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE_TAGS := optional
LOCAL_CERTIFICATE := platform

LOCAL_STATIC_JAVA_LIBRARIES += guava
LOCAL_STATIC_JAVA_LIBRARIES += android-support-v4
LOCAL_STATIC_JAVA_LIBRARIES += android-support-v7-appcompat
LOCAL_STATIC_JAVA_LIBRARIES += appluginmanager

LOCAL_STATIC_JAVA_LIBRARIES += libTuSDKCore libgdx libTuSDKVideo libUniversalImageLoader libTuSDKFace

LOCAL_RENDERSCRIPT_TARGET_API := 18
LOCAL_RENDERSCRIPT_COMPATIBILITY := 18

LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
LOCAL_RESOURCE_DIR += prebuilts/sdk/current/support/v7/appcompat/res

LOCAL_SRC_FILES := $(call all-java-files-under, src)

LOCAL_AAPT_FLAGS := --auto-add-overlay
LOCAL_AAPT_FLAGS += --no-version-vectors
LOCAL_AAPT_FLAGS += --extra-packages android.support.v7.appcompat

LOCAL_PACKAGE_NAME := TestAPP
LOCAL_PROGUARD_ENABLE := disable
LOCAL_DEX_PREOPT := false
LOCAL_PRIVATE_PLATFORM_APIS := true
include $(BUILD_PACKAGE)

##################################################
include $(CLEAR_VARS)
LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES  := libTuSDKCore:libs/TuSDKCore-2.8.4.jar
include $(BUILD_MULTI_PREBUILT)

include $(CLEAR_VARS)
LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES  := libgdx:libs/gdx.jar
include $(BUILD_MULTI_PREBUILT)

include $(CLEAR_VARS)
LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES  := libTuSDKVideo:libs/TuSDKVideo-1.8.0.jar
include $(BUILD_MULTI_PREBUILT)

include $(CLEAR_VARS)
LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES  := libUniversalImageLoader:libs/universal-image-loader-1.9.4.jar
include $(BUILD_MULTI_PREBUILT)

include $(CLEAR_VARS)
LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES  := libTuSDKFace:libs/TuSDKFace-1.0.0.jar
include $(BUILD_MULTI_PREBUILT)

那么如何看懂这个android.mk文件,直接看,一个一个项看它代表什么意思:

  1. LOCAL_PATH:= $(call my-dir) ,很显然这是在给LOCAL_PATH赋值,赋的就是my-dir的值,所以问题关键就是my-dir是什么意思?my-dir代表当前文件的路径,这里的当前文件就指 正在编写的Android.mk文件,也就是说 Android.mk文件的路径是什么,LOCAL_PATH的路径就是什么,所以Makefile编译环境中 时时刻刻是以 Android.mk 为开端的,

官方的解释是这样:每个Android.mk文件必须以定义LOCAL_PATH为开始。它用于在开发tree中查找源文件。宏my-dir
则由Build System提供。返回包含Android.mk的目录路径。

  1. include $(CLEAR_VARS) ,clean 就是清除,它用来清除很多LOCAL_**什么什么开头的变量,因为在make编译一次项目的时候,所有的编译控制文件(例如 Android.mk)是由同一个GNU Make去执行的,它是一个全局变量,不清理的话,到了最后一个Android.mk 会把之前所有的LOCAL_都给加上,> 官方解释是这样:CLEAR_VARS 变量由Build System提供。并指向一个指定的GNU

Makefile,由它负责清理很多LOCAL_xxx.例如:LOCAL_MODULE, LOCAL_SRC_FILES,
LOCAL_STATIC_LIBRARIES等等。但不清理LOCAL_PATH.这个清理动作是必须的,因为所有的编译控制文件由同一个GNU
Make解析和执行,其变量是全局的。所以清理后才能避免相互影响。
一个CLEAR_VARS开启一次编译,一个BUILD——**结束一次编译

  1. LOCAL_MODULE_TAGS := optional ,这个就是说指定当前module编译的类型,不过有个博客说是光指定optional类型,编译出来的库目录会乱的,说是要指定 TARGET_BUILD_VARIANT,但是不影响项目编译通过,下面的这几种类型,就是在使用Makefile命令编译的时候的第二步,lunch 后边的参数,编译的是什么类型

user: 指该模块只在user版本下才编译
eng: 指该模块只在eng版本下才编译
tests: 指该模块只在tests版本下才编译
optional:指该模块在所有版本下都编译

  1. LOCAL_CERTIFICATE := platform,用于设置不同的签名方式build/target/product/security目录中有四组默认签名供Android.mk在编译APK使用:

testkey:普通APK,默认情况下使用。
platform:该APK完成一些系统的核心功能。经过对系统中存在的文件夹的访问测试,这种方式编译出来的APK所在进程的UID为system。
shared:该APK需要和home/contacts进程共享数据。
media:该APK是media/download系统中的一环。

  1. LOCAL_STATIC_JAVA_LIBRARIES +=,这里是指定依赖的静态Java库,和静态Java类库对应的是有一个共享Java类库LOCAL_JAVA_LIBRARIES ,这里首先说明一下静态库和动态库的区别:

官方解释是这样:
1、 LOCAL_STATIC_JAVA_LIBRARIES-静态库是在连接阶段直接拷贝到代码 中使用的,BUILD_STATIC_JAVA_LIBRARY指定生成静态库。编译出来的静态库(这里指jar包)里每个java文件对应的class文件都单独存在,可以直接导入Eclipse等IDE使用,
2、LOCAL_JAVA_LIBRARIES -而共享库是由加载器加载到内存,在运行时使用的。而编译出来的共享库(jar包),内部是Android字节码Dex格式的文件,一般无法导入Eclipse等IDE使用。Android.mk中由BUILD _ JAVA _ LIBRARY指定生成共享库

我觉得静态库和动态库本质上没有区别,可能就是说静态库是编译时期就把jar包中的代码整合到项目中了,动态库就是说在程序运行期,把jar包加载到内存中,每次使用再继续重新加载到内存,

这里有一个问题就是jar包怎么导入到Android.mk的编译体系中,LOCAL _ STATIC _ JAVA _LIBRARIES += libTuSDKCore libgdx libTuSDKVideo libUniversalImageLoader libTuSDKFace
##################################################
include $(CLEAR_VARS)
LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := libTuSDKCore:libs/TuSDKCore-2.8.4.jar
include $(BUILD_MULTI_PREBUILT)#这句是将静态库加入到整体系统中
我们能看到,首先是LOCAL_STATIC_JAVA_LIBRARIES =**这是给静态库起名字,什么都可以,LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES 这个是预编译静态库,它的格式是之前你给静态库起的名字:路径(这个路径的起始位置就是当前的这个Android.mk的路径,如果和它同级那直接写名字,在其他文件夹上就在起始位置的基础上把库的路径带过来),起名字的时候可以空格然后并列起多个名字
导入共享库是这样的:
// MODULE 依赖的共享库
LOCAL_JAVA_LIBRARIES += simple_game
// 安装时module时,共享库需要一起安装。
LOCAL_REQUIRED_MODULES := simple_game 但这是我百度的,不知道系统要怎么才能找到这个simple_game的共享库,app在使用时千万别忘了在AndroidManifest.xml中添加该共享库:

上面是别人的静态库、动态库怎么使用,下面来说说自己怎么编译静态库和动态库:
1、编译静态库:
/ 返回Android.mk所在的当前路径
LOCAL_PATH:= $(call my-dir)
// 清理除LOCAL_PATH变量以外的LOCAL_XXX
include $(CLEAR_VARS)
// 生成静态库的name
LOCAL_MODULE := simple_game
// 设置在那个版本下编译,user, eng, tests, optional(全版本编译)
LOCAL_MODULE_TAGS := optional
// 签名类型 testkey, media, platform, shared, 默认为testkey
LOCAL_CERTIFICATE := platform
// 生成静态库使用的源文件
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_SRC_FILES += $(call all-Iaidl-files-under, src)
// 设置生成静态库
include $(BUILD_STATIC_JAVA_LIBRARY)

2、编译动态库:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := simple_game
LOCAL_MODULE_TAGS := optional
LOCAL_CERTIFICATE := platform
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_SRC_FILES += $(call all-Iaidl-files-under, src)
// 安装时需要一起安装的模块
LOCAL_REQUIRED_MODULES := simple_game.xml
// 设置生成共享库
include $(BUILD_JAVA_LIBRARY)
###############################################################
include $(CLEAR_VARS)
LOCAL_MODULE := simple_game.xml
// 定制LOCAL_MODULE_PATH变量的值
LOCAL_MODULE_CLASS := ETC
// 设置安装的路径
LOCAL_MODULE_PATH := $(TARGET_OUT)/etc/permissions
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := simple_game.xml
// 将文件预置进系统
include $(BUILD_PREBUILT)

注意注意!!!
共享库需要一个xml文件配置安装的信息,LOCAL_REQUIRED_MODULES设置了该文件,当共享库安装时,LOCAL_REQUIRED_MODULES制定的模块也会安装到系
统中。
安装的位置由LOCAL_MODULE_PATH指定,当LOCAL_MODULE_PATH没有设置时,系统将会根据LOCAL_MODULE_CLASS的值来判断安装的位置,
LOCAL_MODULE_CLASS变量将通过/build/core/base_rules.mk文件设置默认的安装目录,常用的值有:
apk文件: APPS so文件: SHARED_LIBRARIES bin文件: EXECUTABLES 其他文件: ETC
当LOCAL_MODULE_PATH和LOCAL_MODULE_CLASS均没有设置时,系统会根据编译生成的不同模块(根据include$()判断)来自动设置LOCAL_MODULE_CLASS的值,
但遇到include $(BUILD_PREBUILT)编译选项时,系统不会设置模块的LOCAL_MODULE_CLASS,需要显示设置。
最后针对单一文件进行预编译需要设置BUILD_PREBUILT,对于多文件需要设置BUILD_MULTI_PREBUILT宏

  1. LOCAL_RENDERSCRIPT_TARGET_API ,LOCAL _ RENDERSCRIPT _COMPATIBILITY ,这俩大概是说在使用RenderScript,RenderScript是运行在Android系统上的一个高性能密集计算框架。RenderScript主要面向并行数据的计算,当然也可以使串行数据计算的负载受益。RenderScript运行时会在一台设备所有可用处理器上并行工作,比如多核的CPU,GPU或者DSP,这使得你可以专注于算法,而不是任务调度或者负载平衡。RenderScript在应用程序执行图像处理,计算摄影或者计算机视觉等方面都非常有用。并不是Android.mk文件的必需品
  2. LOCAL_SRC_FILES ,LOCAL_RESOURCE_DIR ,这个很好理解,src、dir就是编译的源码Java文件(src)和xml资源文件(dir)

LOCAL_SRC_FILES := $(call all-java-files-under, src),这里是要编译Java代码,所以用all-java-files-under,all-java-files-under宏的定义是在build/core/definitions.mk中,它的意思是将Java源码也编译进去。如果是编译c/c++代码, 当涉及到C/C++时,LOCAL_SRC_FILES变量就必须包含将要编译打包进模块中的C或C++源代码文件。注意,在这里你可以不用列出头文件和包含文件,因为编译系统将会自动为你找出依赖型的文件;仅仅列出直接传递给编译器的源代码文件就好。

  1. LOCAL_AAPT_FLAGS ,aapt是Android的打包工具,

1、–auto-add-overlay意思是当不同文件夹有相同的资源id时,只将第一个资源合并打包进来,
2、–extra-packages android.support.v7.appcompat,意思是将extra-package包后边的文件包引入到当前代码框架中,就像给当前代码导入一个jar包,但是这里不限jar、library等等,这样引入编译之后就能合并在一起使用

  1. LOCAL_PACKAGE_NAME 这里是给apk起名,生成的apk名字
  2. LOCAL_PROGUARD_ENABLE :

它有两个值: disable、full
1、disable 制定编译的工程,不需要使用代码混淆的工具进行代码混淆
2 full 意思就是将该工程代码全部混淆,如果要混淆的时候设置LOCAL _ PROGUARD _ FLAG _ FILES
LOCAL_PROGUARD_FLAG_FILES := proguard.flags 然后在Android.mk同级目录下编写 proguard.flags 文件,这个文件中可以设置哪些是不需要混淆的
-keep class com.mediatek.camera.common.jpeg.HwJpegDecodeImpl { *; },这样这个路径下的文件就不会被混淆

  1. LOCAL_DEX_PREOPT 设置apk要不要被预编译生成一份jvm的可执行文件,就是Android虚拟机加载apk的模式,
  2. LOCAL_PRIVATE_PLATFORM_APIS := true设置后,会使用sdk的hide的api來编译

在Android.mk中如果有LOCAL_SDK_VERSION 这个编译配置,就会使编译的应用不能访问hide的api,有时一些系统的class被import后编译时说找不到这个类,就是这个原因造成的。
LOCAL_SDK_VERSION := current 意思是编译时忽略系统隐藏类(@hide)

  1. include $(BUILD_PACKAGE) 有很多值

BUILD_HOST_STATIC_LIBRARY 编译静态库(适用与主机)
BUILD_HOST_SHARED_LIBRARY 编译动态库(适用与主机)
BUILD_HOST_EXECUTABLE 编译可执行程序(适用与主机)
BUILD_HOST_PREBUILT 预编译(适用与主机)
BUILD_HOST_JAVA_LIBRARY 编译java包(适用与主机)
BUILD_JAVA_LIBRARY 编译java包
BUILD_STATIC_JAVA_LIBRARY 编译java静态包
BUILD_STATIC_LIBRARY 编译静态库
BUILD_SHARED_LIBRARY 编译动态库
BUILD_EXECUTABLE 编译可执行程序
BUILD_PACKAGE 编译apk
BUILD_PREBUILT 预编译(针对单个预编译文件)
BUILD_MULTI_PREBUILT 预编译(针对多个预编译文件)

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐