开发者

Suppress make rule error output

开发者 https://www.devze.com 2023-01-11 23:32 出处:网络
I have an rule that creates a directory bin: -mkdir $@ However after the first time the directory has been genera开发者_开发技巧ted, I receive this output:

I have an rule that creates a directory

bin:
    -mkdir $@

However after the first time the directory has been genera开发者_开发技巧ted, I receive this output:

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

Is there some way I can only run the rule if the directory doesn't exist, or suppress the output when the directory already exists?


Another way to suppress the make: error ... (ignored) output is to append || true to a command that could fail. Example with grep that checks for errors in a LaTeX log file:

undefined:
  @grep -i undefined *.log || true

Without the || true, make complains when grep fails to find any matches.

This works for all commands, not just mkdir; that's why I added this answer.


The error is ignored already by the leading '-' on the command line. If you really want to lose the error messages from mkdir, use I/O redirection:

bin:
    -mkdir bin 2> /dev/null

You will still get the 'ignored' warning from make, though, so it might be better to use the option to mkdir that doesn't cause it to fail when the target already exists, which is the -p option:

MKDIR_P = mkdir -p

bin:
    ${MKDIR_P} $@

The -p option actually creates all the directories that are missing on the given paths, so it can generate a a number of directories in one invocation, but a side-effect is that it does not generate an error for already existing directories. This does assume a POSIX-ish implementation of mkdir; older machines may not support it (though it has been standard for a long time now).


The traditional way to handle directory creation is to use a stamp file that is depended on and creates the dir as a side effect. Remove the stamp file when making distclean or whatever your "really clean" target is:

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

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

distclean:
    rm -rf bin

The reason for this is as follows: whenever a file in bin is created/removed, the mtime of the containing directory is updated. If a target depends on bin, then the next time make runs, it will then recreate files that it doesn't need to.


Well I ended up with this construct, maybe someone will find it useful or can comment on it:

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


You rule should not be executed unless its target does not exists or is out of date because of its dependencies. In other words, you should never encounter this error.

[Example Added]

[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'.

Does your folder depend on anything? Is your folder a phony target?


Make assumes the first target is the default target. If that is your complete makefile, then it must be always trying to remake the default target, which is bin. Insert the following lines to the top of your makefile:

all: bin
.PHONY: all
0

精彩评论

暂无评论...
验证码 换一张
取 消