Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android 4.03 編譯系統------lunch

Android 4.03 編譯系統------lunch

編輯:關於Android編程

    前面分析了Android 4.03編譯系統-------envsetup.sh,今天來說lunch命令。

        在Android目錄下執行了envsetup.sh後,下一部就是執行:lunch。lunch是在envsetup.sh裡面定義的函數,函數原型如下:

/**********************************************begin**********************************************/

function lunch()
{
    local answer
    if [ "$1" ] ; then
        answer=$1
    else
        print_lunch_menu
        echo -n "Which would you like? [full-eng] "
        read answer
    fi
    local selection=
    if [ -z "$answer" ]
    then
        selection=full-eng
    elif (echo -n $answer | grep -q -e "^[0-9][0-9]*$")
    then
        if [ $answer -le ${#LUNCH_MENU_CHOICES[@]} ]
        then
            selection=${LUNCH_MENU_CHOICES[$(($answer-1))]}
        fi
    elif (echo -n $answer | grep -q -e "^[^\-][^\-]*-[^\-][^\-]*$")
    then
        selection=$answer
    fi
    if [ -z "$selection" ]
    then
        echo
        echo "Invalid lunch combo: $answer"
        return 1
    fi
    export TARGET_BUILD_APPS=
    local product=$(echo -n $selection | sed -e "s/-.*$//")
    check_product $product
    if [ $? -ne 0 ]
    then
        echo
        echo "** Don't have a product spec for: '$product'"
        echo "** Do you have the right repo manifest?"
        product=
    fi
    local variant=$(echo -n $selection | sed -e "s/^[^\-]*-//")
    check_variant $variant
    if [ $? -ne 0 ]
    then
        echo
        echo "** Invalid variant: '$variant'"
        echo "** Must be one of ${VARIANT_CHOICES[@]}"
        variant=
    fi
    if [ -z "$product" -o -z "$variant" ]
    then
        echo
        return 1
    fi
    export TARGET_PRODUCT=$product
    export TARGET_BUILD_VARIANT=$variant
    export TARGET_BUILD_TYPE=release
    echo
    set_stuff_for_environment
    printconfig

/***********************************************end***********************************************/

函數使用 print_lunch_menu 函數將envsetup.sh 設置的LUNCH_MENU_CHOICES變量打印出來,並等待用戶的輸入,讀入用戶輸入後,將對應數字的字符串賦值給selection, local product=$(echo -n $selection | sed -e "s/-.*$//") ,local variant=$(echo -n $selection | sed -e "s/^[^\-]*-//"),對selection進行處理,得到product以及variant,前者是將selection中最後一個 - 後面的所有內容去掉而得來,後者剛好相反,是將 - 前面的內容去掉,例如:選擇了 4,對應:full_stingray-userdebug,則selection = full_stingray-userdebug,product=full_stingray,variant=userdebug,最後設置環境變量TARGET_PRODUCT=$product等。

        到這裡,我們設置了一個重要的環境變量TARGET_PRODUCT,這個後面多處都是依靠它來尋找編譯文件的。接下是兩個函數:set_stuff_for_environment,printconfig.

set_stuff_for_environment 設置了一下環境變量,就不進去分析了。重點是printconfig函數,其函數體比較簡單:get_build_var report_config,調用了另外一個函數,get_build_var 也比較簡單,重要語句:

         make --no-print-directory -C "$T" -f build/core/config.mk dumpvar-$1

它的意思是執行build/core/config.mk,至於dumpvar-$1,我一直沒找到,也不知道是什麼意思,有知道的告知一下,多謝!

        好了,現在開始進入config.mk文件(其實後面的make命名重復執行,不管了,一步步往下走)。config.mk前面那一堆的變量定義賦值就不說了,直奔重點:

/**********************************************begin**********************************************/
include $(BUILD_SYSTEM)/envsetup.mk
board_config_mk := \
        $(strip $(wildcard \
                $(SRC_TARGET_DIR)/board/$(TARGET_DEVICE)/BoardConfig.mk \
                device/*/$(TARGET_DEVICE)/BoardConfig.mk \
                vendor/*/$(TARGET_DEVICE)/BoardConfig.mk \
        ))
ifeq ($(board_config_mk),)
  $(error No config file found for TARGET_DEVICE $(TARGET_DEVICE))
endif
ifneq ($(words $(board_config_mk)),1)
  $(error Multiple board config files for TARGET_DEVICE $(TARGET_DEVICE): $(board_config_mk))
endif
include $(board_config_mk)
TARGET_DEVICE_DIR := $(patsubst %/,%,$(dir $(board_config_mk)))

/**********************************************end**********************************************/

上面這段代碼裡,有個重要的變量TARGET_DEVICE,它在哪裡定義的呢?它在envsetup.mk中定義的,注意,注意,是envsetup.mk,不要和前面的envsetup.sh搞混了,後則位於build/目錄下,前者位於build/core/目錄下,來看看envsetup.mk,envsetup.mk裡面也設置了一大堆的變量,最重要的是:include $(BUILD_SYSTEM)/product_config.mk,

頭是不是有點暈了?我也暈了,先整理一下思路:我們是進來尋找TARGET_DEVICE的,前面都沒有設置,只能繼續跟進了。finally,在product_config.mk中終於找到了TARGET_DEVICE的定義:

/**********************************************begin**********************************************/

ifneq ($(strip $(TARGET_BUILD_APPS)),)
  $(call import-products,$(call get-product-makefiles,\
      $(SRC_TARGET_DIR)/product/AndroidProducts.mk))
else
  $(call import-products, $(get-all-product-makefiles))
endif # TARGET_BUILD_APPS
$(check-all-products)
ifneq ($(filter dump-products, $(MAKECMDGOALS)),)
$(dump-products)
$(error done)
endif

INTERNAL_PRODUCT := $(call resolve-short-product-name, $(TARGET_PRODUCT))
#$(error TARGET_PRODUCT $(TARGET_PRODUCT) --> $(INTERNAL_PRODUCT))
TARGET_DEVICE := $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_DEVICE)
#$(error TARGET_DEVICE $(TARGET_DEVICE) --> $(INTERNAL_PRODUCT))

/***********************************************end***********************************************/

在分析TARGET_DEVICE之前,先說明一下前面的一小段代碼,也是很重要的。TARGET_BUILD_APPS等於空,所以執行else分支,$(call import-products, $(get-all-product-makefiles))是讀取所有的AndroidProducts.mk,並將其中定義的PRODUCT_MAKEFILES變量都賦值給PRODUCT變量,後面的操作都是在PRODUCT裡面尋找需要的文件。好了現在開始分析TARGET_DEVICE。
         首先,是INTERNAL_PRODUCT,TARGET_PRODUCT是前面定義的,至於函數resolve-short-product-name,定義再produck.mk文件中,我是沒怎麼看懂,我也沒打算看懂了,因為有個好方法可以知道結果,可以將上面的兩個error 打開,這樣就能知道結果了:

               $(error TARGET_PRODUCT $(TARGET_PRODUCT) --> $(INTERNAL_PRODUCT))  ,輸出如下:

                 TARGET_PRODUCT full_stingray --> device/moto/stingray/full_stingray.mk。

經過測試,根據TARGET_PRODUCT=full_stingray尋找full_stingray.mk的條件是:full_stingray.mk文件中的

                                      PRODUCT_NAME == TARGET_PRODUCT

               $(error TARGET_DEVICE $(TARGET_DEVICE) --> $(INTERNAL_PRODUCT)), 輸出如下:

                  TARGET_DEVICE stingray--> device/moto/stingray/full_stingray.mk。

經過測試,TARGET_DEVICE 等於 full_stingray.mk 中的PRODUCT_DEVICE。
          好了目標找到了,終於可以回去了,我們回到config.mk文件中:


/**********************************************begin**********************************************/
include $(BUILD_SYSTEM)/envsetup.mk
board_config_mk := \
        $(strip $(wildcard \
                $(SRC_TARGET_DIR)/board/$(TARGET_DEVICE)/BoardConfig.mk \
                device/*/$(TARGET_DEVICE)/BoardConfig.mk \
                vendor/*/$(TARGET_DEVICE)/BoardConfig.mk \
        ))
ifeq ($(board_config_mk),)
  $(error No config file found for TARGET_DEVICE $(TARGET_DEVICE))
endif
ifneq ($(words $(board_config_mk)),1)
  $(error Multiple board config files for TARGET_DEVICE $(TARGET_DEVICE): $(board_config_mk))
endif
include $(board_config_mk)
TARGET_DEVICE_DIR := $(patsubst %/,%,$(dir $(board_config_mk)))

/**********************************************end**********************************************/

board_config_mk 根據千辛萬苦得來的TARGET_DEVICE來尋找BoardConfig.mk,裡面是一些cpu級別的配置。

         終於把lunch的主線說完了,後面的make就簡單得多了,因為make做了很多重復的操作。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved