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

我需要在我的生成文件中生成一个目录,我想不会得到“目录已经存在的错误”一遍又一遍,即使我可以很容易地忽略它。

我主要使用mingw / msys,但也希望能够在其他shell /系统上运行。

我试过这个,但它没有工作,有什么想法?

ifeq (,$(findstring $(OBJDIR),$(wildcard $(OBJDIR) ))) -mkdir $(OBJDIR) endif 

在UNIX上使用这个:

 mkdir -p $(OBJDIR) 

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

看官方的文档 ,这是一个很好的方法来做到这一点:

 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) 

你应该在这里看到|的使用 pipe道操作员,定义订单只有先决条件。 这意味着$(OBJDIR)目标应该存在(而不是更新 ),以build立当前的目标。

请注意,我使用mkdir -p 。 与文档示例相比,添加了-p标志。 查看另一个select的其他答案。

你可以使用testing命令:

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

这是我用GNU make创build编译器输出目录的一个技巧。 首先定义这个规则:

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

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

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

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

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

  .PRECIOUS: %/.d 

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

在你的makefile里面:

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

如果目录已经存在对您来说不是问题,那么您可以redirect该命令的stderr,摆脱错误信息:

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

在Windows上

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

在Unix上 Linux的

 if [ ! -d "$(OBJDIR)" ]; then mkdir $(OBJDIR); fi 
 ifeq "$(wildcard $(MY_DIRNAME) )" "" -mkdir $(MY_DIRNAME) endif 
 $(OBJDIR): mkdir $@ 

这也适用于多个目录,例如。

 OBJDIRS := $(sort $(dir $(OBJECTS))) $(OBJDIRS): mkdir $@ 

添加$(OBJDIR)作为第一个目标很好。

它在mingw32 / msys / cygwin / linux下运行

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

如果你明确地忽略了返回码并转储错误stream,那么你的make将会忽略错误,如果它发生的话:

 mkdir 2>/dev/null || true 

这不应该造成一个平行的比赛风险 – 但我没有testing它是肯定的。

比拉斯的答案简单一点:

 something_needs_directory_xxx : xxx/.. 

和通用规则:

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

没有触摸文件清理或制作.PRECIOUS 🙂

如果你想看到另一个小的通用gmake技巧,或者如果你感兴趣的是用最less的脚手架进行非recursion构build,你可能会考虑在这个博客中看看两个更便宜的gmake技巧和其他与make相关的post。