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
function; eval
不需要变量名,它需要一个字符串来解析,所以它将是:
$(eval $(buildMQ))
但是,出于同样的原因,这不会执行您想要的操作:它扩展了 buildMQ
变量,这导致所有函数在 eval
看到它们之前先被扩展。
一种选择是转义 buildMQ
中的所有变量和函数引用。但在你的情况下,一个更简单的解决方案是使用 the value
function 来防止在 eval
看到值之前扩展:
$(eval $(value buildMQ))
我正在尝试创建一个函数来确定目录是否存在,如果存在,则将目标添加到所有列表。但出了点问题。这是 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
function; eval
不需要变量名,它需要一个字符串来解析,所以它将是:
$(eval $(buildMQ))
但是,出于同样的原因,这不会执行您想要的操作:它扩展了 buildMQ
变量,这导致所有函数在 eval
看到它们之前先被扩展。
一种选择是转义 buildMQ
中的所有变量和函数引用。但在你的情况下,一个更简单的解决方案是使用 the value
function 来防止在 eval
看到值之前扩展:
$(eval $(value buildMQ))