シンプルで理解しやすいMakefileの紹介(04)-条件付き判断(ifeq、ifneq、ifdef、ifndef)、defineコマンドパッケージdefine、pseudo target

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つのキーワードに条件ステートメントを使用してifeqelseendifその中で:

  • 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使用インジケーターincludeMakefile

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

rmfilecleanコマンドを作成せずにタスクを削除し.o、ファイル名とtestファイルの末尾すべて現在のディレクトリを削除するためのルール

cleanコマンドファイルのときに作業ディレクトリが存在しない場合は、コマンドをshell入力しmake cleanてください。コマンドrm -rf *.o testは常に実行されます。これが望ましい結果です。

cleanケースのファイルが異なっていたときにファイル名が現在のディレクトリの下に存在する場合shell、コマンド実行するmake cleanと、ルールはこのドキュメントに依存しないため、ターゲットは最新であり、定義されたコマンドを実行しないと見なされますルールによって。したがって、コマンドrmは実行されません。

この問題を解決するには、cleanファイルを削除するか、Makefileターゲットをcleanfalseオブジェクトとして宣言します。

目標ステートメントによると、疑似目標は.PHONY、次のように、それを特別なターゲットに依存させることです。

.PHONY:clean

だから、cleanそれは関係なく、カレントディレクトリに存在するかどうかの、擬似的なターゲットとして宣言されたclean私たちが実行すると、ファイルが実行されます。make cleanrm

また、ターゲットが疑似ターゲットとして宣言されて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再実行した後makeecho文は実行されません

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 bbbechoます。

wohu@ubuntu:~/cpp/ifeq$ ls
bbb  Makefile
wohu@ubuntu:~/cpp/ifeq$ make bbb
echo "a is 123"
a is 123
wohu@ubuntu:~/cpp/ifeq$ 

おすすめ

転載: blog.csdn.net/wohu1104/article/details/111022292