Android原始碼編譯命令m/mm/mmm/make分析

2020-08-12 09:01:33

function m()
{
    T=$(gettop)               //函數m呼叫函數gettop得到的是Android原始碼根目錄T
    if [ "$T" ]; then          // 判斷  $T  是否存在
        make -C $T $@    //-C選項用來指定工作目錄     $@  傳遞給指令碼或函數的所有參數。
    else
        echo "Couldn't locate the top of the tree.  Try setting TOP."
    fi
}


function mm()
{
    # If we're sitting in the root of the build tree, just do a
    # normal make.  
   //首先是判斷當前目錄是否就是Android原始碼根目錄  ->判斷方法是 即當前目錄下是否存在一個build/core/envsetup.mk檔案和一個Makefile檔案
  // 如果是那麼  mm作爲普通 make 命令
    if [ -f build/core/envsetup.mk -a -f Makefile ]; then
        make $@
    else
        # Find the closest Android.mk file.
        T=$(gettop)
        local M=$(findmakefile)    //findmakefile從當前目錄開始一直往上尋找是否存在一個Android.mk檔案
        # 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 $@   
            // 將找到的Android.mk檔案的相對路徑設定給環境變數ONE_SHOT_MAKE,表示接下來要對它進行編譯
            // all_modules就表示要對前面指定的Android.mk檔案中定義的所有模組進行編譯。
        fi
    fi
}


function mmm()
{
    T=$(gettop)
    if [ "$T" ]; then
        local MAKEFILE=
        local MODULES=
        local ARGS=
        local DIR TO_CHOP
        local DASH_ARGS=$(echo "$@" | awk -v RS=" " -v ORS=" " '/^-.*$/')  //將以橫線「-」開頭的字串提取出來,並且儲存在變數DASH_ARGS中
        local DIRS=$(echo "$@" | awk -v RS=" " -v ORS=" " '/^[^-].*$/') // 通過命令awk將執行命令mmm時指定的非選項參數提取出來,也就是將非以橫線「-」開頭的字串提取出來,並且儲存在變數DIRS中
        for DIR in $DIRS ; do
            MODULES=`echo $DIR | sed -n -e 's/.*:\(.*$\)/\1/p' | sed 's/,/ /'`  
            //第一個sed命令獲得的是一系列以逗號分隔的模組名稱列表
            //第二個sed命令用來將前面獲得的以逗號分隔的模組名稱列錶轉化爲以空格分隔的模組名稱列表
            //最後,獲得的以空格分隔的模組名稱列表儲存在變數MODULES中。
            if [ "$MODULES" = "" ]; then
                MODULES=all_modules
            fi
            DIR=`echo $DIR | sed -e 's/:.*//' -e 's:/$::'`
            if [ -f $DIR/Android.mk ]; then                     //如果獲得 路徑下面 下麪有 Android.mk 檔案
                TO_CHOP=`(cd -P -- $T && pwd -P) | wc -c | tr -d ' '`  //獲得原始碼絕對路徑字串長度
                TO_CHOP=`expr $TO_CHOP + 1`
                START=`PWD= /bin/pwd`    // 通過執行/bin/pwd命令獲得當前執行命令mmm的目錄
                MFILE=`echo $START | cut -c${TO_CHOP}-`   //當前目錄START相對於Android原始碼根目錄T的路徑
                if [ "$MFILE" = "" ] ; then          //安卓原始碼根目錄
                    MFILE=$DIR/Android.mk
                else                                          //安卓原始碼   非根目錄
                    MFILE=$MFILE/$DIR/Android.mk
                fi
                MAKEFILE="$MAKEFILE $MFILE"  用空格連線 相對目錄
            else
                if [ "$DIR" = snod ]; then
                    ARGS="$ARGS snod"   //表示忽略依賴性地重新打包system.img
                elif [ "$DIR" = showcommands ]; then
                    ARGS="$ARGS showcommands"  //顯示編譯過程中執行的命令
                elif [ "$DIR" = dist ]; then
                    ARGS="$ARGS dist"   //dist表示將編譯後產生的發佈檔案拷貝到out/dist目錄中
                elif [ "$DIR" = incrementaljavac ]; then
                    ARGS="$ARGS incrementaljavac"
                else
                    echo "No Android.mk in $DIR."
                    return 1
                fi
            fi
        done
        ONE_SHOT_MAKEFILE="$MAKEFILE" make -C $T $DASH_ARGS $MODULES $ARGS
    else
        echo "Couldn't locate the top of the tree.  Try setting TOP."
    fi
}


參考
Android原始碼編譯命令m/mm/mmm/make分析