08. make 作業のレシピ
Photo by Monika Grabkowska on Unsplash
make について
make
とは,Makefile と呼ばれるレシピファイルに書かれたレシピに沿って自動的に作業をしてくれるツールである.
特徴としては,
- レシピなので,書き方が単純.使いまわししやすい.
- 「モノ」の依存関係と,その局所的な手順だけ書けば良い.とても単純.
- 必要な作業手順を自動的に判断してくれる. 人間が手順の順番を気にしなくて良い.
- 作業をやり直す際,必要な作業「だけ」やってくれる. シェルスクリプトだと相当作りこまないと,頭からやり直しになる.それに比較すると大変便利.
- 作業の途中でエラーがあって止まったとする.その箇所だけ手作業で対応した場合,もう一度
make
すると,続きからきちんとやってくれる. - より簡単な記述をするための高度な文法もあり,習熟すればするほど簡単に書ける.
というところが挙げられる.
見てわかるように,大変に便利なものである.
今回はこの make
について学ぼう.
これまでに学んだ, シェルスクリプトなども自動的な作業をするツールであるが、
途中で訂正ややり直しが発生するような場合(プログラム開発など)は make
の方が明らかに便利である.
参考資料
- GNU Make
… 泣く子も黙る GNU の
Make
. まあ,ここを情報の起点としておけば間違いない.最新バージョンは 4.3 かな. まあ,make
を自分でインストールする必要になることはまずないだろうから、既にインストールされているものを使えば良い. - GNU Make ver.3.79 マニュアルの日本語訳
… 新堂安孝氏が作成された、GNU
Make
の日本語マニュアル.感謝して,ありがたく読ませてもらおう. マニュアルの原作者はかの リチャード・M・ストールマン, ローランド・マグラス (GNU プロジェクト) だと思われる. - GNU Make ver.3.77 マニュアルの日本語訳
… いのまた みつひろ氏が訳された GNU
Make
の日本語マニュアル.ライセンスは GPL だ.こちらも、感謝してありがたく読ませてもらおう.
他にも,web 上には make
について書いたものが沢山ある.
自分にあったものを探してみよう.
学習用の各環境での make のインストール状況
さて,今回扱う make
は CLI 用のコマンドで,基本的には Unix環境の文字端末エミュレータからコマンドを打ち込む形で用いる.
よって,本授業で学習用に使える環境は以下のような感じだろう.
各自,使える環境を好みで選ぶとよいだろう.
なお,make
コマンドは地味に「使える」コマンドだ.各自 PC にインストールしておくことを推奨する.
環境 | 状況 |
---|---|
阪大情報教育システム CentOS7 |
make 3.82 がインストール済み. |
阪大情報教育システム cygwin |
make 4.3 がインストール済み. |
各自PC CentOS7 obtained at OSBoxes |
make 3.82 がインストール済み. |
各自PC cygwin | make が未インストールならばインストールしよう. cygwin の「パッケージ追加」という文言でweb検索すれば良いだろう |
各自PC Mac OS X | 通常は未インストールの様子.インストールしよう. "Mac OS X makeコマンド" などと web 検索すればよいだろう. |
make でサラダを作ってみよう
まずは例えから入ろう.
make
が料理人で,Makefile はそのレシピに相当すると考えて,レシピを書くことを考える.
そして、簡単なサラダを作るレシピを考えてみよう.
ただし,書き方は make
の流儀で,である.
最初に,簡単なサラダを作る,という作業を,
- 完成品,途中経過品,材料,といった「モノ」の 依存関係
- および、その途中経過での 操作
にわけて丁寧に考えてみよう. まずは依存関係だけ書いてみる.
ターゲット品 | そのターゲットに必要な品 |
---|---|
i. サラダ完成品 | 1. 適度な大きさに切られた清潔かつ新鮮な野菜 2. ドレッシング 3. 綺麗な器 |
ii. 適度な大きさに切られた 清潔かつ新鮮な野菜 |
4. 清潔かつ新鮮な野菜 |
iii. 清潔かつ新鮮な野菜 | 5. 新鮮な野菜 |
iv. ドレッシング | 6. 酢 7. サラダ油 8. 醤油 9. 塩 10. コショウ |
次に,この依存関係の左の「ターゲット品」を作成するためにやる「作業」を追加で書き入れてみよう.
ターゲット品 or 作業 | そのターゲットに必要な品 or 作業内容 |
---|---|
i. サラダ完成品 | 1. 適度な大きさに切られた清潔かつ新鮮な野菜 2. ドレッシング 3. 綺麗な器 |
(上のターゲット i. を作るための作業) | 1 を 3 に入れ,2 をふりかける |
ii. 適度な大きさに切られた 清潔かつ新鮮な野菜 |
4. 清潔かつ新鮮な野菜 |
(ii. を作る作業) | 4 を適当にカットする |
iii. 清潔かつ新鮮な野菜 | 5. 新鮮な野菜 |
(iii. を作る作業) | 5 を洗う |
iv. ドレッシング | 6. 酢 7. サラダ油 8. 醤油 9. 塩 10. コショウ |
(iv. を作る作業) | 6-10 を適量,適度に混ぜる |
この表に従っての作業は以下のようになる.
まず、一番最初のターゲット品 i. についてターゲット品がもしも完成していなければ、その材料である右の欄の「必要品」をチェックする. ここで必要な品が揃っていればその直下の 作業 で作成するし、不足があればそれがターゲット品として書かれているレシピ部分を探す.
そして、またその品の右の欄の必要品ををチェックして… …以下同様に…ということを再帰的に繰り返し、終わったところから再帰的に戻ってくる.
こうして、(レシピが間違っていなければ) サラダがいずれ完成することになるのは理解できるだろう.
これがレシピファイル Makefile を読んでの make
の動作の基本となる.
このように、実際の作業の流れの解釈は make
という料理人がやってくれるのだから,われわれの仕事はこの簡単なレシピを書くだけで済む.
さて,次に make
の文法でこのレシピを書くことを考えよう.
通常はこのレシピファイルは Makefile という名前である.
そしてその中身は, make
の文法に沿うならば以下のようになる.
■ 上のレシピを make
の文法に沿って Makefile として書いたもの ■
|
|
ただし, [Tab ⭾] は, タブ(tab キーを一回押すと入力できる)のことで, ␣ はスペースのことである.
画面表示だと区別がつきにくいので、このように明示的に表記している.
で、見て分かるように、この文法は以下の通り.
Makefile を書くのに最低限必要な文法・知識
これは以下のたった 3つ.
- 依存関係を 作りたいターゲットの品: その作成に直接必要な材料 と書く.
- 作業は次行に [Tab ⭾] 作業 と書く.
- これを十分なだけ繰り返す.
さて,こうやってレシピすなわち Makefile が完成したら,あとは,シェルで
|
|
と打つだけで(材料が揃っているならば), make コマンドがこのレシピにそって作業をして,サラダが完成するというわけである.
サラダ作成を途中からやり直す?
さて,例えの続きといこう.
上のレシピを書き,料理人にサラダを作ってもらった後で,酢が古かったことに気づいて新しい酢でサラダを作り直したくなったと想定しよう. ただし,途中でできた品は充分に余っているとしておこう.これはコンピュータ上では、途中経過ファイルが保存されている状態である.
さてこの場合,必要な作業は
- ドレッシングを再度作成する
- 適切な、清潔新鮮野菜はさっき作って余っているものを使えるので、これに新しいドレッシングをかけてサラダを完成させるだけ.
という,たった 2つで良い.
しかし,この「この 2つの作業だけで良い」という具体的な事実を料理人(make
)にどうやって指示すればよいだろう?
make
を使う場合は、実はこの指示は具体的に伝えなくてよいのだ.
make
が様々なものの依存関係とその製造時間を比較して勝手に判断してくれるのである.
つまり,酢を取り替えたあとでもう一度
|
|
と打つだけで,勝手にこの 2行程だけやり直してくれるのである.
このように,
make の便利な点
make と打つだけで必要な作業だけやり直してくれる!
のである.
これが make
のとても便利な点である.
単純な例
では,プログラムで実際にやってみよう. 最初はごく簡単に,プログラムをコンパイルして,実行するという単純な二段階の作業をさせてみよう.
実習
以下の手順に従い,適当な実習用ディレクトリで make
を動かしてみよう.
ただし,ただやるだけではなく,全体の流れを理解しながらやろう.タイプするだけでは意味がナイぞ.
改行コードは unix にあわせよう
以下のファイル編集作業は、Unix の改行コードにできるツールで行おう.
改行コードのあわせかたは、例えば以下の通り.
ツール | How to |
---|---|
Emacs | ファイルを編集しているときに C-x Return f とするとその文書の漢字コード, 改行コードを尋ねられるので unix と入力すれば良い. |
Notepad++ | 「設定 > 環境設定 > 新規文書」という設定項目でフォーマットを Unix にする. これから新しく作るファイルは Unix の改行コードにしてくれるはずだ. |
1.まず,f-sin.c という名前のファイルを作り,次の中身を書き込んでおく.
|
|
内容は,まあ読めばわかるが,$x \in [0,0.5]$ の範囲で $0.001$ おきに $\sin(100x)+\sin(110x)$ を計算して出力するだけのプログラムだ.
2. 同じディレクトリに Makefile という名前のファイルを作り,次の中身を書き込んでおく.
|
|
上でも書いているように、2, 3, 6行目の [Tab ⭾] は「TAB」キーを押して入力するタブ文字を意味しているので注意しよう.
ちなみに、ここで「タブ」以外の文字を使っていて make
をすると,「分離記号を欠いています (8個の空白でしたが,TAB のつもりでしたか?)」なんて言われたりする.
alias を自分で設定しているために rm
というコマンドの部分でエラーが出る 人は、alias を外してコマンドを素で呼ぶ \rm
に直せば良い.
さて,上は何をするレシピか, 読んで確認しておこう.
3.make してみる.
|
|
4.問題がなければ(warning ぐらいは出るかも),f-sin.c というプログラムがコンパイルされて f-sin.exe という実行ファイルが作られ、そしてそれが実行され,その結果の f-sin.dat というデータファイルができているはずだ.
その内容を,例えば次のようにして覗いてみよう.
|
|
5.結果のデータファイルを消してみよう.
|
|
6.再び make してみる.
この時,どの作業が行われるか,注意深く見ておこう.先と異なるはずだ.
|
|
7.再び実行結果ができているはずなので確認しよう.
|
|
8.今度はプログラムを修正してみよう.
具体的には,f-sin.c の for の行を
|
|
と, 0.5 だったところを 1.0 に修正してみる.
9.再び make してみる.
|
|
10.今度の実行結果は異なるはずだ.見てみよう.
|
|
結局、いろんな変更をしても,いつでも make コマンドだけで済む! 便利だ!
ちょっと複雑になった例
次に,今の例をちょっとだけ修正して,プログラムをコンパイルして,実行して,さらにそのデータファイルからグラフを作成するという,三段階の作業をさせてみよう.
実習
先の続きの形になる.続きとして,以下のようにやってみよう.
1.先と同じディレクトリに sin2pdf.gpl という名前のファイルを作り,次の中身を書き込んでおく.
|
|
なお、最後の行をきっちり改行しておくことを忘れないようにしよう.
2.Makefile の中身を以下のように修正する(先頭に三行が加わる).
|
|
繰り返しになるが、[Tab ⭾] は「タブ」キーで入力する 1文字をこう書いているだけのことに注意!
さて、何をするレシピになったか, これも読んで確認しておこう.
3.make してみる.
|
|
4.問題がなければ,f-sin.pdf という画像ファイルができているので,見てみよう.
Windows ならばエクスプローラーでそのファイルをマウスでダブルクリックすれば良いはずだし,他の OSでも似たようなものだろう..
すると,下記のようになっているはずだ.
このように,作業が何段階かになっていても make
は問題なく使えることを理解しよう.
もうちょっとだけ続くんじゃ…
さて,今度は,上の作業を,
- 2つのプログラムをコンパイルし,
- 2つの実行ファイルを実行して 2つのデータファイルを作らせて,
- データファイルを処理してもう一つデータファイルを作り,
- それら3つのデータを同時にプロットしたグラフファイルを1つ作る
というものにしよう. なに,理屈がわかっていれば簡単だ.
実習
先の続きの形になる.続きとして,以下のようにやってみよう.
1.f-cos.c という名前のファイルを作り,次の中身を書き込んでおく.
|
|
何をするプログラムか, 読解しておこう.
2.Makefile の中身を以下のように修正する(結構変わるので注意深く作業しよう).
|
|
まず,awk が登場していることに着目!
また,Makefile 中で awk コマンドを動かすときに,変数 $1
,$2
を $$1
,$$2
と書いていることに注意.
これは,「単に $なんとか
と書くと Makefileの変数と解釈されて make によって変換されてしまう」ので,その対処をしているのだ.
やはり [Tab ⭾] に注意.
そして、何をするレシピになったか, これもやはり読んで確認しておこう.
3.先と同じディレクトリに all2pdf.gpl という名前のファイルを作り,次の中身を書き込んでおく.
|
|
やはり、最後の行をきっちり改行しておくことを忘れないように!
5.make してみる.
|
|
6.問題がなければ,all.pdf という画像ファイルができているので,上と同じ方法で見てみよう.
下記のような図のはずだ.
7.プログラムのいずれかを適当に修正してみよう.内容はグラフがおかしくならないようなものならなんでも良い.
8.再び make してみる.
|
|
9.今度の実行結果は異なるはずだ.all.pdf を見てみよう.
make の文法をきちんと使うと楽できる例
先の Makefile を見ると,似たようなことが何回も書かれていて,面倒な上に間違えやすい.
もちろん,make
の文法はこういうことは克服できるようになっている.
例えば先の Makefile とほぼ同じ動作(f-cosm.dat は無し)をするような,シンプルな Makefile は次のようになる.
|
|
上の Makefile 中には繰り返しの記述が無いことに注意しよう.無駄もバグの温床もなくなったことになる.
実習
余裕があるならば make
の文法を調べ,上の Makefile を理解しよう.
レポート
以下の課題について能う限り賢明な調査と考察を行い,
2022-AppliedMath7-Report-08
という題名をつけて e-mail にて教官宛にレポートとして提出せよ. なお,レポートを e-mail の代わりに $\TeX$ で作成した書面にて提出してもよい.
注意
近年はセキュリティ上の懸念から,実行形式のプログラムなどをメールに添付するとそのメールそのものの受信を受信側サーバが拒絶したりする.
そういうことを避けるため,レポートをメールで提出するときは添付ファイルにそういった懸念のあるファイルが無いようにしよう.
課題
- Makefile にさらに追加して,できたグラフファイルを圧縮する機能をつけてみよ.
- Makefile を変更して、
make
を実行すると、以前作ったグラフファイルをどこかへバックアップしてから新しいグラフを作るようにしてみよ. - TeX が使える者は,今回の授業例を修正して TeX の編集作業に
make
を使えないか考えてみよ.