GNU Make を使用したオープンソース ソフトウェア開発における「Makefile」の簡単な紹介
GNU Make は、再コンパイルする特定のコード ベースの部分を決定し、コード ベース上でそれらの操作を実行するコマンドを発行できる開発ユーティリティです。この特定のmakeユーティリティは、コマンドを発行してシェルからコンパイルできる限り、任意のプログラミング言語で使用できます。
GNU Make を使用するには、プログラム内のさまざまなファイル間の関係を定義する一連のルールと、各ファイルを更新するためのコマンドが必要です。これらは、「makefile」と呼ばれる特別なファイルに書き込まれます。 「make」コマンドは、「makefile」データベースとファイルの最終変更時刻を使用して決定します。すべてのファイルが再度再コンパイルされます。
メイクファイルの内容
通常、「メイクファイル」には 5 種類のものが含まれます。つまり、暗黙的なルール、明示的なルール、変数定義です。 、 指示 、 そして コメント です。
- 明示的なルールは、1 つまたは複数のファイル (ターゲットと呼ばれ、後で説明します) を作成/再作成する方法と、いつ同じことを行うかを指定します。
- 暗黙のルールは、名前に基づいて 1 つ以上のファイルを作成/再作成する方法を指定します。ターゲット ファイル名が、ターゲットに似た名前を持つ 1 つのファイルにどのように関連付けられるかを説明します。
- 変数定義は、後で置換される変数の文字列値を指定する行です。
- ディレクティブは、makefile の読み取り中に特別な処理を行うよう make に指示するものです。
- 「#」 記号は、メイクファイル内のコメントの開始を表します。 。 「#」で始まる行は単純に無視されます。
メイクファイルの構造
システムを再コンパイルする方法をmakeに伝える情報は、makefileと呼ばれるデータベースを読み取ることで得られます。単純なメイクファイルは、次の構文のルールで構成されます。
target ... : prerequisites ...
recipe
...
...
ターゲットは、プログラムによって生成される出力ファイルとして定義されます。以下で説明する偽のターゲットになる可能性もあります。ターゲット ファイルの例には、実行可能ファイル、オブジェクト ファイル、またはクリーンなどの偽のターゲットが含まれます。 インストール、アンインストールなど。
前提条件は、ターゲット ファイルを作成するための入力として使用されるファイルです。
レシピは、前提条件に基づいてターゲット ファイルを作成するためにmakeが実行するアクションです。 '.RECIPEPREFIX' 変数を指定して他の文字をプレフィックスとして定義しない限り、メイクファイル内の各レシピの前にタブ文字を置く必要があります。レシピに。
サンプルの Makefile
final: main.o end.o inter.o start.o
gcc -o final main.o end.o inter.o start.o
main.o: main.c global.h
gcc -c main.c
end.o: end.c local.h global.h
gcc -c end.c
inter.o: inter.c global.h
gcc -c inter.c
start.o: start.c global.h
gcc -c start.c
clean:
rm -f main.o end.o inter.o start.o
上記の例では、 実行可能ファイル最終を作成するために4 つの C ソース ファイルと 2 つのヘッダー ファイルを使用しました。ここで、各「.o」 ファイルは、メイクファイル内のターゲットであると同時に前提条件でもあります。次に、 最後のターゲット名クリーンを見てみましょう。これはターゲット ファイルではなく単なるアクションです。
通常、コンパイル中にこれは必要ないため、他のルールには前提条件として書かれていません。ファイルを参照せず、単なるアクションであるターゲットを偽のターゲットと呼びます。他のターゲット ファイルのような前提条件はありません。
GNU Make が Makefile を処理する方法
デフォルトでは、make は「makefile」の最初のターゲットから始まり、「 デフォルトの目標」。この例を考慮すると、 最初のターゲットとして最終があります。前提条件には他のオブジェクト ファイルが含まれているため、最終を作成する前に更新する必要があります。これらの各前提条件は、独自のルールに従って処理されます。
再コンパイルはソース ファイル または ヘッダー ファイル に変更が加えられた場合、または オブジェクト ファイル がまったく存在しない場合に発生します。必要なオブジェクト ファイルを再コンパイルした後、make は最終 を再リンクするかどうかを決定します。これは、 ファイル最終が存在しない場合、またはオブジェクト ファイルのいずれかがそれより新しい場合に実行する必要があります。
したがって、ファイル inter.c を変更すると、make の実行時にソース ファイルが再コンパイルされて更新されます。オブジェクト ファイル inter.o とリンク final です。
Makefile 内での変数の使用
この例では、以下に示すように、最終のルールですべてのオブジェクト ファイルを 2 回リストする必要がありました。
final: main.o end.o inter.o start.o
gcc -o final main.o end.o inter.o start.o
このような重複を避けるために、メイクファイル内で使用されているオブジェクト ファイルのリストを保存する変数を導入できます。変数 OBJ を使用すると、サンプルのメイクファイルを以下に示すようなものに書き換えることができます。
OBJ = main.o end.o inter.o start.o
final: $(OBJ)
gcc -o final $(OBJ)
main.o: main.c global.h
gcc -c main.c
end.o: end.c local.h global.h
gcc -c end.c
inter.o: inter.c global.h
gcc -c inter.c
start.o: start.c global.h
gcc -c start.c
clean:
rm -f $(OBJ)
ソースディレクトリをクリーンアップするためのルール
メイクファイルの例で見たように、コンパイル後に不要なオブジェクト ファイルを削除することで、 ソース ディレクトリをクリーンアップするルールを定義できます。たまたまクリーンというターゲット ファイルがあるとします。上記 2 つの状況をどのように区別できますか?ここで偽のターゲットという概念が登場します。
偽のターゲットとは、実際にはファイルの名前ではなく、メイクファイル< から明示的なリクエストが行われるたびに実行されるレシピの名前にすぎないものです。。 偽のターゲット を使用する主な理由の 1 つは、同じ名前のファイルとの競合を避けるためです。もう 1 つの理由は、パフォーマンスの向上です。
このことを説明するために、予期せぬひねりを 1 つ明らかにします。 クリーンのレシピは、makeの実行時にデフォルトでは実行されません。代わりに、 コマンドmake cleanを発行して同じものを呼び出す必要があります。
.PHONY: clean
clean:
rm -f $(OBJ)
次に、 独自のコードベースのメイクファイルを作成してみます。疑問がある場合はお気軽にここにコメントしてください。