学生実験1-3 : Make, CVS の使い方
- 更新情報
- 進め方
- コンテンツ
- 1. Make の使い方
- 1.1 make とは何か: Level 1
- 1.2 make の挙動
- 1.3 makefile を書く: Level 2
- 1.4 make の利用例(オプション)
- 1.5 ネット上に公開されているソフトウェアをコンパイルしてみる
- 2. CVS の使い方
- 2.1 CVS とは何か
- 2.2 クイックスタート
- 2.3 CVS での一日の作業: Level 3
- 1. Make の使い方
- 用語説明
- 参考文献・サイト
実験の進め方
- 内容と達成目標
-
今回のテーマ「make と cvs の使い方」では,システム開発の際に必須のツールと言える make, cvs の基本的な使い方を習得する.make に関してはプログラミング1 or 2 で触れているが,その復習も兼ねて実習を行う.
- 達成目標1:make が必要とされる理由を理解し,自ら開発するシステムに関する Makefile を書けるようになる.
- 達成目標2:オープンソースとして公開されているソフトウェアをインストールできるようになる.
- 達成目標3:バージョン管理ソフト cvs が必要とされる理由を理解し,今後の開発において cvs を導入することが出来る.
- 達成目標4:複数人による共同作業(プログラミング)で利用されているリポジトリに対し,競合時の問題を解決できる.
- 進め方
-
- テキスト・補助教材:本ページや参考文献参照(サンプルソースあり)
- 作業スタイル:個人作業(1人1レポート)
- 評価基準
-
(先週と同じ)レポートでは指定した課題をこなしている(提出している)事を前提に基準点を設け,適宜加点・減点を行う.
- 課題と提出方法
-
- 1人1レポート提出.
- 全ての Level にトライし,レポートとしてまとめよ.ただし,Level 4 は 4.3 のグラフ作成(1つ)までを必須とする.
- 本文とは分けて表紙を作成する事.表紙には以下の項目を記述すること.
- 課題番号,タイトル,担当教員名
- 氏名,学籍番号
- 実験日,提出期限日,提出した日
- レポートは LaTeX で作成し,印刷物を提出すること.
- 提出期限:4/28(金) のクラスの期限は 5/8(月),5/2(火) のクラスは 5/12(金) 中に 705室へ提出すること.
1. make の使い方
1.1 make とは何か
オンラインマニュアルを読む癖をつけるということで,man から抜粋.NAME make - GNU make utility to maintain groups of programs DESCRIPTION The purpose of the make utility is to determine automatically which pieces of a large program need to be recompiled, and issue the commands to recompile them.
ワンポイント
- 再コンパイルが必要なら,必要な部分を自動的に決定し,コンパイルしてくれる.
→どのように自動化しているのか?/自動化させるためには?
- 簡単な説明として「utility to maintain groups of programs」とありますが,要はコンパイルするためのツールと考えてください.汎用性があるためコンパイル専用ツールでは無いんですが,今回は一般的な使い方についてのみ実習します.
- 「pieces of a large program」とありますが,複数ファイルで構成されるプログラムなら make は便利です.1ファイルの場合でも,「コンパイル時に指定するオプションがある」,「ライブラリ等のパスを指定する必要がある」といった場合には,一々コンパイルの都度長ったらしいオプションを書く必要なく「make」だけでコンパイルすることが可能です.
→ソースは1ファイルのみ,コンパイルも gcc hoge.c するだけの場合は?
とりあえず使ってみる
サンプルプログラム:make-sample.tar.gz
- Level 1.1
- 上記サンプルプログラムをダウンロードし,make を実行せよ.make 実行時,端末上にその動作が表示されるはずである.表示された内容を記録し,その内容が何を意味するのか説明せよ.
# gzip -cd make-sample.tar.gz | tar xvf - # cd make-sample # make (何が実行されているのか,観察し考察せよ.)
- Level 1.2
- どれか1つ以上のソースファイルを編集・保存し,make を実行せよ(コンパイルが通るのであれば編集内容は問わない).編集対象毎に make の動作は異なるはずである.どのファイルを編集するとどう動作するのかを確認せよ.
- Level 1.3
- touch コマンドにより1つ以上のソースファイルのタイムスタンプを更新し,make を実行せよ.この時の make の動作は Level 1.2 と比較して同じはずである.何故このような動作になっているのか考察せよ.
1.2 make の挙動
SYNOPSIS make [ -f makefile ] [ option ] ... target ... (DESCRIPTION) To prepare to use make, you must write a file called the makefile that describes the relationships among files in your program, and the states the commands for updating each file. In a program, typically the exe- cutable file is updated from object files, which are in turn made by compiling source files. Once a suitable makefile exists, each time you change some source files, this simple shell command: make suffices to perform all necessary recompilations. The make program uses the makefile data base and the last-modification times of the files to decide which of the files need to be updated. For each of those files, it issues the commands recorded in the data base. make executes commands in the makefile to update one or more target names, where name is typically a program. If no -f option is present, make will look for the makefiles GNUmakefile, makefile, and Makefile, in that order. Normally you should call your makefile either makefile or Makefile. (We recommend Makefile because it appears prominently near the begin- ning of a directory listing, right near other important files such as README.) The first name checked, GNUmakefile, is not recommended for most makefiles. You should use this name if you have a makefile that is specific to GNU make, and will not be understood by other versions of make. If makefile is `-', the standard input is read. make updates a target if it depends on prerequisite files that have been modified since the target was last modified, or if the target does not exist.
ワンポイント
- make を使うには makefile が必要(デフォルトは Makefile).
→複数の makefile がある場合,ファイルを指定するにはどうするのか?
- makefile では「ファイル間の関係と,各ファイルを更新するためのプログラム」を記述する.
例:a.out を作成するためには sampleA.o, sampleB.o が必要であり,これらは sampleA.c, sampleB.c を gcc -c でコンパイルすることで作成する.
→Level 1 のサンプルはどのような構成になっているか?
- make は Makefile とファイルの最終更新時刻を利用して更新する必要のあるファイルを決定し,必要に応じて更新する.
→どういうときに再コンパイルする必要があるのか?
1.3 makefileを書く
基本形
target: [source] [command]
- 「: source」や「 command」の空白は「タブ」で入力すること.
- ソースやコマンドは省略可能である.(ソースを省略すると,常にコマンドが実行される)
- 複数のターゲットが存在する場合,(make 時にターゲットを指定しなければ)最初に書かれたターゲットを生成しようとする.この時,該当ターゲットの生成に関係の無いターゲットは生成しない.
- Level 2.1
-
サンプルには幾つかの Makefile 例があり,makefile2 は詳細動作まで記述した例である.makefile2 の source や command を削除し,make を実行せよ.この例では全く同一の動作になっているはずである.これは make に推論機能が実装されているためである.各自削除した source / command について,具体的に何が推論により補われているのかを示せ.
→(考えてみよう!)ソースとして「hoge.o」を指定した場合,「hoge.c」があれば make はそのソースが cc によりコンパイルします.これは make がそのような関係を知っているからですが,知らないものに対してはどのように教えれば良いのか?
マクロ
CC = gcc CFLAGS = -Wall -O2 LOADLIBS = -lm USER_DEFILED_MACRO = hoge1 hoge2 hoge3
- 上記のように定義した変数(マクロ)は,makefile 中で「$(CC)」のように記述すると,make 実行時に定義した文字列に置き換えて実行する.
→例1:ダウンロードしたサンプル内のmakefile3
→例2:GA for Knapsack
コマンドの応用例
clean: rm -f a.out *.o *~
- 演習1
- 上記の clean は大抵の makefile に定義されている内容である(コマンドやその引数は必要に応じてマクロを使うことが多い).これは何をしているのか.Level 1 でダウンロードした Makefile に類似の機能を記述し,実行せよ.その際,clean 実行前後で何がどう変わるのかを確認しなさい.
1.4 make の利用例
「makefileを書く」で見て来たように,command 部では gcc のようなコンパイラだけでなく,コマンドライン上で実行出来るソフトウェアならば何でも利用することが可能である.いくつか例を見てみよう.
- (TA?)
- LaTeX: Makefile.latex
1.5 ネット上に公開されているソフトウェアをコンパイルしてみる
Makefile は自分が楽するためだけではなく,他の人が利用しやすくするために用意する物でもあります.最近は rpm/fink/epkg などでコンパイル済みのバイナリファイルを直接インストール(コピーするだけ)する方式が増えてきました. make により自分でコンパイルするのと比較した場合の rpm 等の利点・欠点は下記に示したものがあります.
- rpm 等の利点
-
- 自分でコンパイルする必要が無い.
- パッケージの管理が便利(なことが多い).
- rpm 等の欠点
-
- 誰かがパッケージを作成(&公開)するまで待つ必要がある.(epkg は誰が用意しているのか?)
- オプションの指定により機能追加したい等,カスタマイズしたパッケージが欲しい場合には,そのパッケージを探し出す必要がある.(自分でコンパイルした方が早い?)
今回は,例題としてApacheをインストールしてみよう.
- ダウンロード: Apache→ダウンロード→適当なサーバを選択→httpd-2.2.0.tar.gzをダウンロード
- 作業用ディレクトリに移動し,解凍.
% mkdir ~/temp % cd ~/temp % tar xvfz httpd-2.2.0.tar.gz % cd httpd-2.2.0
- コンパイル/インストール方法を確認: README, INSTALLを読んだり,「./configure --help」でインストール時のオプションを設定した上で make を実行する.
(一般的な手順 [今回の手順は別にあります]) % ./configure % make % make test % sudo make install
(今回は ~/apache2 にインストールしてみる) % ./configure --prefix=$HOME/apache2 % make % make install
- 設定ファイルを編集する
% cd ~/apache2/conf % emacs -nw httpd.conf (User, Group, ServerAdmin, ServerName を編集.) User www Group www ServerAdmin j050xx@ie.u-ryukyu.ac.jp ServerName localhost:80
- httpd を起動する
% sudo ~/apache2/bin/apachectl -k start (この apachectl もシェルスクリプトで記述されています!)
- 動作確認する
(1)ブラウザを開き, http://localhost:80/ へアクセスする. (2)アクセスログを確認する % cat ~/apache2/logs/access_log
- httpd を停止する
% sudo ~/apache2/bin/apachectl -k stop
- (オプション課題)configure について
-
- 「configure」は何のために実行する必要があるのか.
- どのようにすれば自分で作成したシステムに configure を導入することが出来るのか.
- 参考キーワード:autoconf, automake
- Easy Package で配布されているパッケージは何故 make する必要がないのか?
2. CVS の使い方
2.1 CVS とは何か
Concurrent Versions System(バージョン管理システム)の略で,プログラムソースだけではなく,テキストベースのファイル一般についてバージョンを管理するためのシステム. 関連するソースファイル一式をプロジェクトとして管理する. ソースファイルの変遷を記録し,日付・リビジョン番号・リソース番号を参照し,任意の時点のソースファイル一式のコピーを取ってくることが可能.
2.2 クイックスタート
iBook で個人用 CVS を使ってみよう!
- 環境変数を設定(メインとなるリポジトリの設定)
# tcsh の人は ~/.tcshrc に以下の設定を記述 setenv CVSROOT $HOME/CVS_DB setenv CVSEDITOR "emacs -nw" # bash の人は ~/.bashrc に以下の設定を記述 export CVSROOT=$HOME/CVS_DB export CVSEDITOR="emacs -nw" (vi 等,emacs 以外を使用したい場合には使用したいエディタを指定)
- シェルに環境変数を読み込む(ターミナルを再起動でもOK)
# tcsh の人 % source ~/.tcshrc # bash の人 % . ~/.bashrc
- リポジトリの作成,確認.
% mkdir ~/CVS_DB % cvs init (一度だけ実行) % ls ~/CVS_DB (~/CVS_DB/CVSROOT/ が作成されていればOK!)
- 例として,ダウンロードした「make-sample」を登録する.
% cd hogehoge/make-sample % make -f makefile2 clean % cvs import make-sample j050xx start (エディタが起動するので, 中身が分かるようにコメントを記入して終了する) (登録が済めば以下のように出力されるはず・・) N make-sample/0readme.txt N make-sample/add.c N make-sample/Makefile N make-sample/makefile1 N make-sample/makefile2 N make-sample/makefile3 N make-sample/multi.c N make-sample/sample.c No conflicts created by this import (この import では競合が発生しなかった) (ls ~/CVS_DB/ や ls ~/CVS_DB/make-sample として確認してみると吉)
- import(新規登録)で登録されていることを確認したら,make-sample を削除し,リポジトリからコピーを取得してみる.
% cd .. % rm -rf make-sample % cvs checkout make-sample (成功すれば以下のような出力が得られます) cvs checkout: Updating make-sample U make-sample/0readme.txt U make-sample/Makefile U make-sample/add.c U make-sample/makefile1 U make-sample/makefile2 U make-sample/makefile3 U make-sample/multi.c U make-sample/sample.c (ls make-sample として,中身を確認してみよう. 一点登録時には無かったモノがあるはずです)
- ソースを更新して,動作確認をした上で,オリジナルと何処が異なるのかを確認する.
% cd make-sample % emacs -nw multi.c ==== multi.c に以下を追加(4行) ==== /* divide: x/y を計算 */ int divide(int x, int y){ return (x/y); } ==== multi.c 追加ここまで ==== ==== sample.c に以下を追加(2行) ==== // 関数宣言部に・・・ int divide(int x, int y); // main 関数内に・・・ fprintf(stdout,"divide(%d,%d)=%d\n",x,y,divide(x,y)); ==== sample.c 追加ここまで ==== (動作確認) % make % ./sample (ちゃんと動いた後で, オリジナル(リポジトリ情報)と比較して どこが変更されているのかを確認する) % cvs status 更新されていないファイルについては File: 0readme.txt Status: Up-to-date 更新されたファイルについては File: multi.c Status: Locally Modified のように, 最新を保っているか, ローカルで更新がなされているのか, 別の誰かが更新されているのか(Status: Needs Patch), を確認できる. 特に,変更箇所を確認したい場合は % cvs diff とすると,変更のあったファイル名,変更点を確認できる.
- 動作確認後,変更したファイルを新バージョンとして登録する.
(ちゃんと動いていれば, 新バージョンとして登録する) % cvs commit (変更されたファイル multi.c と sample.c が自動的に抽出されているのを確認し, 変更内容を記入して保存) (正しくアップデートできれば, 以下のような出力が得られます) cvs commit: Examining . Checking in multi.c; /Users/tnal/CVS_DB/make-sample/multi.c,v <-- multi.c new revision: 1.2; previous revision: 1.1 done Checking in sample.c; /Users/tnal/CVS_DB/make-sample/sample.c,v <-- sample.c new revision: 1.2; previous revision: 1.1 done
- ログ(コメント)を確認してみる.
% cvs log multi.c | nkf -e (コメントは読めますか?)
2.3 CVS での一日の作業
クイックスタートでは具体例を示しながら動作を確認することがメインであったため,全体像が把握しづらかったと思われるが,一般的な作業の流れは以下のようになる.
- import: 新規プロジェクトの登録(プロジェクト開始時の一度のみ).
- checkout: 作業用コピーをチェックアウトする.
- 変更を加える.
- diff, log, update: 自分や共同作業者の作業内容を調べる.
- commit: 最新版としてリポジトリへ変更を通知する.
- Level 3.1
-
余り(%計算)を求める関数 mod(x,y) を mod.c として作成し,main 関数内でその関数を実行するように修正せよ. 動作確認をした後で,新規に追加すべきファイル(mod.c)を追加しつつ,修正した sample.c の修正バージョンの2点を,新バージョンとしてCVSに登録せよ. なお,レポートには cvs commit 時に出力されたログを示すこと.
Hint: cvs add
- Level 3.2
-
現在,make-sample プロジェクトには以下に示すバージョンが含まれているはずである.
- 初期バージョン(ダウンロードしたままのもの.多少の修正はされてても良い)
- 割り算を追加したバージョン
- 余剰計算を追加したバージョン
上記の3バージョン時のソースファイル一式を取り出せ. レポートには取り出した際のコマンドと,その出力結果を引用すること.
- Level 3.3(オプション)
-
make や cvs は共同作業時により有効に機能する. しかし,cvs では checkout 時にロック制御を行わないため,「複数人が現バージョンのコピーを取得し,同じファイルに修正を加える状況(競合)」が起こり得る. この場合,cvs は誰の修正が正しいのかを判断することが出来ないため,ユーザ同士で修正箇所を確認し合い,人手により競合を解決する(正しい修正を通知する)必要がある. 実際にそのような状況を作り出し,実験してみよ.
課題と提出方法
- 課題
-
- 全員必須:全ての Level にトライし,レポートとしてまとめよ.
- オプション:gcc以外にどのような使い道があるか?検討/調査/実験し,その結果を報告せよ.
- 提出方法
-
- 1人1レポート提出.
- レポートは LaTeX で作成し,印刷物を提出すること.
用語説明
- make
- 自動コンパイラ.
- makefile
- make にコンパイル対象・方法を指定するための設定ファイル.
- target, ターゲット
- make で生成したい対象名のこと(例:a.out).指定したターゲットが存在しない場合や,生成元ファイル(ソースと呼びます)の日付が新しい場合に,そのターゲットを生成しようとします.
- source, ソース
- ソースファイル名(例:hello.c).
- command, コマンド
- ソースからターゲットを生成するためのコマンドのこと(例:gcc).
参考文献・サイト
- make 関連
-
- cvs 関連
-
- バージョン管理システム CVS を使う
- CVSリンク集(Web インタフェース, commit 通知システム,安全なサーバを構築する方法,CVS以外の選択肢)
- CVS--Concurrent Versions System v1.11.17
- 書籍:CVSによるオープンソース開発,カールフォーゲル著,オーム社(2002/06)
- バージョン管理システム CVS を使う
- CVSリンク集(Web インタフェース, commit 通知システム,安全なサーバを構築する方法,CVS以外の選択肢)
- CVS--Concurrent Versions System v1.11.17
- 書籍:CVSによるオープンソース開発,カールフォーゲル著,オーム社(2002/06)