わすれっぽいきみえ

みらいのじぶんにやさしくしてやる

make触ってみた

この記事はドワンゴアドベントカレンダー20日目と2015年一人アドベントカレンダー20日目です。

いつも一人でアドベントカレンダーやってて寂しくなったので、今年は気持ちだけ盛り上がったし参加してみました。もう一人じゃない。

Qiitaのアドベントカレンダーランキングなるものははてブは計算に入ってなくてストック数で計算されているとのことなので、ストック数に少しでも貢献できればいいなと思ってはてブロじゃなくQiitaに書きます。きっと変化ない。

はじめに

なんかのパッケージやバイナリをインストールしたことのある人なら一度は見たことがあると思います。

$ ./configure
$ make test
$ make install

インストール時ですらもはやchefとかansibleとかで直接makeコマンド叩いてるところを見ないかもしれないです。私自身何も考えずに叩いてました。見ることは見るけど"How to Install"に書いてたから叩いてみたくらいなもので、自分では書かないし書いたことがないし、いい感じにインストールしてくれるものくらいの認識です。

ところが今年こんな記事が上がりました。

最近のビルドツールって何なの?

gulpを置き換えるかどうかはさておき、そういう使い方もできるということを知らなかったので一人で勝手に衝撃を受けてました。makeって色々できそうですね。

なので、ここはとりあえずmakeがなんなのか、PHP7のMakefileをちょっと見てみてどんな風に使われるものなのか、今後使ってみたいと思えるか、まとめてみようと思います。

make is 何?

man make を実行すると以下が書かれています。

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.

ざっくり訳すと「makeは大規模プログラムのどの部分を再コンパイルするべきか自動的に決め、それらをコンパイルするコマンドを実行するためのもの」です。 よくmakeの使用例に挙げられるのがCのコンパイルですが、実際にはCだけでしか使えないものではなくMakefileの中にシェルコマンドを書きます。

mac(El Capitan)で確認したところ

$ make -v
GNU Make 3.81
Copyright (C) 2006  Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.

が入ってました。 そこで自動化のためのGNU Make入門講座 - Makefileの基本:ルールにある echo Hello World が実行できるか確かめたところ

$ cat Makefile
all:
        echo Hello World!

$ make
echo Hello World!
Hello World!

ちゃんと同じ結果が出ました。gccなどではなく単なるechoを使ってるので、必ずしもCのコンパイルだけで使うものではないことがわかります。

詳しい書き方例は文末に参考リンクを載せておくので、そちらを参照してください。

PHP7のMakefileの中身

PHPはCで書かれてるのでまさにCのコンパイルなわけですが、このphp-srcのリポジトリにどんなMakefileがあるのか読んで使い方を見てみようと思います。

PHPNG (next generation)にインストール方法があり、ざっと叩くコマンドを書くと以下になります。

$ git clone git@github.com:php/php-src.git
$ cd php-src
$ ./buildconf
$ ./configure  # confiugureオプションは略している
$ make
$ make install

./buildconf はただのシェルなので、試しに中身を見てみたら最後の方でMakefileの指定がありました。

if test "$debug" = "yes"; then
  ${MAKE:-make} -s -f build/build.mk SUPPRESS_WARNINGS=""
else
  ${MAKE:-make} -s -f build/build.mk
fi

直接php-srcのリポジトリから見ることができるのでbuild/build.mkを見てみます。簡単に処理内容を書くと以下です。

  • all
    • buildmk.stampとgenerated_listsに依存する
    • build/build2.mkを読み込んでmakeを実行する
  • generate_list
    • make実行時に参照される他のMakefile一覧を出力する
    • ファイルは出力されない
  • buildmk.stamp
    • ビルド可能かを確かめて、タイムスタンプ用のbuildmk.stampファイルを出力する
  • snapshot
    • php7-snapshot.tar.bz2というスナップショットを残す
  • gitclean-work

./buildconf で実行したい処理の実体はbuild/build2.mkにほぼ集約されてるのですが、簡単なリスト出し、タイムスタンプ、スナップショットはbuild/build.mkに直接記載しているようです。単純に ./buildconf を実行するとallが呼ばれるので、buildmk.stampとgenerated_listsとbuild/build2.mkの処理が走ります。 実際に実行してみたところが以下です。

$ ./buildconf
buildconf: checking installation...
buildconf: autoconf version 2.69 (ok)
rebuilding aclocal.m4
rebuilding configure
rebuilding main/php_config.h.in

Makefile@シェルコマンド名 の処理はコンソールに出力されないのでMakefileに記載の行に比べて処理した量が少なく見えますが、これで全体の処理になっています。 ./buildconf 実行後カレントディレクトリにconfigureファイル(私の手元だと106551行!)が生成されましたが、これはbuild/build2.mkに記載の処理です。

configureファイルの行数が多いので、真面目に読み込まずにさっと"Make"でgrepしてみたところ、基本的にはconfigureオプションによってどのMakefileを結合していくかを書いてるようで、絶対手動で実行はしたくない量がシェルでがんがん書かれてました。buildconfを小さく作って自動的にconfigureファイルを作成するのにmake使わないとやってられないのは見て取れます。makeさまさまです。

コンパイル時のMakefileまで含めて見てみようと最初思ってたんですが、configureファイルの時点でだいぶ多いので出来た後のファイル読むのつらそうだなと思ったのと自動生成されるMakefileが人間が読むのに向いてる形とは思えなかったことで、ここで止めています。興味のある方は読んでみるといいかもしれないです。

今後書いていきたいか?

正直なところMakefileは自分で書きたいものではないですし、無理に使うものでもないです。makeが簡単な書き方で柔軟に処理を自動化できること、自動生成されるファイルを手作業で作成するのは簡単に心折れるレベルだったので使い方を覚えれば効果がすごいことはわかりましたが、結局あんまり考えずにインストール時に make install まで叩いて終わっちゃうなと思いました。

あとansibleやchefもMakefileで書こうと思えば書けることはわかりましたし、Makefileの方がさくっと書けるという方もいらっしゃるでしょうが、Makefileの書き方を覚えるために使ってみるならまだしもMakefileの書き方をよくわかっていない人が手を出していきなりいい感じに書けるものではないです。ansibleやchefの方がググると情報が出て来やすいですがmakeは少ないですし、make upとかいって化粧の情報が出て来たりします。手元に本がないと本気でやるには苦労しそうです。

Makefileの文法を覚えただけで他のいろんなものを一気に自動化できるメリットは大きいだろうと想像してみましたが、異なる利用シーンでmakeに統一していくことが本当にいいことと言えるのかはわかりません。結局利用シーンごとに書き方が変わってくるとも思って、だったら初めからツールが分かれてるのとさして変わらないと思いました。統一しなきゃいけないわけじゃないんですけど、もうmakeでよくねには簡単にはならない気がします。

なので今後ガリガリとは書かないだろうと思ってます。ただmakeがどんなものかを知らなくて触ってみたこと自体は無駄じゃないと思ってます。実際Makefileを読むことは昔じゃ割と当たり前だったらしいので、今あるいろんなツールが滅びた時にふと役に立ったりするのかもしれません。あとタイトル通り『make触ってみた』だけなので、ちゃんと触ってディープなところに行くと何かvimのような深遠な幸せにたどり着けるのかもしれないです。makeサイコーって言って…みたくないな、別に。

個人的には役にたつかどうか関係なくて、たまにこういう地味なことをやるのが楽しいだけだったりします。

参考にしたリンク