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)';)