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循环使其工作。
答案 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