1.Makefile条件付き判定機能
条件文は、make
実行される変数の値に応じて、またはMakefile
特定の部分を無視して制御できます。条件文は、2つの異なる変数または定数と変数の間の比較です。
以下は、条件の判断に使用されるいくつかのキーワードです。
キーワード | 特徴 |
---|---|
ifeq | パラメータが等しくないか、trueに等しいか、falseに等しくないかを判断します |
ifneq | パラメータが等しくないか、等しくないかが真であるか、等しいかが偽であるかを判別します |
ifdef | 値があるかどうか、trueの値があるかどうか、falseの値はないかどうかを判断します |
ifndef | 値があるかどうか、値が真でないかどうか、値が偽かどうかを判断します |
2.ifeqおよびifneq
条件付き判断の使用法は次のとおりです。
ifeq (first, second)
ifeq 'first' 'second'
ifeq `first` `second`
ifeq `first` 'second'
ifeq 'first' `second`
例:
first = $(CXX)
second = g++
all:
ifeq ($(first), $(second))
echo `first == second`
else
echo `first != second`
endif
make実行後の出力
wohu@ubuntu:~/cpp/ifeq$ make
echo `first == second`
first == second
wohu@ubuntu:~/cpp/ifeq$
3つのキーワードに条件ステートメントを使用してifeq
、else
、endif
。その中で:
ifeq
条件ステートメントの開始を示し、比較条件(等しい)を指定します。角かっことキーワードを区切るにはスペースを使用し、2つのパラメーターを区切るにはコンマを使用します。パラメータ内の変数参照は、変数値が比較されるときに展開されます。ifeq
後者は、条件が満たされたときに実行され、条件が満たされていない場合は無視されます。else
条件が満たされないときに実行される部分を示します。すべての条件ステートメントがこの部分を実行する必要があるわけではありません。endif
これは判断ステートメントの終了マークであり、Makefileの条件付き判断の終了が存在する必要があります。
実際に、ifneq
そしてifeq
正確に同じを使用するが、条件が逆転された後のステートメントが実行されます。
3.ifdefおよびifndef
使用法は次のとおりです。
ifdef VARIABLE_NAME
その主な機能は、変数の値が空であるかどうかを判断することです(例1)。
a =
b = $(a)
all:
ifdef b
echo yes
else
echo no
endif
make実行後の出力
wohu@ubuntu:~/cpp/ifeq$ make
echo yes
yes
wohu@ubuntu:~/cpp/ifeq$
例2
a =
all:
ifdef a
echo yes
else
echo no
endif
make実行後の出力
wohu@ubuntu:~/cpp/ifeq$ make
echo no
no
wohu@ubuntu:~/cpp/ifeq$
2つの例を比較するyes
と、makeを実行すると、例1の印刷結果がyesであり、例2の印刷結果がyesであることがわかりますno
。
その理由は、例1では、変数のb
定義がであるためb = $(a)
です。変数a
は空ですが、ifdef
判断は真ですが、この方法では明らかに十分ではないと判断するため、ifeq
代わりに変数の値が空であるかどうかを判断する必要がある場合に使用する必要がありますifdef
。
注:条件式の自動化で変数を使用することはできません。自動化された変数は、コマンドのルールで有効であり、2つの異なる
Makefile
ファイルの条件付き排出ポイントの完全なステートメントではありません。
別のファイルを構成する1つのMakefile
使用インジケーター。include
Makefile
4.コマンドパッケージを定義します
関数のようなコマンドパケットビット、同じコマンドを継続的に合成Makefile
して、後で保守しやすいコード量を削減します。
文法:
define <command-name>
command
...
endef
例:
# Makefile 内容
define run_demo_makefile
@echo -n "Hello"
@echo " Makefile!"
@echo "这里可以执行多条 Shell 命令!"
endef
all:
$(run_demo_makefile)
実施した make
wohu@ubuntu:~/cpp/func$ make
Hello Makefile!
这里可以执行多条 Shell 命令!
wohu@ubuntu:~/cpp/func$
5.Makefile疑似ターゲット
いわゆる疑似ターゲットはこのように理解できます。ターゲットファイルを作成するのではなく、ターゲットの下のコマンドを実行したいだけです。疑似ターゲットの存在は、コマンドを見つけて実行するのに役立ちます。
このようなルールを作成する必要がある場合、ルールで定義されるコマンドはファイルを作成することではなく、makeコマンドを介して特定のコマンドを実行するようにファイルを明示的に指定することです。例:
clean:
rm -rf *.o test
rm
fileclean
コマンドを作成せずにタスクを削除し.o
、ファイル名とtest
ファイルの末尾すべての現在のディレクトリを削除するためのルール。
clean
コマンドファイルのときに作業ディレクトリが存在しない場合は、コマンドをshell
入力しmake clean
てください。コマンドrm -rf *.o test
は常に実行されます。これが望ましい結果です。
clean
ケースのファイルが異なっていたときにファイル名が現在のディレクトリの下に存在する場合shell
、コマンドを実行するmake clean
と、ルールはこのドキュメントに依存しないため、ターゲットは最新であり、定義されたコマンドを実行しないと見なされますルールによって。したがって、コマンドrm
は実行されません。
この問題を解決するには、clean
ファイルを削除するか、Makefile
ターゲットをclean
falseオブジェクトとして宣言します。
目標ステートメントによると、疑似目標は.PHONY
、次のように、それを特別なターゲットに依存させることです。
.PHONY:clean
だから、clean
それは関係なく、カレントディレクトリに存在するかどうかの、擬似的なターゲットとして宣言されたclean
私たちが実行すると、ファイルが実行されます。make clean
rm
また、ターゲットが疑似ターゲットとして宣言されてmake
いる場合、このルールを実行するときに、ターゲットを作成するための暗黙的な関係を見つけようとはしません。これはmake
、実装の効率を向上させるためでもありますが、目標や、コンパイルに失敗したファイル名と同じ名前についても心配する必要はありません。
疑似ターゲットを作成するときは、ターゲットが疑似ターゲットであることを宣言する必要があり、それが疑似ターゲットのルール定義になります。clean
完全に書かれたフォーマットのターゲットは次のとおりです。
.PHONY:clean
clean:
rm -rf *.o test
例:
ディレクトリ構造
wohu@ubuntu:~/cpp/ifeq$ tree
.
└── Makefile
0 directories, 1 file
wohu@ubuntu:~/cpp/ifeq$
Makefile
次のように、1つのファイルのみ。
a = 123
bbb:
echo "a is $(a)"
makeの出力は次のとおりです。
wohu@ubuntu:~/cpp/ifeq$ make
echo "a is 123"
a is 123
wohu@ubuntu:~/cpp/ifeq$ make bbb
echo "a is 123"
a is 123
wohu@ubuntu:~/cpp/ifeq$
手動でファイルを作成してbbb
再実行した後make
、echo
文は実行されません
wohu@ubuntu:~/cpp/ifeq$ ls
Makefile
wohu@ubuntu:~/cpp/ifeq$ touch bbb
wohu@ubuntu:~/cpp/ifeq$ make
make: 'bbb' is up to date.
wohu@ubuntu:~/cpp/ifeq$
偽のターゲットを追加した後
a = 123
.PHONY: bbb
bbb:
echo "a is $(a)"
ファイルmake
の現在のディレクトリの存在に関係なく、実行時に次の出力bbb
を実行make bbb
しecho
ます。
wohu@ubuntu:~/cpp/ifeq$ ls
bbb Makefile
wohu@ubuntu:~/cpp/ifeq$ make bbb
echo "a is 123"
a is 123
wohu@ubuntu:~/cpp/ifeq$