Android makefile文件解析
Android编译过程详解
编译步骤
Android的编译步骤包括三步:
1.通过source build/命令将sh文件中的命令加载到环境变量中去;
2. lunch命令用户选择编译选项;
3. make命令制定编译线程数以及错误输出;
source build/功能
整个命令用来加载到环境变量中去,中的命令主要有:
function get_abs_build_var() //获取绝对变量
function get_build_var() //获取构建变量
function check_product //检查product
function check_variant //检查变量
function setpaths() //设置文件路径
function lunch //配置启动选项
function m() //make from top
function findmakefile //查找makefile
function mm() //从当前文件开始编译
function mmm() //make the supplied directories
function croot() //回到根目录
envsetup,sh的命令还会从其他文件夹,如device、vendor、product中寻找,通过这个文件来加载对应的命令,并执行,所以在执行source build/命令的时候,可以看到控制台输出下面的信息:including device/somc/sm34/
lunch命令详解
lunch命令是里面定义的一个命令,让用户来选择编译选项,定义product和编译过程中用到的全局变量。
make命令作用
make –j8 2>&1 | tee 是编译命令,-j8指的是线程数量,一般是cpu核心的两倍,2指的标准错误,&1是标准输出,2>&意思就是将标准错误输出到标准输出中,tee的作用是同时输出到控制台和文件
,的作用是将错误和结果定向到中,make命令执行的结果就是取执行当前目录下的Makefile文件,打开buile/make/core/文件,关注下系统变量BUILD_SYSTEM,引用文件,打开build/make/core/文件,里面有很多变量设置,如CLEAR_VARS指的是用来清除之前定义的变量,另外还包括了另外一个重要的文件,查看文件,其中又包括了product_config.mk文件,里面的配置文件OUT_DIR、SONNG_OUT_DIR、TARGET_OUT_ROOT、HOST_OUT_ROOT分别指定了目标输出的代码位置和主机输出的代码位置,使用get-all-product-makefiles获取所有的文件,打开文件,其中有文件,打开查看,继续查看看 device/somc/sm34/文件,其中有个变量PRODUCT_MAKEFILES文件,其中引用了vendor/parter_gms/products/。
文件加载流程总结
> > Makefile > > > > Product_config.mk
> > ,
文件常用变量
如何编译模块
前面说到了Android编译过程,最后降到了PRODUCT_PACKAGE,现在讲解如何取编译这个模块以及这个模块里面文件中的一些常用变量,LOCAL_PACKAGE_NAME变量代表编译的模块名称,LOCAL_PATH代表mk文件的路径,$(call my-dir)调用NDK内部的函数获得当前.mk文件的路径。每个文件必须以定义LOCAL_PATH为开始。宏my-dir 则由Build System提供,返回包含的目录路径。CLEAR_VARS清空了除了LOCAL_PATH之外的所有LOCAL_xxx变量的值,LOCAL_SRC_FILES代表src源文件地址,LOCAL_MODULE值模块名称,inclue指依赖的java静态库
常用变量
LOCAL_MODULE/LOCAL_PACKAGE_NAME //模块名称
LOCAL_PRIVATE_PLATFROM_APIS //私有API是否能访问
LOCAL_CERTIFICATE //校验证书
LOCAL_PRIVILEGET_MODULE //设置为true,安装位置为system/priv-app
LOCAL_MODULE_TAGS //user版本,eng版本,tests版本,optional版本
LOCAL_POST_INSTALL_CMD //install命令执行后出发
LOCAL_MODULE_OWNER //模块owner somc
LOCAL_INIT_RC //用于将服务相关的RC文件编译到相应位置
LOCAL_SRC_FILES //用于将服务相关的RC文件编译到指定位置
LOCAL_JNI_SHARED_LIBRARIES //JIN打包到apk文件中
LOCAL_STATIC_ANDROID_LIBRARIES //当前模块的android 静态库
LOCAL_JVAV_LIBRARIES //当前模块依赖的java库
LOCAL_STATIC_JVAV_LIBRARIES //当前模块依赖的java静态库
LOCAL_PROGUARD_FLAG_FILES //混淆文件相关
LOCAL_PROGUAR_ENABLED //混淆是否可用
LOCAL_JACK_ENABLED //disabled、full、incremental三种模式
如何预制APK
预制步骤
在device/somc/sm34/文件中添加PRODUCT_PACKAGES += Voicechaner,将和文件放在指定的放第三方apk的路径下,按第三方apk编译要求写好,LOCAL_MODULE和apk名称对应上即可
如何预制GMS包
在device/somc/sm34/文件里面去引用gms包的mk编译脚本,gms包的引用编译脚本在gms包的products下,将PRODUCT_COPY_FILES将对应的文件copy到对应的路径下
文件解析
Android 7.0引入ninja和kati,Android 8.0使用来替换,引入Soong,Android 9.0强制使用,可以支持android_app、cc_binary、cc_binary_host等多种类型:
Ninja
一个编译框架,会根据相应的ninja格式的配置文件进行编译,通常是将文件转换程ninja格式文件来进行编译
bp文件出现的目的就是为了替换文件,Soong类似于之前的Makefile编译系统的核心,负责提供语义解析,并将之转换成Ninja文件。Soong还会编译生成一个androidmk命令,用于将文件转换为文件,不过这个转换功能仅限于没有分支、循环等流程控制的才有效。
Blueprint
Blueprint是生成、解析的工具,是Soong的一部分。Soong负责Android编译而设计的工具,而Blueprint只是解析文件格式,Soong解析内容的具体含义。Blueprint和Soong都是由Golang写的项目,从Android 7.0,prebuilts/go/目录下新增Golang所需的运行环境,在编译时使用。
Kati
kati是专为Android开发的一个基于Golang和C++的工具,主要功能是把Android中的文件转换成Ninja文件。代码路径是build/kati/,编译后的产物是ckati。