Android源码编译过程分析

先整体看一下Android源码的整个编译流程,后面会针对每个过程都做了什么来详细讲解一下。

一、源码编译过程

  1. 清空out目录
make clobber
  1. 初始化参数设置
source build/envsetup.sh
  1. lunch选择平台
$ lunch

You're building on Darwin

Lunch menu... pick a combo:
     1. aosp_arm-eng
     2. aosp_arm64-eng
     3. aosp_mips-eng
     4. aosp_mips64-eng
     5. aosp_x86-eng
     6. aosp_x86_64-eng
     7. aosp_car_arm-userdebug
     8. aosp_car_arm64-userdebug
     9. aosp_car_x86-userdebug
     10. aosp_car_x86_64-userdebug
     11. mini_emulator_arm64-userdebug
     12. m_e_arm-userdebug
     13. m_e_mips-userdebug
     14. m_e_mips64-eng
     15. mini_emulator_x86-userdebug
     16. mini_emulator_x86_64-userdebug
     17. uml-userdebug
      ......
  1. 编译
make -j4

二、参数初始化(envsetp.sh)

envsetp.sh主要做了两件事情:加载编译命令加载平台信息

  • 加载编译命令
function hmm() {
cat <<EOF

Run "m help" for help with the build system itself.

Invoke ". build/envsetup.sh" from your shell to add the following functions to your environment:
- lunch:     lunch <product_name>-<build_variant>
             Selects <product_name> as the product to build, and <build_variant> as the variant to
             build, and stores those selections in the environment to be read by subsequent
             invocations of 'm' etc.
- tapas:     tapas [<App1> <App2> ...] [arm|x86|mips|arm64|x86_64|mips64] [eng|userdebug|user]
- croot:     Changes directory to the top of the tree.
- m:         Makes from the top of the tree.
- mm:        Builds all of the modules in the current directory, but not their dependencies.
- mmm:       Builds all of the modules in the supplied directories, but not their dependencies.
             To limit the modules being built use the syntax: mmm dir/:target1,target2.
- mma:       Builds all of the modules in the current directory, and their dependencies.
- mmma:      Builds all of the modules in the supplied directories, and their dependencies.
- provision: Flash device with all required partitions. Options will be passed on to fastboot.
- cgrep:     Greps on all local C/C++ files.
- ggrep:     Greps on all local Gradle files.
- jgrep:     Greps on all local Java files.
- resgrep:   Greps on all local res/*.xml files.
- mangrep:   Greps on all local AndroidManifest.xml files.
- mgrep:     Greps on all local Makefiles files.
- sepgrep:   Greps on all local sepolicy files.
- sgrep:     Greps on all local source files.
- godir:     Go to the directory containing a file.

Environment options:
- SANITIZE_HOST: Set to 'true' to use ASAN for all host modules. Note that
                 ASAN_OPTIONS=detect_leaks=0 will be set by default until the
                 build is leak-check clean.

Look at the source to view more functions. The complete list is:
EOF
    local T=$(gettop)
    local A=""
    local i
    for i in `cat $T/build/envsetup.sh | sed -n "/^[[:blank:]]*function /s/function \([a-z_]*\).*/\1/p" | sort | uniq`; do
      A="$A $i"
    done
    echo $A
}

脚本执行完成后,会把上面的所有命令都加载到终端上,后面才能够使用上面的这些命令,否则执行上面的命令会提示-bash: ***: command not found

  • 加载平台信息
if [ "x$SHELL" != "x/bin/bash" ]; then
    case `ps -o command -p $$` in
        *bash*)
            ;;
        *)
            echo "WARNING: Only bash is supported, use of other shell would lead to erroneous results"
            ;;
    esac
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 | sort` \
         `test -d vendor && find -L vendor -maxdepth 4 -name 'vendorsetup.sh' 2> /dev/null | sort` \
         `test -d product && find -L product -maxdepth 4 -name 'vendorsetup.sh' 2> /dev/null | sort`
do

从代码中可以看到回去查找device、vendor、product下的vendorsetup.sh脚本并进行加载。
这里有一个需要注意的地方就是必须使用bash执行envsetp.sh脚本。

三、lunch

先看一下lunch命令做了些什么

function lunch()
{
    local answer

    if [ "$1" ] ; then
        answer=$1
    else
        print_lunch_menu
        echo -n "Which would you like? [aosp_arm-eng] "
        read answer
    fi
    ......
}

如果lunch后面带了参数继续执行,没带参数会调用print_lunch_menu去打印提示信息

function print_lunch_menu()
{
    local uname=$(uname)
    echo
    echo "You're building on" $uname
    echo
    echo "Lunch menu... pick a combo:"

    local i=1
    local choice
    for choice in ${LUNCH_MENU_CHOICES[@]}
    do
        echo "     $i. $choice"
        i=$(($i+1))
    done

    echo
}

平台信息是从LUNCH_MENU_CHOICES变量中获取并打印出来的,LUNCH_MENU_CHOICES变量是通过add_lunch_combo函数来进行设置的:

unset LUNCH_MENU_CHOICES
function add_lunch_combo()
{
    local new_combo=$1
    local c
    for c in ${LUNCH_MENU_CHOICES[@]} ; do
        if [ "$new_combo" = "$c" ] ; then
            return
        fi
    done
    LUNCH_MENU_CHOICES=(${LUNCH_MENU_CHOICES[@]} $new_combo)
}

那add_lunch_combo是在什么时候调用的呢?还记得上一步中加载的vendorsetup.sh脚本吗?

这里可以找一个vendorsetup.sh看一下他里面做了什么操作;
下面是device/generic/mini-emulator-arm64/vendorsetup.sh脚本的内容:

# This file is executed by build/envsetup.sh, and can use anything
# defined in envsetup.sh.
#
# In particular, you can add lunch options with the add_lunch_combo
# function: add_lunch_combo generic-eng
add_lunch_combo mini_emulator_x86-userdebug

当我们选择完一个平台后lunch会记录下选择的平台,并做一系列的初始化操作,这样就完成了环境变量的配置

Which would you like? [aosp_arm-eng] aosp_x86_64-eng

============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=9 //android版本9.0
TARGET_PRODUCT=aosp_x86_64 //生成的目标
TARGET_BUILD_VARIANT=eng  //eng版本
TARGET_BUILD_TYPE=release
TARGET_ARCH=x86_64
TARGET_ARCH_VARIANT=x86_64
TARGET_2ND_ARCH=x86
TARGET_2ND_ARCH_VARIANT=x86_64  // 工具链x86
HOST_ARCH=x86_64
HOST_2ND_ARCH=x86
HOST_OS=darwin
HOST_OS_EXTRA=Darwin-18.6.0-x86_64-10.14.5
HOST_BUILD_TYPE=release
BUILD_ID=PQ3B.190605.006
OUT_DIR=out
============================================

再看一下环境变量,会看到增加了很多Android相关的环境变量

$ export
declare -x ANDROID_BUILD_PATHS="/Volumes/M1/aosp/android9.0/out/soong/host/darwin-x86/bin:/Volumes/M1/aosp/android9.0/out/host/darwin-x86/bin:/Volumes/M1/aosp/android9.0/prebuilts/gcc/darwin-x86/x86/x86_64-linux-android-4.9/bin:/Volumes/M1/aosp/android9.0/development/scripts:/Volumes/M1/aosp/android9.0/prebuilts/devtools/tools:/Volumes/M1/aosp/android9.0/external/selinux/prebuilts/bin:/Volumes/M1/aosp/android9.0/prebuilts/android-emulator/darwin-x86_64:"
declare -x ANDROID_BUILD_TOP="/Volumes/M1/aosp/android9.0"
declare -x ANDROID_DEV_SCRIPTS="/Volumes/M1/aosp/android9.0/development/scripts:/Volumes/M1/aosp/android9.0/prebuilts/devtools/tools:/Volumes/M1/aosp/android9.0/external/selinux/prebuilts/bin"
declare -x ANDROID_EMULATOR_PREBUILTS="/Volumes/M1/aosp/android9.0/prebuilts/android-emulator/darwin-x86_64"
declare -x ANDROID_HOME="/Users/huangyoubin/Library/Android/sdk"
declare -x ANDROID_HOST_OUT="/Volumes/M1/aosp/android9.0/out/host/darwin-x86"
declare -x ANDROID_HOST_OUT_TESTCASES="/Volumes/M1/aosp/android9.0/out/host/darwin-x86/testcases"
declare -x ANDROID_JAVA_HOME="/Volumes/M1/aosp/android9.0/prebuilts/jdk/jdk9/darwin-x86"
declare -x ANDROID_JAVA_TOOLCHAIN="/Volumes/M1/aosp/android9.0/prebuilts/jdk/jdk9/darwin-x86/bin"
declare -x ANDROID_NDK="/Users/huangyoubin/Library/Android/sdk/ndk-bundle"
declare -x ANDROID_PRE_BUILD_PATHS="/Volumes/M1/aosp/android9.0/prebuilts/jdk/jdk9/darwin-x86/bin:"
declare -x ANDROID_PRODUCT_OUT="/Volumes/M1/aosp/android9.0/out/target/product/generic_x86_64"
declare -x ANDROID_TARGET_OUT_TESTCASES="/Volumes/M1/aosp/android9.0/out/target/product/generic_x86_64/testcases"
declare -x ANDROID_TOOLCHAIN="/Volumes/M1/aosp/android9.0/prebuilts/gcc/darwin-x86/x86/x86_64-linux-android-4.9/bin"

最后就可以使用make命令进行源码编译了

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容