プロジェクトのコンパイルルールを知りたいなら、Makefileを知っておく必要があります.

13162 ワード

本文は陳皓先輩の私と一緒にMakefileを書いて、勉強の記録に使います!
1.Makefileの前奏知識
Makefileの知識を知る前に、コンパイルとリンクとは何かを知る必要があります.完全なプロジェクトソースコードから最終的に書き込み可能なプログラムを生成するには、コンパイルとリンクのプロセスが必要です.コンパイルとは、ソースファイルを中間ターゲットファイルに生成することです.(たとえば.cファイル生成.oファイル、各ソースファイルに対応する中間ターゲットファイル)では、リンクとは、中間ファイルを実行可能ファイルに合成することを意味します.コンパイル時に必要なのは文法の正確さ、関数と変数の宣言の正確さです.リンク時には、主にリンク関数とグローバル変数です.したがって、中間ターゲットファイルを使用してアプリケーションをリンクすることができますが、ソースファイルが多すぎて、コンパイルで生成された中間ターゲットファイルも多く、リンク時に中間ターゲットファイル名を明らかに指摘する必要があります.これはコンパイルに不便なので、中間ターゲットファイルにパッケージを作ります(Windowsではライブラリファイル、.libファイル、linuxでは.aファイル).
2.Makefileとは
1つの完全なプロジェクトの中で、ソースファイルは多くの額で、しかも機能、タイプ、モジュールなどのソースファイルによって多くの異なるディレクトリの下に置いて、Makefileは主にどのファイルがコンパイルする必要があるか、どのファイルが先にコンパイルする必要があるか、どのファイルが再コンパイルする必要があるかなどを指定するために使用されます.makefileがもたらす最大のメリットは自動化コンパイルであり、1つのプロジェクトがmakeコマンドを実行するだけで、プロジェクト全体が私たちが望むように自動的にコンパイルされ、便利になります.
3.Makefileルール
Makefileの最も核心的なルールは、ターゲット、依存、コマンドです.書くルールは次の通りです.
target:prerequisites //target      ,prerequisites             
	command   //       tab     
a.o:a.c a.h   //      a.o     a.c a.h
	gcc -c  a.c

targetファイルはprerequisitesに依存し、targetファイルがtargetファイルより新しいかprerequisitesファイルがないか、commandコマンドが実行されます.
Makefileの例
//       3    
edit:main.o kbd.o command.o display.o insert.o search.o files.o utils.o
	cc -o edit mian.o kbd.o command.o display.o insert.o search.o files.o utils.o

main.o:main.c main.h
	cc -c main.c

kbd.o:kbd.c defs.h command.h
	cc -c kbd.c

command.o:command.c defs.h command.h
	cc -c command.c

display.o:display.c defs.h buffer.h
	cc -c display.c

insert.o:insert.c defs.f buffer.h
	cc -c insert.c

search.o search.c defs.h buffer.h
	cc -c search.c

files.o:files.c defs.h buffer.h command.h
	cc -c files.c

utils.c: utils.c defs.h
	cc -c utils.c

clean:
	rm edit main.o kbd.o command.o display.o insert.o search.o files.o utils.o

4.makeがどのように働いているか
デフォルトでは、makコマンドのみを入力します.1.makeは現在のディレクトリの下に「makefile」または「Makefile」という名前のファイルを探します.見つかった場合、ファイルの最初のターゲットファイルが見つかります.上記の例では、最初のターゲットファイルが「edit」というファイルであり、このファイルを最終的なターゲットファイルとします.3.editというファイルが存在しない場合、またはeditが依存する後の.oファイルの変更時間はeditというファイルより新しいので、後で定義したコマンドを実行してeditというファイルを生成します.4.editが依存する場合.oファイルも存在する、makeは現在のファイルでターゲットを探します.oファイルの依存性、例えばmain.o、またmainを探しに行きます.o mainに依存する.cとmain.h. makeのプロセス全体は、最終的に最初のターゲットファイルがコンパイルされるまで、ファイルを探す依存関係です.
5.makefileでの変数の使用
上の例ではmain.o kbd.o command.o display.o insert.o search.o files.o utils.o何度も使用していますが、変数を定義して上記の例をいくつか改善することができます.
objs=main.o kbd.o command.o display.o insert.o search.o files.o utils.o

edit:$(objs)
	cc -o edit $(objs)

main.o:main.c main.h
	cc -c main.c

kbd.o:kbd.c defs.h command.h
	cc -c kbd.c

command.o:command.c defs.h command.h
	cc -c command.c

display.o:display.c defs.h buffer.h
	cc -c display.c

insert.o:insert.c defs.h buffer.h
	cc -c insert.c

search.o:search.c defs.h buffer.h
	cc -c search.c

files.o:files.c defs.h buffer.h command.h
	cc -c files.c

utils.o:utils.c defs.h
	cc -c utils.c

clean:
	rm edit $(objs)

6.makeを自動的に導く
make機能は強力で、ファイルやファイル依存関係の後のコマンドを自動的に導くことができるので、それぞれに必要ありません.oファイルの後ろにコンパイルのコマンドが書かれています.makeの時、一つだけ.oファイルは自動的にcファイルは依存関係に追加されます.例えばmakeの時にa.oを見つけると、a.cはa.oの依存関係であり、cc-c a.cも導出される.したがって,上記の例の新しいmakefileはまたこのように書くことができる.
objs=main.o kbd.o command.o display.o insert.o search.o files.o utils.o

edit:$(objs)
	cc -o edit $(objs)

main.o:defs.h
kbd.o:defs.h command.h
command.o:defs.h command.h
display.o:defs.h buffer.h
insert.o:defs.h buffer.h
search.o:defs.h buffer.h
files.o:defs.h buffer.h command.h
utils.odefs.h

.PHONY:clean
clean:
	rm edit $(objs)

7.変わったスタイルのmakefile
前述の例では,依存には多くの重複がある.hファイル、気分が悪いように見えます.書き換え方法は以下の通り
objs=main.o kbd.o command.o display.o insert.o search.o files.o utils.o

edit:$(objs)
	cc -o edit $(objs)

$(objs):defs.h
kbd.o command.o files.o:command.h
display.o insert.o search.o files.o:buffer.h

.PHONY:clean
clean
	rm edit $(objs)

8.ターゲットファイルのクリアルール
makefileごとにターゲットファイル(.oと実行ファイル)を空にするルールを書く必要があります.これは再コンパイルが容易であるだけでなく、バカファイルのクリーン化にも役立ちます.一般的なスタイルは:
clean:
	rm edit $(objs)

より堅牢な方法は、
.PHONY:clean
clean:
	-rm edit $(objs)

.PHONYはcleanが「偽のターゲット」であることを意味し、rmでお金にマイナス記号をつけるように命令したのは、一部のファイルに問題があるかもしれないが、気にしないで、後のことを続けているという意味だ.cleanは一般的にファイルの最後に置かれます.