美文网首页
N1_build&Android_build详解

N1_build&Android_build详解

作者: 黑石_2412 | 来源:发表于2019-11-21 15:49 被阅读0次

    写在开始之前

    本文将按整个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详解

          本文链接:https://www.haomeiwen.com/subject/fmstwctx.html