117

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

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

我试过这个,但它没有用,有什么想法吗?

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

12 回答 12

125

查看官方 make 文档,这是一个很好的方法:

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与文档示例相比,添加了该标志。请参阅其他答案以获取另一种选择。

于 2011-05-29T20:36:55.020 回答
118

在 UNIX 上只需使用这个:

mkdir -p $(OBJDIR)

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

于 2008-09-19T03:07:29.313 回答
69

您可以使用测试命令:

test -d $(OBJDIR) || mkdir $(OBJDIR)
于 2008-09-19T03:09:34.283 回答
18

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

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

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

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

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

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

 .PRECIOUS: %/.d

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

于 2010-09-18T00:06:42.547 回答
13

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

-mkdir $(OBJDIR) 2>/dev/null
于 2008-09-19T03:04:36.760 回答
11

在你的makefile里面:

target:
    if test -d dir; then echo "hello world!"; else mkdir dir; fi
于 2008-09-19T03:07:36.113 回答
10

在 Windows 上

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

在 Unix 上 | Linux

if [ ! -d "$(OBJDIR)" ]; then mkdir $(OBJDIR); fi
于 2010-07-21T14:39:17.373 回答
7
ifeq "$(wildcard $(MY_DIRNAME) )" ""
  -mkdir $(MY_DIRNAME)
endif
于 2008-10-06T19:15:38.743 回答
6
$(OBJDIR):
    mkdir $@

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

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

$(OBJDIRS):
    mkdir $@

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

于 2009-02-04T14:47:37.777 回答
3

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

ifeq "$(wildcard .dep)" ""
-include $(shell mkdir .dep) $(wildcard .dep/*)
endif
于 2012-04-11T06:19:33.643 回答
0

比拉斯的回答简单一点:

something_needs_directory_xxx : xxx/..

和一般规则:

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

无需清理或制作 .PRECIOUS 的触摸文件 :-)

如果您想查看另一个通用的小 gmake 技巧,或者如果您对具有最少脚手架的非递归 make 感兴趣,您可能需要查看该博客中的两个更便宜的 gmake 技巧和其他与 make 相关的帖子。

于 2013-06-30T00:00:04.010 回答
0

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

mkdir 2>/dev/null || true

这不应该在平行制造中造成种族危险——但我还没有测试过它来确定。

于 2015-09-10T07:12:13.007 回答