当目标名称不是文件名时如何建立make依赖

How to build make dependency when the target name is not the file name

我正在尝试编写一个非常简单的 Makefile,但我无法使其按预期工作。

target_a : file.txt
       echo "this is target_a"
       touch 0_$@
target_b : 0_target_a
       echo "executing target_b"
       touch 0_$@

每当我 运行 make taget_b 它给出一个错误:

make: *** No rule to make target '0_target_a', needed by 'target_b'.  Stop.

我可以将 touch 0_$@ 更改为 touch $@。但我真的想要 touch 0_$@ 的解决方案(可以自由选择文件名)。

来自 GNU 手册页 ftp://ftp.gnu.org/old-gnu/Manuals/make-3.79.1/html_chapter/make_2.html

A target is usually the name of a file that is generated by a program; examples of targets are executable or object files. A target can also be the name of an action to carry out

我想知道如何在目标名称为以下时构建 Make 依赖项:

Action

target_b的依赖应该是一个有效的目标本身,或者一个已经存在的文件

target_a : file.txt
       echo "this is target_a"
       touch 0_$@
target_b : target_a
       echo "executing target_b"
       touch 0_$@

如果您想 "alias" 创建 0_target_a 文件到 target_a "action" 您可以添加中间规则:

0_target_a : file.txt
       echo "creating 0_target_a"
       touch 0_$@

target_a : 0_target_a

target_b : target_a
       echo "executing target_b"
       touch 0_$@

恐怕你不能直接做到这一点,你必须帮助自己建立一个中间目标,使目标与其输出之间的联系变得清晰(因此让 make 有机会决定它什么时候做或做不需要重制:

0_target_a: file.txt
        echo "this is target_a"
        touch $@

target_b: 0_target_a
        echo "executing target_b"
        touch 0_$@

即为目标 0_target_a 定义规则并相应地更新 touch 将为您提供您想要的行为,因为现在了解规则目标和文件 0_target_a 之间的连接并知道何时不需要重新制作为 target_b 的依赖项。现在,如果您还想拥有一个独立的 target_a 来生成文件 0_target_a,您可以按如下方式定义它:

target_a: 0_target_a

因为我们知道这个目标本身并没有真正创建一个文件,我们可以不费吹灰之力寻找它的结果 (target_a) 并且如果通过将其声明为虚假文件来创建这样的文件也可以防止冲突.

事实上你可能想给你的 target_b 相同的待遇,否则(同样 make 没有足够的信息来理解 target_b 和 [=23= 之间的关系]) make target_b 总是重新制作,即使文件已经生成。

整个 make 文件如下所示:

.PHONY: target_a target_b
target_a: 0_target_a
target_b: 0_target_b

0_target_a: file.txt
    echo "this is target_a"
    touch $@

0_target_b: 0_target_a
    echo "executing target_b"
    touch $@

如果这是整个文件中重复出现的主题,您还可以通过定义静态模式规则来表达第二行和第三行的关系:

target_a target_b: %:  0_%

这定义了一个规则,即任何目标(第一个 '%' 没有任何其他内容)的先决条件是 0_ 前缀,后跟目标名称(0_%0_ 加上stem 在这种情况下是一个完整的目标名称,与前面的 %) 匹配。并使此规则适用于目标 target_atarget_a。此规则没有配方,因此仅描述两者之间的 target/prerequisite 关系。

换句话说,它与完整示例第 2 行和第 3 行组合的含义相同。