我需要在我的makefile中生成一个目录,但我不想一遍又一遍地收到“目录已经存在”的错误提示,即使我可以轻松地忽略它。
我主要使用mingw/msys,但希望能够适用于其他shell/系统。
我尝试了这个方法,但没有成功,有什么其他建议吗?
ifeq (,$(findstring $(OBJDIR),$(wildcard $(OBJDIR) )))
-mkdir $(OBJDIR)
endif
查看官方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) 目标应该存在(而不是更近)才能构建当前目标。在UNIX中,只需使用以下命令:
mkdir -p $(OBJDIR)
如果目录已存在,mkdir命令的-p选项可以避免错误提示。
你可以使用测试命令:
test -d $(OBJDIR) || mkdir $(OBJDIR)
make -j
)时可能会出现问题,因为存在一个竞争条件,即当目录被测试是否存在和创建之间的时间差。一个作业可以测试它不存在,但在它创建之前,另一个作业创建了该目录。然后当第一个作业尝试创建它时,它将失败,因为该目录已经存在。在这种情况下,最好的解决方案是使用仅顺序先决条件,如@TeKa的答案中所提到的(应该是被接受的答案)。 - C0deH4cker这是我在使用GNU make创建编译输出目录时使用的一个技巧。首先定义以下规则:
%/.d:
mkdir -p $(@D)
touch $@
然后使所有进入该目录的文件都依赖于该目录中的 .d 文件:
obj/%.o: %.c obj/.d
$(CC) $(CFLAGS) -c -o $@ $<
注意使用 $< 而不是 $^。 .PRECIOUS: %/.d
跳过.d文件,直接依赖于目录将无法工作,因为每次在该目录中写入文件时,目录修改时间都会更新,这将导致每次调用make时强制重建。
-mkdir $(OBJDIR) 2>/dev/null
在您的 makefile 内:
target:
if test -d dir; then echo "hello world!"; else mkdir dir; fi
在Windows平台上
if not exist "$(OBJDIR)" mkdir $(OBJDIR)
在Unix | Linux上
if [ ! -d "$(OBJDIR)" ]; then mkdir $(OBJDIR); fi
/bin/sh: 1: Syntax error: end of file unexpected (expecting "then")
- wotaniiifeq "$(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
$(OBJDIR)
目标应该是存在的”。检查文件是否存在(和时间戳)以决定是否需要构建目标。因此,在这里,如果$(OBJDIR)
不存在,它将构建它,以便在内部创建当前目标$(OBJS)
之前,它是存在的。 - ofavre