我需要在 makefile 中生成一个目录,并且我不希望一遍又一遍地出现“目录已经存在错误”,即使我可以很容易地忽略它。
I mainly use mingw/msys but would like something that works across other shells/systems too.
我试过了,但没用,有什么办法吗?
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)
ifeq "$(wildcard $(MY_DIRNAME) )" "" -mkdir $(MY_DIRNAME) endif
$(OBJDIR): mkdir $@
它也适用于多个目录,例如。
OBJDIRS := $(sort $(dir $(OBJECTS))) $(OBJDIRS): mkdir $@
添加 $(OBJDIR)作为第一个目标工作得很好。
$(OBJDIR)
On Windows
if not exist "$(OBJDIR)" mkdir $(OBJDIR)
On Unix | Linux
if [ ! -d "$(OBJDIR)" ]; then mkdir $(OBJDIR); fi
下面是我在使用 GNU 创建编译器输出目录时使用的一个技巧:
%/.d: mkdir -p $(@D) touch $@
然后使所有进入该目录的文件依赖于该目录中的. d 文件:
obj/%.o: %.c obj/.d $(CC) $(CFLAGS) -c -o $@ $<
注意使用 $< 代替 $^ 。
最后防止.d 文件被自动删除:
.PRECIOUS: %/.d
跳过。D 文件,并且直接取决于目录,将无法工作,因为每次在该目录中写入文件时,目录修改时间都会更新,这将强制在每次调用 make 时重新构建。
Looking at 官方制作文件, 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) $< all: $(OBJS) $(OBJS): | $(OBJDIR) $(OBJDIR): mkdir -p $(OBJDIR)
You should see here the usage of the | pipe operator, defining an order only prerequisite. 这意味着为了构建当前目标,应该存在 $(OBJDIR)目标(而不是 more recent)。
注意,我使用了 mkdir -p。与文档的示例相比,添加了 -p标志。 查看其他答案,寻找另一种选择。
mkdir -p
-p
It works under 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
这应该不会在并行制作中引起竞争危险-但我还没有测试它来确定。