代码之家  ›  专栏  ›  技术社区  ›  KPexEA

使用mkdir时如何防止生成文件中出现“目录已存在错误”

  •  122
  • KPexEA  · 技术社区  · 17 年前

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

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

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

    ifeq (,$(findstring $(OBJDIR),$(wildcard $(OBJDIR) )))
    -mkdir $(OBJDIR)
    endif
    
    12 回复  |  直到 11 年前
        1
  •  100
  •   Community Mohan Dere    9 年前

    在UNIX上,只需使用以下命令:

    mkdir -p $(OBJDIR)
    

    如果目录存在,mkdir的-p选项会阻止错误消息。

        2
  •  116
  •   13rac1    9 年前

    the official make documentation ,这里有一个很好的方法:

    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) 目标应该存在(而不是 最近的 )以建立当前目标。

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

        3
  •  66
  •   Matthew Simoneau Pär Wieslander    13 年前

    您可以使用test命令:

    test -d $(OBJDIR) || mkdir $(OBJDIR)
    
        4
  •  18
  •   Matthew Simoneau Pär Wieslander    13 年前

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

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

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

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

    注意$<而不是$^。

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

     .PRECIOUS: %/.d
    

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

        5
  •  13
  •   andrewdotnich Matt    17 年前

    如果目录已经存在对你来说不是问题,你可以重定向该命令的stderr,去掉错误消息:

    -mkdir $(OBJDIR) 2>/dev/null
    
        6
  •  11
  •   Lee H    17 年前

    在您的makefile中:

    target:
        if test -d dir; then echo "hello world!"; else mkdir dir; fi
    
        7
  •  9
  •   Edgard Leal Noah    8 年前

    在Windows上

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

    Unix | Linux

    if [ ! -d "$(OBJDIR)" ]; then mkdir $(OBJDIR); fi
    
        8
  •  7
  •   Michael McCarty    17 年前
    ifeq "$(wildcard $(MY_DIRNAME) )" ""
      -mkdir $(MY_DIRNAME)
    endif
    
        9
  •  6
  •   Martin Fido    16 年前
    $(OBJDIR):
        mkdir $@
    

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

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

    加法 $(OBJDIR) 因为第一个目标工作良好。

        10
  •  3
  •   kleopatra Aji kattacherry    13 年前

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

    ifeq "$(wildcard .dep)" ""
    -include $(shell mkdir .dep) $(wildcard .dep/*)
    endif
    
        11
  •  0
  •   Andrew    10 年前

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

    mkdir 2>/dev/null || true
    

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

        12
  •  0
  •   kenorb    10 年前

    比Lars的回答简单一点:

    something_needs_directory_xxx : xxx/..
    

    通用规则:

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

    无需清理或制作触摸文件。珍贵:-)

    如果你想看到另一个通用的gmake技巧,或者如果你对使用最小脚手架的非递归make感兴趣,你可能会想看看 Two more cheap gmake tricks 另一个在那个博客上发布相关帖子。