Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何预防;目录已存在错误";使用mkdir时在makefile中_Makefile_Directory_Exists - Fatal编程技术网

如何预防;目录已存在错误";使用mkdir时在makefile中

如何预防;目录已存在错误";使用mkdir时在makefile中,makefile,directory,exists,Makefile,Directory,Exists,我需要在我的makefile中生成一个目录,我不想一遍又一遍地得到“directory ready exists error”,即使我可以很容易地忽略它 我主要使用mingw/msys,但也希望其他shell/系统也能使用 我试过了,但没用,有什么想法吗 ifeq (,$(findstring $(OBJDIR),$(wildcard $(OBJDIR) ))) -mkdir $(OBJDIR) endif 如果目录已经存在对您来说不是问题,那么您可以为该命令重定向stderr,从而消除错误消

我需要在我的makefile中生成一个目录,我不想一遍又一遍地得到“directory ready exists error”,即使我可以很容易地忽略它

我主要使用mingw/msys,但也希望其他shell/系统也能使用

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

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

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

-mkdir $(OBJDIR) 2>/dev/null
在UNIX上,只需使用以下命令:

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

在makefile中:

target:
    if test -d dir; then echo "hello world!"; else mkdir dir; fi

您可以使用test命令:

test -d $(OBJDIR) || mkdir $(OBJDIR)
它也适用于多个目录,例如

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

$(OBJDIRS):
    mkdir $@
添加
$(OBJDIR)
作为第一个目标效果很好。

在Windows上

if not exist "$(OBJDIR)" mkdir $(OBJDIR)
在Unix | Linux上

if [ ! -d "$(OBJDIR)" ]; then mkdir $(OBJDIR); fi

下面是我使用GNUMake创建编译器输出目录的技巧。首先定义此规则:

  %/.d:
          mkdir -p $(@D)
          touch $@
然后使进入该目录的所有文件依赖于该目录中的.d文件:

 obj/%.o: %.c obj/.d
    $(CC) $(CFLAGS) -c -o $@ $<
跳过.d文件,并直接依赖于目录,将不起作用,因为每次在该目录中写入文件时,目录修改时间都会更新,这将在每次调用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:=OBJDIR
OBJS:=$(addprefix$(OBJDIR)/,foo.o bar.o baz.o)
$(OBJDIR)/%.o:%.c
$(COMPILE.c)$(输出选项)$<
全部:$(OBJS)
$(OBJS):|$(OBJDIR)
$(OBJDIR):
mkdir-p$(OBJDIR)
您应该在这里看到| pipe操作符的用法,它定义了一个仅限订单的先决条件。 这意味着为了构建当前目标,
$(OBJDIR)
目标应该存在(而不是最近的)

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

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

ifeq "$(wildcard .dep)" ""
-include $(shell mkdir .dep) $(wildcard .dep/*)
endif

比拉尔斯的回答简单一点:

something_needs_directory_xxx : xxx/..
和一般规则:

%/.. : ;@mkdir -p $(@D)
无需清理或制作触摸文件。珍贵:-)


如果你想看另一个通用的gmake小把戏,或者如果你对使用最小支架的非递归make感兴趣,你可能想在该博客中查看其他make相关文章。

如果你明确忽略返回代码并转储错误流,那么如果出现错误,make将忽略错误:

mkdir 2>/dev/null || true


这应该不会在并行模式中造成竞争危险-但我还没有测试它以确定。

这也有在Windows上工作的优点。别忘了命令前面的“-”,这样make就不会保释了。啊,谢谢,我正试着让这样的东西起作用。我不想在几个目标上使用“test-d foo | | mkdir foo”,因为使用“make-j2”会同时测试它们,两个测试都给出false,然后两个进程会尝试mkdir,最后一个失败。这肯定是解决这个问题的官方方法。@CraigMcQueen:我真正的意思是“应该存在
$(OBJDIR)
目标”。检查文件是否存在(以及时间戳),以确定是否需要构建目标。因此,在这里,如果
$(OBJDIR)
不存在,它将构建它,这样它就存在,以便构建将在内部创建的当前目标
$(OBJS)
(我正在尝试在windows/linux之间生成尽可能通用的makefiles)-这几乎是我唯一可以使用的makefiles,但它工作得很好!:)“一般来说,坚持广泛支持的(通常是posix指定的)这些程序的选项和功能。例如,不要使用“mkdir-p”,尽管它可能很方便,因为一些系统根本不支持它,与其他系统一起,并行执行是不安全的。“
-p
在Windows上不工作,这大概就是问题所在。不知道这是怎么被接受的。对于Windows,请投票:如果你在MinGW外壳之外使用GNU Make,你可能做错了什么。不过,这是您的选择。如果您需要makefiles在Windows(使用gnuwin32和PowerShell)和POSIX兼容操作系统中工作,这是首选的方法。前提是您有gnuwin32 CoreUtils包来提供“测试”实用程序。这里已经很晚了,但我想指出,在并行构建时,此解决方案可能会中断(
make-j
)由于测试目录是否存在与创建目录之间存在竞争条件。一个作业可以测试它是否不存在,但在创建它之前,另一个作业会创建目录。然后,当第一个尝试创建它时,它将失败,因为目录已经存在。在这种情况下,最好的解决方案是使用@TeKa的答案(应该是公认的答案)中提到的仅限订单的先决条件。@MarcusJ在我的OS X El Capitan上工作。哪个版本打破了它?@C0deH4cker-原谅我的无知。。。哪个答案是TeKa?我认为TeKa在你发表评论后更改了他的/她的名字。这对mingw的make很有效,不需要额外的工具。这一个适用于Windows。
/bin/sh:1:语法错误:文件结尾意外(应为“then”)
第一个版本适用于Windows,第二个选项适用于Linux,正如@checksum所说的,第一个是Windows,版本不是原子的,因此当另一个进程(例如,并行模式下的规则)在“不存在”和“mkdir”之间创建目录时,版本不起作用。
something_needs_directory_xxx : xxx/..
%/.. : ;@mkdir -p $(@D)
mkdir 2>/dev/null || true