makefile作成

5095 ワード

1つのプログラムファイルが多すぎて、コンパイルが不便でいつもエラーが発生した場合、makefileファイルを作成しなければなりません.
makefileとは?多くのWinodwsのプログラマーはこれを知らないかもしれません.WindowsのIDEがあなたのためにこの仕事をしたからです.しかし、professionalのプログラマーになるには、makefileが理解しなければならないと思います.これは今こんなに多くのHTMLのエディタがあるようですが、専門家になりたいなら、HTMLの標識の意味を理解しなければなりません.特にUnixでのソフトウェアコンパイルでは、自分でmakefileを書かないわけにはいきません.makefileを書くかどうか、大きなプロジェクトを完成させる能力があるかどうかを一つの側面から説明します.なぜなら、makefileはプロジェクト全体のコンパイルルールに関係しているからです.1つのプロジェクトのソースファイルはカウントされず、タイプ、機能、モジュール別にいくつかのディレクトリに配置されます.makefileは、makefileがShellスクリプトのようにオペレーティングシステムのコマンドを実行できるため、どのファイルが先にコンパイルされる必要があるか、どのファイルが後にコンパイルされる必要があるか、どのファイルが再コンパイルされる必要があるか、さらに複雑な機能操作を実行する必要があるかを指定する一連のルールを定義しています.makefileがもたらすメリットは「自動化コンパイル」であり、書き上げるとmakeコマンドが1つしか必要なく、エンジニアリング全体が完全に自動コンパイルされ、ソフトウェア開発の効率が大幅に向上します.makeはコマンドツールで、makefileのコマンドを説明するコマンドツールです.一般的に、ほとんどのIDEにはこのコマンドがあります.例えば、Delphiのmake、Visual C++のnmake、LinuxのGNUのmakeなどです.makefileはいずれもエンジニアリング面でのコンパイル方法となっていることがわかる.
makeコマンドの実行には、makeコマンドがどのようにプログラムをコンパイルおよびリンクする必要があるかを示すMakefileファイルが必要です.まず、Makefileの表記規則を一例で説明します.みんなに感興的な認識を与えるためです.この例はGNUのmakeマニュアルに由来し、この例では、8つのCファイルと3つのヘッダファイルがあり、makeコマンドがこれらのファイルをどのようにコンパイルし、リンクするかを示すMakefileを書きます.私たちのルールは:1)このプロジェクトがコンパイルされていない場合、私たちのすべてのCファイルはコンパイルされ、リンクされます.2)このプロジェクトのいくつかのCファイルが修正された場合,我々は修正されたCファイルのみをコンパイルし,ターゲットプログラムをリンクする.3)このプロジェクトのヘッダファイルが変更された場合,これらのヘッダファイルを参照したCファイルをコンパイルし,ターゲットプログラムをリンクする必要がある.
一、MakefileのルールこのMakefileについて話す前に、Makefileのルールをざっと見てみましょう.target ... : prerequisites ... command ... ... targetはターゲットファイルであり、Object Fileであっても実行ファイルであってもよい.ラベル(Label)も使用できます.ラベルという特性については、後続の「擬似ターゲット」章で説明します.prerequisitesとは、そのtargetを生成するために必要なファイルまたはターゲットです.commandとは、makeが実行する必要があるコマンドです.(任意のShellコマンド)これは1つのファイルの依存関係であり、すなわちtargetという1つ以上のターゲットファイルはprequisitesのファイルに依存し、その生成規則はcommandに定義される.はっきり言って、prerequisitesにtargetファイルよりも1つ以上のファイルが新しい場合、commandで定義されたコマンドが実行されます.これがMakefileのルールです.つまりMakefileの中で最も核心的な内容です.
二、一例
TARGET=cumtdial.so
OBJECTS=dial.o pap-secrets.o d3des.o fake_md5.o base64.o
cc=gcc
CFLAGS=-shared

all:$(TARGET)

$(TARGET):$(OBJECTS)
	$(CC) $(OBJECTS) $(CFLAGS) -o $@

dial.o:dial.c
	$(CC) dial.c -c -o dial.o

pap-secrets.o:pap-secrets.c pap-secrets.h
	$(CC) pap-secrets.c -c -o pap-secrets.o

d3des.o:d3des.c d3des.h
	$(CC) d3des.c -c -o d3des.o

fake_md5.o:fake_md5.c fake_md5.h
	$(CC) fake_md5.c -c -o fake_md5.o

base64.o:base64.c base64.h
	$(CC) base64.c -c -o base64.o
clean:
	rm -f $(TARGET) $(OBJECTS) 

.PHONY: clean

上記のファイルの内容では,「.PHONY」はcleanが擬似ターゲットファイルであることを示す.
デフォルトでは、makeコマンドは、現在のディレクトリの下で「GNUmakefile」、「makefile」、「Makefile」というファイルを順番に探し、このファイルを解釈します.この3つのファイル名の中で、「Makefile」というファイル名を使うのが一番いいです.このファイル名の最初の文字は大文字なので、目立つ感じがします.「GNUmakefile」は使わないほうがいいです.このファイルはGNUのmakeで認識されています.他にも、すべて小文字の「makefile」ファイル名にのみ敏感なmakeもありますが、基本的には、ほとんどのmakeは「makefile」と「Makefile」の2つのデフォルトファイル名をサポートしています.もちろん、「Make.Linux」、「Make.Solaris」、「Make.AIX」など、別のファイル名でMakefileを書くことができます.特定のMakefileを指定する場合は、makeの「-f」と「--file」パラメータ、例えばmake-f Make.Linuxまたはmake--file Make.AIX.
3、自動化変数上記のモードルールでは、ターゲットと依存ファイルは一例のファイルですが、異なる依存ファイルから対応するターゲットを生成するためにどのようにコマンドを書きますか?パターンルールの解析のたびに、異なるターゲットと依存ファイルになるからです.自動化変数はこの機能を完了します.前に、自動化変数について言及しましたが、ここで感性を認識していると信じています.自動化変数とは,この変数がモードで定義された一連のファイルを自動的に1つずつ取り出し,すべてのモードに合致するファイルが取り出されるまでである.この自動化変数は、ルールのコマンドにのみ表示されます.次に、すべての自動化変数とその説明を示します:$@はルール内のターゲットファイルセットを表します.モード・ルールで複数のターゲットがある場合、$@はターゲットのモード定義に一致する集合です.$%ターゲットが関数ライブラリファイルである場合のみ、ルール内のターゲットメンバー名を表します.たとえば、ターゲットが「foo.a(bar.o)」である場合、「$%」は「bar.o」であり、「$@」は「foo.a」である.ターゲットが関数ライブラリファイルでない場合(Unixでは[.a]、Windowsでは[.lib])、値は空です.$<依存ターゲットの最初のターゲット名.依存ターゲットがモード(%)で定義されている場合、$<はモードに適合する一連のファイルセットになります.注意して、それは1つ1つ取り出したのです.$?ターゲットよりも新しい依存ターゲットのすべての集合.スペースで区切ります.$^すべての依存ターゲットの集合.スペースで区切る.依存ターゲットに複数の重複がある場合、この変数は重複依存ターゲットを除去し、1部のみ保持します.$+この変数は「$^」に似ており、すべての依存ターゲットの集合でもあります.ただし、重複する依存ターゲットは除去されません.$*この変数は、ターゲットモードの「%」とその前の部分を表します.ターゲットが「dir/a.foo.b」であり、ターゲットのモードが「a.%.b」である場合、「$*」の値は「dir/a.foo」である.この変数は、関連付けられたファイル名を構築するのに比較されます.ターゲットにパターンの定義がない場合、「$*」も導出できませんが、ターゲットファイルの接尾辞がmakeで認識されている場合、「$*」は接尾辞の一部を除きます.たとえば、ターゲットが「foo.c」の場合、「.c」はmakeで認識できる接尾辞名であるため、「$*」の値は「foo」です.この特性はGNU makeであり、他のバージョンのmakeと互換性がない可能性が高いので、暗黙的なルールや静的モードでない限り、「$*」の使用をできるだけ避けるべきです.ターゲットの接尾辞がmakeで認識されない場合、$*は空の値です.更新された依存ファイルのみを操作したい場合は、「$?」明示的なルールでは便利です.たとえば、他のいくつかのobjectファイルで更新される関数ライブラリファイル「lib」があるとします.では、objectファイルをパッケージ化する比較的効率的なMakefileルールは、lib:foo.o bar.o lose.o win.o ar r lib $? 上記に列挙した自動量変数にあります.4つの変数($@、$<、$%、$*)は拡張時に1つのファイルしか存在しませんが、もう3つの値は1つのファイルリストです.この7つの自動化変数は、ファイルのディレクトリ名または現在のディレクトリのモードに合致するファイル名を取得することもできます.「D」または「F」の文字を組み合わせるだけです.これはGNU makeの古いバージョンの特性で、新しいバージョンでは関数「dir」や「notdir」を使えばできます.「D」の意味はDirectory、ディレクトリ、「F」の意味はFile、ファイルです.以下は、上の7つの変数に対してそれぞれ「D」または「F」の意味を加える:$(@D)は「$@」のディレクトリ部分(スラッシュで終わらない)を表し、「$@」の値が「dir/foo.o」であれば「$(@D)」は「dir」であり、「$@」にスラッシュが含まれていなければ「.」である.(現在のディレクトリ).(@F)は「$@」のファイル部分を表し、「$@」の値が「dir/foo.o」の場合、「$(@F)」は「foo.o」であり、「$(@F)」は関数「$(notdir$@)」に相当する.「$(*D)」「$(*F)」は、前述したのと同様に、ファイルを取るディレクトリ部分とファイル部分でもあります.上記の例では、「$(*D)」は「dir」を返し、「$(*F)」は「foo」「$(%D)」「$(%F)」は、関数パッケージファイルメンバーのディレクトリ部分とファイル部分をそれぞれ表す.これは、「archive(member)」形式のターゲットの「member」に異なるディレクトリが含まれている場合に役立ちます.「$(