Android 完成编译的时候先执行  source build/envsetup.sh。  在这个shell 脚本中定义了 help,  croot, m, mm, mmm 等 function

之后在当前目录下执行help 可以发现它给出的信息和此前见过linux 下面help 的信息不一样了:

Invoke ". build/envsetup.sh" from your shell to add the following functions to your environment:- croot:   Changes directory to the top of the tree.- m:       Makes from the top of the tree.- mm:      Builds all of the modules in the current directory.- mmm:     Builds all of the modules in the supplied directories.- cgrep:   Greps on all local C/C++ files.- jgrep:   Greps on all local Java files.- resgrep: Greps on all local res/*.xml files.- godir:   Go to the directory containing a file.

关于source

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


m 的解释

m 的定义如下:
 561 function m() 562 { 563     T=$(gettop) 564     if [ "$T" ]; then 565         make -C $T [email protected] 566     else 567         echo "Couldn't locate the top of the tree.  Try setting TOP." 568     fi 569 } 570 
当你在任何一个目录下打 m 的时候, 它会执行上面的function.  gettop 返回源码的顶层目录,如果这个目录存在,比如在我的机器上是:
~/Android/an403/external/webkit/Source/WebKit/android/jni/test$ gettop/home/mypc/Android/an403

[email protected] 返回调用这个脚本时传入的参数
比如我们执行  m showcommands -d 经过 function m 的翻译后就执行
make -C /home/yajun/Android/an403 showcommands -d
当然如果 当前的目录不在源码树里面,gettop 就返回空,这样 m 的结果就时
~$ mCouldn't locate the top of the tree.  Try setting TOP.

下面主要讲解mm 

mm 的定义如下,功能是 Builds all of the modules in the current directory.
 591 function mm() 592 { 593     # If we're sitting in the root of the build tree, just do a 594     # normal make. 595     if [ -f build/core/envsetup.mk -a -f Makefile ]; then 596         make [email protected] 597     else 598         # Find the closest Android.mk file. 599         T=$(gettop) 600         local M=$(findmakefile) 601         # Remove the path to top as the makefilepath needs to be relative 602         local M=`echo $M|sed 's:'$T'/::'` 603         if [ ! "$T" ]; then 604             echo "Couldn't locate the top of the tree.  Try setting TOP." 605         elif [ ! "$M" ]; then 606             echo "Couldn't locate a makefile from the current directory." 607         else 608             ONE_SHOT_MAKEFILE=$M make -C $T all_modules [email protected] 609         fi 610     fi 611 }

从它的注释可以看出,当你在某个目录下执行 mm 的时候, 它首先现判断当前目录是不是 TOP 目录,如果是,就直接开始make 了~ 如果不是,就调用findmakefile 寻找 Android.mk , 搜索的路径是 当前目录-> 父目录 -> 父目录 -> ... -> 到根目录
 571 function findmakefile() 572 { 573     TOPFILE=build/core/envsetup.mk 574     # We redirect cd to /dev/null in case it's aliased to 575     # a command that prints something as a side-effect 576     # (like pushd) 577     local HERE=$PWD 578     T=  579     while [ \( ! \( -f $TOPFILE \) \) -a \( $PWD != "/" \) ]; do 580         T=$PWD 581         if [ -f "$T/Android.mk" ]; then 582             echo $T/Android.mk 583             cd $HERE > /dev/null 584             return 585         fi 586         cd .. > /dev/null 587     done 588     cd $HERE > /dev/null 589 }

文章写到一半 CSDN 挂了。。。 当在某个目录下找到Android.mk后,就把它echo 出来。然后 cd $HERE 返回调用 findmakefile 的目录。
以我在 /home/yajun/Android/an403/external/webkit/Source/WebKit/android/benchmark/ 下执行 mm 为例 findmakefile 的返回结果是 /home/yajun/Android/an403/external/webkit/Source/WebKit/android/benchmark/Android.mk 而 gettop 的返回结果是 /home/yajun/Android/an403 所以执行local M=`echo $M|sed 's:'$T'/::'` 之后, M =external/webkit/Source/WebKit/android/benchmark/Android.mk
ONE_SHOT_MAKEFILE=$M make -C $T all_modules [email protected] 展开后就是 
ONE_SHOT_MAKEFILE=external/webkit/Source/WebKit/android/benchmark/Android.mk make -C /home/yajun/Android/an403 all_modules

到后面怎么make 的?() 上面的执行就可以看作是: make -C /home/yajun/Android/an403 all_modules ONE_SHOT_MAKEFILE=external/webkit/Source/WebKit/android/benchmark/Android.mk

接下来的执行会进入到  build/core/main.mk 中,在这里会 include external/webkit/Source/WebKit/android/benchmark/Android.mk
439 ifneq ($(ONE_SHOT_MAKEFILE),)                                                  440 # We've probably been invoked by the "mm" shell function                       441 # with a subdirectory's makefile.                                              442 include $(ONE_SHOT_MAKEFILE)                                                   443 # Change CUSTOM_MODULES to include only modules that were                      444 # defined by this makefile; this will install all of those                     445 # modules as a side-effect.  Do this after including ONE_SHOT_MAKEFILE         446 # so that the modules will be installed in the same place they                 447 # would have been with a normal make.                                          448 CUSTOM_MODULES := $(sort $(call get-tagged-modules,$(ALL_MODULE_TAGS)))        449 FULL_BUILD :=                                                                  450 # Stub out the notice targets, which probably aren't defined                   451 # when using ONE_SHOT_MAKEFILE.                                                452 NOTICE-HOST-%: ;                                                               453 NOTICE-TARGET-%: ;                                                             454                                                                                455 else # ONE_SHOT_MAKEFILE 
把其中的变量读取进来:
LOCAL_PATH:= $(call my-dir)include $(CLEAR_VARS)LOCAL_SRC_FILES := \        main.cpp# Pull the webkit definitions from the base webkit makefile.LOCAL_SHARED_LIBRARIES := libwebcore $(WEBKIT_SHARED_LIBRARIES)LOCAL_LDLIBS := $(WEBKIT_LDLIBS)LOCAL_MODULE := webcore_testLOCAL_MODULE_TAGS := optionalinclude $(BUILD_EXECUTABLE)
这一段开始的地方会 include $(CLEAR_VARS), 我们可用在下面的地方找到 build/core/config.mk:54:CLEAR_VARS:= $(BUILD_SYSTEM)/clear_vars.mk 它所做的事情是Clear out values of all variables used by rule templates.
LOCAL_MODULE:=LOCAL_MODULE_PATH:=LOCAL_MODULE_STEM:=LOCAL_DONT_CHECK_MODULE:=LOCAL_CHECKED_MODULE:=LOCAL_BUILT_MODULE:=。。。。。。
在最后一句会 include $(BUILD_EXECUTABLE)  它的定义在:build/core/config.mk:60:BUILD_EXECUTABLE:= $(BUILD_SYSTEM)/executable.mk
ifeq ($(strip $(LOCAL_MODULE_CLASS)),)LOCAL_MODULE_CLASS := EXECUTABLESendififeq ($(strip $(LOCAL_MODULE_SUFFIX)),)LOCAL_MODULE_SUFFIX := $(TARGET_EXECUTABLE_SUFFIX)endifinclude $(BUILD_SYSTEM)/dynamic_binary.mkifeq ($(LOCAL_FORCE_STATIC_EXECUTABLE),true)$(linked_module): $(TARGET_CRTBEGIN_STATIC_O) $(all_objects) $(all_libraries) $(TARGET_CRTEND_O)        $(transform-o-to-static-executable)else$(linked_module): $(TARGET_CRTBEGIN_DYNAMIC_O) $(all_objects) $(all_libraries) $(TARGET_CRTEND_O)        $(transform-o-to-executable)endif
到这里相信写过 Makefile 的朋友顿时觉得熟悉了吧,只是这里的 target, dependencies, executable commands 都被变量代替了:
$(linked_module): $(TARGET_CRTBEGIN_DYNAMIC_O) $(all_objects) $(all_libraries) $(TARGET_CRTEND_O)        $(transform-o-to-executable)

如果想进一步了解这里做了什么事情,我们需要知道上面的变量都是什么值,最方便的做法是把他们打印出来。
include $(BUILD_SYSTEM)/dynamic_binary.mk$(warning "-------------------------------------------")$(warning "linked_modle=$(linked_module)")$(warning "TARGET_CRTBEGIN_DYNAMIC_O=$(TARGET_CRTBEGIN_DYNAMIC_O)")$(warning "all_objects=$(all_objects)")$(warning "all_libraries=$(all_libraries)")$(warning "TARGET_CRTEND_O=$(TARGET_CRTEND_O)")$(warning "transform-o-to-executable=$(transform-o-to-executable)")$(warning "--------------------------------------------")ifeq ($(LOCAL_FORCE_STATIC_EXECUTABLE),true)
可以然后就可以看出来这里做要 build 出来的是什么东西啦:
build/core/executable.mk:16: "-------------------------------------------"build/core/executable.mk:17: "linked_modle=out/target/product/generic/obj/EXECUTABLES/webcore_test_intermediates/LINKED/webcore_test"build/core/executable.mk:18: "TARGET_CRTBEGIN_DYNAMIC_O=out/target/product/generic/obj/lib/crtbegin_dynamic.o"build/core/executable.mk:19: "all_objects=   out/target/product/generic/obj/EXECUTABLES/webcore_test_intermediates/main.o           "build/core/executable.mk:20: "all_libraries=out/target/product/generic/obj/lib/libwebcore.so out/target/product/generic/obj/lib/libc.so out/target/product/generic/obj/lib/libstdc++.so out/target/product/generic/obj/lib/libm.so  "build/core/executable.mk:21: "TARGET_CRTEND_O=out/target/product/generic/obj/lib/crtend_android.o"build/core/executable.mk:22: "[email protected] -p @echo "target Executable:  ()"  -nostdlib -Bdynamic -Wl,-T,build/core/armelf.x -Wl,-dynamic-linker,/system/bin/linker -Wl,--gc-sections -Wl,-z,nocopyreloc -o  -Lout/target/product/generic/obj/lib -Wl,-rpath-link=out/target/product/generic/obj/lib   out/target/product/generic/obj/lib/crtbegin_dynamic.o       -Wl,-z,noexecstack -Wl,--icf=safe -Wl,--fix-cortex-a8   prebuilt/linux-x86/toolchain/arm-linux-androideabi-4.4.x/bin/../lib/gcc/arm-linux-androideabi/4.4.3/armv7-a/libgcc.a out/target/product/generic/obj/lib/crtend_android.o"build/core/executable.mk:23: "--------------------------------------------"

我们现看一下上面第八行的 dynamic_binary.mk 做了什么事情: include $(BUILD_SYSTEM)/dynamic_binary.mk

更多相关文章

  1. Android添加自定义系统服务
  2. 自定义ListView分割线
  3. Android 2.1 Compatibility Definition 中文版 - Android 2.1 兼
  4. 通过查看系统的ProgressBar样式来自定义旋转动画
  5. Android 定时重启Android系统源(手机root后可用) [系统支持自定义

随机推荐

  1. Android日常整理(三)---intent打开浏览器、
  2. android 模拟器root
  3. Android中Service的理解与使用
  4. android知识链接汇总(2)
  5. Android(安卓)自定义View--ProgressBar篇
  6. Android最新获取oaid的方法及sdk
  7. 谷歌宣布关闭Google TV,由Android(安卓)TV
  8. Android(安卓)腾讯入门教程( 智能手表UI
  9. android 定时器(Handler Timer Thread Al
  10. 我见过的最好的DataBinding解析