gmake 函数 / ifneq/else/endif

gmake function / ifneq/else/endif

我正在尝试创建一个函数来确定目录是否存在,如果存在,则将目标添加到所有列表。但出了点问题。这是 Makefile 代码片段:

define buildMQ  
    $(info ****     Checking to see if the MQ series directory exist     *****)  
    ifneq "$(wildcard $(MQ_DIR) )" ""   
        $(info /opt/mqm was found)  
        MQ_APPS=MQSAPP  
    else  
        $(error $n$n****     ERROR - The MQ Series direcory: "$(MQ_DIR)" does not exist     ******$n$n)
   endif 
endef

ifeq ('$(FN)' , 'TEST')
    TEST_APPS= 
endif

ifeq ('$(FN)' , 'ONSITE_TEST')
   ONSITE_TEST_APPS=  # insert ONSITE_TEST only apps here
   $(call buildMQ)
endif
ifeq ('$(FN)' , 'ACCOUNT')
    ACCOUNT_APPS=  
    $(call buildMQ)
endif
all:$(COMMON_APPS) $(TEST_APPS) $(ONSITE_TEST_APPS) $(ACCOUNT_APPS) $(MQ_APPS) makexit

当我 运行 它与 FN = ONSITE_TEST:

****     Checking to see if the MQ series directory exist     *****
/opt/mqm was found
Makefile:128: *** 

****     ERROR - The MQ Series direcory: "/opt/mqm" does not exist     ******

如何打印两个打印语句?我错过了什么?
该目录确实存在

这里对how call works有很多误解。 call 函数接受一个变量(名称),加上零个或多个参数。它将参数分配给 </code>、<code> 等,然后 扩展 变量。

请注意,这里的 "expands" 并不是 "interprets the variable value as if it were a makefile"。我们的意思很简单,遍历变量的值,找到所有的 make 变量和函数,并用适当的值替换它们。

因此,您调用 $(call buildMQ)。这不会为 </code> 等分配任何值,因为您没有提供任何参数:实际上这与使用 <code>$(buildMQ) 完全相同; call 函数在这里没有影响。

因此 make 扩展了 buildMQ 变量的值...基本上它将值作为一个长字符串:

$(info ****     Checking to see if the MQ series directory exist     *****) ifneq "$(wildcard $(MQ_DIR) )" "" $(info /opt/mqm was found) MQ_APPS=MQSAPP else $(error $n$n****     ERROR - The MQ Series direcory: "$(MQ_DIR)" does not exist     ******$n$n) endif

并扩展它。所以首先它扩展 $(info ... Checking ... 函数并打印出来。然后它扩展 $(wildcard ..) 并替换它。然后它扩展 $(info /opt/mqm ...) 并打印出来。然后它展开 $(error ...) 并显示消息并退出。

如果它没有退出,那么你会遇到语法错误,因为像 call 这样的函数不能扩展为多行语句;如上所述,它不像一组 makefile 行那样被评估。它必须扩展为单值 makefile 行。

如果你想让 make 像解析 makefile 一样解析变量的内容,你需要使用 the eval functioneval 不需要变量名,它需要一个字符串来解析,所以它将是:

$(eval $(buildMQ))

但是,出于同样的原因,这不会执行您想要的操作:它扩展了 buildMQ 变量,这导致所有函数在 eval 看到它们之前先被扩展。

一种选择是转义 buildMQ 中的所有变量和函数引用。但在你的情况下,一个更简单的解决方案是使用 the value function 来防止在 eval 看到值之前扩展:

$(eval $(value buildMQ))