【问题标题】:gmake function / ifneq/else/endifgmake 函数/ifneq/else/endif
【发布时间】:2018-07-17 12:58:50
【问题描述】:

我正在尝试创建一个函数来确定目录是否存在,如果存在,则将目标添加到所有列表。但有些不对劲。这是Makefile代码sn-p:

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     ******

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

【问题讨论】:

    标签: function gnu-make


    【解决方案1】:

    这里有很多关于how call works 的误解。 call 函数接受一个变量(名称),加上零个或多个参数。它将参数分配给$1$2 等,然后扩展变量。

    请注意,这里的“扩展”并不是指“将变量值解释为好像它是一个生成文件”。我们的意思很简单,遍历变量的值,找到所有的 make 变量和函数,并用适当的值替换它们。

    因此,您调用$(call buildMQ)。这不会为$1 等分配任何值,因为您没有提供任何参数:实际上这与仅使用$(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 行。

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

    $(eval $(buildMQ))
    

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

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

    $(eval $(value buildMQ))
    

    【讨论】:

    • 我认为还有一个误解 ifneq 的工作原理。我这样解释 [gnu.org/software/make/manual/html_node/…,使用任何条件语句都会修改多行变量的组合方式,在函数内部创建条件语句是没有用的。要做到这一点,必须使用$(if ),不是吗?
    • 谢谢。 $(eval $(value buildMQ)) 解决了这个问题。
    猜你喜欢
    • 2010-11-12
    • 2014-10-04
    • 2021-10-29
    • 1970-01-01
    • 1970-01-01
    • 2011-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多