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
となります。
TIP
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
を使うのでall
にfoobar
を依存関係として書いています。
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とか他の言語やったほうがいい気がするけどなぁ