処理のフロー
図のように3つのソースファイルを用意します。それぞれのファイルの概要は次のとおりです。ファイル名 | 説明 |
---|---|
main.c | メインのソースコード |
sub.c | ユーザ定義関数を含むソースコード |
sub.h | ユーザ定義関数のヘッダファイル |
*.o | *.cファイルをコンパイルして生成したオブジェクトファイル |
prog2 | 2つのオブジェクトファイルをリンクして作成される実行ファイル |
prog2: main.o sub.o gcc -o prog2 main.o sub.o main.o: main.c sub.h gcc -c -o main.o main.c sub.o: sub.c sub.h gcc -c -o sub.o sub.c各ソースコードについては、末尾に掲載します。
Makefileの説明
処理ルールと入力ファイル
図の青い部分は、処理を表しています。Makefileでもそれに対応して、3つのルールが記載されています。 前回は、:の右側の入力ファイルがひとつだけの例を紹介しました。今回の例のように入力ファイルを複数記述することも可能です。 その場合、入力ファイルのどれか一つでも変更があれば、出力ファイルを作成するための処理が実行されます。ルール記述の順序
Makefileの中でprog2の作成ルールが最も先頭に記載されています。例えば、main.oの作成ルールを先頭にすることはできません。 なぜなら、Makefileは、複数のルールが記述されていた場合、先頭のルールで記述された出力ファイルを作成しようとするからです。 つまり、main.oの作成ルールが先頭にあると、makeを実行してもmain.oが作成されて動作が完了します。
prog2の入力ファイルとしてmain.oとsub.oが記述されています。 初めてmakeを実行する場合、これらのファイルが存在しません。 その場合、makeは、次のようにmain.oとsub.oの作成ルールにしたがって、それらを作成します。
$ make gcc -c -o main.o main.c gcc -c -o sub.o sub.c gcc -o prog2 main.o sub.o
一部のファイルを更新
ここで、sub.cだけを更新してみます。実際には内容を更新しますが、ここではmakeの動作を確かめるのが目的なので、touchコマンドでタイムスタンプのみ更新します。touch sub.cmakeを実行するとsub.oが再作成され、それに依存しているprog2も再作成されました。 main.oについては、その入力ファイルであるmain.cが更新されていないため、なにも処理が行われませんでした。 このように依存関係にしたがって、必要な処理のみを実行することがmakeの利点です。
$ make gcc -c -o sub.o sub.c gcc -o prog2 main.o sub.o
ヘッダファイルの更新
sub.hは、main.cでもsub.cでも使われており、main.oおよびsub.o両方の入力ファイルとしてMakefileに記載されています。 このヘッダファイルを更新すると、以下のようにどちらの.oファイルが更新されて、それに依存するprog2も再作成されます。$ touch sub.h $ make gcc -c -o main.o main.c gcc -c -o sub.o sub.c gcc -o prog2 main.o sub.o
ソースコード
main.c
#include <stdio.h> #include "sub.h" int main() { printf("Calculated result: %d\n", calc(1, 3)); return 0; }
sub.h
int calc(int a, int b);
sub.c
int calc(int a, int b) { return a * 2 + b - 1; }
まとめ
本記事では、複数のルールをMakefileに記述する方法について説明しました。 次回は、自動変数と拡張子ルールという機能を説明します。
以下には、make入門の全記事がリストアップされています。
0 件のコメント:
コメントを投稿