为什么下面的makefile重建了目标;“建立”;每次
我有以下代码来解压目录中的所有文件,并将其移动到build目录。如果我多次调用make,它每次都会尝试执行“build”目标,即使build目录已经存在。有人见过这个吗 我发现了这个问题,但它不一样。 操作系统:Ubuntu 12.04 节目:GNU Make 3.81为什么下面的makefile重建了目标;“建立”;每次,makefile,gnu-make,Makefile,Gnu Make,我有以下代码来解压目录中的所有文件,并将其移动到build目录。如果我多次调用make,它每次都会尝试执行“build”目标,即使build目录已经存在。有人见过这个吗 我发现了这个问题,但它不一样。 操作系统:Ubuntu 12.04 节目:GNU Make 3.81 build: mkBuildDir untar chmod 700 build .PHONY: mkBuildDir untar mkBuildDir: mkdir build untar: *.
build: mkBuildDir untar
chmod 700 build
.PHONY: mkBuildDir untar
mkBuildDir:
mkdir build
untar: *.tar.gz
for prefix in *.tar.gz; do \
tar xvf $$prefix --directory=build; \
done
clean:
rm -Rf build
这与您链接的问题基本相同。您从未创建名为mkBuildDir
的文件,因此它总是过期的,所以build
总是过期的
您的mkBuildDir
目标没有做任何有用的事情(尽管我认为这是一个精简的makefile)。如果你这样做了
# it'd be better to list the TARFILES explicitly, though this will probably work
TARFILES=`ls *.tar.gz`
all: build untar
build: $(TARFILES)
test -d build || mkdir build
chmod 700 build
for prefix in $(TARFILES); do \
tar xvf $$prefix --directory=build; \
done
clean:
rm -Rf build
这可能会完成你想要的
在Makefile中有太多虚假目标通常是Makefile的“代码气味”。它们很少是最好的/惯用的做事方式。我认为最好使用
TARFILES=$(wildcard*.tar.gz)
。在原始情况下,如果没有匹配的文件名,则TARFILES
将是*.tar.gz
而不是空列表。更重要的是,只需要创建一个进程就可以了。没错,但这种通配符行为只适用于某些shell中的某些设置。另外,$(通配符…
是GNU Make扩展,因此不可移植(这可能是个问题,也可能不是问题)。最后,每一个操作行都会创建一个新的进程,因此在这里保存一个进程并没有多大好处。如果使用两个目标都需要构建目录,那么并行生成似乎会失败。mkdir-p将修复它(尽管您可能会得到不必要的命令输出)。