Lichee(三) Android4.0的目标产品目录与Lichee的纽带---extract-bsp

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

out/

├── android

│   ├── bImage

│   ├── lib

│   ├── toolchain

│   ├── uImage

│   └── zImage

└── u-boot.bin


小贴士:

几种linux内核文件的区别:

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

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

3、bzImage
bz表示“big zImage”,不是用bzip2压缩的。两者的不同之处在于,zImage解压缩内核到低端内存(第一个640K),bzImage解压缩内核到高端内存(1M以上)。如果内核比较小,那么采用zImage或bzImage都行,如果比较大应该用bzImage。

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

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

6、initrd   是“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其中的一种,代表编译的是工程机的类型,为了让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是后面的重中之重,到时候可能还会花大力气分析本文已经提到的一些内容(比如目标目录的创建),这里也就简单带过了。

Lichee(三) Android4.0的目标产品目录与Lichee的纽带---extract-bsp

时间: 2024-10-12 22:40:46

Lichee(三) Android4.0的目标产品目录与Lichee的纽带---extract-bsp的相关文章

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

由<Lichee() 在sun4i_crane平台下的编译>介绍了编译lichee的基本情况,我们终于得到了编译后的结果例如以下: out/ ├── android │   ├── bImage │   ├── lib │   ├── toolchain │   ├── uImage │   └── zImage └── u-boot.bin 小贴士: 几种linux内核文件的差别: 1.vmlinux  编译出来的最原始的内核文件,未压缩. 2.zImage   是vmlinux经过gzip

Android4.0(Phone)拨号启动过程分析(三)与Framework层通信

由于Android几乎所有的代码都是公开的,如果要对Framework层分析就必需先拿到Framework层的代码,我在前面已经搭建好了ubuntu14.04的环境,下载好了Android4.0的源码,其中也包括了Framework层和Package的代码,导出到宿主机Windows XP中用Source Insight 3.5工具来查看源码,Package中的代码可以导入到Eclipse下查看,我是把frameworks\base整个目录都导入到Source Insight 3.5工程中,可以

Android4.0设置界面改动总结(三)

Android4.0设置界面改动总结大概介绍了一下设置改tab风格,事实上原理非常easy,理解两个基本的函数就可以: ①.invalidateHeaders(),调用此函数将又一次调用onBuildHeader()来又一次读取xml文件里的header,又一次刷新HeaderAdapter中的数据,因此刷新了ListView的内容,从而更新了界面. ②.onBuildHeaders()中调用loadHeadersFromResource(resId, headers); 就可以又一次载入Hea

Android4.0设置界面修改总结(三)

Android4.0设置界面修改总结大概介绍了一下设置改tab风格,其实原理很简单,理解两个主要的函数即可: ①.invalidateHeaders(),调用此函数将重新调用onBuildHeader()来重新读取xml文件中的header,重新刷新HeaderAdapter中的数据,因此刷新了ListView的内容,从而更新了界面. ②.onBuildHeaders()中调用loadHeadersFromResource(resId, headers); 即可重新加载HeaderAdapter

QT210 android2.3 和android4.0 烧写编译日记

QT210下载烧录编译android2.3过程 工作环境:ubuntu12.04.5 | QT210开发板光盘 | QT210开发板 android2.3编译环境:gcc version 4.4.7  | java version 6 | java version 5 | git version 1.7.9.5 tips by chsry:浅灰色是终端窗口运行保存的部分命令和信息,ubuntu14.04无法编译QT210 android2.3(无法安装java6) 安装好ubuntu12.04.

【转】如何下载并编译Android4.0内核源码goldfish(图文)

原文网址:http://blog.csdn.net/flydream0/article/details/7070392 关于如何下载Android4.0源码,请查看我的博客内另一篇文章(同样是图文教程): http://blog.csdn.net/flydream0/article/details/7036156 如何编译Android4.0源码请看: http://blog.csdn.net/flydream0/article/details/7046612 下面进入正题: 第一步:下载gol

【转】如何在Ubuntu11.10(32位)下编译Android4.0源码(图文)

原文网址:http://blog.csdn.net/flydream0/article/details/7046612 关于如何下载Android4.0的源码请参考我的另一篇文章: http://blog.csdn.net/flydream0/article/details/7036156 3 开始编译 3.1 初始化环境$ source build/envsetup.sh3.2 选择目标$ lunch full-eng大概会再现如下提示:============================

一个Activity掌握Android4.0新控件 (转)

原文地址:http://blog.csdn.net/lavor_zl/article/details/51261380 谷歌在推出Android4.0的同时推出了一些新控件,Android4.0中最常用的新控件有下面5种. 1. Switch的使用 Switch顾名思义,就是开关的意思,有开和关两种状态. 当Switch处于关闭状态时: 当Switch处于打开状态时: 怎么在定义xml中定义Switch <Switch android:id="@+id/_switch" andr

搭建Android开发环境之——Android4.0.3, 4.1, 4.2, 4.3, 4.x,及升级 ADT(22.0.5)和SDK(22.x)

搭建Android开发环境之旅(Android4.0.3) 1.首先要下载相关的软件 1). JDK 6 以上 2). eclipse( Version 3.6.2  or higher ) 点击下载 3). SDK(android-sdk_r18-windows) 眼下是最新的 点击下载 4). ADT 18  (Android Development Tools  安装开发工具) 插件 点击下载 5). 还得下载 Android SDK 4.0.4 system img,其它版本号的可能不要