我试图在makefile中编写一个简单的日志包装器,如下所示
define do_log
ifeq ($(1),1)
$(info ---------- $(shell date +%H:%M:%S) $(2))
else ifeq ($(1),2)
$(warning ^^^^^^^^^^ $(shell date +%H:%M:%S) $(2))
else ifeq ($(1),3)
$(error !!!!!!!!!! $(shell date +%H:%M:%S) $(2))
endif
endef
但是每次我调用此功能
$(call do_log,1,"hello")
所有语句都将执行
$ make
---------- 18:22:45 "hello"
Makefile:16: ^^^^^^^^^^ 18:22:45 "hello"
Makefile:16: *** !!!!!!!!!! 18:22:45 "hello". Stop.
有人可以帮助我了解我在做什么错吗?
ifeq
等更类似于预处理程序语句。它们仅对make的makefile解析器有意义。它们对变量扩展等没有特殊的意义或意义,就像您无法在运行时使用C / C ++预处理程序语句一样。
您看到的行为是因为call
首先扩展了变量,并且在这种情况下仅考虑了变量。这意味着调用会看到类似这样的内容:
<text> $(1) <text>
$(info ---------- $(shell date +%H:%M:%S) $(2))
<text> $(1) <text>
$(warning ^^^^^^^^^^ $(shell date +%H:%M:%S) $(2))
<text> $(1) <text>
$(error !!!!!!!!!! $(shell date +%H:%M:%S) $(2))
<text>
并且所有这些变量/函数引用均被扩展。通常,您不能在ifeq
变量除非中使用define
等,否则您希望将其与eval
一起使用(它将使用makefile解析器解析其字符串)。
由于您尚未真正向我们展示您如何使用此功能,因此很难提出最佳替代方案,但是要从字面上翻译您在这里所做的事情,您可以使用:
define do_log
$(if $(filter-out 1,$(1)),,$(info ---------- $(shell date +%H:%M:%S) $(2)))
$(if $(filter-out 2,$(1)),,$(warning ^^^^^^^^^^ $(shell date +%H:%M:%S) $(2)))
$(if $(filter-out 3,$(1)),,$(error !!!!!!!!!! $(shell date +%H:%M:%S) $(2)))
endef
这可以通过eval
实现:
define do_log
ifeq ($(1),1)
$$(info ---------- $(shell date +%H:%M:%S) $(2))
else ifeq ($(1),2)
$$(warning ^^^^^^^^^^ $(shell date +%H:%M:%S) $(2))
else ifeq ($(1),3)
$$(error !!!!!!!!!! $(shell date +%H:%M:%S) $(2))
endif
endef
$(eval $(call do_log,3,"hello"))