http://blog.youkuaiyun.com/span76/article/details/21104175
使用 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/.*:\(.*$\)/\1/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)