我們也說說Android.mk(2)
函數進階教程 - 分支、循環(huán)、子程序
按照面向過程程序設計的標準流程,我們講完了順序結構,就要講分支、循環(huán)和子程序。下面我們就開始講用于分支、循環(huán)和子程序調用功能的函數。
分支函數
要走分支,一定是要有條件要判斷。
在Makefile里,最主要的判斷就是看字符串能不能找到了。
通過findstring函數來進行這個判斷,然后用if函數使用findstring函數的結果。
例:
.PHONY : all5
bootoatfile := out/target/product/ali6753_65t_m0/dex_bootjars/system/framework/arm64/boot.oat
result_findString := $(findstring boot.oat,$(bootoatfile))
result_findString2 := $(findstring boot.oat,$(oatfile))
all5 :
$(if $(result_findString), @echo found boot.oat, @echo cannot find boot.oat)
$(if $(result_findString2), @echo found boot.oat, @echo cannot find boot.oat)
輸出:
found boot.oat
cannot find boot.oat
循環(huán)函數
Makefile中對于循環(huán)結構的支持是foreach函數
語法格式為:$(foreach 變量,列表,對變量對操作)
這樣的循環(huán)在Android.mk中遍地都是,比如對模塊進行遍歷,對產品進行遍歷等。
我們看一個例子,這個例子寫在build/core/main.mk中:
# A helper goal printing out install paths
.PHONY: GET-INSTALL-PATH
GET-INSTALL-PATH:
@$(foreach m, $(ALL_MODULES), $(if $(ALL_MODULES.$(m).INSTALLED), \
echo 'INSTALL-PATH: $(m) $(ALL_MODULES.$(m).INSTALLED)';))
再看一個更復雜一點的,加深一下印象:
# A static Java library needs to explicily set LOCAL_RESOURCE_DIR.
ifdef LOCAL_RESOURCE_DIR
need_compile_res := true
all_resources := $(strip \
$(foreach dir, $(LOCAL_RESOURCE_DIR), \
$(addprefix $(dir)/, \
$(patsubst res/%,%, \
$(call find-subdir-assets,$(dir)) \
) \
) \
))
子程序調用
makefile的子程序結構當然就是函數了。
定義函數很簡單,就是定義一個變量就是了。參數可以用$(1),$(2)等等來表示
例:
isBootOat = $(findstring boot.oat,$(1))
調用的時候要注意,用call函數來調用,call和函數名之間是空格,之后的參數要用逗號分隔。
我們看個簡單的例子,將前邊講過的findstring的功能封裝成一個函數。
例:
.PHONY : all6
isBootOat = $(findstring boot.oat,$(1))
all6 :
$(if $(call isBootOat,$(bootoatfile)), @echo found boot.oat, @echo cannot find boot.oat)
$(if $(call isBootOat,$(oatfile)), @echo found boot.oat, @echo cannot find boot.oat)
輸出:
$ make all6
found boot.oat
cannot find boot.oat