M+フォント研究(1) M+フォントの構成

M+フォントはオープンソースで、すべての作成素材が公開されている。
しかし説明する文書はないようだ。

説明がないから、動作を追ってみていくしかないのかな


http://sourceforge.jp/cvs/view/mplus-fonts/mplus_outline_fonts/

こちらでソースの変更履歴を見れるぞ。

とりあえず、トップから見ていこう。

  bdf.d/	 	 	 	 
  cvs/	 	 	 	 
  doc/	 	 	 	 
  eps.d/	 	 	 	 
  release/	 	 	 	 
  sample.d/	 	 	 	 
  scripts/	 	 	 	 
  svg.d/	 	 	 	 
  ucstable.d/	 	 	 	 
  .cvsignore
  Makefile

この文字末尾に「/」がついているのはディレクトリ(フォルダ)だ。
ついてないのがファイル。

あと、「cvs/」というディレクトリと「.cvsignore」というファイルは履歴管理のために勝手に作られるファイルだ。
無視していい。


ということは、このトップでは「Makefile」というのだけがファイルで、あとはディレクトリだね。

Makefile

Makefileというのは makeコマンドが読み込むテキストファイルだ。
詳しくは google:Makefileのほうを見てくれ。


簡単にいうと、以下のような記述が並んでいる。

ターゲット: 材料
    材料に加える作業
    材料に加える作業
    ...

ここでターゲットを「カレーライス」としよう。
材料はカレーとライスだ。

カレーを材料っていうのは‥
カレールーやにんじん、たまねぎ、肉、じゃがいも、とかを普通は材料っていうよ。

じゃあ、こうなるな。

カレーライス : カレーソース ライス
    ライスとカレーソースを一つの皿であわせる。

カレーソース : ニンジン タマネギ 肉 ジャガイモ カレールー
    肉、ニンジン、タマネギを炒める。
    水をいれる。
    煮る。
    ジャガイモを入れる。
    カレールーを割って入れる。
    煮込む。

ライス : 米
    米を研ぐ。
    米を炊飯器で炊く。

で、このカレー調理がmakeコマンドとなんの関係があるんだっけ?


これは「依存関係」をあらわしたテキストになってるんだ。

にんじん、たまねぎ、肉、じゃがいも、米とカレールーが揃っていても、
いきなりカレーをライスにかけることはできないだろ?


?? そりゃ まずはカレーを作ってからでないと、載せるカレーがないものね。


つまり、カレーライスを作るにはカレーとライスが必要。しかしカレーを作るには肉、ニンジン‥が必要。というふうに必要となるものが連なっている。



さっき

ターゲット: 材料
    材料に加える作業
    材料に加える作業
    ...

と書いたけど、実際のパソコンで使うMakefile

ターゲット: 依存ファイル
    コマンド行
    コマンド行
    ...

という説明になっている。
「依存ファイル」というのは、ターゲットを作るために必要なファイル、つまりターゲットは「依存ファイル」に依存しているわけだ。


なんか説明がややこしくなってるよ。カレーの例のほうがいいや。


ところで、Makefileを作るとき、いちいち全部の文を書いてたらめんどうなので、ラクをするために記号が導入されたんだ。

ターゲットは「$@」と書けばいいし、依存ファイルすべては「$^」と書ける。依存ファイルの最初のひとつは「$<」。
この記号を使うと‥

カレーライス : カレーソース ライス
    $^を一つの皿であわせる。

カレーソース : ニンジン タマネギ 肉 ジャガイモ カレールー
    肉、&<、タマネギを炒める。
    煮る。
    ジャガイモ、カレールーを入れる。
    煮込む。

ライス : 米
    $^を研ぐ。
    $^を炊飯器で炊く。

え゛ー。読みにくくなってるよー。ラクになってないよ。


まあ確かに慣れないと読みにくいな。この例では使う意味があまりないってのもあるが。

でも読むのはちょっと面倒になるが、Makefileを書いたり管理するのはラクになるんだ。ファイル名を少し変えるたびに、あちこち書き直すのは、修正ミスが発生するだろ。この記号を使っておけば、書き直すところが減るわけ。


あー、そういう「ラク」なのか。


同じくラクをするために、マクロとか変数と呼ばれているものもある。
変数を使って書き換えると‥

FRIED = ニンジン タマネギ 肉
BOILED = ジャガイモ カレールー
SOUP = カレーソース

夕食 : $(SOUP) ライス
    $^を一つの皿であわせる。

$(SOUP) : $(FRIED) $(BOILED)
    $(FRIED) を炒める。
    煮る。
    $(BOILED)を入れる。
    煮込む。

ライス : 米
    $^を研ぐ。
    $^を炊飯器で炊く。

と、なるぞ。


確かに「ニンジン タマネギ 肉」と毎回書くよりは、書くのがちょっとラクかも‥。


それだけじゃない。
いったん変数にすると、makeコマンドを実行するときに変数の中身を変更できるのだ。

たとえばさっきのMakefile

$ make 

とすればカレーライスができあがるが、

$ make FRIED="タマネギ 肉" BOILED="赤ワイン ドミグラスソース" SAUCE="ハヤシソース"

とすると、同じ調理法というか同じMakefileなのに、ハヤシライスができあがってしまうのだ!


な、なんだってーΩΩ
そうか、Makefileを書き換えなくてもいいのは確かにMakefile書く人や管理する人にはラクかも。




さて、荒っぽい説明だがMakefileの説明はこんなところ。
パソコンのファイルをビルド(作成)するのもこれと要領は同じさ。

さっきのMakefileを見てみよう。
http://sourceforge.jp/cvs/view/mplus-fonts/mplus_outline_fonts/Makefile?revision=1.24&view=markup

最初のほうにある

UNABRIDGED_GROUPS:=

というのは変数定義だね。


「:=」というのは?


http://www.ecoop.net/coop/translated/GNUMake3.77/make_6.jp.html#SEC58
に書いてある「単純展開変数」だ。
要するに makeファイルの「=」は「再帰展開」でちょっと扱いにくいので、もっと単純なのがほしい人のための代入記号。


単なる代入かあ。


これは?

ifdef MPLUS_FULLSET
UNABRIDGED_GROUPS+=	${OPTIONAL_GROUPS}
endif

ifdef のところは変数が定義されているか調べるよ。
もしMakefile

MPLUS_FULLSET=abcde

と、この変数を定義していれば、endifまでの処理が実行されるよ。
ちなみに

MPLUS_FULLSET=

のカラ文字列の場合はダメだ。中身が必要なんだ。


でもこのMakefileの中では定義されてないよ。


その場合でもmakeコマンドを実行するときに

$ make MPLUS_FULLSET=abcde

とか指定すればいいんだ。
実際
http://mplus-fonts.sourceforge.jp/mplus-outline-fonts/download/

$ MPLUS_FULLSET=yes make SPLIT_CONCURRENCY=2 -j2

と書いてあるだろ。
これは

$ make MPLUS_FULLSET=yes SPLIT_CONCURRENCY=2 -j2

と入力しても同じだよ。


確かに書いてある。
「+=」は文字列連結だよね。







TTFファイルを作るには、
ねえ、

「ニンジン : 
    スーパーでニンジンを買う。
」という行は、ターゲットのニンジンしかなくて、
ニンジン : 
    スーパーでニンジンを買う。

タマネギ : 
    スーパーでタマネギを買う。

ジャガイモ : 
    スーパーでジャガイモを買う。

米 : 
    スーパーで米を買う。

さっき

ターゲット: 材料
    材料に加える作業
    材料に加える作業
    ...

と書いたけど、実際のパソコンで使うMakefile

ターゲット: 依存ファイル
    コマンド行
    コマンド行
    ...

という説明になっている。
「依存ファイル」というのは、ターゲットを作るために必要なファイル、つまりターゲットは「依存ファイル」に依存しているわけだ。


なんか説明がややこしくなってるよ。カレーの例のほうがいいや。