434
技術社區[雲棲]
Android編譯中m、mm、mmm 詳解
https://blog.csdn.net/yajun0601/article/details/7309010
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 $@
- 566 else
- 567 echo "Couldn't locate the top of the tree. Try setting TOP."
- 568 fi
- 569 }
- 570
gettop 返回源碼的頂層目錄,如果這個目錄存在,比如在我的機器上是:
- ~/Android/an403/external/webkit/Source/WebKit/android/jni/test$ gettop
- /home/mypc/Android/an403
比如我們執行 m showcommands -d
經過 function m 的翻譯後就執行
當然如果 當前的目錄不在源碼樹裏麵,gettop 就返回空,這樣 m 的結果就時
- make -C /home/yajun/Android/an403 showcommands -d
- ~$ m
- Couldn'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 $@
- 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 $@
- 609 fi
- 610 fi
- 611 }
它首先現判斷當前目錄是不是 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 }
當在某個目錄下找到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 $@ 展開後就是
ONE_SHOT_MAKEFILE=external/webkit/Source/WebKit/android/benchmark/Android.mk make -C /home/yajun/Android/an403 all_modules
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_test
- LOCAL_MODULE_TAGS := optional
- include $(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:=
- 。。。
- 。。。
- ifeq ($(strip $(LOCAL_MODULE_CLASS)),)
- LOCAL_MODULE_CLASS := EXECUTABLES
- endif
- ifeq ($(strip $(LOCAL_MODULE_SUFFIX)),)
- LOCAL_MODULE_SUFFIX := $(TARGET_EXECUTABLE_SUFFIX)
- endif
- include $(BUILD_SYSTEM)/dynamic_binary.mk
- ifeq ($(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
- $(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: "transform-o-to-executable=@mkdir -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
最後更新:2017-04-04 07:03:03