Makefile 抑制生成规则错误输出

Makefile 抑制生成规则错误输出,makefile,gnu-make,Makefile,Gnu Make,我有一个创建目录的规则 bin: -mkdir $@ 但是,在第一次生成目录后,我收到以下输出: mkdir bin mkdir: cannot create directory `bin': File exists make: [bin] Error 1 (ignored) 是否有某种方法只能在目录不存在时运行该规则,或者在目录已存在时禁止输出?命令行上的前导“-”已忽略该错误。如果确实要丢失来自mkdir的错误消息,请使用I/O重定向: bin: -mkdir bin 2

我有一个创建目录的规则

bin:
    -mkdir $@
但是,在第一次生成目录后,我收到以下输出:

mkdir bin
mkdir: cannot create directory `bin': File exists
make: [bin] Error 1 (ignored)

是否有某种方法只能在目录不存在时运行该规则,或者在目录已存在时禁止输出?

命令行上的前导“
-
”已忽略该错误。如果确实要丢失来自
mkdir
的错误消息,请使用I/O重定向:

bin:
    -mkdir bin 2> /dev/null
但是,您仍然会从
make
中收到“忽略”警告,因此最好使用
mkdir
选项,当目标已存在时,该选项不会导致失败,即
-p
选项:

MKDIR_P = mkdir -p

bin:
    ${MKDIR_P} $@

-p
选项实际上创建了给定路径上缺少的所有目录,因此它可以在一次调用中生成多个目录,但其副作用是不会为现有目录生成错误。这确实假设POSIX ish实现了
mkdir
;较旧的计算机可能不支持该规则(尽管它很长一段时间以来一直是标准的)。

除非其目标不存在或由于其依赖性而过时,否则不应执行该规则。换句话说,您不应该遇到此错误

[添加示例]

[max@truth tmp]$ ls -la
total 20
drwxr-xr-x.  2 max users 4096 Aug 14 21:11 .
drwx------. 80 max max   4096 Aug 14 18:25 ..
-rw-rw-r--   1 max max     38 Aug 14 21:11 Makefile
[max@truth tmp]$ cat Makefile 
.PHONY: all
all: bin

bin:
    mkdir $@

[max@truth tmp]$ make
mkdir bin
[max@truth tmp]$ ls -la
total 24
drwxr-xr-x.  3 max users 4096 Aug 14 21:11 .
drwx------. 80 max max   4096 Aug 14 18:25 ..
drwxrwxr-x   2 max max   4096 Aug 14 21:11 bin
-rw-rw-r--   1 max max     38 Aug 14 21:11 Makefile
[max@truth tmp]$ make
make: Nothing to be done for `all'.
[max@truth tmp]$ make
make: Nothing to be done for `all'.

你的文件夹依赖于什么吗?你的文件夹是假的目标吗?

好吧,我以这个结构结束,也许有人会发现它有用,或者可以对它发表评论:

BINDIR = .
TMPDIR = tmp
OUTDIRS = $(BINDIR) $(TMPDIR)
$(OUTDIRS):
    @test -d $@ || mkdir $@

Make假设第一个目标是默认目标。如果这是完整的makefile,那么它必须始终尝试重新生成默认目标,即bin。在makefile的顶部插入以下行:

all: bin
.PHONY: all

处理目录创建的传统方法是使用一个戳文件,该文件依赖并创建目录作为副作用。在进行
distclean
或任何“真正干净”的目标时删除戳记文件:

bin/.dirstamp:
    mkdir -p $(DIRS)
    touch $@

bin/foo: bin/.dirstamp
    $(MKFOO) -o $@

distclean:
    rm -rf bin

原因如下:每当创建/删除
bin
中的文件时,包含目录的mtime都会更新。如果目标依赖于
bin
,那么下次运行
make
时,它将重新创建不需要的文件。

另一种抑制
make:error的方法。。。(忽略)
输出是将
| | true
附加到可能失败的命令。检查LaTeX日志文件中错误的grep示例:

undefined:
  @grep -i undefined *.log || true
如果没有
| | true
,当grep找不到任何匹配项时进行投诉


这适用于所有命令,而不仅仅是mkdir;这就是我添加这个答案的原因。

没有。它总是过时的,你在OP中看到的就是我所拥有的。Make为你做
test
,所以它最后统计了目录两次。这只是隐藏了默认目标是。(点)的问题。接近重复:dir dep是否会处理生成到该位置的所有文件?在该目录中创建的每个文件都需要直接或间接依赖stampfile,以确保它是在使用之前创建的。daniel,make规则中命令的
-
前缀字符执行相同的操作,尽管不需要shell来处理它。这可能更快,也不太可能适得其反。
-
前缀会导致make输出恼人的“错误忽略”输出,而我的解决方案不会这样做。因此,不,这两者做的事情不一样。这只在我的Windows build上用作| |:(管道冒号)。为什么这样的
2>&1
重定向帮助?我理解
2>/dev/null
将stderr发送到遗忘,但将其发送到stdout…..?@humanityANDpeace:你说得对-早在2010年的thinko。我已经修好了。谢谢