公開日: 2021年7月4日 / 最終更新日: 2023年7月28日

アプリケーションをインストールする (後編): ports

前編に引き続き、FreeBSD へのアプリケーションのインストールについて記します。後編は ports です。ports とは何か? packages との関係は? などについて前編でざっくりと触れているので、そちらも参照してください。

ports に関する注意事項

  • packages との併用は (基本的に) 避けましょう

    前編にも書きましたが、ports と packages それぞれからインストールしたソフトウェアを混在させるのは避けたほうがよいです。混在させる場合は ports と packages でリポジトリのブランチを合わせる必要があります。具体的な作業方法は別記事「packages と ports を併用する前にやっておくこと」を参照してください。ただし次項で述べるカスタマイズを行ってしまうと、ブランチを合わせるだけでは対処できません。

  • カスタマイズは、依存関係を把握したうえで慎重に行いましょう

    ソフトウェアの機能を有効にしたり無効にしたりして自分向けにカスタマイズできるのは ports の利点ですが、依存関係を把握したうえでやらないとトラブルの原因となります。例えば有名な GLib というユーティリティライブラリでは NLS (Native Language Support) を無効にすることができますが、この機能に依存する別のソフトウェアがもしあって、システム上で稼働していた場合、何らかの障害を引き起こすかもしれません。というわけで繰り返しになりますが、ソフトウェア間の依存関係にどのような影響があるかを把握しておく必要があります。

    (私を含め) 一般の利用者はよほどの理由がなければカスタマイズは封印して、デフォルト設定で使うのが無難だと思われます。

ports という名称について

正式名称はよくわかりませんが「ports コレクション」とか「ports ツリー」などとも呼ばれ、これらはだいたい同じ意味で使われるようです。いろいろなドキュメントを読んだ感じでは、各アプリケーション単体 (例えば www/w3m とか) の場合は単数形で port と書き、それが複数になって ports、ports を総称して ports コレクション、ports コレクションの実際のディレクトリ構造 (/usr/ports 以下) を指して ports ツリーと書かれることが多いように思います (どなたか正確な使い分けをご存じでしたら教えてください)。本稿でも、そのような感じでゆるく使い分けることにします。

ports のセットアップ

前置きはこのくらいにして、ports を利用する準備に取りかかります。ports コレクションは Git で管理されているので、まずは Git をインストールします。portsnap や gitup といった他のツールを使うことも可能ですが、ここでは割愛します。
# pkg install -y git
ports リポジトリをcloneして/usr/ports に展開します。
# git clone https://git.freebsd.org/ports.git /usr/ports
# ls /usr/ports
.arcconfig      accessibility   editors         misc            textproc
.git            arabic          emulators       multimedia      ukrainian
.gitignore      archivers       finance         net             vietnamese
.hooks          astro           french          net-im          www
CHANGES         audio           ftp             net-mgmt        x11
CONTRIBUTING.md base            games           net-p2p         x11-clocks
COPYRIGHT       benchmarks      german          news            x11-drivers
GIDs            biology         graphics        packages        x11-fm
Keywords        cad             hebrew          polish          x11-fonts
MOVED           chinese         hungarian       ports-mgmt      x11-servers
Makefile        comms           irc             portuguese      x11-themes
Mk              converters      japanese        print           x11-toolkits
README          databases       java            russian         x11-wm
Templates       deskutils       korean          science
Tools           devel           lang            security
UIDs            distfiles       mail            shells
UPDATING        dns             math            sysutils
ちなみに、FreeBSD カーネルのソースコードやドキュメントも同じ方法で取得することができます。アナロジカルでいいですね。
# git clone https://git.freebsd.org/src.git /usr/src
# git clone https://git.freebsd.org/doc.git /usr/doc
これで準備完了ですが、リモートリポジトリのほうは今後も時々刻々と更新されていきます。そのときはリモートリポジトリの変更をローカルにも反映させましょう。/usr/ports に移動してからpullします。
# cd /usr/ports
# git pull
または下記でもよいです。
# git -C /usr/ports pull

ports を利用してみる

各 port は /usr/ports の下にカテゴリごとに分類されて展開されています。ソフトウェアをインストールするには、その下にある各 port のサブディレクトリまで降りていって root 権限でmake installまたはmake install cleanを実行します。あとは自動でソースコードの取得からパッチの適用、ビルド、システムへのインストールまでやってくれます。makeコマンドのターゲットにcleanを加えると、ビルドに使用した一時的なファイルなどをあとで削除してくれます。例としてバイナリエディタ hexedit をインストールしてみましょう。
# cd /usr/ports/editors/hexedit
# make install clean
コマンドを新しくインストールしたら、コマンド一覧を更新しましょう。csh 系はrehashコマンド、sh 系はhash -rで更新します。
% rehash
余談ですが、make installしてから実際にインストールが完了するまでの間には「ソースコードを取ってくる」「それを展開する」「パッチを当てる」「ビルドする」などいくつかの工程があります。makeのターゲットとしてfetchextractpatchbuildを指定するとそれぞれの工程まで完了したところで処理を一時停止させることができます。詳しくは ports(7) のマニュアルを参照してください。

ビルドオプションをカスタマイズしてみる

ソフトウェアによってはmake installすると途中でオプションをカスタマイズする画面が表示され、機能ごとに有効 / 無効を選択することができます (とその前に、上に書いた「ports に関する注意事項」を読み飛ばした方は一応目を通してください)。例として今度はテキストベースのウェブブラウザである w3m をインストールしてみましょう。
# cd /usr/ports/www/w3m
# make install
程なくして図 1 のような画面が表示されます。画像をインライン表示するINLINE_IMAGEや、Migemo によるインクリメンタルサーチを可能にするJAPANESEなどを有効にしたくなるかもしれません。必要に応じてチェックを ON/OFF してください。インストールするソフトウェアによっては、依存関係にある別のソフトウェアのカスタマイズ画面も表示される場合があります。
図 1: w3m のカスタマイズ画面
図 1: w3m のカスタマイズ画面
ところで、カスタムした内容は /var/db/ports/ の下の各 port のディレクトリ下に option というファイル名で保存されます。よって次回make installしたときも、今回と同じカスタム内容でビルドが実行されます。もしこの port のカスタム内容を削除してリセットしたい場合は、make rmconfigを実行します。なお、依存関係にあるすべての ports も含めてリセットしたい場合は、make rmconfig-recursiveを実行します。
# cd /usr/ports/www/w3m
# make rmconfig

カスタム画面をスキップしたい

さて、make installを実行すると、中にはビルド中に仮眠がとれてしまうほど時間がかかる port もあります。そんなときにカスタム画面が出てきて止まってしまうのは悲しいです。
図 2: 寝て起きてこれが出てたら凹む
図 2: 寝て起きてこれが出てたら凹む
これを回避する方法は、私の知るかぎり 2 つあります。
  1. BATCH変数にyesを指定してすべてのオプションをおまかせにする。
    # make BATCH=yes install
    
    ただし中にはユーザーの明示的な回答を要求する port もあるようで、そういった場合にはこの方法は適用できないと思われます。
  2. 最初に (依存関係にある ports も含めて) すべてのオプションを設定する。
    ビルドする前にmake config-recursiveを実行すると、ビルドオプションの選択を最初にまとめて行うことができます。
    # make config-recursive
    
    注意点として、以前にこの port のカスタマイズを行ったことがあると、そのときのカスタム内容が保存されているので、make config-recursive しようとしても
    # make config-recursive
       ===> Setting user-specified options for w3m-0.5.3.20230129 and dependencies
    
    と言われて変更できません。その場合はmake rmconfig-recursiveを実行して保存内容を一旦削除してください。

    カスタマイズが終わってプロンプトに戻ってきたらmake installしましょう。

ソフトウェアをアップグレードする

ports を使ってインストールしたソフトウェアは packages の場合と同様にpkg infopkg querypkg versionなどのコマンドを使って管理することができます。それならインストール後は両者を完全に統一的に扱えるのかというと残念ながらそうはいかず、ことアップグレードに関してはpkg upgradeではなく別のツールが必要です。FreeBSD ハンドブック第 4.5 節には ports のアップグレードを行うツールが 3 種類紹介されていますが、ここでは一番お手軽そうな portmaster を使用してみましょう。まず ports か packages を使って portmaster をインストールします。
# pkg install -y portmaster
git pullで ports ツリーをアップデートしてから、portmaster -Lでアップグレード可能な ports があるかを調べます。
# git -C /usr/ports pull
# portmaster -L | grep New
...
        ===>>> New version available: w3m-0.5.3.20230129
...
上の例では w3m を 0.5.3.20230129 にアップグレード可能なようです。現在インストールされている w3m の情報をpkg infoで調べてみましょう。
% pkg info w3m
w3m-0.5.3.20230112
Name           : w3m
Version        : 0.5.3.20230112
...
Options        :
        DOCS           : on
        INLINE_IMAGE   : on
        JAPANESE       : on
        KEY_LYNX       : off
        NLS            : on
...
現在のバージョンは 0.5.3.20230112 となっています。また、ports を利用してINLINE_IMAGE(画像のインライン表示) とJAPANESE(日本語メッセージや Migemo による検索) を有効化したバイナリパッケージになっています。

実際にアップグレードするには、次のようにします。

# portmaster w3m
または次のように-aオプションを付けると、アップグレード可能な ports をすべてアップグレードします。
# portmaster -a
アップグレードが終わったら、またpkg infoで確認してみます。
% pkg info w3m
w3m-0.5.3.20230129
Name           : w3m
Version        : 0.5.3.20230129
...
Options        :
        DOCS           : on
        INLINE_IMAGE   : on
        JAPANESE       : on
        KEY_LYNX       : off
        NLS            : on
...
バージョンが 0.5.3.20230129 に上りました。また、INLINE_IMAGEJAPANESEも相変わらず ON になっており、問題なくアップグレードできているようです。

ソフトウェアを pkg upgrade の対象から除外する

pkg upgradeportmaster --packagesを使ってアップグレードを実行すると、packages (デフォルトオプションでビルドされたバイナリパッケージ) を使ってアップグレードされてしまいます。これは、ports でカスタムビルドしたソフトウェアをアップグレードする場合に問題となります (せっかくカスタムしたのにデフォルトに戻ってしまう)。そのようなときは、pkg lockコマンドを使ってアップグレード対象から外す (ロックする) ことができます。

例えば、(本稿ではいまやお馴染みとなった)INLINE_IMAGEJAPANESEを有効にした www/w3m がすでにインストールされているとします。pkg versionで確認すると、w3m を含めいくつかの packages でリモートリポジトリに最新バージョンが存在するようです。

# pkg version -l '<' -vR
at-spi2-core-2.46.0                <   needs updating (remote has 2.48.0)
atf-0.21                           <   needs updating (remote has 0.21_1)
awesome-4.3_3,1                    <   needs updating (remote has 4.3_4,1)
...
w3m-0.5.3.20230112                 <   needs updating (remote has 0.5.3.20230129)
...

これをこのままpkg upgradeすると、デフォルトオプション (INLINE_IMAGEJAPANESEが無効) でビルドされたバイナリファイルで上書きされてしまうので、次のようにしてロックしておきます。

# pkg lock w3m

この状態でアップグレードを実行しpkg versionで確認すると、w3m だけが元のバージョンのままでありアップグレードが回避されたことがわかります。

# pkg upgrade -y
% pkg version -l '<' -vR
w3m-0.5.3.20230112                 <   needs updating (remote has 0.5.3.20230129)

さて、portmaster に--packagesオプションを付けてアップグレードしようとすると、これと同様の結果になると思われますが、--packagesオプションを付けずに実行するとどうなるでしょうか?

# portmaster w3m

===>>> w3m-0.5.3.20230112 has an +IGNOREME file or the package is locked
    ===>>> Update anyway? y/n [n] y

% pkg info w3m
w3m-0.5.3.20230129
Name           : w3m
Version        : 0.5.3.20230129
...
Options        :
    DOCS           : on
    INLINE_IMAGE   : on
    JAPANESE       : on
    KEY_LYNX       : off
    NLS            : on
...

ロックしてあるので一応「本当にやってよいか?」と確認を促されるものの、yesと答えるとアップグレードが実行されるようです。予想ではpkg unlockしないとアップグレードされないのかと思いましたが。とはいえ、バージョンはちゃんと上がっていますし、自分でカスタムしたオプション (INLINE_IMAGEJAPANESE) も健在で、無事にアップグレードできたようです。

この結果をふまえると、次のような感じで運用するのがよいのかなと思います。

  • ports でカスタムインストールしたソフトウェアはpkg lockしておく。
  • ソフトウェアをアップグレードするときは、まずpkg upgradeで packages (デフォルトオプションなバイナリパッケージ) をアップグレードする。
  • 次いで、ロックされている packages を portmaster でアップグレードする。

なお、pkg-lock(8) のマニュアルには「ロックした package が依存する packages もアップグレード対象にならない」というようなことが書かれていますが、私が確認したかぎり、ロックされるのはコマンドラインで指定した package だけでした (何かオプションが必要なのかな?)。このあたりの仕様が私にはまだ理解できていません。

ちなみに、現在ロックされているソフトウェアの一覧を表示するには-l(エル) オプションを付けます。

# pkg lock -l
Currently locked packages:
w3m-0.5.3.20230129

ロックを解除するにはpkg unlockを使います。

# pkg unlock w3m