Makefile-quick-guide
なぜMakefileなのか?
ソースコードファイルのコンパイルは、特に複数のソースファイルをインクルードし、コンパイルする必要があるたびにコンパイルコマンドを入力する必要がある場合、疲れる場合があります。 Makefileは、このタスクを簡素化するソリューションです。
メイクファイルは、プロジェクトのビルドと管理を自動的に支援する特別な形式のファイルです。
たとえば、次のソースファイルがあるとします。
main.cpp
hello.cpp
factorial.cpp
functions.h
以下は、main.cppソースファイルのコードです-
以下に示すコードはhello.cppソースファイル用です-
factorial.cppのコードは以下のとおりです-
以下は、fnctions.hのコードです-
ファイルをコンパイルして実行可能ファイルを取得する簡単な方法は、コマンドを実行することです-
このコマンドは、_hello_バイナリを生成します。 この例では、4つのファイルしかなく、関数呼び出しのシーケンスがわかっています。 したがって、上記のコマンドを入力し、最終的なバイナリを準備することが可能です。
ただし、数千のソースコードファイルがある大規模なプロジェクトでは、バイナリビルドを維持することが困難になります。
次のセクションでは、プロジェクトのメイクファイルを準備する方法を説明します。
Makefile-マクロ
特別なマクロ
ターゲットルールセットでコマンドを発行する前に、事前定義された特定の特別なマクロがあります-
- $ @は、作成するファイルの名前です。
- $? 変更された依存の名前です。
たとえば、次のようなルールを使用できます-
この例では、$ @は_hello_および$?を表します。 または、$ @。cppは、変更されたすべてのソースファイルを取得します。
暗黙のルールで使用される特別なマクロがさらに2つあります。 彼らは-
- $ <アクションを引き起こした関連ファイルの名前。 $ ターゲットおよび依存ファイルによって共有されるプレフィックス。
一般的な暗黙のルールは、.cpp(ソースファイル)から.o(オブジェクト)ファイルを作成することです。
従来のマクロ
さまざまなデフォルトマクロがあります。 それらを確認するには、「make -p」と入力してデフォルトを出力します。 ほとんどは、それらが使用されるルールから非常に明白です。
これらの事前定義変数、つまり暗黙のルールで使用されるマクロは、2つのクラスに分類されます。 彼らは次のとおりです-
- プログラムの名前であるマクロ(CCなど) *プログラムの引数を含むマクロ(CFLAGSなど)。
以下は、メイクファイルの組み込みルールでプログラムの名前として使用される一般的な変数のいくつかの表です-
Sr.No | Variables & Description |
---|---|
1 |
アーカイブ管理プログラム。デフォルトは「ar」です。 |
2 |
AS アセンブリファイルをコンパイルするプログラム。デフォルトは「as」です。 |
3 |
CC Cプログラムをコンパイルするプログラム。デフォルトは「cc」です。 |
4 |
CO RCSからファイルをチェックアウトするプログラム。デフォルトは「co」です。 |
5 |
CXX C プログラムをコンパイルするプログラム。デフォルトは「g 」です。 |
6 |
CPP Cプリプロセッサーを実行するためのプログラム。結果は標準出力に出力されます。デフォルトは `$(CC)-E 'です。 |
7 |
FC FortranおよびRatforプログラムをコンパイルまたは前処理するプログラム。デフォルトは `f77 'です。 |
8 |
GET SCCSからファイルを抽出するプログラム。デフォルトは「get」です。 |
9 |
LEX Lex文法をソースコードに変換するために使用するプログラム。デフォルトは「lex」です。 |
10 |
YACC Yacc文法をソースコードに変換するために使用するプログラム。デフォルトは「yacc」です。 |
11 |
LINT ソースコードでlintを実行するために使用するプログラム。デフォルトは「lint」です。 |
12 |
M2C Modula-2ソースコードのコンパイルに使用するプログラム。デフォルトは「m2c」です。 |
13 |
PC Pascalプログラムをコンパイルするためのプログラム。デフォルトは「pc」です。 |
14 |
MAKEINFO TexinfoソースファイルをInfoファイルに変換するプログラム。デフォルトは「makeinfo」です。 |
15 |
TEX TeXソースからTeX dviファイルを作成するプログラム。デフォルトは `tex 'です。 |
16 |
TEXI2DVI TexinfoソースからTeX dviファイルを作成するプログラム。デフォルトは「texi2dvi」です。 |
17 |
WEAVE WebをTeXに変換するプログラム。デフォルトは「weave」です。 |
18 |
CWEAVE C WebをTeXに変換するプログラム。デフォルトは「cweave」です。 |
19 |
TANGLE WebをPascalに翻訳するプログラム。デフォルトは「もつれ」です。 |
20 |
CTANGLE C WebをCに変換するプログラム。デフォルトは「ctangle」です。 |
21 |
RM ファイルを削除するコマンド。デフォルトは「rm -f」です。 |
上記のプログラムの追加引数が値である変数の表を次に示します。 特に明記しない限り、これらすべてのデフォルト値は空の文字列です。
Sr.No. | Variables & Description |
---|---|
1 |
ARFLAGS アーカイブ管理プログラムに与えるフラグ。デフォルトは `rv 'です。 |
2 |
ASFLAGS
|
3 |
CFLAGS Cコンパイラに与える追加のフラグ。 |
4 |
CXXFLAGS Cコンパイラに与える追加のフラグ。 |
5 |
COFLAGS RCS coプログラムに与える追加のフラグ。 |
6 |
CPPFLAGS Cプリプロセッサとそれを使用するプログラム(CやFortranコンパイラなど)に与える追加フラグ。 |
7 |
FFLAGS Fortranコンパイラーに与える追加のフラグ。 |
8 |
GFLAGS SCCS取得プログラムに与える追加のフラグ。 |
9 |
LDFLAGS コンパイラーがリンカー「ld」を呼び出すことになっているときにコンパイラーに与える追加フラグ。 |
10 |
LFLAGS レックスに与える追加のフラグ。 |
11 |
YFLAGS Yaccに与える追加のフラグ。 |
12 |
PFLAGS Pascalコンパイラに渡す追加のフラグ。 |
13 |
RFLAGS Ratforプログラム用のFortranコンパイラーに与える追加フラグ。 |
14 |
LINTFLAGS 糸くずに与える追加フラグ。 |
注-「-R」または「--no-builtin-variables」オプションを使用して、暗黙のルールで使用されるすべての変数をキャンセルできます。
以下に示すように、コマンドラインでマクロを定義することもできます-
Makefileでの依存関係の定義
最終的なバイナリがさまざまなソースコードとソースヘッダーファイルに依存することは非常に一般的です。 依存関係は、ターゲットのソースについて make を知らせるために重要です。 次の例を考慮してください-
ここでは、helloはmain.o、factorial.o、hello.oファイルに依存していることを make に伝えます。 したがって、これらのオブジェクトファイルのいずれかが変更されるたびに、 make がアクションを実行します。
同時に、 make に.oファイルの準備方法を伝える必要があります。 したがって、これらの依存関係も次のように定義する必要があります-
Makefileでのルールの定義
Makefileのルールを学習します。
Makefileターゲットルールの一般的な構文は次のとおりです-
上記のコードでは、括弧内の引数はオプションであり、省略記号は1つ以上を意味します。 ここで、各コマンドの前にタブが必要なことに注意してください。
以下に、他の3つのファイルからターゲットを作成するルールを定義する簡単な例を示します。
注-この例では、ソースファイルからすべてのオブジェクトファイルを作成するルールを指定する必要があります。
セマンティクスは非常に単純です。 「ターゲットを作る」と言うと、 make は適用されるターゲットルールを見つけます。そして、依存関係のいずれかがターゲットよりも新しい場合、 make はコマンドを一度に1つずつ実行します(マクロ置換後)。 依存関係を作成する必要がある場合は、最初に依存関係が発生します(したがって、再帰が発生します)。
人々は、Makefileの特定のターゲットを期待するようになりました。 常に最初に参照する必要があります。 ただし、ターゲットall(またはmakeのみ)、install、およびcleanが検出されることを期待するのは合理的です。
- make all -アプリケーションをインストールする前にローカルテストを実行できるように、すべてをコンパイルします。
- make install -アプリケーションを適切な場所にインストールします。
- make clean -アプリケーションをクリーンアップし、実行可能ファイル、一時ファイル、オブジェクトファイルなどを取り除きます。
Makefileの暗黙のルール
このコマンドは、ソースコードx.cppから実行可能ファイルxをビルドするすべての場合に機能するはずです。 これは暗黙のルールとして述べることができます-
この暗黙のルールは、x.cからxを作成する方法を示しています。x.cでccを実行し、出力xを呼び出します。 特定のターゲットが言及されていないため、ルールは暗黙的です。 すべての場合に使用できます。
もう1つの一般的な暗黙のルールは、.cpp(ソースファイル)から.o(オブジェクト)ファイルを作成することです。
Makefileでのカスタムサフィックスルールの定義
これは、以下に示すように、Makefileをさらに削減します-
これらの特別なサフィックスを使用して独自のルールを作成することを make に通知します。
最初のルールでは、。foo_ファイルから.bar_ファイルを作成できます。 基本的にファイルをスクランブルします。 2番目のルールは、。c_ファイルから.o_ファイルを作成するために make によって使用されるデフォルトのルールです。
Makefile-ディレクティブ
さまざまな形式で利用可能な多数のディレクティブがあります。 システム上の make プログラムは、すべてのディレクティブをサポートしていない場合があります。 あなたの make がここで説明しているディレクティブをサポートしているかどうかを確認してください。 GNU make はこれらのディレクティブをサポートしています。
条件付きディレクティブ
条件付きディレクティブは-
- ifeq ディレクティブは条件を開始し、条件を指定します。 コンマで区切られ、括弧で囲まれた2つの引数が含まれています。 両方の引数で変数置換が実行され、それらが比較されます。 ifeqに続くmakefileの行は、2つの引数が一致する場合に従います。それ以外の場合は無視されます。
- ifneq ディレクティブは条件を開始し、条件を指定します。 コンマで区切られ、括弧で囲まれた2つの引数が含まれています。 両方の引数で変数置換が実行され、それらが比較されます。 2つの引数が一致しない場合、ifneqに続くメイクファイルの行に従います。それ以外の場合は無視されます。
- ifdef ディレクティブは条件を開始し、条件を指定します。 単一の引数が含まれます。 指定された引数がtrueの場合、条件はtrueになります。
- ifndef ディレクティブは条件を開始し、条件を指定します。 単一の引数が含まれます。 指定された引数がfalseの場合、条件はtrueになります。
- else ディレクティブは、前の条件が失敗した場合、次の行に従います。 上記の例では、これは、最初の代替が使用されない場合は常に2番目の代替リンクコマンドが使用されることを意味します。 条件にelseを含めることはオプションです。
- endif ディレクティブは条件を終了します。 すべての条件はendifで終わる必要があります。
条件ディレクティブの構文
他のない単純な条件付き構文は次のとおりです-
text-if-trueは任意のテキスト行で、条件がtrueの場合にメイクファイルの一部と見なされます。 条件が偽の場合、代わりにテキストは使用されません。
複雑な条件の構文は次のとおりです-
条件が真の場合、text-if-trueが使用されます。それ以外の場合、text-if-falseが使用されます。 text-if-falseには、テキストの任意の行数を指定できます。
条件ディレクティブの構文は、条件が単純であろうと複雑であろうと同じです。 さまざまな条件をテストする4つの異なるディレクティブがあります。 彼らは与えられたとおりです-
上記の条件の反対のディレクティブは次のとおりです-
条件付きディレクティブの例
includeディレクティブ
- includeディレクティブ*を使用すると、 make は現在のメイクファイルの読み取りを一時停止し、続行する前に1つ以上の他のメイクファイルを読み取ります。 ディレクティブは、次のように見えるメイクファイル内の行です-
ファイル名には、シェルファイル名のパターンを含めることができます。 行の先頭では余分なスペースを使用できますが、タブは使用できません。 たとえば、3つの「.mk」ファイル、つまり「a.mk」、「b.mk」、および「c.mk」、および$(bar)がある場合、bish bashに展開され、次に表現。
オーバーライドディレクティブ
コマンド引数で変数が設定されている場合、makefile内の通常の割り当ては無視されます。 コマンド引数で設定された変数をメイクファイルに設定したい場合は、オーバーライドディレクティブを使用できます。
Makefile-再コンパイル
ファイルのコンパイル中、 make はオブジェクトファイルをチェックし、タイムスタンプを比較します。 ソースファイルにオブジェクトファイルより新しいタイムスタンプがある場合、ソースファイルが変更されたと仮定して、新しいオブジェクトファイルを生成します。
再コンパイルの回避
数千のファイルで構成されるプロジェクトが存在する場合があります。 ソースファイルを変更した場合でも、それに依存するすべてのファイルを再コンパイルしたくない場合があります。 たとえば、他のファイルが依存するヘッダーファイルにマクロまたは宣言を追加するとします。 保守的であるため、 make はヘッダーファイルの変更にはすべての依存ファイルの再コンパイルが必要であることを前提としていますが、再コンパイルが不要であり、コンパイルを待つ時間を無駄にしないことを知っています。
ヘッダーファイルを変更する前に問題を予測した場合は、-tフラグを使用できます。 このフラグは、ルール内のコマンドを実行するのではなく、最終変更日を変更してターゲットを最新の状態にマークするように make に指示します。 あなたはこの手順に従う必要があります-
- コマンド `make 'を使用して、本当に再コンパイルが必要なソースファイルを再コンパイルします。
- ヘッダーファイルに変更を加えます。
- コマンド `make -t 'を使用して、すべてのオブジェクトファイルを最新としてマークします。 次回makeを実行すると、ヘッダーファイルの変更によって再コンパイルは発生しません。
一部のファイルが再コンパイルを必要とするときにヘッダーファイルを既に変更している場合、これを行うには遅すぎます。 代わりに、指定されたファイルを「古い」としてマークする「-o file」フラグを使用できます。 つまり、ファイル自体は再作成されず、そのアカウントでは他の何も再作成されません。 あなたはこの手順に従う必要があります-
- `make -o header file 'を使用して、特定のヘッダーファイルとは無関係の理由でコンパイルが必要なソースファイルを再コンパイルします。 複数のヘッダーファイルが関係している場合は、ヘッダーファイルごとに個別の「-o」オプションを使用します。
- すべてのオブジェクトファイルを「make -t」で更新します。
Makefile-その他の機能
この章では、Makefileのその他のさまざまな機能について説明します。
Makeの再帰的な使用
この例をコピーするだけで、再帰的な make コマンドを作成できます。 ただし、それらがどのように機能し、なぜ、そしてサブメイクがトップレベルのメイクにどのように関連するかについて知る必要があります。
サブメイクへの変数の伝達
最上位の make の変数値は、明示的な要求によって環境を通じてサブメイクに渡すことができます。 これらの変数は、サブメイクでデフォルトとして定義されています。 `-e 'スイッチを使用しない限り、サブmake makefileで使用されるmakefileで指定されているものをオーバーライドすることはできません。
変数を渡す、またはエクスポートするには、 make は変数とその値を環境に追加して、各コマンドを実行します。 サブメイクは、環境を使用して変数値のテーブルを初期化します。
特別な変数SHELLおよびMAKEFLAGSは常にエクスポートされます(エクスポートをアンエクスポートしない限り)。 MAKEFILESは、何かに設定するとエクスポートされます。
特定の変数をサブメイクにエクスポートする場合は、以下に示すように、エクスポートディレクティブを使用します-
変数がエクスポートされないようにする場合は、以下に示すように、unexportディレクティブを使用します-
変数MAKEFILES
環境変数MAKEFILESが定義されている場合、 make は、その値を他のメイクファイルの前に読み込まれる追加のメイクファイルの名前(空白で区切られた)のリストと見なします。 これはincludeディレクティブと同じように機能します。さまざまなディレクトリでそれらのファイルが検索されます。
MAKEFILESの主な用途は、 make の再帰呼び出し間の通信です。
異なるディレクトリのヘッダーファイルを含める
ヘッダーファイルを別のディレクトリに配置し、別のディレクトリで make を実行している場合、ヘッダーファイルのパスを指定する必要があります。 これは、メイクファイルの-Iオプションを使用して実行できます。 functions.hファイルが/home/finddevguides/headerフォルダーにあり、残りのファイルが/home/finddevguides/src/フォルダーにあるとすると、makefileは次のように記述されます-
変数にさらにテキストを追加する
多くの場合、すでに定義されている変数の値にテキストを追加すると便利です。 これを行うには、次のように「+ =」を含む行を使用します-
変数オブジェクトの値を取得し、テキスト「another.o」を追加します。次に示すように、スペースを1つ付けます。
上記のコードは、オブジェクトを「main.o hello.o factorial.o another.o」に設定します。
`+ = 'の使用は次のようになります。
Makefileの継続行
Makefileの大きすぎる行が気に入らない場合は、以下に示すようにバックスラッシュ「\」を使用して行を分割できます-
コマンドプロンプトからMakefileを実行する
「Makefile」という名前のMakefileを準備した場合は、コマンドプロンプトでmakeと記述するだけでMakefileファイルが実行されます。 しかし、あなたがMakefileに他の名前を付けている場合は、次のコマンドを使用します-
Makefile-例
これは、helloプログラムをコンパイルするためのMakefileの例です。 このプログラムは、3つのファイル_main.cpp 、 factorial.cpp_、および_hello.cpp_で構成されています。
これで、 make を使用してプログラム hello をビルドできます。 コマンド make clean を発行すると、現在のディレクトリで使用可能なすべてのオブジェクトファイルとコアファイルが削除されます。