makefile是否可以将目录作为目标?

makefile是否可以将目录作为目标?,makefile,makepp,Makefile,Makepp,我想说的是“只有在yank/目录存在的情况下,git存储库的下载才会起作用。如果yank/目录不存在,那么就让它下载” 我正在使用makepp- 我得到了一个错误: [metaperl@andLinux ~/edan/pkg/gist.el] makepp makepp: Loading makefile `/home/metaperl/edan/pkg/gist.el/Makeppfile' makepp: Entering directory `/home/metaperl/edan/pkg

我想说的是“只有在yank/目录存在的情况下,git存储库的下载才会起作用。如果yank/目录不存在,那么就让它下载”

我正在使用makepp- 我得到了一个错误:

[metaperl@andLinux ~/edan/pkg/gist.el] makepp
makepp: Loading makefile `/home/metaperl/edan/pkg/gist.el/Makeppfile'
makepp: Entering directory `/home/metaperl/edan/pkg/gist.el'
mkdir yank
mkdir: cannot create directory `yank': File exists
makepp: error: Failed to build target `/home/metaperl/edan/pkg/gist.el/yank' [1]
makepp: 0 files updated, 0 phony targets built and 1 target failed
[metaperl@andLinux ~/edan/pkg/gist.el] 

但是,如果yank目录存在,它为什么要尝试创建它呢?“源”已经创建了…

是的,
Makefile
可以有一个目录作为目标

您的问题可能是
cd
没有做您想要做的事情:它做
cd
,而
git克隆
是在原始目录中执行的(您
cd
的源目录,而不是您
cd
的目标目录)。这是因为
Makefile
中的每个命令都会创建一个额外的shell。一种解决方法是运行
cd
并使用shell的
&
作为一个命令进行克隆

这应该起作用:

bla/f: dir
    cd dir && touch f

dir:
    mkdir dir

您的makefile应该做您期望的事情。因为yank没有依赖性,所以如果它存在,就不会被重新制作。这看起来像是makepp中的一个bug。您可以通过使用make的传统实现尝试makefile来确认这一点。

你需要的是一份工作


快速搜索没有找到对makepp和order only先决条件的任何引用,但它可能仍然有效。

是的,Makefile可以将目录作为目标

然而,你不应该。在目录中添加或删除文件时,其mtime将更新。这会导致依赖于单个目录的多个目标彼此隐式重建,从而导致奇怪的行为。因此,根据经验,应该避免使用目录作为目标和/或依赖项

all: d/a d/b

d/a d/b: d
  rm -f $@
  touch $@

d:
  mkdir $@
多次运行此命令的输出看起来像

$ make
mkdir d
rm -f d/a
touch d/a
rm -f d/b
touch d/b

$ make
rm -f d/a
touch d/a

$ make
rm -f d/b
touch d/b

$ make
rm -f d/a
touch d/a

我们已经讨论过如何创建目录:。您可能还想知道。@Pavel:创建目录的方式很好,因为它是文件的依赖项。在您引用的示例中,问题恰恰在于目录不是使用它的目标的依赖项,而是另一个目标的依赖项,这没有任何好处。@Gilles,好的,你说得对,我把这些问题混在一起了。我只是想说服你,目录作为目标不是一个好的选择……没错,根据一般原则,makefile应该总是
&&
而不是
。但是,这不是问题:
cd
仅在重新制作了
yank
目标后运行。我通常使用
dir/.dirstamp
作为目标,而不是
dir
,规则为
mkdir-p dir&&touch$@
。当目录的内容发生更改时,unix中dirs上的时间戳将发生更改,从而阻止依赖规则运行。
$ make
mkdir d
rm -f d/a
touch d/a
rm -f d/b
touch d/b

$ make
rm -f d/a
touch d/a

$ make
rm -f d/b
touch d/b

$ make
rm -f d/a
touch d/a