いままでのプログラムであれば,リスト
1〜
3
をひとつのファイルで書いていた.そして,「
gcc」コマンドでコンパイルを行い
実行ファイル(機械語)を作っていた.なぜ,ソースプログラムはリストリスト
1〜
3のように分割する必要があるのだろう
か? これらのファイルに記述されていることは今までひとつのソースファイルに書いていたこと
である.
ソースプログラムを分割する理由として,参考文献 [2]には以下のような
記述がある.
-4pt
- 機能単位の開発を可能にする.
- モジュールごとのテスト/デバックを可能にする.
- 必要があれば,ソースコードを隠蔽し,モジュールのみを提供することができる.
- プログラムを修正した際に,必要な部分のみコンパイルすることができる.
- モジュールの再利用性を高める
- プログラムの見通しを良くする.
これらの理由の大部分は,長いプログラムを書くためと考えてよい.世の中で使われてい
るある程度のプログラムはソースコードは長く,複数のプログラマーによって書かれてい
る.このように複数のプログラマーでひとつのプログラムを作成する際に,分割コンパイ
ルは威力を発揮する.プログラマー毎,あるいは機能別にソースプログラムを書くことが
でき,各々がコンパイルすることができる.分割したファイル毎に,バグ取りができるの
である.最後に完成した全てのファイルを集めて,コンパイルすれば実行ファイルを作る
ことができる.
プログラムの分割は,いままで作成したソースプログラムを適当なファイルに書き出すだ
けで特別なテクニックは無い.実際には,プログラマー毎,あるいは機能別に開発のしや
すいように分割すればよい.最初からソースプログラムを分割して開発するのである.こ
うして分割したファイル毎にコンパイルを行い,エラーの無いプログラムを作成する.全
てのファイルができあがったの後,合わせてコンパイルを行いひとつの実行ファイルを作
成する.
このテクニックは一人でプログラムを作成する場合にも有効である.私がある程度のプロ
グラムを開発するとき,機能別に分けてソースファイルを作る.そうするとプログラムが
整理でき,分かり易くなる.
先ほどの例では,リスト
3がヘッダーファイルである.これには関
数のプロトタイプ宣言が書かれている.プロトタイプ宣言は,ソースプログラムをコンパ
イルする際に,引数や戻り値が正しいか?--のチェックのときに参照される.そのため,
リスト
1やリスト
2をコンパイルするときに必要である.
これらのプログラムをコンパイルするときに,それぞれのファイルの先頭にプロトタイプ
宣言を書くと二度手間である.同じことを2つのファイルに書かなくてはならない.100個
のソースファイルに使われている関数があれば,100個のソースファイルに同じプロトタ
イプ宣言を書くことになる.そうなると,たぶん間違いが生じる.そこで,プロトタイプ
宣言をヘッダーファイルにまとめて,それぞれのソースファイルで読み出すことが考えら
れた.リスト1やリスト2の#include
"functions.h"は,指定されたファイル--ここでは functions.h --を呼び出して,こ
の部分に書けという命令である.
参考文献 [
2]によると,ヘッダーファイルに書くべきものは,以下の通り
である.
-4pt
- 外部に公開するマクロ定義(関数型のマクロの定義)
- 外部に公開する定数の定義(#defineやenumによる定義)
- 外部に公開する構造体,共用体の定義
- 外部に公開する方の定義(typedefによる型の定義)
- グローバル関数のプロトタイプ宣言
- グローバル変数のextern宣言
ようするに分割した他のソースファイルでも使うものをヘッダーファイルに書け--とい
うことである.これらヘッダーファイルに書くべきものは,分割されたソースファイルの
コンパイルに必要なものである.リスト
3は,グローバル関数のプ
ロトタイプ宣言が書かれている.
複数のソースファイルがある場合,ひとつひとつコンパイルする作業は大変である.コン
パイル方法を書いたファイルをひとつ作り,それを実行させることによりコンパイルでき
れば便利である.
このような用途のために Makefile がある.リスト1〜
3から構成されるソースファイルは,リスト4
のようなメイクファイルにより,コマンド「make」一発でコンパイルできる.極め
て便利である.構成するファイルの数が多くなればなるほど,この恩恵にあずかれる.
Makefileの書き方の基本は,次の通りである.
ターゲット : 構成ファイル
コマンド行
ターゲットはコマンド行を実行させて作成されるファイル
2である.構成ファイルは,ターゲットを構成す
るファイルである
3.コマンド行は,コマンドを書く.その先頭は,「
Tab」ではじめなくては
ならない.スペースはダメである.
リスト4の例を見ると
main.o : main.c
gcc -c main.c
となっている.オブジェクトファイル
main.o がターゲットで,
main.cがその
構成ファイルである.オブジェクトファイルは,コマンド行に示すように,gcc にオプショ
ン(-c)を付けて作成する
4.オブジェクトファイルとは,ほとん
ど機械語でできたファイルで,必要なオブジェクトファイルをまとめる(リンク)と実行ファ
イルができあがる.オブジェクトファイルから,実行ファイルを作成する部分はMakefile
上で
mkdat : main.o functions.o
gcc -o mkdat main.o functions.o -lm
である.
Makefileには,この他にもたくさんの便利な機能がある.それを書き出すだけでも一冊の
本になるくらいである.諸君が長いプログラムを書くときに,Makefileのさまざまな機能
の書き方に付いて学習すれば良いだろう.
ホームページ:
Yamamoto's laboratory著者:
山本昌志
Yamamoto Masashi
平成19年5月8日