首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >GNU Make - Trailing“/”被删除了吗?

GNU Make - Trailing“/”被删除了吗?
EN

Stack Overflow用户
提问于 2019-01-10 09:00:42
回答 2查看 244关注 0票数 2

我正在开发一个makefile,它在输出目录中创建多个文件。为了创建这些文件,输出目录必须已经存在,否则文件创建将失败。

下面是一个最小的示例,它演示了我遇到的问题:

代码语言:javascript
复制
.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/”中删除尾随的"/“:

代码语言:javascript
复制
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.

顺便说一句,在命令行上请求一个目录目标的效果很好:

代码语言:javascript
复制
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/"

我怎么才能让make做我想做的事呢?

理想情况下,我正在寻找一种通用的解决方案。上面的示例只有一个子目录,但实际的项目将有许多子目录,所以我希望避免将解决方案复制粘贴到任何地方。

EN

回答 2

Stack Overflow用户

发布于 2019-01-10 10:20:30

是的,/被丢弃在dir/目标中(这个问题可以在GNU Make 3.81下重现)。

另一种解决方案是使用automatic variable $(@D)获取目标文件名的目录部分,去掉尾部斜杠。并在touch文件之前创建目录:

代码语言:javascript
复制
.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下的测试通过:

代码语言:javascript
复制
$ 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"
票数 0
EN

Stack Overflow用户

发布于 2019-01-10 15:30:48

您的%/规则仅匹配具有尾随/的目标名称。因为,根据您使用的make的版本,在名称被视为目标名称之前,可以删除或不删除尾随的/,因此这并不总是有效的。

对于单个目录,不要使用这个尾随的/,也不要使用模式规则:

代码语言:javascript
复制
dir/%.dat: | dir
    touch "$@"

dir:
    mkdir -p "$@"

对于更通用的解决方案,leiyc的解决方案很好。还有其他的:

  1. 如果您可以获得要创建的所有目录的列表,则可以使用以下命令一次性创建所有目录:

目录目录... .SECONDEXPANSION::| $$(@D) $( DIRS ):mkdir -p $@

可能还有其他的可能性...

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54120630

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档