makefile中的$(eval)导致配方在第一个目标错误之前开始

时间:2015-04-28 13:33:39

标签: makefile eval

CFormat:

define Format_File :=
    @echo Formatting
ifneq ("$(wildcard $(1))","")
    @echo if1

    # The default extensions for intermediate files are not used,
    # to avoid collisions with backup files open in the editor, etc.
    # Save the original source file with an '_X' suffix on the extension.
ifneq("$(wildcard $(1)_X)","") 
    @echo if2
else 
    @echo else2
endif
    @ren $(1) $(1)_X
    # C-Comment is invoked separately, due to pathing limitations
    # The redirection is a means to suppress blabbering.
    @echo Formatting $(1) . . .
    $(CFORMAT_PATH)\Cformat -h$(CFORMAT_PATH) $(1)_X -o$[Base, $(1)].tmp -ino >temp.tmp; 
    $(CFORMAT_PATH)\Ccomment -h$(CFORMAT_PATH) $[Base, $(1)].tmp -o$(1) >temp.tmp; 
else 
    @echo else1
endif
endef


FormatAll: CFormat
$(foreach loopFile,$(ALL_S_SOURCES),$(eval $(call Format_File,$(loopFile))))


.PHONY: FormatAll

当我用信息替换eval时,它正确打印出函数调用,但每次我尝试实际评估格式化程序时,它都会在标题中给出错误。

编辑:这个问题在任何地方都受到语法错误的困扰,但是根据@MadScientist的建议,我最终能够使用shell循环使其工作。

2 个答案:

答案 0 :(得分:3)

最简单的答案是,你不能这样做。像$(foreach ...)这样的单个函数或单个变量扩展可以永远扩展到makefile中的多个逻辑行。这不是make解析器的工作方式。

此外,$(eval ...)可用于构建完整规则,但您不能使用它来构建规则的一部分:在make开始解析评估的输出之前,它将“关闭”任何规则当前正在定义(就像你不能将规则的引入放在一个文件中,并将配方放在另一个文件中,并使用include来包含配方)。

你还没有真正解释为什么你想以这种方式做事。一个简单的答案是使用shell循环,而不是makefile循环,如下所示:

FormatAll: CFormat
        @for f in $(ALL_S_SOURCES); do \
            echo Formatting; \
            if [ -f $$f ]; then \
                echo if1; \
                if [ -f $${f}_X ]; then \ 
                    echo if2; \
                else \
                    echo else2; \
                fi; \
                ren $$f $${f}_X; \
                echo Formatting $$f . . .; \
                $(CFORMAT_PATH)\Cformat -h$(CFORMAT_PATH) $F{f}_X -o$[Base, $$f].tmp -ino >temp.tmp; \
                $(CFORMAT_PATH)\Ccomment -h$(CFORMAT_PATH) $[Base, $$f].tmp -o$$f >temp.tmp; \
            else \
                echo else1; \
            fi; \
        done

我同意Etan认为$[Base ...]语法很奇怪,当然不对。

如果您需要有关eval和调试的更多详细信息,可以查看this post以及系列中较早的内容。

答案 1 :(得分:0)

错误消息非常清楚:foreach循环在目标配方定义之前/之外吐出配方命令。

您可以尝试以下内容:

all: 
    $(foreach loopFile,$(ALL_S_SOURCES),$(eval $(call Format_File,$(loopFile))))

.PHONY: all