技術は楽するために

日々の開発で作ったプログラムの一部を公開していきます。

超簡単なmakefile 第2回

第1回から随分月日が経ってしまいましたが、第2回です。
前回は、以下のようなサンプルのMakefileを使ったコンパイル、ビルドの手順について書きました。


そして今回は、サンプルのMakefileを書く手順について1つ1つ意味を確認していきます。
私は、Makefileは3つのブロックに分けて考えると理解しやすいと考えています。
1. Makeに必要な情報
2. ターゲットの生成
3. Make実行オプション

では、各ブロックにわけて説明していきます。

1. Makeに必要な情報

Makeに必要な情報を記載してきます。コンパイルの下準備的な感じです。サンプルの1-19行目に当たります。

(1)コンパイラ

使用するコンパイラを記載します。今回は、gccコンパイラを使っています。
ただし、C++コンパイルするため表記はg++です。

(2)コンパイルオプション

コンパイルに使用するオプションです。
追加することで「使用できる機能」や「コンパイル時に出力される警告」などを
制御することができます。
オプションの種類やより詳しい説明は、次回以降とします。

(3)実行ファイル名

実行ファイルの名前をつけます。好きな名前をつけてください。

(4)コンパイル対象のソースコード

コンパイル対象のソースコードを指定します。
今回は、1ファイルしか指定していませんが、ソースファイルが複数ある場合は複数指定してください。
複数指定する場合の例。

SRCS    = hoge1.cpp
SRCS    += hoge2.cpp
SRCS    += hoge3.cpp
(5)オブジェクトファイル名

オブジェクトファイルの名称を定義します。
ソースファイル名と同一のオブジェクトファイルを作ることが多いです。

(6)インクルードファイルのあるディレクトリパス

参照するインクルードファイルが存在するパスを指定します。
インクルードファイル名は記載不要です。

(7)ライブラリファイルのあるディレクトリパス

OSSなどライブラリを指定する必要がある場合は、そのライブラリが存在するパスを指定します。
今回は、省略しています。

(8)追加するライブラリファイル

(7)同様、省略します。

2. ターゲットの生成

ここで言うターゲットとは「TARGET」と「OBJS」のことを指します。
「1.」で示した情報を形成して、オブジェクトファイルと実行ファイルの生成ルールを記述する箇所になります。
サンプルの21-27行目に当たります。

(9)ターゲットファイル生成

以下の2行の構成でターゲットファイルの生成ルールを記述しています。

$(TARGET): $(OBJS)
	$(CC) -o $@ $^ $(LIBDIR) $(LIBS)

1行目は、$(TARGET): $(OBJS)と記載して、「TARGET」が「OBJS」に依存することを示しています。
2行目は、コマンド行と言います。リンク対象のライブラリを指定します。
今回は、リンクするライブラリは存在しないため、「OBJS」との依存関係のみ管理することになります。

(10)オブジェクトファイル生成

(9)で依存する「OBJS」の生成ルールです。オブジェクトファイルは、ソースと機械語の中間ファイルに当たるため、ソースコードに依存します。
基本的な記載ルールは、(9)と同じです。

3. Make実行オプション

実は、「1.」、「2.」だけでコンパイルおよびビルドはできるのですが、
makeのルールをオプションとして自由に定義することが可能です。
こうすることで、より効率よくコンパイル、ビルドができるようになります。
サンプルでは、よく指定される、2つ例を示します。
サンプルの29-33行目に当たります。

(11)"make all"で make cleanとmakeを同時に実施。

タイトルのとおり、(12)のcleanとmakeコマンドを同時に実行してくれるallオプションを作りました。
make allとうつだけで、前のビルド時に生成したファイルを削除したうえで、再ビルドを実行してくれます。

(12).oファイル、実行ファイル、.dファイルを削除

ビルドで生成したファイルを削除します。
削除対象は、オブジェクトファイル、実行ファイル、そしてデフォルトで生成される依存関係ファイルを削除してくれます。