FreeBSDにはpkgというパッケージシステムがあるんですが、更新が遅いのとmakeオプションを変えられないので長年Portsで運用してきました。
また、一時期portsのビルドが面倒になってpkg運用一本に切り替えようかともしたのですが、長期運用で少しづつ各パッケージのバージョンを上げていこうとすると、パッケージ間で参照しているライブラリのパッケージバージョンが不一致で、どちらかしかインストールできないなんて状態になったりで結局あきらめました。
※バイナリpkgが導入された直後の昔のことなんで、今は良くなってるんでしょうかね?
そもそもFreeBSDのports/pkgの更新も「portsコード→バイナリパッケージ(pkg)」の順番に更新される訳なんですが、このタイムラグが結構あって、最新のセキュリティパッチとか、ただでさえportsコードに取り込まれるのが遅かったりするので、pkgだと相当遅かったりします。
そんなわけでひたすらPorts運用一筋。教科書?に載ってないようなPorts運用のノウハウをちょっと書いてみたいと思います。
更新作業について
各パッケージは日々バージョンアップされていきます。昨今ではセキュリティ関連の更新が多く「安定稼働しているから」と、古いバージョンのまま放置するわけにもいきません。
そんなわけで定期的に各portsの、アップデート作業を行うのがPorts運用の基本となります。
とりあえず/usr/ports/UPDATEは読みましょう。大規模なアップデートが有る時に、必要な作業が載ってます。読んでないと嵌まることあります。
基本的にportupgradeを使ってます。rubyのいらないportmasterが好まれるようですが、あっちは良く分かりません。
portupgrade -R <port name>
とか、-Rオプションおすすめです。
依存パッケージも更新してくれるのですが、依存パッケージが古くてコンパイル通らないとか良く有るので。
make uninstall or pkg delete/make installとかすると、ちょいちょい大変な目に遭います。と言うのも、新しいPortsのビルドが通らないことが、困ったことに「結構良く」あります。
原因は様々ですが、その原因の一つが、以下に挙げる/usr/local/lib/comat/pkgだったりします。
/usr/local/lib/compat/pkgの管理
昔は共有ライブラリのバージョンを上げたら、ライブラリのI/Fが変わってて、依存しているパッケージが軒並み動作がおかしくなるなんて事がありました。
今では共有ライブラリのパッケージを更新すると、古いバージョンがこのディレクトリに置かれて、そして新しいバージョンがインストールされるようになっています。
それはそれで互換性の面でありがたいのですが、古いライブラリは自動的には消してくれないんですよね。さらに、残った古いライブラリが悪さして、別のパッケージのビルドが通らないなんて事も起こります。
ライブラリのパッケージ自体を削除しても、移動された古いライブラリはそのまま残ってしまうんですが、それが悪さをすることもしばしば…。
なので、定期的にチェックして手動で消す必要があります。
pkg shlib <shard library>
ってすると、その古いライブラリを参照しているパッケージを教えてくれます。依存しているパッケージを再ビルドすると新しいパッケージを参照するようになります。
それらのパッケージを一つずつ、portupgrade -fで再ビルドしましょう。全てのパッケージを再ビルドして、古いライブラリを参照しているパッケージが無くなったら、ようやく消すことが出来ます。
portupgrade -f `pkg shlib -qR <shard library>`
ってやって、一括してアップデートするのも手です。
再ビルドひつようなのにうっかり消してしまったり、その他の要因で必要なライブラリが無くなっていたりしないか?を確認するにはこちら。
portmaster --check-depends
それでも新しいportsがビルドできない
ports運用上の最大の障害がこれ。クリーンインストールなら問題なくても、長年アップデートを繰り返してきた環境だと、わりと遭遇します。
組み合わせると動かないパッケージがある
よく似た機能のパッケージで、普通はどちらかしか使わないのを両方入れてたら、それらに依存しているパッケージがビルドできないパターンがあります。
netatalkとavahi/mdnsあたりだったかな。
機能のかぶるパッケージが入ってないかチェックしましょう。
依存関係が機能不全
依存パッケージが入ってるのに「無い」って言われてビルドできなかったり、逆に無いのに自動的にインストールされずにビルドエラーで終わってしまうパターン。
ports側で依存関係が変わったりとか、パッケージの構成変更や、ports名の変更とかだったりします。
普通は/usr/ports/UPDATEをよく見てると注意喚起が載ってたりするんですが、載ってないこともあります。
関連するパッケージを一度消してから、再インストールすると上手くいくことが多いです。
それでもどうしてもビルド出来ない
まだ古いパッケージをアンインストールしていないなら、とりあえず待ちましょう。ports側で修正されることがあります。
依存関係を疑って、一度消しちゃった場合は、portsを古いバージョンに戻してビルドします。
そのために、portsはportsnapではなくSubversionで更新するのがおすすめです。該当するportsのディレクトリだけ古いバージョンに戻してビルドします。