如何防止“目录已存在错误” 使用 mkdir 时在 makefile 中

发布于 2024-07-05 10:45:59 字数 247 浏览 6 评论 0原文

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

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

我尝试过,但没有成功,有什么想法吗?

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

I need to generate a directory in my makefile and I would like to not get the "directory already exists error" over and over even though I can easily ignore it.

I mainly use mingw/msys but would like something that works across other shells/systems too.

I tried this but it didn't work, any ideas?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

白芷 2024-07-12 10:45:59

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

OBJDIR := objdir
OBJS := $(addprefix $(OBJDIR)/,foo.o bar.o baz.o)

$(OBJDIR)/%.o : %.c
    $(COMPILE.c) $(OUTPUT_OPTION) 
lt;

all: $(OBJS)

$(OBJS): | $(OBJDIR)

$(OBJDIR):
    mkdir -p $(OBJDIR)

您应该在这里看到 | 的用法 管道运算符,仅定义订单先决条件。
这意味着 $(OBJDIR) 目标应该存在(而不是更新)才能构建当前目标。

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

Looking at the official make documentation, here is a good way to do it:

OBJDIR := objdir
OBJS := $(addprefix $(OBJDIR)/,foo.o bar.o baz.o)

$(OBJDIR)/%.o : %.c
    $(COMPILE.c) $(OUTPUT_OPTION) 
lt;

all: $(OBJS)

$(OBJS): | $(OBJDIR)

$(OBJDIR):
    mkdir -p $(OBJDIR)

You should see here the usage of the | pipe operator, defining an order only prerequisite.
Meaning that the $(OBJDIR) target should be existent (instead of more recent) in order to build the current target.

Note that I used mkdir -p. The -p flag was added compared to the example of the docs.
See other answers for another alternative.

只有一腔孤勇 2024-07-12 10:45:59

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

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

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

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

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

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

 .PRECIOUS: %/.d

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

Here is a trick I use with GNU make for creating compiler-output directories. First define this rule:

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

Then make all files that go into the directory dependent on the .d file in that directory:

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

Note use of $< instead of $^.

Finally prevent the .d files from being removed automatically:

 .PRECIOUS: %/.d

Skipping the .d file, and depending directly on the directory, will not work, as the directory modification time is updated every time a file is written in that directory, which would force rebuild at every invocation of make.

美人骨 2024-07-12 10:45:59

您可以使用测试命令:

test -d $(OBJDIR) || mkdir $(OBJDIR)

You can use the test command:

test -d $(OBJDIR) || mkdir $(OBJDIR)
千と千尋 2024-07-12 10:45:59

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

mkdir -p $(OBJDIR)

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

On UNIX Just use this:

mkdir -p $(OBJDIR)

The -p option to mkdir prevents the error message if the directory exists.

花开雨落又逢春i 2024-07-12 10:45:59
$(OBJDIR):
    mkdir $@

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

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

$(OBJDIRS):
    mkdir $@

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

$(OBJDIR):
    mkdir $@

Which also works for multiple directories, e.g..

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

$(OBJDIRS):
    mkdir $@

Adding $(OBJDIR) as the first target works well.

久隐师 2024-07-12 10:45:59
ifeq "$(wildcard $(MY_DIRNAME) )" ""
  -mkdir $(MY_DIRNAME)
endif
ifeq "$(wildcard $(MY_DIRNAME) )" ""
  -mkdir $(MY_DIRNAME)
endif
情何以堪。 2024-07-12 10:45:59

在 Windows 上

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

在 Unix 上 | Linux

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

On Windows

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

On Unix | Linux

if [ ! -d "$(OBJDIR)" ]; then mkdir $(OBJDIR); fi
念三年u 2024-07-12 10:45:59

在你的 makefile 中:

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

Inside your makefile:

target:
    if test -d dir; then echo "hello world!"; else mkdir dir; fi
趁年轻赶紧闹 2024-07-12 10:45:59

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

-mkdir $(OBJDIR) 2>/dev/null

If having the directory already exist is not a problem for you, you could just redirect stderr for that command, getting rid of the error message:

-mkdir $(OBJDIR) 2>/dev/null
素食主义者 2024-07-12 10:45:59

比 Lars 的答案简单一点:

something_needs_directory_xxx : xxx/..

通用规则:

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

没有需要清理或制作的触摸文件。PRECIOUS :-)

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

A little simpler than Lars' answer:

something_needs_directory_xxx : xxx/..

and generic rule:

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

No touch-files to clean up or make .PRECIOUS :-)

If you want to see another little generic gmake trick, or if you're interested in non-recursive make with minimal scaffolding, you might care to check out Two more cheap gmake tricks and the other make-related posts in that blog.

软糖 2024-07-12 10:45:59

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

mkdir 2>/dev/null || true

这不应导致并行 make 中的竞争危险 - 但我还没有测试它来确定。

If you explicitly ignore the return code and dump the error stream then your make will ignore the error if it occurs:

mkdir 2>/dev/null || true

This should not cause a race hazard in a parallel make - but I haven't tested it to be sure.

傾旎 2024-07-12 10:45:59

它运行在 mingw32/msys/cygwin/linux 下

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

It works under mingw32/msys/cygwin/linux

ifeq "$(wildcard .dep)" ""
-include $(shell mkdir .dep) $(wildcard .dep/*)
endif
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文