android源码编译相关
在rom开发过程中,经常需要编译源代码生成一系列文件,然后再拷贝出来做成pac包然后刷进手机中,编译这个环节必不可少,那么现在来看看有哪些最常用的命令吧
source build/envsetup.sh
如果有时间有兴趣,可以看一看build中的envsetup.sh文件,envsetup提供了很多的shell脚本函数,如mmm,lunch等,只有先加载他,我们才能进行下一步的编译
值得一提的是,有时可能不止需要source这个envsetup,例如我们可能需要在一台电脑上时不时的编译android5.0和7.0的源码,而他们的编译环境又不完全相同,比较简单的方式是通过写一个脚本,动态的来加载编译5.0或7.0的java环境及其他环境
lunch
lunch这玩意主要还是选择编译时的脚本,举个最简单的例子,user版本和debug版本编译的时候就不一样,需要编译哪种类型的版本就需要选择对应的编译脚本
xxxx
在这一步时,有些平台的源码可能需要手动添加库文件,即C的头文件,平台一般会提供一个脚本供执行以将这些文件放置进out目录。ps:xxxx指的是该命令,而并不是xxxx......
make
其实这一步没啥好说的,就是全部编译,简称全编,在已经有out目录存在的时候,它会自动检测哪些地方的代码有修改,然后针对那些地方单编,最后再打包,但这里需要注意是,假设已经有out目录存在,有些地方的改动,例如替换了一个资源文件,在make编的时候可能会没办法自动检测到,所以不会被更新进out目录
mmm
我们知道android是由很多的模块组成,该命令加上具体路径就是单独编译某模块的命令,简称单编,需要注意的是有些时候直接mmm的话可能也会漏掉改动,建议后面加上 -B 以完全单编这个模块
除了通过make命令编译可以整个android源码外,Google也为我们提供了相应的命令来支持单独模块的编译.
make snod
重新打包系统镜像,编译好指定模块后,如果我们想要将该模块放入系统镜像中,则可以使用make snod
指令重新打包系统镜像,这样我们新生成的system.img中就包含了刚才编译的单编模块了
以下是一些感想:
在实际开发中,在我们进行了一系列改动,想编译并且打包出来测试时,会发现有两点比较令人苦恼
1,如果每次都将输出目录,即out目录删干净再重新编译,耗时费力(我们知道完全编译一次android源码是很费时的)
2,如果每次都闭着眼睛直接make,则有些地方的改动不会被编译进去,即做了修改,但是make之后没有检查到改动,并未把这次的改动编译进去,刷机之后会发现还是上个版本的内容,又需要确认是没有改成功还是因为没有被编译进去,非常麻烦
这里给两种方法
1,我们知道mmm命令加上-B是可以完全编译该模块的(ps:前提是你确认这个东西是一个模块,即目录下存在android.mk文件),我们使用该命令编译的时候,不管out目录下有无该模块,都会重新编译并且放入out目录
2,我们知道最终输出的目录即out目录,既然全部的东西都是我们后面生成的(需要注意的是有些平台的代码有所谓的outbase,每次编译时需要拷一个outbase出来并且重命名为out作为out目录的基础),那么我们大可删去这一部分相关内容然后使用make指令进行编译(举个例子,我们在package中的一个app做了改动,假设改的是launcher3这个app,那么我们大可进out目录,找到system/app下的这个launcher3,直接删除,然后再使用make进行编译),make指令会自动检查out目录里没有,但是需要被编译进out目录的部分代码进行编译,所以这个launcher3就会被编译进out目录了
简单来说,如果我们能够简单快捷的找到修改部分的代码是在哪个模块中,那么我们单编该模块即可,如果不是很好找,我们就去out目录中删去该模块相关的内容,然后让make自动去检测哪部分有缺省,让他自己通过单编来补全那部分,当然也有两者都不好找的情况(当然我个人认为找不到的话可能还是由于对目录理解不够),那就直接删去out目录再次编译,即clean之后再编译(ps:有些平台代码clean后会有很多问题,这种情况建议先剪切到其他目录下,然后从第一步开始重新编译,编译的时候回头把剪切出去的这个out目录直接删除,这样比较简单)。