わかりやすいMakefile入門(01)— Makefileとは何か、Makefileを使用する理由、Makefileルール、およびMakefileプロセスでインクリメンタルコンパイルを実現する方法

1.Makefileとは

MakefileドキュメントにはLinuxC/C++自動化C/C++プロジェクトのコンパイルに使用されるプロジェクトのシステムコンパイルルールが記載されていますライティングが優れたライティングMakefileペーパー、makeコマンドが1つだけになると、プロジェクト全体が自動的にコンパイルされ始めGCC、コマンドを手動で実行する必要がなくなりますC/C++プロジェクトの大きなソースファイルには、機能、モジュール、タイプに応じて数百があり、異なるディレクトリに配置されていMakefileます。ファイルは、ソースファイルの依存関係のコンパイル順序、再コンパイルの必要性、および再コンパイルの必要性を示す一連のルールを定義します。など。

Makefileこれは、プロジェクトファイルのコンパイルルールと見なすことができ、プロジェクト全体のコンパイルルールとリンクルールを記述します。これには、コンパイルする必要のあるファイル、コンパイルする必要のないファイル、最初にコンパイルする必要のあるファイル、後でコンパイルする必要のあるファイル、再構築する必要のあるファイルなどが含まれます。関係するプロジェクト全体のニーズをコンパイルしますMakefile。両方で説明できます。つまり、Makefileプロジェクトのコンパイルは、毎回大量のソースファイルとパラメーターを手動で入力しなくても自動化できます。

2.Makefileを使用する理由

特定のマルチファイルコンパイラがファイルを生成することを説明する例として言語開発Linux下げるためCに、コンパイラコマンドは次のとおりです。

gcc -o outfile name1.c name2.c ...

outfile生成される実行可能プログラムの名前nameN.cは、ソースファイルの名前です。これは、サンプルファイルをコンパイルするLinuxためにgccコンパイラで使用するものCです。遭遇するソースファイルの数がそれほど多くない場合は、このコンパイル方法を選択できます。ソースファイルが多すぎると、次の問題が発生します。

2.1コンパイル時にライブラリをリンクする問題

手動でリンクする必要があるいくつかの標準ライブラリは次のとおりです。

  • name1.c数学ライブラリmath関数を使用するため、パラメータを手動で追加する必要があります-lm
  • name4.c小さなデータベースSQLite関数を使用します-lsqlite3手動でパラメータを追加する必要があります
  • name5.cスレッドを使用する場合は、手動でパラメーターを追加する必要があります-lpthread

多くのファイルがあるため、多くのサードパーティライブラリをリンクする必要があります。そのため、コンパイル時にコマンドが非常に長くなり、コンパイル時にファイルリンクの順序に関与する可能性があるため、手動でのコンパイルは非常に面倒になります。

そうでMakefileない場合の使用法を学ぶと、コンパイラーの操作が大幅に簡素化されます。でライブラリファイルをリンクするにはMakefile、適切なルールと対応するリンク順序を作成します。したがってmake、コマンドを実行するだけで、プロジェクトはパラメータオプションと省略されたコマンドの手動コンパイルを自動的にコンパイルします。これは非常に便利です。

2.2大規模なプロジェクトのコンパイルには長い時間がかかります

Makefileマルチスレッドの並行操作をサポートすると、コンパイル時間が大幅に短縮されます。ソースファイルを変更する場合、プロジェクト全体をコンパイルする場合、makeコマンドは変更したファイルのみをコンパイルし、変更されていないファイルを再コンパイルする必要はありません。時間のかかる問題を解決しました。

また、ファイルMakefileは1回だけ実行する必要があります。通常、ファイルを追加したりプロジェクトを削除したりするMakefileことはありません基本的に変更する必要はなく、コンパイル時に1つのmakeコマンドのみを使用しますそれは私たちに大きな利便性を提供し、コンパイルの効率を大幅に向上させます。

3.Makefileルール

そのルールは主に依存関係と実行コマンドの2つの部分で構成され、その構造は次のとおりです。

targets : prerequisites
    command

または

targets : prerequisites; command
    command

関連する手順は次のとおりです。

  • targets:ルールのターゲットは必須であり、Object File(一般に中間ファイルと呼ばれます)、実行可能ファイル、またはラベルにすることができます。
  • prerequisitestargetsファイルまたは目的のターゲットを生成するための依存ファイル複数ある場合もあれば、スペースで区切られている場合もあります。
  • commandmakeコマンド(いずれかのshellコマンドを実行する必要があります)。複数のコマンドが存在する可能性があり、各コマンドは1行を占めます。

command長すぎる場合\、改行を使用できます。

注:目標と依存ファイルの間にコロンを使用するには、開始コマンドでTabキーを使用する必要があります。スペースバーは使用できません。

Makefileの内容を簡単に要約すると、主に5つの部分で構成されています。

3.1明示的なルール

明示的なルールは、1つ以上のオブジェクトファイルを生成する方法を説明します。これはMakefile、結果のファイル、ファイルの依存関係、生成されたコマンドをライターが明確に指摘したことが原因です。

3.2あいまいなルール

make自動導出関数の名前として、あいまいなルールを使用するMakefileと、makeサポートされているコマンドである大まかな地面を簡単に書くことができます。

3.3変数の定義

Makefile中央我々は、一般的に、文字列の変数のセットを定義する必要があり、これは、C言語のマクロのようなビットであるMakefile変数は、対応する基準位置まで延長され、実行は、。

3.4ドキュメントの説明

これは3つの部分で構成され、一方はC言語のようにMakefile他方への参照であり、プリコンパイルされたC言語と同じように、特定の指定された有効な部分に従って他のケースを参照します。複数行のコマンドを定義することです。 。MakefileincludeMakefile#if

3.5注意事項

Makefileインラインコメントと、コメントが文字UNIXShellあるのと同じスクリプトのみで文字の使用#を希望するMakefile場合は#、次のように円記号でエスケープできます\#

3.6ルールのワイルドカード

  • * 1つ以上の文字を表します
  • ? 任意の文字を表します
  • [...] [abcd]はa、b、c、dの任意の文字を意味し、[^ abcd]はa、b、c、d以外の文字を意味し、[0-9]は0から9までの任意の数字を意味します
  • ~ ユーザーのホームディレクトリを表します

4.Makefileの例

main.cpp コード:

#include <iostream>

int main()
{
    
    
    std::cout << "hello,world" << std::endl;
    return 0;
}

具体的には、MakefileルールMakefileファイルの使用に関する次の例で、次のコードを追加します。

main: main.cpp
	g++ main.cpp -o main

これmainがターゲットファイルであり、結果の実行可能ファイルです。main.cppソースファイル、オブジェクトファイルの操作がそれを再構築するために行う必要がある依存ファイルg++ main.cpp -o mainこれは、Makefile基本的な文法規則の使用です。

使用Makefile方法:最初に適切なMakefileファイルを作成してから、シェルmakeコマンドを実行する必要があります。プログラムが自動的に実行され、最終的な宛先ファイルが取得されます。

wohu@ubuntu:~/cpp/demo$ ls
main.cpp  `Makefile`
wohu@ubuntu:~/cpp/demo$ make 
g++ main.cpp -o main
wohu@ubuntu:~/cpp/demo$ ls
main  main.cpp  `Makefile`
wohu@ubuntu:~/cpp/demo$ ./main 
hello,world
wohu@ubuntu:~/cpp/demo$ 

コマンドの先頭でスペースバーを使用すると、エラーが報告されます

Makefile:2: *** missing separator.  Stop.

Makefile:2行目のエラーの場合は2、Tab開始する必要があります。

5.Makefileプロセス

makeコマンドを実行すると、makeファイルである現在のファイルの下でルールのコンパイルを探すためにが実行されMakefileます。私たちは書くMakefileあなたが使用することができたときに、ファイルの名前をGNUMakefilemakefileMakefilemake実行するときに探しに戻ってMakefile、ファイルをファイル・シーケンスは次のようである見つけます。

使用をお勧めしますMakefile(通常、プロジェクトではこのように記述され、大文字はより標準化されます)。ファイルが存在しない場合は、makeエラーが報告され、次のプロンプトが表示されます。

make: *** No targets specified and no `Makefile` found.  Stop.

ではMakefile、次のコードを追加:

main: main.o   name.o greeting.o
	g++ main.o name.o greeting.o -o main
main.o: main.cpp
	g++ -c main.cpp -o main.o
name.o: name.cpp
	g++ -c name.cpp -o name.o
greeting.o: greeting.cpp
	g++ -c greeting.cpp -o greeting.o

プロジェクトファイルをコンパイルするとき、デフォルトでmake実行がMakefile最初のルール(Makefile最初の依存関係が表示されます)であり、このルールの最初の目的は「最終目標」または「最終目標」と呼ばれます。

shellコマンドラインmakeコマンドは、実行可能ファイルを取得することができますmainし、中間ファイルをmain.oname.oそしてgreeting.omain私たちの最終文書が生成されるという。

することによりMakefile、当社のターゲットを見つけることができますmainMakefile最初の目標、それはmake究極の目標、任意のファイルを変更したときに、実行make究極の目標を再構築しますがmain

その特定の作業順序は次のとおりです。shell入力がmake後続のコマンドをプロンプトするときmake現在のディレクトリMakefileファイルを読み込み、Makefile実行の「最終目標」として最初の目標ファイルし、最初のルール(最終目標があるルール)の処理を開始します。

この例では、最初のルールはルールの目標mainが配置されていることです。ルールはmain依存関係を記述し、リンク.oファイル生成ターゲットmainコマンドを定義しますmake最初の処理ターゲットによって定義されたこのコマンドルールを実行する前に、mainすべての依存ファイル(ファイルの例.o)更新ルール(これらの.oファイルターゲットルール)。

.o次の3つのケースファイルを処理するこれらのターゲティングルール:

  • ターゲット.oファイルが存在しません。説明ルールを使用して作成してください。
  • ターゲット.oファイルが存在します。ターゲット.oファイルは、任意のターゲット比率の.o「更新」ファイル(変更後の最後の作成)の「.cpp」ソース「.h」ファイルに依存し、それに応じてルールを再コンパイルします。
  • ターゲット.oファイルが存在し、.oその依存関係のいずれよりもターゲットファイル(「.c」ソース、「。H」ファイル)「更新」(ファイルが変更後に変更されていないかどうかによって異なります)、何もしません。

上記の更新ルールにより、.oファイルのコンパイル時に生成される中間ファイルの役割を理解できます。この機能は、特定のソースファイルが変更されているかどうか、および最終的なターゲットファイルを再構築する必要があるかどうかを確認することです。

makeコマンドを実行すると、変更されたソースファイルまたは存在しないターゲットファイルのみが再構築されますが、これらのファイルは再コンパイルせずに変更されないため、大部分の時間を節約し、プログラミング効率を向上させます。

おすすめ

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