使用mkdir时如何防止makefile中的“目录已存在错误”

使用mkdir时如何防止makefile中的“目录已存在错误”

how to prevent “directory already exists error” in a makefile when using mkdir

我需要在我的makefile中生成一个目录,我不想一次又一次地得到"目录已经存在错误",即使我可以很容易地忽略它。

我主要使用mingw/msys,但也希望在其他shell/系统中工作。

我试过了,但没用,有什么想法吗?

1
2
3
ifeq (,$(findstring $(OBJDIR),$(wildcard $(OBJDIR) )))
-mkdir $(OBJDIR)
endif

查看官方制作文档,以下是一个很好的方法:

1
2
3
4
5
6
7
8
9
10
11
12
OBJDIR := objdir
OBJS := $(addprefix $(OBJDIR)/,foo.o bar.o baz.o)

$(OBJDIR)/%.o : %.c
    $(COMPILE.c) $(OUTPUT_OPTION) $<

all: $(OBJS)

$(OBJS): | $(OBJDIR)

$(OBJDIR):
    mkdir -p $(OBJDIR)

您应该在这里看到管道操作符的用法,它定义了仅限订单的先决条件。也就是说,为了构建当前的目标,应该存在(而不是最近的)$(OBJDIR)目标。

注意我用了mkdir -p。与文档示例相比,添加了-p标志。另一种选择见其他答案。


在Unix上,只需使用:

1
mkdir -p $(OBJDIR)

mkdir的-p选项可防止目录存在时出现错误消息。


您可以使用test命令:

1
test -d $(OBJDIR) || mkdir $(OBJDIR)

下面是我使用GNU make创建编译器输出目录的一个技巧。首先定义此规则:

1
2
3
  %/.d:
          mkdir -p $(@D)
          touch $@

然后使进入目录的所有文件依赖于该目录中的.d文件:

1
2
 obj/%.o: %.c obj/.d
    $(CC) $(CFLAGS) -c -o $@ $<

注意使用$<而不是$^。

最后,防止自动删除.d文件:

1
 .PRECIOUS: %/.d

跳过.d文件(直接取决于目录)将不起作用,因为每次在该目录中写入文件时都会更新目录修改时间,这将在每次调用make时强制重新生成。


如果目录已经存在对您来说不是问题,您可以为该命令重定向stderr,从而消除错误消息:

1
-mkdir $(OBJDIR) 2>/dev/null

在makefile中:

1
2
target:
    if test -d dir; then echo"hello world!"; else mkdir dir; fi


在Windows上

1
if not exist"$(OBJDIR)" mkdir $(OBJDIR)

关于UNIX Linux

1
if [ ! -d"$(OBJDIR)" ]; then mkdir $(OBJDIR); fi

1
2
3
ifeq"$(wildcard $(MY_DIRNAME) )"""
  -mkdir $(MY_DIRNAME)
endif

1
2
$(OBJDIR):
    mkdir $@

它也适用于多个目录,例如

1
2
3
4
OBJDIRS := $(sort $(dir $(OBJECTS)))

$(OBJDIRS):
    mkdir $@

添加$(OBJDIR)作为第一个目标效果良好。


它在mingw32/msys/cygwin/linux下工作

1
2
3
ifeq"$(wildcard .dep)"""
-include $(shell mkdir .dep) $(wildcard .dep/*)
endif

如果您显式地忽略返回代码并转储错误流,那么如果发生错误,您的make将忽略该错误:

1
mkdir 2>/dev/null || true

这不应该造成一个平行的种族危险-但我还没有测试它确定。


比拉尔斯的回答简单一点:

1
something_needs_directory_xxx : xxx/..

和一般规则:

1
%/.. : ;@mkdir -p $(@D)

没有要清理或制作的触摸文件。珍贵的:-)

如果你想看到另一个通用的gmake小技巧,或者如果你对使用最小脚手架的非递归make感兴趣,你可能会想在那个博客中找到两个更便宜的gmake技巧和另一个相关的make文章。


推荐阅读