我正在尝试编写一个非常简单的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
目标通常是程序生成的文件的名称;目标的示例是可执行文件或对象文件。目标也可以是执行的动作的名称
我想知道当目标名称是:时如何构建Make依赖项
Action
恐怕你不能直接做到这一点,你必须帮助自己找到一个中间目标,使目标与其输出之间的连接清晰(因此让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
和0_target_b
之间的关系)即使文件已经生成,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_
加上词干,在这种情况下,它是一个完整的目标名称,与之前的%
匹配)。并且使得该规则适用于目标CCD_ 20和CCD_。该规则没有配方,因此只描述了两者之间的目标/先决条件关系。
换句话说,它的含义与完整的示例行2和3的组合相同。
target_b
的依赖项应该是一个有效的目标本身,或者是一个已经存在的文件
target_a : file.txt
echo "this is target_a"
touch 0_$@
target_b : target_a
echo "executing target_b"
touch 0_$@
如果你想将0_target_a
文件的创建"别名"为target_a
的"操作",你可以添加中间规则:
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_$@