我需要在我的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上,只需使用:
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文件:
跳过.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 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/.. |
和一般规则:
没有要清理或制作的触摸文件。珍贵的:-)
如果你想看到另一个通用的gmake小技巧,或者如果你对使用最小脚手架的非递归make感兴趣,你可能会想在那个博客中找到两个更便宜的gmake技巧和另一个相关的make文章。