117

メイクファイルでディレクトリを生成する必要があり、簡単に無視できるにもかかわらず、「ディレクトリが既に存在するというエラー」が何度も発生しないようにしたいと考えています。

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

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

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

12 に答える 12

125

公式の make documentationを見ると、これを行う良い方法があります。

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)ターゲットが存在する必要があることを意味します ( more recentではなく)。

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

于 2011-05-29T20:36:55.020 に答える
118

UNIXでは、これを使用してください:

mkdir -p $(OBJDIR)

-p オプションを mkdir に指定すると、ディレクトリが存在する場合にエラー メッセージが表示されなくなります。

于 2008-09-19T03:07:29.313 に答える
69

次のテスト コマンドを使用できます。

test -d $(OBJDIR) || mkdir $(OBJDIR)
于 2008-09-19T03:09:34.283 に答える
18

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

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

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

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

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

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

 .PRECIOUS: %/.d

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

于 2010-09-18T00:06:42.547 に答える
13

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

-mkdir $(OBJDIR) 2>/dev/null
于 2008-09-19T03:04:36.760 に答える
11

メイクファイル内:

target:
    if test -d dir; then echo "hello world!"; else mkdir dir; fi
于 2008-09-19T03:07:36.113 に答える
10

Windows の場合

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

Unix の場合 | Linux

if [ ! -d "$(OBJDIR)" ]; then mkdir $(OBJDIR); fi
于 2010-07-21T14:39:17.373 に答える
7
ifeq "$(wildcard $(MY_DIRNAME) )" ""
  -mkdir $(MY_DIRNAME)
endif
于 2008-10-06T19:15:38.743 に答える
6
$(OBJDIR):
    mkdir $@

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

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

$(OBJDIRS):
    mkdir $@

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

于 2009-02-04T14:47:37.777 に答える
3

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

ifeq "$(wildcard .dep)" ""
-include $(shell mkdir .dep) $(wildcard .dep/*)
endif
于 2012-04-11T06:19:33.643 に答える
0

Larsの答えより少し簡単です:

something_needs_directory_xxx : xxx/..

および一般的なルール:

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

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

別のちょっとした一般的な gmake トリックを見たい場合、または最小限の足場で非再帰的な make に興味がある場合は、そのブログの2 つの安価な gmake トリックと他の make 関連の投稿をチェックしてみてください。

于 2013-06-30T00:00:04.010 に答える
0

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

mkdir 2>/dev/null || true

これにより、並列の make で競合が発生することはありませんが、確認するためにテストしていません。

于 2015-09-10T07:12:13.007 に答える