zoukankan      html  css  js  c++  java
  • m mm等和envsetup.sh

    一、envsetup.sh简介

    Android 完成编译的时候先执行 source build/envsetup.sh。在这个shell 脚本中定义了 help, croot, m, mm, mmm 等 function,这些function可以作为命令行工具使用

    source命令:source 命令会把对应脚本中的内容读取到当前的bash 解释器中,在当前的执行环境中执行;其中定义的 function 以及通过 export 声明的变量等在 source 执行结束之后依然存在于当前的bash 环境中。比如我们常用的 source .bashrc 或者 source .profile等目的是为了引用刚刚改动过的环境变量。

    envsetup.sh中提供一下工具:

    lunch:lunch<product_name> - <build_variant>

    tapas:tapas[<App1> <App2> ...] [arm | x86 | mips] [eng | userdebug | user]

    croot:将目录更改为树的顶部。

    m:从树顶make。

    mm:构建(build)当前目录中的所有模块。

    mmm:构建(build)所提供目录中的所有模块。

    cgrep:Greps所有本地C/C ++文件。

    jgrep:Greps所有本地Java文件。

    resgrep:Greps on all local res/*.xml文件。

    godir:到包含文件的目录。

    add_lunch_combo:在lunch函数的菜单中添加一个条目

    m:编译整个安卓系统。
    mm:编译当前目录下的模块,当前目录下需要有Android.mk,否则就往上找最近的Android.mk文件。
    mma:当前目录新增或删除文件后,可以用mma重新编译。
    mmm:编译指定路径下的模块,指定的路径下面需要有Android.mk。
    mmma:指定目录下新增或删除文件后,可以用mmma重新编译。(未全编译的情况系下,可以使用该命令单编译模块)

    mmm的编译过程:

    build/core/main.mk(是Android编译系统的入口文件)
        ->build/core/config.mk(会定好编译类型和目标文件)
            ->build/core/definitions.mk(定义在编译过程中用到的宏)
            ->ONE_SHOT_MAKEFILE->build/core/package.mk(编译Apk库文件)
                ->build/core/java_library.mk(编译Java库文件)
                ->build/core/static_java_library.mk(编译Java静态库文件)
                ->build/core/shared_library.mk->build/core/dynamic_library.mk->build/core/binary.mk->build/core/base_rules.mk
                    ->build/core/static_library.mk(编译.a静态库文件)
                    ->build/core/executable.mk(编译可执行文件)
                    ->build/core/prebuilt.mk(编译已经预编译好的第三方库文件)
                        ->build/core/Makfile(有system.img、boot.img、recovery.img等镜像文件生成规则)
    View Code

    环境变量ONE_SHOT_MAKEFILE中存放要编译模块的Android.mk的文件路径,如果环境变量值为空,表示执行的是m或者make命令,会对Android源代码中的所有模块进行编译(bug)

    1. m
    当在任何一个目录下打 m 的时候, 它会执行下面的function.

    function m()
    {
        T=$(gettop)
        if [ "$T" ]; then
            make -C $T $@
        else
            echo "Couldn't locate the top of the tree.  Try setting TOP."
        fi
    }
    View Code

    $@ 返回调用这个脚本时传入的参数,比如执行$ m showcommands -d 经过 function m 的翻译后就执行

    make -C /home/yajun/Android/an403 showcommands -d   $T可以使用 $ gettop 来查看,若当前目录不在源码树中,$T就为空,打印上面的错误信息。

    2. mm
    build当前目录中的所有模块

    function mm()
    {
        # If we're sitting in the root of the build tree, just do a
        # normal make.
        if [ -f build/core/envsetup.mk -a -f Makefile ]; then
            make $@
        else
            # Find the closest Android.mk file.
            T=$(gettop)
            local M=$(findmakefile)
            # Remove the path to top as the makefilepath needs to be relative
            local M=`echo $M|sed 's:'$T'/::'`
            if [ ! "$T" ]; then
                echo "Couldn't locate the top of the tree.  Try setting TOP."
            elif [ ! "$M" ]; then
                echo "Couldn't locate a makefile from the current directory."
            else
                ONE_SHOT_MAKEFILE=$M make -C $T all_modules $@
            fi
        fi
    }
    View Code

    从它的注释可以看出,当你在某个目录下执行 mm 的时候,它首先现判断当前目录是不是 TOP 目录,如果是,就直接开始make 了,如果不是,就调用findmakefile 寻找 Android.mk , 搜索的路径是 当前目录-> 父目录 -> 父目录 -> ... -> 到根目录.

    function findmakefile()
    {
        TOPFILE=build/core/envsetup.mk
        # We redirect cd to /dev/null in case it's aliased to
        # a command that prints something as a side-effect
        # (like pushd)
        local HERE=$PWD
        T=
        while [ ( ! ( -f $TOPFILE ) ) -a ( $PWD != "/" ) ]; do
            T=`PWD= /bin/pwd`
            if [ -f "$T/Android.mk" ]; then
                echo $T/Android.mk
                cd $HERE > /dev/null
                return
            fi
            cd .. > /dev/null
        done
        cd $HERE > /dev/null
    }
    View Code

    当在某个目录下找到Android.mk后,就把它echo 出来。然后 cd $HERE 返回调用 findmakefile 的目录。

    3. gettop
    返回源码的顶层目录,如果这个目录存在。

    function gettop
    {
        local TOPFILE=build/core/envsetup.mk
        if [ -n "$TOP" -a -f "$TOP/$TOPFILE" ] ; then
            echo $TOP
        else
            if [ -f $TOPFILE ] ; then
                # The following circumlocution (repeated below as well) ensures
                # that we record the true directory name and not one that is
                # faked up with symlink names.
                PWD= /bin/pwd
            else
                # We redirect cd to /dev/null in case it's aliased to
                # a command that prints something as a side-effect
                # (like pushd)
                local HERE=$PWD
                T=
                while [ ( ! ( -f $TOPFILE ) ) -a ( $PWD != "/" ) ]; do
                    cd .. > /dev/null
                    T=`PWD= /bin/pwd`
                done
                cd $HERE > /dev/null
                if [ -f "$T/$TOPFILE" ]; then
                    echo $T
                fi
            fi
        fi
    }
    View Code

    如果这个目录存在,比如在我的机器上是:

    $ gettop
    /media/ubuntu/works/tiny4412/android-5.0.2

    4.croot

    回到顶层目录,测试如下:

    root@ubuntu:/media/ubuntu/works/tiny4412/android-5.0.2/frameworks/support/v4/froyo# croot
    root@ubuntu:/media/ubuntu/works/tiny4412/android-5.0.2#

    6. godir

    转到对应文件所在的目录中,测试如下:

    root@ubuntu:/media/ubuntu/works/tiny4412/android-5.0.2# godir InputReader.cpp
       [1] ./external/lldb/source/API
       [2] ./external/lldb/source/Core
       [3] ./frameworks/native/services/inputflinger
    Select one: 3
    root@ubuntu:/media/ubuntu/works/tiny4412/android-5.0.2/frameworks/native/services/inputflinger# 

    7. cgreop

    在C/C++文件中检索字符串,测试如下:

    # cgrep EventHub

    二、Android.mk中的LOCAL_MODULE_TAGS 选项说明

    LOCAL_MODULE_TAGS :=user eng tests optional
    user: 指该模块只在user版本下才编译
    eng: 指该模块只在eng版本下才编译
    tests: 指该模块只在tests版本下才编译
    optional:指该模块在所有版本下都编译

    LOCAL_MODULE:= 这是对变量LOCAL_MODULE赋值为空!!

    可以在.mk文件中打印变量linked_module的值进行查看:$(warning "linked_modle=$(linked_module)")  它会将“”中的内容打印出来。

    参考:https://blog.csdn.net/yajun0601/article/details/7309010  对m mm分析的教详细

  • 相关阅读:
    sqlite遇到database is locked问题的完美解决
    Delphi使程序的窗口出现在最前面并激活
    win10 家庭版不支持gpedit.msc的解决办法
    Delphi Record To Stream
    SQL Server 查看CPU情况
    JavaScript 获取 Url 上的参数(QueryString)值
    关于EF分页查询报错(Count must have a non-negative value.)的解决方案
    调用微信退款接口时出现System.Security.Cryptography.CryptographicException: 出现了内部错误 解决办法
    Javascript中“==”与“===”的区别
    IE浏览器各版本的CSS Hack
  • 原文地址:https://www.cnblogs.com/hellokitty2/p/10275040.html
Copyright © 2011-2022 走看看