如何在使用mkdir時防止makefile中的“目錄已存在錯誤”


Answers

官方的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)目標應該存在(而不是更新 )以構建當前目標。

請注意,我使用mkdir -p 。 與文檔示例相比,添加了-p標誌。 查看其他答案的另一種選擇。

Question

我需要在我的生成文件中生成一個目錄,並且我希望不會一遍又一遍地得到“目錄已存在的錯誤”,即使我可以輕鬆忽略它。

我主要使用mingw / msys,但希望能夠在其他shell /系統上運行。

我嘗試過,但它沒有工作,有什麼想法?

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



比拉斯的回答簡單一點:

something_needs_directory_xxx : xxx/..

和通用規則:

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

沒有觸摸文件來清理或製作.PRECIOUS :-)

如果你想看到另一個小的通用gmake技巧,或者如果你對最小腳手架的非遞歸製作感興趣,你可能會考慮在該博客中查看兩個更便宜的gmake技巧和其他與製作相關的帖子。




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

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



這是我用GNU make創建編譯器輸出目錄的一個技巧。 首先定義這個規則:

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

然後使所有進入該目錄的文件都依賴於該目錄中的.d文件:

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

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

最後,防止自動刪除.d文件:

 .PRECIOUS: %/.d

跳過.d文件,直接取決於目錄,將不起作用,因為每次將文件寫入該目錄時都會更新目錄修改時間,這會在每次調用make時強制進行重建。




如果擁有目錄已經存在對您來說不是問題,那麼您可以重定向該命令的stderr,從而擺脫錯誤消息:

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



ifeq "$(wildcard $(MY_DIRNAME) )" ""
  -mkdir $(MY_DIRNAME)
endif