如何在使用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。