天天看點

核心makefile echo-cmd表達式

    Kbuild.include中提供了核心編譯時基礎函數,其中echo-cmd變量的功能讓我一直能疑惑。其定義如下:

echo-cmd = $(if $($(quiet)cmd_$(1)),\
  echo '  $(call escsq,$($(quiet)cmd_$(1)))$(echo-why)';)      

    從字面了解,應該是回顯指令,而且初看也是列印指令到終端。但是,事實上,那隻是他一半的功能,另一半是執行指令。空口無憑,來試一下

squote  := '
escsq = $(subst $(squote),'\$(squote)',$1)

echo-cmd = $(echo '  $(call escsq,ls)';)

vmlinux:FORCE
  $(echo-cmd) ls
FORCE:      

這段makefile是我從Kbuild.include中截取和修改的,運作的結果為:

root@ubuntu:~/Desktop# make -f echo-cmd.mk
ls
39-usb-reboot.rules   linux-3.7.4.tar.xz  udev      

    展開這個規則,首先escsq = $(subst $(squote),'\$(squote)',$1)是一個表達式,call函數除了可以調用函數,還可以調用表達式,形如下面的規則:

reverse =  $(2) $(1)
squeue=$(1) $(2)
__all:
  @echo foo=$(call reverse,a,b)
  @echo foo=$(call squeue,a,b)      

執行的結果是:

root@ubuntu:~/Desktop# make -f call.mk
foo=b a
foo=a b      

    是以不用懷疑$(call escsq,ls)這句的正确性,call傳遞給escsq的參數1是ls,是以,表達式escsq = $(subst $(squote),'\$(squote)',$1)的結果為 echo ls。最終echo-cmd變量的值是echo 'ls';。把這個變量在vmlinux目标中擴充開,就是

vmlinux:FORCE

    echo 'ls';ls 

    這個規則中有兩條指令,makefile規定,指令間用分号分割,是以這個規則做了兩件事:1.顯示指令,2.執行指令

    最後,看下Kbuild.include中完整的echo-cmd指令

echo-cmd = $(if $($(quiet)cmd_$(1)),\
  echo '  $(call escsq,$($(quiet)cmd_$(1)))$(echo-why)';)      

繼續閱讀