makeを使ってソフトウェアをビルドしてみよう仕事で使える魔法のLAMP(8)

今回は、ビルド作業に必要な「make」というコマンドの使い方と、makeコマンドが実際にしている処理の内容を解説します(編集部)

» 2011年06月07日 00時00分 公開
[山口晴広株式会社イメージズ・アンド・ワーズ]

コンパイラやリンカのコマンドを順次実行するのがビルド

 前回はライブラリの概要を解説しました。実はライブラリを利用するときは、インクルードファイルというものにも注意しなければならないのですが、これは次回以降に取り上げることして、今回はmakeコマンドについて解説します。

 ここで、フリーソフトウェアオープンソースソフトウェア(以下FOSS)をインストールするときの一般的な手順を思い出してください。連載第6回では、以下のようにコマンドを入力すると説明しましたね。ここで2番目に実行しているのがmakeコマンドです。

$ ./configure
$ make
$ sudo make install

 このmakeコマンドがソフトウェアをビルドするのです。第6回と第7回では、その裏側で動いている作業と関連する用語について解説しました。それを簡単にまとめると次のようになります。

 最初に、コンパイラで、ソースコードファイルをコンパイルして、オブジェクトファイルにします。続いて、コンパイルしたオブジェクトファイルとライブラリを、リンカでリンクして、実行形式ファイルにするということになるわけです。

 つまり、ビルドという作業の実体はコンパイラやリンカのコマンドを順次実行していくことにほかなりません。第6回では実際にコンパイラを実行する例を示しました。ソースコードファイルが1つだけのごく単純な例でしたから、コンパイラのコマンドを一度実行しただけで実行可能な形式のファイルが完成しました。しかし、現実のFOSSはソースコードファイルの数は多く、ビルド手順も複雑です。

 ビルド手順が長く複雑になれば、人の手で順番に実行するというのは現実的ではなくなってきます。そのため、ビルドの手順は自動化しなくてはなりません。自動化のためのソフトウェアを一般にビルドツールと呼び、makeはその代表格です。makeは主にC言語で記述したプログラムのビルドに使う、歴史のあるツールです。もちろんmake以外にもビルドツールはあり、LAMPで関係するものとしてはMySQLなどで使うCMakeがあります。

シェルスクリプトではダメなのか?

 コマンドの実行手順を自動化する手段といえば、真っ先にシェルスクリプトを思い浮かべる人も多いでしょう。シェルスクリプトでビルドするわけにはいかないのだろうかと疑問を抱く方もいらっしゃるかもしれません。FOSSを独自にビルドするときは、ビルドツールの使い方や設定方法もある程度覚えなければならないわけですから、覚えることを増やすよりも、既存の技術で何とかしたいと思うのは自然です。

 そもそもmakeなどのビルドツールは、インストールするユーザーだけが利用するものではありません。ソフトウェア開発者も開発中に利用するものです。というより、利用する回数は開発者のほうがずっと多いでしょう。ソフトウェアの開発中は、何度も繰り返しビルドを実行しますし、開発が進むにつれてビルド手順が増えることもあります。手順を書き換える必要に迫られることもあります。

 このような状況で開発者が求めるのは、単に手順通りビルドできればよい、というツールではありません。ビルド手順を簡潔に表すことができて、高速にビルドできるツールが必要なのです。さらにはOSなどのプラットフォーム間の互換性を維持したいということもあります。ビルドツールはそういった期待に応えるべく設計されているのです。

実際に使ってみよう

 簡単なサンプルプログラムを用意して、実際にmakeを使ってみましょう。まずはmakeをインストールします。

$ sudo yum install make

 次に、C言語で記述したソースコードのファイルを2つ用意します。それぞれに「main.c」「hello.c」という名前を付けましょう。これは第6回の例で使った「Hello, World!」と表示するコードを元に、文字を表示する部分だけ別のソースコードファイルに移動して、2つに分割したものです。

●main.c
main()
{
  hello();
}
 
 
●hello.c
#include
 
hello()
{
  printf("Hello, World!\n");
}

 用意した2つのソースコードから実行可能な形式のファイルをビルドするには、次のようにコマンドを実行します。gccの-cオプションはコンパイルのみ実行するように指示するものです。

$ gcc -c main.c
$ gcc -c hello.c
$ gcc main.o hello.o -o hello

 3行目にgccを実行しているのがリンク作業になります。gccは内部でリンカを呼び出しますので、リンカとしても振る舞えるのです。素のリンカはldというコマンドですが、通常はldを使わず、gcc経由で使います。リンク時は実行形式のファイル名を-oで指定していますが、コンパイル時は、コンパイル後にできるオブジェクトファイルの名前を指定する必要はありません。コンパイラが自動的に拡張子を.oに変更して保存します。

 さて、このビルド手順をmakeコマンドで置き換えてみます。その前に、先ほど作った実行可能な形式のファイルとオブジェクトファイルを削除しましょう。

$ rm hello main.o hello.o

 makeにはビルドに関する情報を格納した設定ファイルが必要です。これは、Makefileというファイル名がデフォルトになっています。次の内容でMakefileを作成してください。

hello: main.o hello.o

 たった1行のファイルですが、これがあればmakeでビルドできます。実際にmakeを実行してみましょう。コマンドシェルで「make」とだけ入力してEnterキーを押してください。次のような文字列が現れ、ビルドが完了するはずです。

$ make
cc    -c -o hello.o hello.c
cc    -c -o main.o main.c
cc   hello.o main.o   -o hello

 コンパイラのコマンドがccになっているのと、オブジェクトファイルの名前を明示していることを除けば、ビルドの手順は同じになっていることが分かると思います。実は、コンパイラのコマンド名は標準ではccになっています。gccをインストールしたときにgccへのリンクとしてccも自動的に作成されているため、ccでも動作するのです。

 では、ここで次のようにコマンドを実行してみましょう。touchはファイルの更新日時をコマンド実行時点に書き換えるコマンドです。

$ touch hello.c

 完了したら、もう一度makeを実行してみてください。

$ make
cc    -c -o hello.o hello.c
cc   hello.o main.o   -o hello

 すると、main.cをコンパイルすることなく、hello.cだけをコンパイルしてリンクを実行することが分かります。これはファイルの更新日時を比較して、必要最小限の手順で済むようにmakeが制御しているのです。ファイルを削除しても、必要なものだけが生成されます。いろいろ試してみてください。

 ソフトウェアの開発中は1つ〜2つのソースコードファイルを編集してはビルド、という工程を繰り返します。たった2ファイル、しかも内容も数行だけでは不要な作業を省略する仕組みの効果は感じられません。しかし、大量のソースコードから実行可能な形式のファイルをビルドするときは、不要な作業を省略することでビルド時間を大幅に短縮できるのです。ビルド中は待つしかありませんので、これは開発者にとっては非常に大きなメリットです。

 次回は、makeやMakefileについてさらに詳しく解説します。

著者紹介

株式会社イメージズ・アンド・ワーズ
代表取締役
山口晴広(やまぐち はるひろ)



「仕事で使える魔法のLAMP」バックナンバー

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。