web-dev-qa-db-ja.com

mkdirを使用するときに、メイクファイルで「ディレクトリが既に存在するエラー」を防ぐ方法

メイクファイルにディレクトリを生成する必要があり、「ディレクトリがすでに存在するエラー」を簡単に無視できますが、繰り返し発生しないようにします。

私は主にmingw/msysを使用していますが、他のシェル/システムでも機能するものが欲しいです。

私はこれを試しましたが、うまくいきませんでした、アイデアはありますか?

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

UNIXの場合は、これを使用します。

mkdir -p $(OBJDIR)

Mkdirの-pオプションは、ディレクトリが存在する場合のエラーメッセージを防ぎます。

104
tchen

公式の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)
_

ここでの使用法が表示されます|パイプ演算子、順序のみの前提条件を定義します。現在のターゲットをビルドするために、(moreの代わりに)$(OBJDIR)ターゲットが存在する必要があることを意味します。

_mkdir -p_を使用したことに注意してください。ドキュメントの例と比較して、_-p_フラグが追加されました。別の選択肢については、他の回答をご覧ください。

119
ofavre

Testコマンドを使用できます。

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

以下は、コンパイラ出力ディレクトリを作成するためにGNU makeで使用するトリックです。最初にこのルールを定義します。

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

次に、そのディレクトリにあるすべてのファイルを、そのディレクトリの.dファイルに依存するようにします。

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

$ ^の代わりに$ <を使用していることに注意してください。

最後に、.dファイルが自動的に削除されないようにします。

 .PRECIOUS: %/.d

.dファイルをスキップし、ディレクトリに直接依存する場合は機能しません。ファイルがそのディレクトリに書き込まれるたびにディレクトリ変更時間が更新され、makeの呼び出しごとに強制的に再構築されるためです。

18
Lars Hamrén

ディレクトリがすでに存在していても問題ない場合は、そのコマンドのstderrをリダイレクトして、エラーメッセージを削除できます。

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

メイクファイル内:

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

Windows

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

Unixで| Linux

if [ ! -d "$(OBJDIR)" ]; then mkdir $(OBJDIR); fi
9
wmad
ifeq "$(wildcard $(MY_DIRNAME) )" ""
  -mkdir $(MY_DIRNAME)
endif
7
Michael McCarty
_$(OBJDIR):
    mkdir $@
_

これは、複数のディレクトリでも機能します。

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

$(OBJDIRS):
    mkdir $@
_

最初のターゲットとして$(OBJDIR)を追加するとうまく機能します。

6
Martin Fido

Mingw32/msys/cygwin/linuxで動作します

ifeq "$(wildcard .dep)" ""
-include $(Shell mkdir .dep) $(wildcard .dep/*)
endif
3
lygstate

リターンコードを明示的に無視してエラーストリームをダンプした場合、makeはエラーが発生しても無視します。

mkdir 2>/dev/null || true

これは並列makeで競合の危険を引き起こすべきではありません-しかし、私はそれを確認するためにテストしていません。

0
Andrew

ラースの答えよりも少し簡単です:

something_needs_directory_xxx : xxx/..

および一般的な規則:

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

クリーンアップまたは.PRECIOUSを作成するためのタッチファイルはありません:-)

別の小さな汎用gmakeトリックを見たい場合、または最小限の足場で非再帰的なmakeに興味がある場合は、 2つのより安価なgmakeトリック およびその他のmake関連のそのブログの投稿。

0
Mischa