回答:
UNIXの場合これを使用するだけです。
mkdir -p $(OBJDIR)
mkdirの-pオプションは、ディレクトリが存在する場合のエラーメッセージを防ぎます。
-p
Windowsでは動作しません。これはおそらく質問が尋ねていることです。これがどのように受け入れられたのかはわかりません。
make -p
UnixとLinuxのどちらですか?
公式の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
フラグは、ドキュメントの例と比較して加えました。別の選択肢については、他の回答を参照してください。
$(OBJDIR)
ターゲットがあるべき存在」。ファイルの存在(およびタイムスタンプ)をチェックして、ターゲットを構築する必要があるかどうかを判断します。したがって、ここで$(OBJDIR)
は、存在しない場合は構築され、現在のターゲットを構築するために存在し$(OBJS)
ます。これは内部に作成されます。
testコマンドを使用できます。
test -d $(OBJDIR) || mkdir $(OBJDIR)
make -j
、ディレクトリの存在がテストされてから作成されるまでの競合状態により、このソリューションが並列でビルドするときに失敗する可能性があることを指摘しておきます()。あるジョブはそこにないことをテストできますが、作成する前に別のジョブがディレクトリを作成します。その後、最初に作成しようとすると、ディレクトリがすでに存在するため失敗します。この場合の最良の解決策は、@ TeKaの回答(これは受け入れられた回答であるべきです)で述べられているように、順序のみの前提条件を使用することです。
以下は、コンパイラの出力ディレクトリを作成するために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
Windowsの場合
if not exist "$(OBJDIR)" mkdir $(OBJDIR)
Unixの場合| Linux
if [ ! -d "$(OBJDIR)" ]; then mkdir $(OBJDIR); fi
/bin/sh: 1: Syntax error: end of file unexpected (expecting "then")
ifeq "$(wildcard $(MY_DIRNAME) )" ""
-mkdir $(MY_DIRNAME)
endif
ラースの答えよりも少し簡単です:
something_needs_directory_xxx : xxx/..
そして一般的なルール:
%/.. : ;@mkdir -p $(@D)
クリーンアップまたは.PRECIOUSを作成するタッチファイルはありません:-)
別の小さな一般的なgmakeトリックを見たい場合、または最小限のスキャフォールディングで再帰的でないmakeに興味がある場合は、そのブログの2つのさらに安価なgmakeトリックと他のmake関連の投稿をチェックしてみてください。