Makefile GNU能制造';s自动变量的范围是否仅限于当前配方定义?

Makefile GNU能制造';s自动变量的范围是否仅限于当前配方定义?,makefile,gnu-make,Makefile,Gnu Make,GNU Make创建的应用程序在某些情况下非常方便: .SECONDEXPANSION: %-processed.md: $$(wildcard $$*.m4) $(wildcard macros/*.m4) %.md m4 $^ > $@ 但是,当有人试图在makefile中的其他地方添加依赖项时,这个idilic世界就会崩溃: .PHONY: force force: ; mybook-processed.md: force 现在突然m4抱怨“force”不是有效的输入

GNU Make创建的应用程序在某些情况下非常方便:

.SECONDEXPANSION:

%-processed.md: $$(wildcard $$*.m4) $(wildcard macros/*.m4) %.md
    m4 $^ > $@
但是,当有人试图在makefile中的其他地方添加依赖项时,这个idilic世界就会崩溃:

.PHONY: force
force: ;

mybook-processed.md: force
现在突然
m4
抱怨“force”不是有效的输入文件。当然不是,但是它显示在
$^
变量中,因为它被附加到先决条件列表中


有没有一种方法可以只访问即时配方定义中定义的先决条件,而忽略其他先决条件?

到目前为止,我找到的唯一方法是停止使用自动变量并编写自己的先决条件。我真的希望有人能提出更好的答案,但我目前的解决方案是:

.SECONDEXPANSION:

process_prereqs = $(wildcard $1.m4) $(wildcarad macros/*.m4)
%-processed.md: %.md $$(call process_prereqs,$$*)
    m4 $(call process_prereqs,$$*) $< > $@
。第二次扩展:
进程_prereqs=$(通配符$1.m4)$(通配符宏/*.m4)
%-processed.md:%.md$$(调用进程\u prereqs,$$$*)
m4$(呼叫过程\u预请求,$$*)$<>$@

这种方法只有更稳定的
$到目前为止,我发现唯一的方法就是停止使用自动变量,编写自己的变量。我真的希望有人能提出更好的答案,但我目前的解决方案是:

.SECONDEXPANSION:

process_prereqs = $(wildcard $1.m4) $(wildcarad macros/*.m4)
%-processed.md: %.md $$(call process_prereqs,$$*)
    m4 $(call process_prereqs,$$*) $< > $@
。第二次扩展:
进程_prereqs=$(通配符$1.m4)$(通配符宏/*.m4)
%-processed.md:%.md$$(调用进程\u prereqs,$$$*)
m4$(呼叫过程\u预请求,$$*)$<>$@

这样只会更稳定
$不,这是不可能的。这些信息甚至在make的内部结构中都不可用

你的示例解决方案不是我会使用的。如果您的命令只接受某些类型的文件,我将使用
filter
确保它只看到这些类型的文件:

.SECONDEXPANSION:

%-processed.md: $$(wildcard $$*.m4) $(wildcard macros/*.m4) %.md
        m4 $(filter %.m4 %.md,$^) > $@

不可能。这些信息甚至在make的内部结构中都不可用

你的示例解决方案不是我会使用的。如果您的命令只接受某些类型的文件,我将使用
filter
确保它只看到这些类型的文件:

.SECONDEXPANSION:

%-processed.md: $$(wildcard $$*.m4) $(wildcard macros/*.m4) %.md
        m4 $(filter %.m4 %.md,$^) > $@

您可以对伪目标采用命名约定,例如
force
,比如
MAGIC/force
。然后
$(过滤掉MAGIC/%,$^)
--仍然有点重复,但不是那么糟糕。

您可以对伪目标采用命名约定,例如
force
,比如
MAGIC/force
。然后
$(过滤掉MAGIC/%,$^)
--仍然有一点重复,但没有那么糟糕。

如果您只添加了伪目标,那么这是很好的。但是,您可能需要将其他非源代码项作为先决条件:如果发生更改,将强制重新生成的脚本,甚至您可能希望在发生更改时依赖
m4
本身。在我看来,准确选择你想要的东西比试图摆脱你可能不想要的所有不同的东西更可靠。如果你添加的都是伪目标,这很好。但是,您可能需要将其他非源代码项作为先决条件:如果发生更改,将强制重新生成的脚本,甚至您可能希望在发生更改时依赖
m4
本身。等等。在我看来,选择你想要的东西比试着扔掉你可能不想要的东西更可靠。谢谢。不幸的是,为了提问,我的例子被大大简化了,这不会直接映射到解决方案,但它仍然是一个有用的范例,我不知道。我在未来会看到很多Makefile重构。谢谢。不幸的是,为了提问,我的例子被大大简化了,这不会直接映射到解决方案,但它仍然是一个有用的范例,我不知道。在我的未来,我会看到很多Makefile重构。注意GNU Make 4.3添加了一个新变量
。额外的PREREQS
,它可能被强制完成这项任务。注意GNU Make 4.3添加了一个新变量
。额外的PREREQS
,可能被强制完成这项任务。