Android编译流程

众所周知,Android系统其实就是一个运行在Linux系统上面的应用桌面程序,当然这样概括可能不是很准确,但是他们的编译确实异曲同工之妙。

在Linux系统中,我们可以通过make命令来编译代码。执行Make命令默认会在当前目录找到一个Makefile文件,然后根据Makefile文件中的指令来对代码进行编译(makefile语法课参考《GNU make中文手册》)。也就是说make命令执行的是Makefile文件中的指令,Makefile文件中的指令可以是编译命令(例如gcc,也可以是其它命令)。

在Android系统中,随着源代码越来越复杂,光一个makefile在性能上已经满足不了,因此在该机制之上新增了自己的android.mk和android.bp方式,为了优雅的与makefile兼容,soong就此诞生了。

一、编译流程

google已经给出了android的原生编译流程:source build/envsetup.sh加载命令初始化环境、lunch选择平台、make执行编译命令。

1、初始化编译环境

进入android源代码根目录执行命令source build/envsetup.sh即可初始化编译环境。其实该过程从source命令就可以看出主要是执行了envsetup.sh脚本且加载环境变量到当前终端。脚本envsetup.sh中其实定义了很多函数,如下:

//android/build/envsetup.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, or a subdirectory thereof.
- m:          Makes from the top of the tree.
- mm:         Builds and installs all of the modules in the current directory, and their
              dependencies.
- mmm:        Builds and installs all of the modules in the supplied directories, and their
              dependencies.
              To limit the modules being built use the syntax: mmm dir/:target1,target2.
- mma:        Same as 'mm'
- mmma:       Same as 'mmm'
- 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.
- gogrep:     Greps on all local Go 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 and *.bp files.
- owngrep:    Greps on all local OWNERS files.
- sepgrep:    Greps on all local sepolicy files.
- sgrep:      Greps on all local source files.
- godir:      Go to the directory containing a file.
- allmod:     List all modules.
- gomod:      Go to the directory containing a module.
- pathmod:    Get the directory containing a module.
- refreshmod: Refresh list of modules for allmod/gomod.
Environment options:
- SANITIZE_HOST: Set to 'address' to use ASAN for all host modules.
- ANDROID_QUIET_BUILD: set to 'true' to display only the essential messages.
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
}
# Get the exact value of a build variable.
function get_build_var() { }
# check to see if the supplied product is one we can build
function check_product() { }
# 设置环境变量
function setpaths() { }
function chooseproduct() { }
function add_lunch_combo() { }
function print_lunch_menu() { }
function lunch() { }
function croot() { }
function m() { }
function mm() { }
function make() { }
# 加载执行产商定义vendorsetup.sh
function source_vendorsetup() {
    unset VENDOR_PYTHONPATH
    allowed=
    for f in $(find -L device vendor product -maxdepth 4 -name 'allowed-vendorsetup_sh-files' 2>/dev/null | sort); do
        if [ -n "$allowed" ]; then
            echo "More than one 'allowed_vendorsetup_sh-files' file found, not including any vendorsetup.sh files:"
            echo "  $allowed"
            echo "  $f"
            return
        fi
        allowed="$f"
    done

    allowed_files=
    [ -n "$allowed" ] && allowed_files=$(cat "$allowed")
    for dir in device vendor product; do
        for f in $(test -d $dir && \
            find -L $dir -maxdepth 4 -name 'vendorsetup.sh' 2>/dev/null | sort); do

            if [[ -z "$allowed" || "$allowed_files" =~ $f ]]; then
                echo "including $f"; . "$f"
            else
                echo "ignoring $f, not in $allowed"
            fi
        done
    done
}
validate_current_shell
source_vendorsetup  # 加载执行vendor分区的vendorsetup.sh  芯片产商通常会将自己的一些配置加载改文件
addcompletions

source build/envsetup.sh执行之后,为当前终端加载了上面的这些函数,之后可以在该终端执行这些命令(函数名)来执行这些函数的内容,最后调用函数source_vendorsetup加载其他目录(device vendor product)下的vendorsetup.sh脚本。注意,该命令只在当前终端生效,如果未生效那么lunch和mm等命令是无法使用的

2、选择编译平台

3、开始编译

上一篇:oracle12.1 升级到 oracle12.2之后的问题


下一篇:Django中的配置信息