はじめに
2020年にもなって、まだコンパイルしてるの?
と言われるくらい、現在のFreeBSDでは、ベースシステムはもちろんのこと、サードパーティ製アプリのバイナリパッケージの使用(インストール)が進んできました。
実際、軽くセットアップして使う分には十分過ぎるほどバイナリパッケージが用意されていると思います。
ただまぁ自分の場合、ガッチガチにカスタマイズして使ってる関係で、バイナリパッケージに満足することができず…と言う事情もあり、ポーツコレクションのカスタマイズ方法についてまとめてみました。
なおポート(FreeBSD ports)とは何?については参考文献をご覧ください。すみません。
動作対象環境
2020年現在、導入から5年以上経過していることもあり、現在サポート対象となっている全てのFreeBSD環境で使用できます。まぁおおよそバージョン10以降で考えてもらえばいいかと。
OPTIONSという仕組み
OPTIONS(/usr/ports/Mk/bsd.options.mk
)という仕組みの導入1により、ポートを使用してサードパーティ製アプリをコンパイルする時の、カスタマイズする方法が統一されました。
これが導入される前後でMakefileの書き方が変わっており、OPTIONS導入以前の仕組みは(ほぼ)残っていません2。
いや厳密に調べてみると残っているというか、使われてたりすることもありますが、あまりに特殊な、ハッキング的カスタマイズ用途で使われたりするので、今回はスルースキルを発動することにします。
OPTIONSとは
各ポートのカスタマイズ出来る項目のオン・オフを制御するための仕組みで、以下のコントロールを行うための仕組みを提供しています。
- 何をカスタマイズできるのか(オプション名)
- どのような機能であるか(解説)
- 何をデフォルトで、オンにするかオフするか(デフォルト値)
- 振る舞い(依存関係の明示やインストール方法等)についての補助
ポートメンテナーはこれらをMakefileに記載することにより、利用者はオンオフを選ぶだけでカスタマイズできるようになっています。
ダイアログでの選択
コンパイル時にダイアログが表示され、これらカスタマイズをどうするかインタラクティブに取捨選択ができます。
具体的には以下のコマンドにより設定できる項目となります34。
make config
make config-recursive
make showconfig
make showconfig-recursive
make rmconfig
make rmconfig-recursive
特に、一度ダイアログで確定してしまった場合、make config
を明示的に実行するか、あるいは、新しくオプションが追加されたときしか、ダイアログを表示することはありません。
またデフォルトに戻したい場合は make rmconfig
とすることで、ダイアログで設定した内容が削除されます。
グローバルな設定
/etc/make.conf
中に記載することで、大域的にカスタマイズ内容(オン・オフ)を定義することができます。
X11が不要である場合や、圧縮アルゴリズムとしてLZ4を使用したいなど、全てのポートで統一的に設定を図りたい場合に設定します。
OPTIONS_SET+= LZ4 LZO LZO2 LZMA ZLIB ZSTD BROTLI
OPTIONS_UNSET+= X11 CUPS GDBM TEST DEBUG TESTS
グローバルなポート別設定
/etc/make.conf
中には更に、ポート別にカスタマイズを定義することができます。
たとえば、基本的にはドキュメント類はインストールしておきたいが、そのドキュメントをインストールするためにTeXまでインストールし始める、みたいなケースではドキュメントのインストールを諦めたいのが心情かと思います。
そのようなケースでは ${OPTIONS_NAME}_SET
ないしは ${OPTIONS_NAME}_UNSET
で定義してやります。
emulators_open-vm-tools_UNSET= DOCS FUSE LIBNOTIFY
${OPTIONS_NAME}
は各ポートで make -VOPTIONS_NAME
を実行して得られる文字列となります。
上記の例のように、中には変数名に -
や +
を含むことがあるようですが、Makefile的には問題無いようで。
なおOPTIONS導入当時 OPTIONS_NAME
ではなく UNIQUENAME
を使う、とありましたが、他の機構と衝突するとのことで、OPTIONS_NAME
に変更になっています。
bsd.options.mk でのデフォルト設定
bsd.options.mk の中で以下の設定についてはポート側のデフォルト設定に関係無く、有効化されています。
DOCS
NLS
EXAMPLES
IPV6
ダイアログの選択肢に DOCS
があるのに、ポート側のデフォルト設定には DOCS
が無いにもかかわらず、実際には DOCS
がオンになっているのは、これの影響となります。
OPTIONSの優先順位
-
/etc/make.conf
(${OPTIONS_NAME}_SET_FORCE
/${OPTIONS_NAME}_UNSET_FORCE
) -
/etc/make.conf
(OPTIONS_SET_FORCE
/OPTIONS_UNSET_FORCE
) make config
-
/etc/make.conf
(${OPTIONS_NAME}_SET
/${OPTIONS_NAME}_UNSET
) -
/etc/make.conf
(OPTIONS_SET
/OPTIONS_UNSET
) -
make WITH="オプション1 オプション2..." WITHOUT="オプション1 オプション2..."
と指定したケース5 bsd.options.mk
-
Makefile
/Makefile.local
なお、_SET
が処理されてから _UNSET
の処理が行われるので、優先順位は _UNSET
> _SET
となり、_UNSET
の効果の方が強くなります。
カスタマイズ不要!
つまりパッケージシステムはカスタマイズ無しでコンパイルされてるはずで、ダイアログの表示無く処理されているはずです! 6
実際にそのようなオプションはあります。/etc/make.conf
に下記のように書いておけば、全てのポートのダイアログ表示無し(≒カスタマイズ無し)でコンパイル始めます。
NO_DIALOG= yes
実際にはダイアログの表示がスキップされるだけで、以前に実行した make config
の結果や先に説明した OPTIONS_SET
/OPTIONS_UNSET
等の設定が反映された上で処理されます。
そういう意味では完全にデフォルトではないですが、バイナリパッケージ互換の運用はこうすることで提供可能であることが分かるかと思います。
ports-mgmt/portconf
portconf は /usr/local/etc/ports.conf
という設定ファイルで各ポートのカスタマイズ設定を記述できるツールです。
インストール時に /etc/make.conf
へのフックを入れ、/usr/local/etc/ports.conf
→ /usr/local/libexec/portconf
→ /etc/make.conf
と連携することで、あたかも最初からそこに設定が書いてあったがごとく振る舞います。よってこのフックを /etc/make.conf
から削除してはいけません。
やってることは設定ファイル中のポートディレクトリ名とカレントディレクトリを比較(グロブでマッチング)して、該当すればその内容を取り込む、という動きになります。
例えば下記の例では、/usr/ports/databases/sqlite3
のディレクトリで /usr/local/libexec/portconf
を実行してやれば、|NO_DIALOG=yes
と表示されることが確認できると思います。
databases/sqlite3: NO_DIALOG=yes
lang/perl5.*: NO_DIALOG=yes
本例でのSQLite3のように、かなり細かくカスタマイズできるのですが、バイナリ互換性を失うようなカスタムが後から入ることもあり(その場合デフォルトオフで入る)、下手にカスタマイズしない方がいい類いのポートとなっています。
OPTIONSとの使い分け
OPTIONSの場合 ${OPTIONS_NAME}_SET
/${OPTIONS_NAME}_UNSET
のように、ポート毎(${OPTIONS_NAME}
)に OPTIONS_SET
/OPTIONS_UNSET
が明示できます。しかし NO_DIALOG
のようなグローバルな名前だと、ポート個別に設定することはできません。よってそういうところでportconfを使用します。
もちろん ${OPTIONS_NAME}_SET
/${OPTIONS_NAME}_UNSET
を使用せず OPTIONS_SET
/OPTIONS_UNSET
を使用するために、ports.conf
に記述してもいいのですが、portconfがインストールされてない環境で構築した場合の影響が多大なので、あまり影響ないところで使いこなすのが粋な使い方となります。
上記理解が済めば、それ以外の指定方法についても pkg info -D portconf
を実行して、内容を読めば書けると思います。
よくある質問とその答え
Q.ポートからコンパイルしたものとバイナリパッケージは共用運用できないの?
全てのポートを NO_DIALOG
付でかつカスタマイズ無しの時に可能です。
パッケージの反映が遅いな、ポートからコンパイルしちゃえ、という運用をしたいなら、カスタムしないようにしてください。
Q.カスタムしたポートとバイナリパッケージは共用運用できないの?
基本できないと思ってください。限定して運用すればできることがあるかもしれませんが、試行錯誤が必要です。またその試行錯誤の結果が今後も保証される保証はありません。
カスタマイズした場合に、その機能の有効または無効によって、あるべき機能が無かったり、欲しい機能が無いことがあえります。ポートの依存関係では分からず、インストール後(ランタイム)に判明する場合があります(バイナリ互換性が無い)。
この種の変更(カスタマイズ)はバージョンアップによる影響よりも大きいことがあります。
まあちょっと脅しになってしまいましたが、ミドルウェア(特にライブラリ)と言われるポートで「なければ」、アプリケーションと言われるポートで「あれば」、問題無く動くと思います。
Q.オンとオフ、SET
と UNSET
何か飛躍があるような気がします!
A.大丈夫だ。問題無い。その認識は正しい。ちゃんと説明するべきであるが疲れたので寝る。
参考文献
- [FreeBSD-Ports-Announce] Configuring options in make.conf
- アプリケーションのインストール - packages と ports 【日本語版】 【英語版】7
- Ports Collection の利用 【日本語版】 【英語版】7
- bsd.port.mk
- bsd.port.options.mk
- portconf
-
2012年05月以降。もちろん仕組みが導入されてすぐ、全てのポートが対応したわけではないが、既に8年以上経過…。 ↩
-
WITHOUT_X11
等のメジャーなカスタマイズ設定は…残って…いませ…ん(正確には間違った使い方です)。 f( --; ↩ -
config
は設定、showconfig
は現在の設定の閲覧、rmconfig
は設定の削除。 ↩ -
-recursive
はそれぞれ依存関係を追って処理します。 ↩ -
WITH
で指定されたオプションはSET
され、WITHOUT
で指定されたオプションはUNSET
されます。 ↩ -
パッケージビルドシステムの運用について軽く調べたのですが、どう運用してるという情報は無く、使用しているツールと、カスタマイズなんてしてられないだろう?という予測からの,、個人的かつ無責任な断定。 ↩
-
日本語版の記述が古いため英語版を読むときの参考にしてください。特にpkgngについての記述は完全に無視してください(pkgngになってからずいぶん時間が経過しているため)。 ↩ ↩2