• Lichee(三) Android4.0该产品的目标文件夹,Lichee链接---extract-bsp


    由《Lichee() 在sun4i_crane平台下的编译》介绍了编译lichee的基本情况,我们终于得到了编译后的结果例如以下:

    out/
    ├── android
    │   ├── bImage
    │   ├── lib
    │   ├── toolchain
    │   ├── uImage
    │   └── zImage
    └── u-boot.bin

    小贴士:
        几种linux内核文件的差别:

    1vmlinux  编译出来的最原始的内核文件,未压缩。

    2zImage   vmlinux经过gzip压缩后的文件。

    3bzImage bz表示“big zImage”,不是用bzip2压缩的。

    两者的不同之处在于。zImage解压缩内核到低端内存(第一个640K)bzImage解压缩内核到高端内存(1M以上)。假设内核比較小,那么採用zImagebzImage都行,假设比較大应该用bzImage

    4uImage   U-boot专用的映像文件。它是在zImage之前加上一个长度为0x40tag

    5vmlinuz  bzImage/zImage文件的拷贝或指向bzImage/zImage的链接。

    6initrd   是“initial ramdisk”的简写。

    一般被用来暂时的引导硬件到实际内核vmlinuz可以接管并继续引导的状态



    我们能够清晰的看到,我们已经有了u-boot.bin uImage 已经lib文件夹下的modules。我们如今唯一缺少的就是根文件系统rootfs了,我们知道主流的cubieboard一開始能够使用主流的Linux操作系统各种发行版本号,比方Ubuntu、Debian、Fedora、OpenSUSE、ArchLinux等等。详情请看《cubieboard开发板简单介绍》一文,所以说,Lichee自己主动化编译的过程事实上也包括了rootfs的编译。仅仅是我们是基于Android的sun4i_crane平台的讨论,在《Lichee(二) 在sun4i_crane平台下的编译》一文中有益没有展开。首先本文还是沿着Lichee这条主线去探讨与Lichee相关的Android编译的过程,具体的Android编译的原理将在以后讨论。

    让我们先看一下仅仅有4句话的编译命令
    source build/envsetup.sh
    lunch 9
    extract-bsp
    make -j8


    • 一、 创建目标产品文件夹
       通常情况下。我们将自己的产品文件夹创建在device文件夹下。在较早的Android版本号中,有时候将自己的目标产品放在vendor文件夹下,由于Android有一套完备的方法和脚本让我们只改动目标产品文件夹的文件,就能够对系统进行配置。这里的内容许多,后面的文章我们将具体地一一分析。这里只提到与编译相关的地方

    device/
    ├── common
    ├── generic
    ├── google
    ├── sample
    ├── samsung
    ├── softwinner
    └── ti
    device文件夹下有各种平台的子文件夹。softwinner即代表全志的系列 common顾名思义即代表通用地
    这里假定我们的产品名叫做mt7332,我们能够在device/softwinner中创建一个名为crane-mt7332的文件夹

    device/softwinner/
    ├── common
    ├── crane-3g
    ├── crane-common
    ├── crane-m1003h6
    ├── crane-MID9742-sc3052
    └── crane-mt7332 这就是我们自己创建的
    首先,我们必需要创建一个名为 vendorsetup.sh的脚本文件。由于每一个目标产品文件夹都有这个文件。这个脚本中仅仅有一句话

    add_lunch_combo crane_mt7332-eng


    add_lunch_combo 是build/envsetup.sh中的一个脚本函数。能够理解为把你自己创建的目标产品注冊到Android系统中去,否则将无法编译到目标产品
    crane_mt7332-eng 就是对自己的目标产品的命名。eng是VARIANT当中的一种,代表编译的是project机的类型,为了让Android系统指导你的目标机是eng、user、userdebug。这个名字必须是xxx-eng xxx-user xxx-userdebug等这样的格式来命名。crane代表的是全志A10中的Android的项目


    小贴士:
        VARIANT的官方解释
    eng This is the default flavor. A plain make is the same as make eng.
    *       Installs modules tagged with: eng, debug, user, and/or development.
    *       Installs non-APK modules that have no tags specified.
    *       Installs APKs according to the product definition files, in addition to tagged APKs.
    *       ro.secure=0
    *       ro.debuggable=1
    *       ro.kernel.android.checkjni=1
    *       adb is enabled by default.
    *       Setupwizard is optional

    user make user
    This is the flavor intended to be the final release bits.
    *       Installs modules tagged with user.
    *       Installs non-APK modules that have no tags specified.
    *       Installs APKs according to the product definition files; tags are ignored for APK modules.
    *       ro.secure=1
    *       ro.debuggable=0
    *       adb is disabled by default.
    *       Enable dex pre-optimization for all TARGET projects in default to speed up device first boot-up

    userdebug make userdebug
    The same as user, except:
    *       Also installs modules tagged with debug.
    *       ro.debuggable=1
    *       adb is enabled by default.


    • 二、指定目标产品(target product)
    source build/envsetup.sh
    lunch




    小贴士:
    source的含义
    source在当前bash环境下运行命令。而scripts是启动一个子shell来运行命令。这样假设把环境变量设置(或alias等等)的命令写进scripts中,就仅仅会影响子shell,无法改变当前的BASH,所以通过文件(命令列)环境变量设置时,要用source 命令。build/envsetup.sh脚本的工作最主要就是要环境变量设置,所以必须带source



    编译Android之前。我们往往要运行这2条命令。让我们选择目标产品。

    这2条命令看似简单,事实上蕴含着极大的智慧。

    它能够让Android独立于不同的架构、不同的处理器、不同的屏幕尺寸和朝向、不同的外设驱动等等。始终就是一套代码,所以编译Android之前必需要选择到底编译的是哪一款目标产品。

    build/envsetup.sh与编译有关的大致有下面function

    function add_lunch_combo()            # 加入lunch项目
    function print_lunch_menu()              # 打印lunch列表
    function lunch()                    # 配置lunch,选择目标产品
    function m()                   # Android根文件夹编译, 必须在lunch之后才干使用,用的较少,由于在根文件夹下编译一般使用make
    function findmakefile()              # 查找makefile
    function mm()                  # 编译当前文件夹下的Android.mk。 必须在lunch之后才干使用,使用方法演示样例 cd packages/apps/Music && mm
    function mmm()                 # 编译指定文件夹下Android.mk。 必须在lunch之后才干使用 mmm packages/apps/Music 等用于 cd packages/apps/Music && mm

    我们着重探讨一下lunch()

    function lunch()
    {
        local answer
        #假设你明白地知道lunch后的结果能够直接lunch $1  $1代表目标产品的编号 比方我通常就是使用lunch 9
        if [ "$1" ] ; then
            answer=$1
        else
        # 假设不知道是第几个,就调用print_lunch_menu,打印出全部的目标产品。然后read你的输入
            print_lunch_menu
            echo -n "Which would you like? [full-eng] "
            read answer
        fi
    
        local selection=
    
        if [ -z "$answer" ]
        then
            selection=full-eng
        #假设lunch后有输入。仅仅接受前2个字符的数字。忽略后面的字符
        elif (echo -n $answer | grep -q -e "^[0-9][0-9]*$") 
        then
            if [ $answer -le ${#LUNCH_MENU_CHOICES[@]} ]
            then
                selection=${LUNCH_MENU_CHOICES[$(($answer-1))]}
            fi
    # 正則表達式 ^[^-][^-]*-[^-][^-]*$ 表示 字符串中间仅仅能有一个字符'-' 比如 a-b符合条件, 而-a-b , a-b- a--b这些都不符合条件
        elif (echo -n $answer | grep -q -e "^[^-][^-]*-[^-][^-]*$")
        then
            selection=$answer
        fi
        
        #选择是无效字符
        if [ -z "$selection" ]
        then
            echo
            echo "Invalid lunch combo: $answer"
            return 1
        fi
    
        export TARGET_BUILD_APPS=
        # sed -e "s/-.*$//") 是将字符'-'后面的都去掉。剩下前面的内容, 演示样例:crane_mt7332-eng 通过 sed -e "s/-.*$//"后。变成了crane_mt7332
        local product=$(echo -n $selection | sed -e "s/-.*$//")
        check_product $product
        if [ $? -ne 0 ]
        then
            echo
            echo "** Don't have a product spec for: '$product'"
            echo "** Do you have the right repo manifest?"
            product=
        fi
        # sed -e "s/^[^-]*-// 表示将字符 '-'之前的内容都去掉,仅仅剩下后面的编译版本号,演示样例:crane_mt7332-eng 通过 sed -e "s/-.*$//"后。变成了eng
        local variant=$(echo -n $selection | sed -e "s/^[^-]*-//")
        check_variant $variant
        if [ $? -ne 0 ]
        then
            echo
            echo "** Invalid variant: '$variant'"
            echo "** Must be one of ${VARIANT_CHOICES[@]}"
            variant=
        fi
    
        if [ -z "$product" -o -z "$variant" ]
        then
            echo
            return 1
        fi
        # 将获取的目标产品,VARIANT和类型写入到环境变量
        export TARGET_PRODUCT=$product
        export TARGET_BUILD_VARIANT=$variant
        export TARGET_BUILD_TYPE=release
        
        echo
    
        set_stuff_for_environment
        printconfig
    }

    目标产品的选择就此完毕

    实际步骤例如以下:

    $ source build/envsetup.sh
    including device/samsung/maguro/vendorsetup.sh
    including device/samsung/tuna/vendorsetup.sh
    including device/softwinner/common/vendorsetup.sh
    including device/softwinner/crane-3g/vendorsetup.sh
    including device/softwinner/crane-m1003h6/vendorsetup.sh
    including device/softwinner/crane-MID9742-sc3052/vendorsetup.sh
    including device/softwinner/crane-mt7332/vendorsetup.sh
    including device/ti/panda/vendorsetup.sh
    including sdk/bash_completion/adb.bash

    $ lunch
    You're building on Linux
    Lunch menu... pick a combo:
         1. full-eng
         2. full_x86-eng
         3. vbox_x86-eng
         4. full_maguro-userdebug
         5. full_tuna-userdebug
         6. crane_3g-eng
         7. crane_m1003h6-eng
         8. crane_MID9742_sc3052-userdebug
         9. crane_mt7332-eng
         10. full_panda-eng
    Which would you like? [full-eng] 9
    ============================================
    PLATFORM_VERSION_CODENAME=REL
    PLATFORM_VERSION=4.0.4
    TARGET_PRODUCT=crane_mt7332
    TARGET_BUILD_VARIANT=eng
    TARGET_BUILD_TYPE=release
    TARGET_BUILD_APPS=
    TARGET_ARCH=arm
    TARGET_ARCH_VARIANT=armv7-a-neon
    HOST_ARCH=x86
    HOST_OS=linux
    HOST_BUILD_TYPE=release
    BUILD_ID=IMM76D
    ============================================


    • 三、 extract-bsp

    extract-bsp是一个脚本函数,在device/softwinner/common/vendorsetup.sh 他也是在lunch的时候被运行的,也就是说假设先不运行lunch extract-bsp是无效的


    让我们来看看extract-bsp

    function lunch()
    {
        local answer
        #假设你明白地知道lunch后的结果能够直接lunch $1  $1代表目标产品的编号 比方我通常就是使用lunch 9
        if [ "$1" ] ; then
            answer=$1
        else
        # 假设不知道是第几个。就调用print_lunch_menu,打印出全部的目标产品。然后read你的输入
            print_lunch_menu
            echo -n "Which would you like? [full-eng] "
            read answer
        fi
    
        local selection=
    
        if [ -z "$answer" ]
        then
            selection=full-eng
        #假设lunch后有输入,仅仅接受前2个字符的数字。忽略后面的字符
        elif (echo -n $answer | grep -q -e "^[0-9][0-9]*$") 
        then
            if [ $answer -le ${#LUNCH_MENU_CHOICES[@]} ]
            then
                selection=${LUNCH_MENU_CHOICES[$(($answer-1))]}
            fi
    # 正則表達式 ^[^-][^-]*-[^-][^-]*$ 表示 字符串中间仅仅能有一个字符'-' 比如 a-b符合条件, 而-a-b , a-b- a--b这些都不符合条件
        elif (echo -n $answer | grep -q -e "^[^-][^-]*-[^-][^-]*$")
        then
            selection=$answer
        fi
        
        #选择是无效字符
        if [ -z "$selection" ]
        then
            echo
            echo "Invalid lunch combo: $answer"
            return 1
        fi
    
        export TARGET_BUILD_APPS=
        # sed -e "s/-.*$//") 是将字符'-'后面的都去掉,剩下前面的内容。 演示样例:crane_mt7332-eng 通过 sed -e "s/-.*$//"后,变成了crane_mt7332
        local product=$(echo -n $selection | sed -e "s/-.*$//")
        check_product $product
        if [ $? -ne 0 ]
        then
            echo
            echo "** Don't have a product spec for: '$product'"
            echo "** Do you have the right repo manifest?"
            product=
        fi
        # sed -e "s/^[^-]*-// 表示将字符 '-'之前的内容都去掉。仅仅剩下后面的编译版本号,演示样例:crane_mt7332-eng 通过 sed -e "s/-.*$//"后,变成了eng
        local variant=$(echo -n $selection | sed -e "s/^[^-]*-//")
        check_variant $variant
        if [ $? -ne 0 ]
        then
            echo
            echo "** Invalid variant: '$variant'"
            echo "** Must be one of ${VARIANT_CHOICES[@]}"
            variant=
        fi
    
        if [ -z "$product" -o -z "$variant" ]
        then
            echo
            return 1
        fi
        # 将获取的目标产品,VARIANT和类型写入到环境变量
        export TARGET_PRODUCT=$product
        export TARGET_BUILD_VARIANT=$variant
        export TARGET_BUILD_TYPE=release
        
        echo
    
        set_stuff_for_environment
        printconfig
    }


    总的来说,经行分析extract-bsp脚本发现。事实上就是将lichee编译的结果输出到device/softwinner/vendor文件夹下,事实上这个过程是为了android的编译在做准备。而Android的编译过程很复杂,由于我们是要沿着Lichee这条主线继续走下去,可是不正确Android的编译过程以及目标产品的概念进行简单地分析,又不能充分了解到function extract-bsp()这个函数的用处。实际上本文的真正用意就是要了解extract-bsp的过程和背景,这个函数也是联系Lichee和Android之间的纽带。本文在这个系列中第一次提到了Android BSP相关的知识,可能理解起来就有点困难了。Android的BSP是后面的重中之重,到时候可能还会花大力气分析本文已经提到的一某些内容(例如,创建目标文件夹),在这里,我们简单地接管。

    版权声明:本文博客原创文章。博客,未经同意,不得转载。

  • 相关阅读:
    linux tcp中time_wait
    linux查看系统信息
    运行程序出错无法找到库文件
    安装keepalived
    python 深拷贝与浅拷贝
    python import eventlet包时提示ImportError: cannot import name eventlet
    [原创] 用两个queue实现stack的功能
    [原创] 用两个stack实现queue的功能
    [原创] 编写函数,实现对链表元素的排序与分类
    python 装饰器
  • 原文地址:https://www.cnblogs.com/yxwkf/p/4709741.html
Copyright © 2020-2023  润新知