mkdir を使用するときにメイクファイルで「ディレクトリがすでに存在するエラー」を防ぐ方法
質問
メイクファイルにディレクトリを生成する必要がありますが、「ディレクトリはすでに存在します」というエラーが何度も表示されるのは避けたいのですが、それは簡単に無視できます。
私は主に mingw/msys を使用していますが、他のシェル/システムでも動作するものが欲しいと考えています。
これを試してみましたがうまくいきませんでした。何かアイデアはありますか?
ifeq (,$(findstring $(OBJDIR),$(wildcard $(OBJDIR) )))
-mkdir $(OBJDIR)
endif
解決
UNIX の場合は次のようにしてください。
mkdir -p $(OBJDIR)
mkdir に -p オプションを指定すると、ディレクトリが存在する場合にエラー メッセージが表示されなくなります。
他のヒント
見つめている 公式の 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
ドキュメントの例と比較してフラグが追加されました。別の選択肢については、他の回答を参照してください。
テストコマンドを使用できます。
test -d $(OBJDIR) || mkdir $(OBJDIR)
ここでは、コンパイラ出力ディレクトリを作成するために 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
メイクファイル内:
target:
if test -d dir; then echo "hello world!"; else mkdir dir; fi
Windows の場合
if not exist "$(OBJDIR)" mkdir $(OBJDIR)
unix | Linux
if [ ! -d "$(OBJDIR)" ]; then mkdir $(OBJDIR); fi
ifeq "$(wildcard $(MY_DIRNAME) )" ""
-mkdir $(MY_DIRNAME)
endif
$(OBJDIR):
mkdir $@
これは複数のディレクトリでも機能します。
OBJDIRS := $(sort $(dir $(OBJECTS)))
$(OBJDIRS):
mkdir $@
追加 $(OBJDIR)
最初のターゲットはうまく機能します。
mingw32/msys/cygwin/linux で動作します
ifeq "$(wildcard .dep)" ""
-include $(shell mkdir .dep) $(wildcard .dep/*)
endif
リターン コードを明示的に無視してエラー ストリームをダンプすると、make はエラーが発生してもそれを無視します。
mkdir 2>/dev/null || true
これにより、並列メイクで競合の危険が生じることはありませんが、確実にテストしたわけではありません。
ラースの答えよりも少し単純です。
something_needs_directory_xxx : xxx/..
そして一般的なルール:
%/.. : ;@mkdir -p $(@D)
タッチファイルをクリーンアップしたり、.PRECIOUS を作成したりする必要はありません :-)
別の少し一般的な gmake トリックを見たい場合、または最小限のスキャフォールディングを使用した非再帰的 make に興味がある場合は、以下をチェックしてみてください。 さらに 2 つの安価な gmake トリック およびそのブログ内の他の make 関連の投稿。