# makeを使ってCのコンパイルで楽をしよう!

# どうしてmakeを使うのか

私はいま大学生をしていますが、そこでC言語の授業があります。C言語のコンパイルはだるいので、 簡単にコンパイルするためのツールが使いたい! ということでmakeを使っています。

# makeとは

makeというのはたくさんのファイルに渡るコードベースがあったとき、自動的に何が再コンパイルが必要か判断し、コンパイルしてくれる便利なプログラムです。
簡単に言えば「makeと打てばすべてのコードをコンパイルしてくれる」というツールです。

# 簡単な使い方(コンパイルするファイルが一つのとき)

コンパイルするファイルが一つのときにはあまりmakeの恩恵が感じられませんが一番簡単な例なので載せておきます。
ディレクトリの中身が次のようになっているとします。

sample
├── Makefile
└── main.c

このとき、Makefileに次のように記述します。

main:

これだけです。
これを入力して、コマンドラインで次のコマンドを打ちます。

$ make
cc     main.c   -o main
$ ls
Makefile  main  main.c

これでmainというバイナリが生成されます。簡単ですね!

# 解説

# Makefile

Makefileはざっくり書くと次のような文法でかけます。

タスク名: ソースファイル名(.c -> .oに変える) もしくはタスク
	バイナリを出力するための手順

このとき、タスク名とソースの名前が同じ時、タスク名の名前のバイナリを吐き、手順を省略できます
また、タスク名とソース名が同じ時ソースのファイル名は省略可です。

よって、main.cからmainを吐くには

main:

でOKです。
しっかりとすべてを書くとすると、

main: main.o
	gcc -o main main.c

となります。

MakefileではインデントはTabで行う必要があります。

# makeコマンド

実行方法です。

$ make [タスク名] [変数=データ]*

タスク名や、変数は省略できます。
タスクが複数ある時にタスク名を省略するとallを実行します

# 複数ファイルをコンパイルするとき

例えばmain.c,foo.c,bar.cをすべてコンパイルして、foobarというバイナリを作りたい時、

DEPS=main.o foo.o bar.o

all: foobar

foobar: $(DEPS)
	$(CC) $(DEPS) -o $@

clean:
	rm -f foobar *.o

これでできます。
ばらばらにして考えると、

DEPS=main.o foo.o bar.o

これでDEPSという変数を定義して、必要なソースの一覧を格納しています。

all: foobar

makeは複数のタスクがある時、allを使うのでallfoobarを依存関係として書いています。

foobar: $(DEPS)

foobarを変数DEPSから作りたいので変数の値を取り出すために$()で囲っています。

	$(CC) $(DEPS) -o $@

多数の変数が出ていますが

  • $(CC)コンパイラ
  • $(DEPS)はソースファイル
  • $@はタスク名

です。
つまり

	gcc main.o foo.o bar.o -o foobar

みたいなものです

clean:
	rm -f foobar *.o

コンパイルには必要ありませんが、make cleanと実行することでコンパイルされたファイルの削除を簡単にできます。

# 終わりに

makeを使うとCで書かれたソースを簡単にコンパイルすることができます。これでC言語ライフを楽しみましょう!C言語やるよりかはPythonとか他の言語やったほうがいい気がするけどなぁ

profile picture
Pineapplehunter
農工大生のLinux好きの人です。