写在开始之前
本文将按整个ROM的编译流程逐步讲解,N1部分用红色表示,Android部分用黑色表示
Shell脚本的基本语法也需要简单掌握。
第一步源码根目录下的操作
按照有方提供的编译命令,在系统源码根目录下执行以下命令
./build.sh N1
此处执行根目录下的build.sh, 输入参数为N1
打开build.sh中,可以找到以下代码
if[[ $# -lt 1 ]] //如果当前输入参数小于1,将执行if语句
then
usage && exit 1
fi
build_pro=$1 //将第一个输入参数复制给build_pro,这里是N1
is_jsr_project
shift //将第一个参数替换为下一个,即$1不再是N1,为空
cp_and_co_check $1
build_ver=userdebuginput_ver=$1 // shift之后,此处input_ver为空
if [[ "$input_ver" == "user" ]]
then
build_ver=user
shift
fi
if [[ "$input_ver" == "userdebug" ]] || [["$input_ver" == "eng" ]]
then
shift
fi
build_target=$1 // shift之后,此处input_ver为空, 因此会执行下面的make命令
…….
…….
sourcebuild/envsetup.sh >/dev/null
lunch ${build_pro}-${build_ver}
//根据上面的解释,这两个命令等价于以下命令
//
source build/envsetup.sh >/dev/null
//
lunch N1 userdebug
…….
…….
else
make -j8 $@ 2>&1 | tee
${build_pro}-${build_ver}_build.log
fi
第二部源码build目录下的操作
在上一步的代码里 会执行下面两条命令
source
build/envsetup.sh >/dev/null
lunch
N1 userdebug
接下来我们分别来看这两条命令都做了些什么工作
[if !supportLists]1. [endif] sourcebuild/envsetup.sh >/dev/null
需要在build目录下加载envsetup.sh。
这里需要简单解释一下这个文件的作用,简单讲这个文件就是为了完成一些编译命令的初始化,详细的解释可以看这篇博客https://blog.csdn.net/piaozhiye/article/details/7522153
整个文件基本是按照原生AOSP的思路实现的,但是也加入了N1自己的东西
function lunch()
{
…
//这里会执行N1的prebuild,文件很大,有3G左右,从命令到代码都是加密的
if [ "$TARGET_BUILD_VARIANT" = "userdebug" ]
then
./neoway/build/scripts/neoprebuilt.sh.x
else
./neoway/build/scripts_usr/neoprebuilt_usr.sh.x
fi
}
在文件的最末有以下代码。
# Execute the contents of any vendorsetup.sh files we can find.
for f in `test -d
device&& find -L device -maxdepth 4 -name 'vendorsetup.sh' 2> /dev/null` \
`test -d
vendor&& find -L vendor -maxdepth 4 -name 'vendorsetup.sh' 2> /dev/null` \
`test -d
neoway&& find -L neoway -maxdepth 4 -name 'neosetup.sh' 2> /dev/null`
do
echo "including $f"
. $f
done
unset f
这里比较重要,主要会在vendor和device和neoway 三个目录将厂商指定的vendorsetup.sh也source到当前shell当中,比防说device目录下的vendorsetup.sh
add_lunch_combo N1-userdebug // add_lunch_combo函数可以在build/envsetup.sh找到
add_lunch_combo N1-user
[if !supportLists]2. [endif]Lunch N1 userdebug
关于lunch命令的详解请参考这篇博文
http://www.lupaworld.com/home.php?mod=space&uid=131820&do=blog&id=149462
第三步 执行make命令
在第一步中的最后,会执行
make
-j8 $@ 2>&1 | tee ${build_pro}-${build_ver}_build.log
根据输入的参数这条命令实际上是
make
-j8 $@ 2>&1 | tee N1-userdebug_biuld.log
make命令会查找当前目录下,即根目录下的Makefile文件,打开Makefile会看到以下代码
### DONOT EDIT THIS FILE ###
include build/core/main.mk
### DO NOT EDIT THIS FILE ###
到了这里就需要简单了解一下Android的编译系统了
整个Android只有一个Makefile,这听起来似乎是一件很疯狂的事情,因为这个Makefile可能会变得无比庞大和复杂。其实不用担心,我们可以按照模块来将这个Makefile划分成一个个Makefile片段(fragement),然后通过Makefile的include指令来将这些Makefile片段组装在一个Makefile中。与递归Makefile相比,每一个模块现在拥有的是一个Makefile片段,而不是一个Makefile文件。这正是Android编译系统的设计思想和原则,也就是说,我们平时所编写的Android.mk编译脚本都只不过是整个Android编译系统的一个Makefile片段。
明白了Android编译系统的设计思想和原则之后,我们就可以通过下面这个图来观察一下Android编译系统的整体架构了:原图文链接:https://blog.csdn.net/huangxiaominglipeng/article/details/41745199
通过这张图我们也能看到build/core/main.mk加载过程中会加载以下的文件
build/core/config.mk
build/core/definitions.mk
指定的Android.mk
build/core/Makefile
下面的图会更清晰的展示main.mk干了些什么。
所有的Makefile都通过build/core/main.mk这个文件组织在一起,它定义了一个默认goals:droid,当我们在TOP目录下,敲Make实际上就等同于我们执行make droid。
当Make
include所有的文件,完成对所有make我文件的解析以后就会寻找生成droid的规则,依次生成它的依赖,直到所有满足的模块被编译好,然后使用相应的工具打包成相应的img。其中,config.mk,envsetup.mk,product_config.mk文件是编译用户指定平台系统的关键文件。上图中红色部分是用户指定平台产品的编译主线,我们先来看下config.mk的主要作用。
原文链接:https://blog.csdn.net/huangxiaominglipeng/article/details/41745199
注意这条线路
build/core/config.mk
-> build/core/envsetup.mk
-> build/core/product_config.mk
-> build/core/product.mk
在product_config.mk中有以下代码
//读取指定的目录下所有的AndrodProducts.mk文件中定义的产品信息
其实get-all-product-makefiles返回所有的产品文件xxx.mk
# Read in all of the product definitions specified by the AndroidProducts.mk
# files in the tree.
all_product_configs := $(get-all-product-makefiles)
这里的阶段性总结是
结合前面的图,product_config.mk主要读取vendor|device目录下不同厂商自己定义的AndrodProducts.mk文件,从该文件里取得所有产品的配置文件,然后再根据lunch选择的编译项TARGET_PRODUCT,找到与之对应的配置文件,然后设置TARGET_DEVICE变量,用于后续编译。
我们项目的命令是 lunch N1 userdebug, 那肯定是去device/device/jsr/N1目录下去找对应的AndroidProducts.mk
除了product_config.mk外还有board_config.mk需要注意,这条线的路径跟product相似,只是最终目的不同。
borad主要是设计到硬件芯片的配置,比如是否提供硬件的某些功能,比如说GPU等等,或者芯片支持浮 点运算等等。product是指针对当前的芯片配置定义你将要生产产品的个性配置,主要是指APK方面的配置,哪些APK会包含在哪个product中, 哪些APK在当前product中是不提供的。
如需更详细的解释请看博客https://blog.csdn.net/qq_26787115/article/details/79745022