GNU Make - 尾随“/”被删除?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了GNU Make - 尾随“/”被删除?相关的知识,希望对你有一定的参考价值。
我正在研究一个在输出目录中创建多个文件的makefile。为了创建这些文件,输出目录需要已经存在,否则文件创建失败。
这是一个最小的例子,演示了我遇到的问题:
.PHONY: default
default: dir/file.dat dir/other.dat
# In order to create these files, their parent directory must exist
dir/%.dat: | dir/
touch "$@"
# To create a directory, use mkdir -p
%/:
mkdir -p "$@"
当我运行makefile时,我得到一个错误,即没有规则来制作dir
。调试运行显示make正在从“dir /”中删除尾部“/”:
root@69654136a2ae:~# make -rdf dirs.mk
GNU Make 3.81
[snipped]
Considering target file `default'.
File `default' does not exist.
Considering target file `dir/file.dat'.
File `dir/file.dat' does not exist.
Considering target file `dir'.
File `dir' does not exist.
Looking for an implicit rule for `dir'.
No implicit rule found for `dir'.
Finished prerequisites of target file `dir'.
Must remake target `dir'.
make: *** No rule to make target `dir', needed by `dir/file.dat'. Stop.
顺便说一下,在命令行上询问目录目标就可以了:
root@69654136a2ae:~# make -rdf dirs.mk /some/dir/
GNU Make 3.81
[snipped]
Updating goal targets....
Considering target file `/some/dir/'.
File `/some/dir/' does not exist.
Looking for an implicit rule for `/some/dir/'.
Trying pattern rule with stem `/some/dir'.
Found an implicit rule for `/some/dir/'.
Finished prerequisites of target file `/some/dir/'.
Must remake target `/some/dir/'.
mkdir -p "/some/dir/"
我怎样才能做我想做的事? 理想情况下,我正在寻找一个通用的解决方案。上面的例子只有一个子目录,但实际的项目有很多子目录,所以我想避免在任何地方复制粘贴解决方案。
答案
是的,/
在dir/
目标中被删除(问题可以在GNU Make 3.81下复制)。
另一种解决方案是使用automatic variable $(@D)
获取目标文件名的目录部分,并删除尾部斜杠。并在touch
之前创建目录:
.PHONY: default
default: dir/file.dat dir/other.dat
# In order to create these files, make their parent directory first
dir/%.dat:
mkdir -p $(@D)
touch "$@"
在GNU Make 3.81下通过测试:
$ make --version
GNU Make 3.81
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
...
$ make
mkdir -p dir
touch "dir/file.dat"
mkdir -p dir
touch "dir/other.dat"
另一答案
您的%/
规则仅匹配具有尾随/
的目标名称。因为,根据您使用的make的版本,在将名称作为目标名称之前,可以从名称中删除或不删除/
,这并不总是有效。
对于一个目录,只是不要使用此尾随/
并且不使用模式规则:
dir/%.dat: | dir
touch "$@"
dir:
mkdir -p "$@"
对于更通用的解决方案,leiyc的解决方案很好。还有其他:
- 如果您可以获取要创建的所有目录的列表,则可以使用以下命令一次创建所有目录:
DIRS := dir ... $(shell mkdir -p $(DIRS) > /dev/null) <any-target>: <prerequisites> <recipe>
- 如果您可以获取要创建的所有目录的列表,但更喜欢仅订购的先决条件,则可以使用secondary expansion和规则来创建目录:
DIRS := dir ... .SECONDEXPANSION: <any-target>: <prerequisites> | $$(@D) <recipe> $(DIRS): mkdir -p $@
而且可能还有其他可能性......
以上是关于GNU Make - 尾随“/”被删除?的主要内容,如果未能解决你的问题,请参考以下文章