我需要在嵌套目录结构中创建一堆文件。结构和文件名不受我的控制。我想确保Makefile创建嵌套目录(如果缺少)。目录的名称取决于文件名,因此我使用二级扩展来从目标名称确定它。
Makefile如下所示:
.SECONDEXPANSION:
data/%.txt: data/$$(*D)
echo "$(*D) = $(*F)" > "$@"
data/%:
mkdir -p "$@"
并且这样调用:
make data/foo/foo.txt
现在我希望这会执行以下命令:
mkdir -p "data/foo"
echo "foo = foo" > "data/foo/foo.txt"
不幸的是,事实并非如此。相反,它执行:
mkdir -p "data/foo/foo.txt"
这让我感到困惑,因为第一条规则的主干较小且should thus be given preference as being more specific。
我可以通过在路径中添加尾随/
来“修复”此问题:
.SECONDEXPANSION:
data/%.txt: data/$$(*D)/
echo "$(*D) = $(*F)" > "$@"
data/%/:
mkdir -p "$@"
现在make
尝试执行以下命令,几乎我想要的内容:
mkdir -p "data/foo/"
echo "foo = foo" > "data/foo/foo.txt"
rm data/foo/
...但请注意最后一行:make
认为文件夹名称是中间规则,并希望将其删除。由于我不知道文件/文件夹的名称,因此无法在Makefile中对它们进行硬编码,因此我无法将它们指定为.SECONDARY
。无论如何,添加尾随/
仅仅是为了消除路径的歧义感觉是错误的。
为什么make
没有找到正确的规则而没有文件夹规则的尾部斜杠?
(注意:上面只适用于GNUMake≥3.82。在此之前,Makefile完成完全不同的事情。)