理解 Android 的 ONE_SHOT_MAKEFILE

使用 mmm 編譯的時候 Android 執行的 ONE_SHOT make, 其如何實現?

mmm 的源代碼在 build/envsetup.sh 中

function mmm()
    641 {
    642     T=$(gettop)
    643     if [ "$T" ]; then
    644         local MAKEFILE=
    645         local MODULES=
    646         local ARGS=
    647         local DIR TO_CHOP
    648         local DASH_ARGS=$(echo "$@" | awk -v RS=" " -v ORS=" " '/^-.*$/')
    649         local DIRS=$(echo "$@" | awk -v RS=" " -v ORS=" " '/^[^-].*$/')
    650         for DIR in $DIRS ; do
    651             MODULES=`echo $DIR | sed -n -e 's/.*:\(.*$\)//p' | sed 's/,/ /'`
    652             if [ "$MODULES" = "" ]; then
    653                 MODULES=all_modules
    654             fi
    655             DIR=`echo $DIR | sed -e 's/:.*//' -e 's:/$::'`
    656             if [ -f $DIR/Android.mk ]; then
    657                 TO_CHOP=`(cd -P -- $T && pwd -P) | wc -c | tr -d ' '`
    658                 TO_CHOP=`expr $TO_CHOP + 1`
    659                 START=`PWD= /bin/pwd`
    660                 MFILE=`echo $START | cut -c${TO_CHOP}-`
    661                 if [ "$MFILE" = "" ] ; then
    662                     MFILE=$DIR/Android.mk
    663                 else
    664                     MFILE=$MFILE/$DIR/Android.mk
    665                 fi
    666                 MAKEFILE="$MAKEFILE $MFILE"
    667             else
    668                 if [ "$DIR" = snod ]; then
    669                     ARGS="$ARGS snod"
    670                 elif [ "$DIR" = showcommands ]; then
    671                     ARGS="$ARGS showcommands"
    672                 elif [ "$DIR" = dist ]; then
    673                     ARGS="$ARGS dist"
    674                 elif [ "$DIR" = incrementaljavac ]; then
    675                     ARGS="$ARGS incrementaljavac"
    676                 else
    677                     echo "No Android.mk in $DIR."
    678                     return 1
    679                 fi
    680             fi
    681         done
    682         ONE_SHOT_MAKEFILE="$MAKEFILE" make -C $T $DASH_ARGS $MODULES $ARGS
    683     else
    684         echo "Couldn't locate the top of the tree.  Try setting TOP."
    685     fi
    686 }

但運行下面的命令

mmm sdk/emulator/opengl/tests/translator_tests/GLES_V2

最終生成命令行

ONE_SHOT_MAKEFILE=sdk/emulator/opengl/tests/translator_tests/GLES_V2/Android.mk make -C /home/payne/njb all_modules

註意

ONE_SHOT_MAKEFILE=sdk/emulator/opengl/tests/translator_tests/GLES_V2/Android.mk 是參數

make -C /home/payne/njb all_modules 才是命令

就是說帶著 ONE_SHOT_MAKEFILE 的參數去執行 make 命令, 而make的target 是 all_modules

在 build/core/main.mk#467

ifneq ($(ONE_SHOT_MAKEFILE),)
# We've probably been invoked by the "mm" shell function
# with a subdirectory's makefile.
include $(ONE_SHOT_MAKEFILE)
# Change CUSTOM_MODULES to include only modules that were
# defined by this makefile; this will install all of those
# modules as a side-effect.  Do this after including ONE_SHOT_MAKEFILE
# so that the modules will be installed in the same place they
# would have been with a normal make.
CUSTOM_MODULES := $(sort $(call get-tagged-modules,$(ALL_MODULE_TAGS)))
FULL_BUILD :=
# Stub out the notice targets, which probably aren't defined
# when using ONE_SHOT_MAKEFILE.
NOTICE-HOST-%: ;
NOTICE-TARGET-%: ;

當環境變量 ONE_SHOT_MAKEFILE不是空的時候, 就被 include 進來瞭,此 mk 的 LOCAL_MODULE 也將會讓 all_modules 去依賴(加入到變量ALL_MODULES中),這樣 make all_modules 的時候,就會先編譯依賴的 LOCAL_MODULE瞭; 當然不相關的 module不會加入到 ALL_MODULES

build/core/main.mk#813

813 .PHONY: all_modules
814 all_modules: $(ALL_MODULES)

發佈留言