彼の answer @Grundlefleckでは、ディレクトリが存在するかどうかを確認する方法を説明しています。私は次のようにmakefile
内でこれを使用しようとしました:
foo.bak: foo.bar
echo "foo"
if [ -d "~/Dropbox" ]; then
echo "Dir exists"
fi
ランニング make foo.bak
(とすれば foo.bar
が存在する場合)次のエラーが発生します。
echo "foo"
foo
if [ -d "~/Dropbox" ]; then
/bin/sh: -c: line 1: syntax error: unexpected end of file
make: *** [foo.bak] Error 2
回避策は、テストが実装されているスタンドアロンのbashスクリプトを使用して、makefile
からスクリプトを呼び出すことでした。ただし、これは非常に面倒です。 makefile
内からディレクトリが存在するかどうかを確認するより良い方法はありますか?
シェルコマンドの場合、コマンドを1行にするか、ライン拡張にバックスラッシュを使用して複数行にする必要があります。したがって、このアプローチは機能します。
foo.bak: foo.bar
echo "foo"
if [ -d "~/Dropbox" ]; then echo "Dir exists"; fi
または
foo.bak: foo.bar
echo "foo"
if [ -d "~/Dropbox" ]; then \
echo "Dir exists"; \
fi
このアプローチは、最小限のエコーで機能します。
.PHONY: all
all:
ifneq ($(wildcard ~/Dropbox/.*),)
@echo "Found ~/Dropbox."
else
@echo "Did not find ~/Dropbox."
endif
ディレクトリの不在に基づいて行動する
ディレクトリが存在しないかどうかだけを知る必要があり、ディレクトリを作成するなどしてそのディレクトリに基づいて動作する場合は、通常のMakefileターゲットを使用できます。
directory = ~/Dropbox
all: | $(directory)
@echo "Continuation regardless of existence of ~/Dropbox"
$(directory):
@echo "Folder $(directory) does not exist"
mkdir -p $@
.PHONY: all
備考:
|
は、makeがタイムスタンプを気にしないことを示します( order-only-prerequisite です)。mkdir -p $@
と書く代わりに、false
と書いて終了するか、別の方法でケースを解決できます。また、ディレクトリのexistenceに対して特定の一連の命令を実行する必要がある場合は、上記を使用できません。つまり、次と同等です。
if [ ! -d "~/Dropbox" ]; then
echo "The ~/Dropbox folder does not exist"
fi
else
ステートメントはありません。
ディレクトリの存在に基づいて行動する
逆のif文が必要な場合は、これも可能です。
directory = $(wildcard ~/Dropbox)
all: | $(directory)
@echo "Continuation regardless of existence of ~/Dropbox"
$(directory):
@echo "Folder $(directory) exists"
.PHONY: all $(directory)
これは次と同等です:
if [ -d "~/Dropbox" ]; then
echo "The ~/Dropbox folder does exist"
fi
繰り返しますが、else
ステートメントはありません。
ディレクトリの有無に応じて行動する
これはもう少し面倒になりますが、最終的には両方の場合に素晴らしいターゲットを提供します:
directory = ~/Dropbox
dir_target = $(directory)-$(wildcard $(directory))
dir_present = $(directory)-$(directory)
dir_absent = $(directory)-
all: | $(dir_target)
@echo "Continuation regardless of existence of ~/Dropbox"
$(dir_present):
@echo "Folder $(directory) exists"
$(dir_absent):
@echo "Folder $(directory) does not exist"
.PHONY: all
これは次と同等です:
if [ -d "~/Dropbox" ]; then
echo "The ~/Dropbox folder does exist"
else
echo "The ~/Dropbox folder does not exist"
fi
当然、ワイルドカードの展開はif-else-statementよりも遅い場合があります。ただし、3番目のケースはおそらく非常にまれであり、完全性のために追加されただけです。
これを試して:
.PHONY: all
something:
echo "hi"
all:
test -d "Documents" && something
これは、something
が存在する場合にのみ、Documents
の下のコマンドを実行します。
コメントに記載されている 問題 に対処するには、次のような変数を作成します。
PATH_TEST = ~/SomeDirectory
test -d $(PATH_TEST) && something
Makefile
上記のアプローチが機能しない場合。 here このように使用できる素敵なソリューションを見つけました:
MY_DIRNAME=../External
ifneq "$(wildcard $(MY_DIRNAME) )" ""
# if directory MY_DIRNAME exists:
INCLUDES += -I../External
else
# if it doesn't:
INCLUDES += -I$(HOME)/Code/External
endif
これは、MY_DIRNAME
に保存されているディレクトリが存在するかどうかに基づいて、変数INCLUDES
を変更します。
(動機:私の場合、この変数は後で最初に含まれる別のMakefile
で使用されます:
include $(SFRAME_DIR)/Makefile.common
2つの異なる環境で同じMakefile
を簡単な方法で動作させたかったのです。)
1つのシェルでif
ステートメントを想定したとおりに使用できるようにする非常に異なる回答があります。
.ONESHELL:
foo.bak: foo.bar
echo "foo"
if [ -d "~/Dropbox" ]; then
echo "Dir exists"
fi
唯一の違いはONESHELL 特別なターゲット であることに注意してください。