N1_build&Android_build详解

写在开始之前

本文将按整个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()

{

//这里会执行N1prebuild,文件很大,有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


这里比较重要,主要会在vendordeviceneoway 三个目录将厂商指定的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

你可能感兴趣的:(N1_build&Android_build详解)