Chienomi

Arch Linux/Manjaro Linux初心者のためのAUR入門

Live With Linux::manjaro

この記事はArch LinuxやManjaro Linuxを使い始めたばかりのビギナーや、これらのディストリビューションに関心のある他のディストリビューション使い(例えばUbuntu, Mint, Debian, openSUSE, Fedora, Mageiaなど)の人に向けた記事である。

ちなみに、私はAURでfcitx-mozc-neologd-ut/mozc-neologd-utパッケージのメンテナを務めているのだが、実はここらへんに関してはアップストリームの作者がArch使いでPKGBUILDを書いてくれているので、私はその検証と手直しをしてAURで使えるようにしているだけなので、大したことはしていない。

What is AUR

AUR(Arch User Repository)はArch Linuxにおいてユーザーが投稿できるパッケージデータベースである。

このような仕組みがあるディストリビューションは珍しいが、Ubuntuには似たようなLaunchpad(PPA)という仕組みがある。

実のところ、AURの存在はArch Linuxにとって非常に大きなポイントになっている。

まず、ユーザー投稿できるということは、コミュニティによってサポートされていないソフトウェアがパッケージ管理ツールによって導入・管理可能であることを意味する。 このため、Arch Linuxが扱うことができるパッケージは、圧倒的な数にのぼる。追随できるのはUbuntuとGentooくらいのものであり、私が使用した感じではArch Linuxがもっとも「パッケージがよくある」ディストリビューションである。

そして、AURという「パッケージそのものは公式ではないが、場所自体は公式に提供されている」というのが大きい。 サードパーティリポジトリというのは、だいたいソフトウェア個別にリポジトリを追加する必要があり、だからこそ相互に検証したりはしておらず、色々と追加すると問題が発生しやすい。 だが、AURは「Archの環境+AUR」で検証されており、他のAURパッケージに対する配慮もしっかりなされている。

また、AURはかなりしっかりとしたルールがあり、他のユーザーによるフラグ立てなどもできることから、他の非公式リポジトリと比べるとかなりしっかりメンテナンスされていて信頼性も高い。 「AURヘルパー」によって統一的に扱うことができ、廃止したパッケージも知ることができるといったことから扱いやすさも優れている。

さらに、AURとArch Linuxのパッケージの仕組みにさらなるポイントがある。

Arch Linuxのパッケージの正体はPKGBUILDというファイルである。 ソースパッケージとしてはPKGBUILDさえあれば、バイナリパッケージが作れる。 これは他のパッケージと比べても非常にシンプルである。

さらに良いところはPKGBUILDは(専用に色々と定義された状態で読まれる)シェルスクリプトである、ということなのだが、まぁそれは置いておこう。 だが、RPMのSpecと比べるとできることはすごく多い。

とにかく、「PKGBUILDを用意したら、あとはmakepkgとやればパッケージができる」というのがポイントだ。 ソースファイルは? ビルドの準備は? と思うかもしれない。 PKGBUILDには必要なソースをHTTP経由でアクセスできる場所や、Gitを使って取ってこれるものなどを指定することができる。これによって、PKGBUILDを使ってパッケージを作成する過程でソースの入手も行うことができる。 それ以降の作業は段階ごとにシェルスクリプトの関数として定義している。

ここで重要なのは、「PKGBUILDさえあれば良いので、パッケージを獲得する上でソフトウェアそのものを配布しなくて良い」ということである。 つまり、二次配布が禁止されているなど、ライセンス的にディストリビューションとして配布できないようなパッケージも簡単に配布できる。

このようなメリットは、Gentooや、FreeBSDにあるものである。 これをArch Linuxでも実現しており、実際ほとんどのAURのパッケージはPKGBUILDだけでできている。 fcitx-mozc-neologd-utも一時期はパッチを含めていたものの、現在はPKGBUILDだけになっている。

余談だが、Archの公式パッケージはバイナリパッケージなので、全部ビルドするGentooと比べると「いいとこ取り」感がある。さらにいうと、ABSというものを使うと公式パッケージのものをソースからビルドすることもできたりする。 Manjaroに関してはABSはないが、manjaro-tools-pkgで同じようなことができる。

AURの存在感とAURヘルパー

Arch LinuxであればパッケージはPacmanを使って操作することになる。 だが、Pacmanで操作できるのは公式パッケージだけだ。

AURからパッケージをインストールすることは難しくはない。 例えばTrizenをインストールするならば次のようにする。

$ git clone https://aur.archlinux.org/trizen
$ cd trizen
$ makepkg
$ sudo pacman -U *.pkg.tar.*

現在のAURはシンプルなGitリポジトリ群になっており、AURパッケージを取得したらやるべきことはもうmakepkgして、そしてpacman -Uで出来上がったパッケージをインストールすることだけだ。

このように全然難しくないのだが、それでもこのような方法ではなく、AURヘルパーというソフトウェアを使うことが圧倒的に多い。

今挙げた「Trizen」というソフトウェアはAURヘルパーのひとつだ。 以前はAURヘルパーといえばYaourtというソフトウェアが有名で、Pacaurというソフトウェアも知られていた。 だが、Yaourtは問題があったため開発を終了したし、Pacaurも問題のあるソフトウェアとなっている。

現在有効なAURヘルパーはたくさんある。AURヘルパーはAUR自体がArchの公式ではないので、AURヘルパー自体もまたAURパッケージである。 ただし、ManjaroではPacaur, Trizen, Yayが公式パッケージになっていて、Pacmanで入る。 特に最近はYayは最初から入っている。

と、ここまではArch流の説明をしてきたが、実のところManjaroにおいてはもっと話は単純である。 ManjaroにはPamacというGUIのパッケージ管理ツール1があるのだが、これで設定で「AURを有効にする」とやると、公式パッケージもAURも同じように扱うことができる。 画像で「インストール」となっているのは公式パッケージで、「ビルド」となっているのはAURだ。

PamacでAURを有効にする
Pamacで「fcitx」を検索

コマンドラインからだと難しいかというとそんなことはない。 Yaourtがそうだった関係で、多くのAURヘルパーはアクション引数を与えないと引数のワードをAND検索して公式パッケージもAURも一緒くたにパッケージを探してリストしてくれる。あとはインストールしたいパッケージの番号を入力してEnterを押すだけだ。

Trizenで「fcitx」を検索

そして、Pamacこそないものの、AURにはGUIのAURヘルパーも存在する。

Manjaroでは最初からAURパッケージをインストールする方法があるので問題ないのだが、Arch Linuxの場合はmakepkgはbuild dependを解決してくれたりしないので、依存が深いパッケージのインストールはまぁまぁ大変である。 大体のAURヘルパーはこの依存関係の面倒も見てくれるようになっている。 そのため、TrizenがGoで書かれており、Goさえあればビルドできることからインストールが結構簡単なので、とりあえずTrizenを入れて、そこからお好みのAURヘルパーを入れるのがお勧め。あるいは、ビルド済みのyay-binなどを入れるか。

AURのビルドをチューニングする

概要

AURはAURヘルパーを使うとしても、結局のところ

  1. AURパッケージをとってくる
  2. makepkgする
  3. Pacmanでインストールする

という手順である。

このうち、パッケージをビルドしているのがmakepkgであり、makepkgの設定をいじることでパッケージのビルドをチューニングできる。makepkgの設定ファイルは/etc/makepkg.confだ。

ビルドを速くする

最近のイケてるPCはだいたいコアがいっぱい載っている。 Ryzen 9なんて16コアもあるし、AMDがリッチなコアをたくさん積むようになったので、Intelの「コンシュマー向けは4コアまで」という制限もなくなってIntelもいっぱいコアを積むようになった。

このコアを活用するのにまず思いつくのが、マルチコアでビルドするということだ。 これはMAKEFLAGSで設定できるのだが、うちの環境ではデフォルトで次のようになっている。

MAKEFLAGS="-j$(($(nproc)+1))"

なので、4コアなら5スレッドでビルドされる。 MAKEFLAGSに関してはこれで十分だと思う。

じゃあマルチコアは最初から活かされているのかぁ…と思うことなかれ。 実は、マルチコアが活きていない部分がある。それが「圧縮」だ。 パッケージはコンパイル後に圧縮される。今だと普通はxzに圧縮されるのだが、xzは重いし遅い。 そして、特に「バイナリで提供されているが、大きくて圧縮が大変なバイナリ」であるところのChromeとかVivaldiとかは圧縮にかかる時間がかなり大きい。あと、フォントなんかもそうだ。

そして、デフォルトの設定ではxzはシングルスレッドで動作する。 この設定はCOMPRESSXZにある。

COMPRESSXZ=(xz -c -z -)

見ての通り(配列になった)コマンドだ。 ここでオプションを追加すれば、圧縮をマルチスレッドで行うことができる。

COMPRESSXZ=(xz -c -z -T0 -)

うちのマシンはしょぼい20コアが載っているので、これをするのとしないのでは全然時間が変わってくる。 4コア以上載っているマシンならぜひ設定すべきだ。もちろん、その分集中的にリソースを投入することになるが。

もうひとつやっておきたいのが、「tmpfsでビルドする」だ。 これは、少なくともメモリは16GB以上あったほうがいい。8GBだとコケる可能性が高いし、パッケージによっては16GBでもコケる可能性がある。だが、メモリが潤沢にあるのであれば、ビルドはtmpfsでやったほうがずっとずっと速くなる。

これは

#BUILDDIR=/tmp/makepkg

という行をアンコメントして

BUILDDIR=/tmp/makepkg

とすればOKだ。

他にもdistccやccacheを使って速くすることもできるが、それは上級者向けの話題だろう。

バイナリを最適化する

CFLAGSCXXFLAGSgccなどに渡される引数だ。このオプションを変更することで生成されるバイナリを変えることができる。

こういう話はArchよりGentooのほうが詳しい

だが、色んなことを散々考え抜いた挙げ句、出てくる結論はシンプルだ。

もし、同じアーキテクチャのマシンが複数あり(今Archに関してはx86_64しかないので違うアーキテクチャのマシンがあるかというと疑問だが)、それらでパッケージを共有したい場合は 何も変えない で、ビルドしたパッケージをエクスポートするようにする。

例えば超強力なRyzen Threadripperマシンと、非力なCore-mマシンがあったとする。 どちらもx86_64プロセッサだが、方や超高性能のワークステーションであり、方や省電力が命のモバイルだ。 省電力マシンで重たい処理を延々やるのもどうかと思うし、かかる時間もまるで違う。

そこで、ThreadripperマシンでAURパッケージをビルドしてエクスポートし、そこで作られたパッケージをCore-mマシンにコピーしてpacman -Uでインストールするわけである。

このためにはAURヘルパーにビルドしたパッケージをエクスポートするように設定しなくてはならない。 Trizenの場合、~/.config/trizen/trizen.conf

  movepkg                    => 0,                               # bool -- Move built packages in the directory `movepkg_dir`.
  movepkg_dir                => "/var/cache/pacman/pkg",         #  str -- Absolute path to the directory where to move built packages (with `movepkg`).

という行があり、movepkg1にすればエクスポートしてくれるようになる。 エクスポート先が公式パッケージと同じ/var/cache/pacman/pkgであるべきか、それとも分けるべきかはやや悩ましい。

いずれにせよ、こうした設定によりAURのビルド済みパッケージを共有できるわけだ。 もし、Threadripperマシンでは必要ないが、Core-mマシンでは必要なパッケージを、パワフルなThreadripperマシンでビルドしたい、というような希望があるならば、Trizenであればtrizen -S --noinstall fcitx-mozc-neologd-utのようにしてビルド済みパッケージを入手することができる。

一方、このような共有の必要がないのであれば、そのマシンに最適化されたバイナリを生成するとより高い性能を発揮できるかもしれない。

そのためにはCFLAGSCXXFLAGSを編集する必要がある。

しかし、結局のところ深く考える必要はない。 大抵の場合、両方とも-march=genericとなっているものを、-march=nativeとするだけに留めるのがベストだ。 これは、大きな犠牲を払うことなくバイナリを高速化してくれるだろう。