Android.mk(3) 宏

來源:互聯網
上載者:User

標籤:未定義   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) 宏

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.