標籤:未定義 UI 宏定義 判斷 bsp for 語句 pat android
https://www.jianshu.com/p/7c20b299ee63
傳統上我們一直稱這種東西為makefile中的變數,其實本質上就是一個宏,只是做的是字串替換。我們何如就把它叫做宏呢。
宏的命名
makefile的宏可以包含字元、數字、底線。需要注意的一點是,宏就是宏,反正是要做字串替換的,所以名字以數字開頭是沒問題的。makefile本身也不是用於數值處理的,以字串為主。
使用一個宏的時候需要使用$符號,所以如果字串中要使用shell變數,需要用$$。
從中可以看到,我們前面學到的函數,其實本質上也就是宏,只不過是帶有了參數的宏。
宏的賦值= 和 :=
宏可以用其他宏的值來定義自己。最強大的是用=運算子。makefile是定義式的語言,不是按順序一條一條執行的,所以,可以使用在這一行還沒有定義的宏來為當前宏賦值,反正就是個宏展開麼。
但是,這樣如果造成的循環參考,就會引發意想不到的錯誤。在這種情況下,使用:=運算子,它是只允許引用在它之前定義的變數的。
?=
如果不知道定義沒定義,可以使用?=來賦值,如果未定義,則定義。如果已經定義了,就什麼也不做。
+=
如果之前未定義,則相當於=。如果之前有:=定義,則將新值按:=的規則添加到原值後面。
對宏進行比較
有4個關鍵字用於對宏的比較:
- ifeq:判斷相等
- ifneq:判斷不相等
- ifdef:判斷非空,相當於ifneq(<參數>,)
- ifndef:如果為空白,相當於ifeq(<參數>,)
例:
.PHONY : all7ifeq ($(DEX2OAT_HOST_INSTRUCTION_SET_FEATURES),)DEX2OAT_HOST_INSTRUCTION_SET_FEATURES := defaultendifall7 : @echo $(DEX2OAT_HOST_INSTRUCTION_SET_FEATURES)
輸出:
$ make all7default
請注意,ifeq, else, endif這些語句之前不能有Tab。
上面的例子是從Android.oat.mk中改造的。其實,跟下面的是等價的:
ifndef DEX2OAT_HOST_INSTRUCTION_SET_FEATURESDEX2OAT_HOST_INSTRUCTION_SET_FEATURES := defaultendif
定義多行的宏
可以通過使用define / endef來定義多行的大宏。
我們看一個例子:
# $(1): compiler - default, optimizing, jit or interpreter. # $(2): wrapper. # $(3): dex2oat suffix.define create-core-oat-host-rule-combination $(call create-core-oat-host-rules,$(1),no-pic,,$(2),$(3)) $(call create-core-oat-host-rules,$(1),pic,,$(2),$(3)) ifneq ($(HOST_PREFER_32_BIT),true) $(call create-core-oat-host-rules,$(1),no-pic,2ND_,$(2),$(3)) $(call create-core-oat-host-rules,$(1),pic,2ND_,$(2),$(3)) endifendef
這個宏其實是個函數了。
eval函數
eval函數用於在宏定義或者是分支、迴圈結構中使用其他makefile語句時。
我們看一個在foreach中使用eval的例子:
$(foreach m,$(ALL_MODULES), $(eval r := $(ALL_MODULES.$(m).REQUIRED)) $(if $(r), $(eval r := $(call module-installed-files,$(r))) $(eval t_m := $(filter $(TARGET_OUT_ROOT)/%, $(ALL_MODULES.$(m).INSTALLED))) $(eval h_m := $(filter $(HOST_OUT_ROOT)/%, $(ALL_MODULES.$(m).INSTALLED))) $(eval t_r := $(filter $(TARGET_OUT_ROOT)/%, $(r))) $(eval h_r := $(filter $(HOST_OUT_ROOT)/%, $(r))) $(eval t_m := $(filter-out $(t_r), $(t_m))) $(eval h_m := $(filter-out $(h_r), $(h_m))) $(if $(t_m), $(eval $(call add-required-deps, $(t_m),$(t_r)))) $(if $(h_m), $(eval $(call add-required-deps, $(h_m),$(h_r)))) ) )
vpath宏
vpath宏用於指定makefile搜尋源檔案的目錄,這個倒是有點變數的意思了
引用其他makefile
makefile基本上就是字串替換,我們當然也可以通過include命令將一系列的其他makefile引用進當前的makefile.
例:
include art/build/Android.common_build.mk
自動宏
自動宏就是由make工具已經定義好的變數。
[email protected] 目標檔案集
[email protected]是指整個目標的檔案集
例:
$(built_odex) : $(dir $(LOCAL_BUILT_MODULE))% : $(built_dex) $(hide) mkdir -p $(dir [email protected]) && rm -f [email protected] $(add-dex-to-package) $(hide) mv [email protected] [email protected] $(call dexpreopt-one-file,[email protected],[email protected]) $(hide) rm [email protected]endif
$<
依賴的第一個檔案名稱,可以和[email protected]一起共用。
例:
$(built_odex) : $(my_prebuilt_src_file) $(call dexpreopt-one-file,$<,[email protected])
調試與錯誤處理輸出訊息
makefile的命令,預設都會輸出出來。可以用@來隱藏顯示。
通過echo命令,可以輸出訊息。一般都是用@echo,免得看見兩次。
幾條命令一起執行
如果這條命令用到上條命令的結果,需要在上條命令後面加分號
錯誤處理
如果makefile遇到命令出錯,就會中止當前的依賴執行。可以通過在命令之前加上“-”來忽略錯誤。
我們也可以將忽略錯誤的目標以.IGNORE來聲明。
如:
.IGNORE : all7
Jtag特工
連結:https://www.jianshu.com/p/7c20b299ee63
來源:簡書
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。
Android.mk(3) 宏