三、Android 编译过程分析

一、Android 编译过程

  1. 初始化参数设置

  2. 检查环境变量与目标环境;

  3. 选择 lunch 并读取目标配置和平台信息;

  4. 清空输出目录;

  5. 编译;

  6. 生成升级包。

二、build/envsetup.sh 分析

1. 加载编译命令

  首先我们大概看一下 envsetup.sh,里面说明此脚本的主要用途是将一些命令添加到我们的环境中。

  

  接下来我们看看,执行 envsetup.sh 脚本前后有什么差异。

  在执行此脚本前,我们在控制台输入 mm、lunch 等命令,会提示“未找到命令”。接下来我们执行 source ./build/envsetup.sh 命令,可以到控制台多了一些输出:

  

   这些输出提示我们,这里 include 了一些文件。我们选 lunch 时,要从这些 device 目录下的脚本文件中寻找分支信息。

  运行脚本之后,mm、lunch 等命令就可以执行了。

2. 加载平台信息

  我们在控制台输入 lunch 后,会列出所有 lunch 的选项。注意,lunch 的分支信息,就是从上文所说的 device 目录下的脚本文件中获取的。

  首先,我们在 envsetup.sh 中找到 lunch() 函数。

  

  可以看到,lunch 函数首先对参数进行判断。这意味着,如果我们在执行 lunch 命令时带了参数(如 lunch 1),那么直接执行对应分支。如果没有带参数,则会列出所有分支,以供选择。

  接下来,我们看看 print_lunch_menu 函数是如何列出所有分支的:

  

  可以看到,所有分支信息保存在 LUNCH_MENU_CHOICES 中。那么 LUNCH_MENU_CHOICES 的数据又是如何添加的?我们继续追代码,可以看到 add_lunch_combo 函数,它的作用就是添加分支:

  

  前文提到,lunch 的平台信息,是在 envsetup.sh 导入的 device 目录下的脚本中获取的。我们打开一个看看:

  

  可以看到,在导入的 device 目录下的脚本中,调用了 add_lunch_combo 函数,从而为 lunch 添加了分支信息。

  除了通过导入的脚本来获取分支,envsetup.sh 脚本本身也可能会调用  add_lunch_combo 函数来添加分支(下图是 HiSilicon 的代码,可能是由于完全用不掉,所以注释掉了)。

  

三、lunch 相关

  当我们选择一个分支之后,lunch 函数就会根据分支进行初始化,这样就完成了环境变量的配置。在选择分支后,控制台也会输出一些信息:

  

  在这些信息中,有 Android 系统版本(PLATFORM_VERSION)、TARGET_PRODUCT、TARGET_BUILD_VARIANT、工具链、编译服务器、输出目录等信息。

  此时再通过 export 来查看环境变量,会发现多了很多 Android 的配置。

1. 如何在 lunch 中减少一个分支

  注释掉脚本中 add_lunch_combo 相关的语句,即可将对应分支去掉

2. 如何在 lunch 中增加一个分支

(1)为什么要在 lunch 中增加分支

  同一套产品,不同的客户可能提出差异化的需求。如果我们在代码仓库上拉不同的分支,这意味着很多修改都要同步到这些分支上,十分繁琐。同时,硬件的迭代,也会导致差异。如果我们只是在 lunch 中增加分支,那么绝大多数代码都是共用主干的,修改量较少。

  

(2)lunch 的不同分支之间有什么差异

  每个分支的目录下都有一些 mk 文件,其中会有差异化的动作,譬如将指定文件 copy 到 out 目录下的指定位置等,这样就会生成差异化的升级包。

四、Android 编译命令使用

  如果整体编译完成后,我们想单独编译某个模块,可以使用 mm 命令或 mmm 命令。

  mmm 命令要加参数,指定编译的模块。譬如 mmm external/libpng,就是单独编译此模块。编译完成后,会生成一个新的库文件,并将其替换到 out 目录下。

  mm 命令则需要进入到待编译的目录,然后直接输入 mm,回车运行即可。同样会生成新的库文件,并替换到 out 目录下。

五、总结

  

  当执行 build/envsetup.sh 时,首先是加载命令和分支。而执行 lunch 时,则是选择具体分支,配置编译环境变量,指定输出目录。

猜你喜欢

转载自www.cnblogs.com/murongmochen/p/12331506.html