ここしばらく「Linuxカーネルの歴史を振り返る」という、読むのも書くのも大変な話題が続いたので、今回は少し気分を変えて、最近取り組んでいるPlamo Linuxのビルドスクリプトの改修について取りあげることにします。
Plamo Linuxのビルドスクリプトやパッケージ管理ツールについては、以前、この連載でもとりあげたことがあるものの、記事の日付を見ると4年前でした。
PlamoBuildスクリプトを使ってパッケージを作成し、installpkgかupdatepkgを使ってインストール、removepkgを使ってアンインストール、という枠組みは変っていないものの、この4年ほどの間にPlamoBuildスクリプトやPlamoBuildスクリプトを生成するメタ・ビルドスクリプトもだいぶ進化してきたので、今回はそのあたりの最新状況を紹介します。
ビルドスクリプトの改修
最初期のPlamoBuildスクリプトは、configure && make install を中心に、それぞれのソフトウェアをパッケージ化するための処理を手書きしたスクリプトでした。
そのうち、いちいち0から手書きするのも面倒なので、典型的な手順を整理してテンプレートを作り、パッケージ作成の際はそのテンプレートをコピーして使うようになりました。
さらには、ソースコードを指定するとパッケージ名やバージョン番号を設定したビルドスクリプトを生成するメタ・ビルドスクリプトを使うようになったのは過去の記事で紹介した通りです。
もともとPlamoBuildスクリプトを使い始めた当時は、GNU Autotoolsが生成するconfigureスクリプトを使うソフトウェアが主流だったので、ビルドスクリプトのテンプレートもconfigureを使うことを前提にしていました。
しかし過去の記事でも指摘したように、GNU AutotoolsはUNIXの仕様が分裂していた時代に開発されたこともあり、ずいぶん煩雑な設定を必要とします。そのため、新しく開発されたソフトウェアではGNU Autotoolsではなく、cmakeを使ってMakefileを生成する例が多くなってきました。加えて、最近ではPythonやPerlで書かれたアプリケーションも広まってきて、Python用のsetup.pyやPerl用のMakefile.PLを用いてビルドする例も目に付きます。
テンプレート化したビルドスクリプトを使い回す方法は簡単なものの、1つのテンプレートでこれら全てに対応しようとすると、それぞれの方法に応じた手順を用意して、configureやCMakeList.txt等の有無で動作を変えるような処理が必要になります。加えて、同梱するドキュメント類を圧縮する機能やファイルの所有者をチェックする機能など、便利な機能をあれこれテンプレートに組み込んでいった結果、シンプルさが売りものだったはずのPlamoBuildスクリプトがずいぶん複雑になってしまいました。
もともとPlamo Linuxは「作者(メンテナ)と利用者(ユーザ)の垣根を低くする」ことをひとつの目的としていました。パッケージがどのような設定や手順で作られているかを紹介するビルドスクリプトはユーザとメンテナをつなぐ重要なツールなので、複雑化して読みづらくなるのは問題です。
そこでPlamo Linuxの原点に回帰するためにも、ビルドスクリプトをよりシンプルな形に再構成することにしました。
ビルドスクリプトの再構成
PlamoBuildスクリプトはシェルスクリプトなので、シンプル化といってもそれほど凝ったことができるわけではありません。せいぜい汎用的な処理をサブルーチン化して別ファイルに括り出し、ビルドスクリプトの先頭付近でそのファイルを読み込む程度です。
今回は、この別ファイルを/usr/share/plamobuild_functions.shという名前にして、テンプレートのうちすでにサブルーチン化できている部分と、作成したバイナリを作業用ディレクトリに仮インストールしてパッケージ用に調整する部分の処理を括り出すことにしました。
コードの断片だけで恐縮ですが、例に示したprune_symlink()は指定したディレクトリ以下のシンボリックリンクを刈り取る処理、strip_all()は生成したバイナリファイルからデバッグ用のシンボルを取りのぞく処理です。
このような形で、prune_symlink()やstrip_all()の他、指定したディレクトリにある全てのファイルを圧縮するgzip_dir()、指定したURLからソースコードをダウンロードするdownload_sources()等のコードをplamobuild_functions.shに切り出した結果、テンプレートを250行ほど削減することができました。
plamobuild_functions.shはメンテナの加藤さんがGitHubで管理してくれているので、GitHubのページで全体をご覧いただけます。
メタ・ビルドスクリプトの仕様変更
前節で紹介したplamobuild_functions.shに汎用的な処理を切り出すことでビルドスクリプトのテンプレートはずいぶん見通しがよくなりました。そこにconfigureやcmakeそれぞれの処理を盛り込むのも見苦しいので、ビルドスクリプトを作るスクリプト(メタ・ビルドスクリプト)がそのソフトウェアに応じた設定方法を判断し、ビルドスクリプトにはconfigureならconfigure用、cmakeならcmake用の処理のみを組み込むようにしました。
そのためにはメタ・ビルドスクリプト(make_PlamoBuild.py)がソースコード中にconfigureがあるか、あるいはCMakeList.txtがあるか、等を調べなければなりません。そこで以前のバージョンとは仕様が変わるものの、make_PlamoBuild.pyの必須引数にはソースコードのアーカイブファイルではなく、ソースコードを展開したディレクトリを指定するようにしました。
make_PlamoBuild.pyはソースコードを展開したディレクトリを引数に与えると,ディレクトリ名から作成するパッケージの名前とバージョンを取り出すと共に、configureやcmakeそれぞれに合わせたビルドスクリプトを生成します。また、手動で設定方法を指定するための-mオプションも用意しました。
make_PlamoBuild.pyもplamobuild_functions.sh同様、メンテナの加藤さんがGitHubで管理してくれているので、最新版のコードはGitHubから入手できます。
メタ・ビルドスクリプトの使用例
ビルドスクリプトに記載するソースコードのURLは-uオプションで指定できるので、ソースコードを入手してビルドスクリプトを生成する手順は以下のようになります。
まず、ブラウザでそのソフトウェアのダウンロード用ページを調べ、ダウンロード用のURLをコピーしておきます。その後、適切なディレクトリに移り、ソースコードをダウンロードして展開します。
コピーしたURLを-uオプションに指定してmake_PlamoBuild.pyでビルドスクリプトを生成します。
このコマンドで作成されたorc-0.4.26用ビルドスクリプトは以下のようになります。
例に用いたorc-0.4.26の場合、自動生成したビルドスクリプトに手を加える必要はなく、そのままで新バージョンのパッケージが作成できました。
上記ビルドスクリプトをご覧いただければ分かるように、新しいスクリプトではbshレベルのシンプルな機能しか使っておらず、先に紹介したplamobuild_functions.shを15行目でsourceし、39行目のdownload_sources、80行目のcheck_root、91行目のinstall_tweak、97行目のconvert_linksの4ヵ所でplamobuild_functions.shに隠蔽した処理を呼び出しています。
旧バージョンのorcをパッケージ化する際に利用したビルドスクリプトは292行だったので、行数は1/3ほどに削減できたようです。
「別ファイルに処理を分けるとスクリプトの独立性が低くなってわかりにくくなる」という意見もあるものの、この程度ならばシンプル化して読みやすくするメリットの方が大きいように思うので、手元ではこのスタイルのビルドスクリプトでパッケージを作ることにしました。
Plamo Linuxの場合、rpmやdebのような専用のパッケージシステムを利用していないため、今回紹介したようなシンプルなスクリプトでパッケージを作れるメリットがあります。その一方、統一された方法が無いため、もっと技巧を凝らしたビルドスクリプトを愛用するメンテナもいます。そのあたりの多様性もPlamo Linuxの特徴のひとつとしておきましょう(苦笑)。