自由のなる木

RSS
公開日
2021-12-23

GNU Guix といふもの

現在、自宅で使用している個人用端末では、GNU Guix (以後、Guix と書く) という GNU/Linux ディストリビューションを利用している。

日本での Guix 利用者が少ないためか、Guix について書かれた日本語の記事は、今のところかなり少ない。

Guix を利用するようになって、少し知見もたまってきたので、Guix について紹介する記事を書いてみることにした。1

Guix とは何か

公式ドキュメントを読むと、Guix (Geeks と同じように発音) はパッケージマネジメントツールであり、GNU オペレーションシステム (GNU/Linux と読み替えても良い) のディストリビューションである、とある。

Guix には GNU/Linux のパッケージマネージャとしての側面と、GNU/Linux ディストリビューションとしての側面があり、Guix を単にパッケージマネージャとして利用することも、ディストリビューションとして利用することもできる。

私は、個人用端末以外ではパッケージマネージャとして Guix を利用し、個人用端末ではディストリビューションとして利用している。

なお、Guix は Nix の GNU 版フォークなので、Guix の特徴は Nix の特徴であるとも言える。2

この記事では Nix 由来の特徴もすべて、Guix の特徴として紹介しているので、あらかじめご了承いただきたい。(特に Nix ユーザーの方に向けて。)

パッケージマネージャとしての Guix

まずはパッケージマネージャとしての Guix について紹介する。

Guix では、その他のパッケージマネージャと同じように、パッケージの検索、追加、更新、削除のオペレーションをコマンドから実行できる。

よく使用する基本的なコマンドは以下のようなものだ。

# パッケージリポジトリの更新
$ guix pull
# パッケージの検索
$ guix search PACKAGE
# パッケージの表示
$ guix show PACKAGE
# パッケージのインストール
$ guix install PACKAGE
# パッケージの削除
$ guix remove PACKAGE
# パッケージの更新
$ guix upgrade PACKAGE

コマンド自体に特筆するようなことはほとんどない。

Guix が特徴的なのは、後述するパッケージ管理の仕組みの方だ。

なお、Guix には emacs-guix という Emacs パッケージがあり、Emacs からも操作ができる。

Emacs ユーザはこちらを利用するのが便利だ。

Magit と同じように Transient を活用しているため、emacs-guix の使用方法を知らなくても、すぐに使い始めることができる。

そして、使用しているうちに勝手に学習が進む。

私は、このパッケージを活用し始めてからは、Guix は Emacs から操作するものだ、とさえ思うようになった。

パッケージ管理の仕組み

Guix が他のパッケージマネージャと異なる特徴的な点は、そのパッケージ管理の仕組みにある。

Guix のパッケージ管理は、純粋関数型アプローチを採用している。

Guix のパッケージのインストール処理は、APT のようにコンパイル済みのバイナリをフェッチしてシステムにインストールするのではなく、ソースコードのアーカイブをフェッチして、それをビルドしてできた生成物をシステムにインストールする処理となっている。

この際、Guix のパッケージのビルド処理は、純粋関数のように振る舞う。

純粋関数とは、関数に同じ入力を与えた場合、必ず同じ結果を返却する特徴を持つ (参照透過性を持つ) 関数のことだ。

Guix のパッケージのビルド処理は、パッケージ定義にあらかじめ指定されたコンパイラやライブラリなどを、ビルド処理の入力として受け取り、その入力を利用してソースコードをビルド & インストールし、処理結果としてインストールしたパッケージを返す。

ビルド処理では、入力として与えられたソフトウェアやスクリプトのみを利用でき、一時的に生成されたビルドディレクトリやインストールディレクトリ以下のファイルやディレクトリのみを作成、更新、削除できる。

つまり、パッケージのビルド処理は参照透過であり、副作用もないということだ。

それであれば確かに、パッケージのビルド処理が純粋関数のように振る舞うものだと言われても違和感は感じない。

ビルド処理が参照透過なため、既存のシステムがどんな状態にあろうと、常に同じ条件でパッケージをビルドできる。

さらに、副作用がないため、既存のシステムを壊してしまう心配がない。

そのため、Guix は、既存のパッケージマネージャと安全に組み合わせることができ、共存させることができる。

また、パッケージは最終的に、読み取り専用の /gnu/store というディレクトリ以下に配置される。

パッケージをアップデートして、パッケージ自身や、パッケージの依存関係 (パッケージのビルド処理の入力) に更新がある場合は、更新前後でパッケージのハッシュ値が変わる。

パッケージのハッシュ値は、パッケージのディレクトリ名にも使われているため、新しいパッケージは、更新前のパッケージのパスではなく、/gnu/store 以下の別のパスにインストールされる。

つまり、Guix のパッケージは不変性も持つ。

パッケージの不変性が保証されているため、異なるパッケージ間で同一のハッシュ値を持つ依存パッケージを安全に共有できる。

さらにパッケージの不変性の恩恵によって、パッケージ構成が世代管理されており、いつでも任意の世代に巻き戻すことができる。

Guix の環境が壊れた3としても、世代を戻せば簡単に復旧できるということだ。

# 1 世代前に戻す
$ guix package --roll-back
# 世代一覧を出力する
$ guix package --list-generations
# 任意の世代にスイッチする
$ guix package --switch-generation=PATTERN

Guix はその仕組み上、ストレージの消費量が多いため、不要になったパッケージや世代は、guix gc を使用して定期的にクリーンナップすることが推奨される。

すでにガベージコレクトされた世代には巻き戻すことができない点は注意が必要だ。

Guix はその出自からして、Emacs 関連のパッケージが充実している。

メンテナの多くが Emacs に精通していて信頼できるため、「常に最新版の Emacs を利用したい」という目的のために Guix を導入するというのも、Guix に触れる入口としてはアリなのかもしれない。4

参考: Managing Software the Guix Way (GNU Guix Reference Manual)

パッケージ定義

参考のため、Guix のパッケージがどのように定義されているかについても少し触れておく。

例えば sed のパッケージ定義が以下だ。

(define-public sed
  (package
   (name "sed")
   (version "4.8")
   (source (origin
            (method url-fetch)
            (uri (string-append "mirror://gnu/sed/sed-" version
                                ".tar.gz"))
            (sha256
             (base32
              "0alqagh0nliymz23kfjg6g9w3cr086k0sfni56gi8fhzqwa3xksk"))
            (patches (search-patches "coreutils-gnulib-tests.patch"))

            ;; Remove this snippet once upstream releases a fixed version.
            ;; This snippet changes Makefile.in, even though the upstream
            ;; patch changes testsuite/local.mk, since we build sed from a
            ;; release tarball.  See: https://bugs.gnu.org/36150
            (snippet
             '(begin
                (substitute* "Makefile.in"
                  (("^  abs_srcdir='\\$\\(abs_srcdir\\)'.*" previous-line)
                   (string-append
                    previous-line
                    "  CONFIG_HEADER='$(CONFIG_HEADER)'\t\t\\\n")))))
            (modules '((guix build utils)))))
   (build-system gnu-build-system)
   (synopsis "Stream editor")
   (native-inputs (list perl))                    ;for tests
   (description
    "Sed is a non-interactive, text stream editor.  It receives a text
input from a file or from standard input and it then applies a series of text
editing commands to the stream and prints its output to standard output.  It
is often used for substituting text patterns in a stream.  The GNU
implementation offers several extensions over the standard utility.")
   (license gpl3+)
   (home-page "https://www.gnu.org/software/sed/")))

パッケージ定義は、Scheme で書かれた DSL を利用して記述するため、Scheme の能力を如何なく発揮できる。

Scheme の処理系は言わずもがな、GNU の公式拡張言語である GNU Guile だ。

Guix は Guile のキラーアプリでもある。

話がそれた。パッケージ定義の話に戻る。

パッケージ定義に記述されている define-public というシンタックスは、 Guile のモジュール定義で使用する一般的なシンタックスで、Guix 固有のシンタックスではない。(R6RS のものでも、R7RS のものでもない処理系依存のシンタックス)

package というシンタックスが Guix 固有のシンタックスで、パッケージ定義の本体になる。

パッケージ定義の中に native-inputs というフィールドがあるが、これがパッケージのビルド処理の入力になる。

この例では native-inputsperl を渡している。

つまり、このパッケージ定義におけるビルド処理は、入力として perl を受け取り、perl を利用して (※ テストで利用している) sed をビルド & インストールした後、sed パッケージを返す関数 (sed-package-process :: perl -> package) と捉えることができる。

パッケージ定義からは、それ以外にも以下の内容が読み取れる。

  • mirror://gnu/sed/sed-4.8.tar.gz からソースコードのアーカイブを取得する
  • あらかじめ用意された coreutils-gnulib-tests.patch を適用する
  • Makefile.in を Guix 向けに置換する
  • パッケージのビルドシステムは gnu-build-system を使用する

gnu-build-system は、./configure && make && make check && make install を実行してパッケージをインストールするビルドシステムだ。

パッチの適用や Makefile.in の書き換えなどの下準備をした後、GNU Make によってパッケージがビルドされ、インストールされる。

gnu-build-system 以外にも、CMake、Maven、 npm などと言った、多種多様なビルドシステムが Guix には用意されている。

それらを利用してインストールできるソフトウェアは、Guix を利用してもインストールできる。

参考: Build Systems (GNU Guix Reference Manual)

また、ビルド処理は、ビルドの各フェーズ (unpackbuildinstall など) のフックなどを利用して任意にカスタマイズできる。

参考: GNU Guix Cookbook

チャンネル

Guix ではパッケージが収録されたリポジトリのことをチャンネルと呼ぶ。

公式のチャンネルは、Guix 自身の Git リポジトリだ。

https://git.savannah.gnu.org/cgit/guix.git

リポジトリの gnu/packages 配下にパッケージを定義したモジュールが含まれていて、Guile のコードからは (use-modules (gnu packages sed)) の様にモジュールをインポートする。

参考: Using Guile Modules (Guile Reference Manual)

このチャンネルには多数のパッケージが収録されているが、Free Software Directory に掲載されるような自由ソフトウェアしか収録されていない。

公式リポジトリに収録されていないソフトウェアをインストールしたい場合は、別のチャンネルを追加するか、自分でチャンネルを作成する必要がある。(その他の方法もあるが後述する。)

チャンネルは、パッケージをエクスポートする Guile モジュールを含む Git リポジトリであれさえば良く、そのディレクトリをローカル、または、インターネットからアクセスできる Git リポジトリに置き、設定ファイルで指定すればチャンネルが追加できる。

# Guix が自動的に参照してくれるチャンネルのコンフィグファイルの中身を表示する
$ cat ~/.config/guix/channels.scm
(cons* (channel
        (name 'my-github-channel)
        (url "https://github.com/USERNAME/my-github-channel"))
       (channel
        (name 'my-local-channel)
        (url "file:///home/USERNAME/my-local-channel"))
       %default-channels)
# チャンネルのパッケージ情報を最新化する
$ guix pull
# パッケージをインストールする (my-*-channel のパッケージもインストールできる)
$ guix install my-channel-package

環境

Guix はシステムにソフトウェアをインストールする以外にも、パッケージを元にアドホックな環境を作ったり、VM を作ったり、Docker イメージを作ったりもできる。

例えば、NumPy や SciPy を使用して何らかの計算をしたいとする。

その場合、以下のコマンドを実行すれば良い。

# NumPy と SciPy が使用できる Python インタラクティブシェルを開く
$ guix shell python python-numpy python-scipy -- python3

システムにあらかじめインストールしていなくても、アドホックに NumPy と SciPy が使用できる Python インタラクティブシェルが起動できる。

Docker でもこれと同じようなことが実現できるが、この方法は Dockerfile を記述する手間が省けるし、依存パッケージの組み合わせも自由なため、とても便利だ。

ちなみに、この記事を書いている最中にも guix shell が役に立った。

このブログは Pelican で作られているが、コードブロックには Pygments が使われている。

Pygments は端末に明示的にインストールしていなかったため、以下のコマンドを実行して、シンタックスハイライト用の CSS ファイルをアドホックに生成した。

$ guix shell python-pygments -- pygmentize -S solarized-light -f html -a .highlight > themes/static/css/pygment.css

便利だ。

参考: From ‘guix environment’ to ‘guix shell’ — 2021 — Blog — GNU Guix

プロファイル

Guix にはプロファイルの概念がある。

Guix は、コマンドに明示的に指定しない限り、デフォルトプロファイルを使用するが、プロファイルを明示的に指定することで、指定したプロファイルにパッケージを導入できる。

例えば、複数のバージョンの OpenJDK をプロジェクトによって切り替えたい場合、以下のようなプロファイルの使い方が考えられる。

  • OpenJDK のバージョン毎にプロファイルを作成し、プロジェクト毎に使い分ける
  • プロジェクト毎にプロジェクトで使用する OpenJDK を含むプロジェクト用プロファイルを作成する

前者の方法を採用した場合は、下記のようにプロファイルを作成すれば良いだろう。

# OpenJDK プロファイル用のディレクトリを作成する
$ mkdir -p $HOME/.guix-extra-profiles/openjdk
# openjdk-16 をインストールする
$ guix install --profile=$HOME/.guix-extra-profiles/openjdk/openjdk-16 openjdk@16
# openjdk-14 をインストールする
$ guix install --profile=$HOME/.guix-extra-profiles/openjdk/openjdk-14 openjdk@14
# プロジェクトで使用している JDK の確認
$ cd /path/to/openjdk16-project
$ cat .env
JAVA_HOME="$HOME/.guix-extra-profiles/openjdk/openjdk-16"
PATH="$PATH:$JAVA_HOME/bin"
$ . .env
$ java -version
openjdk 16.0.1 2021-04-20
OpenJDK Runtime Environment (build 16.0.1+0-adhoc..source)
OpenJDK 64-Bit Server VM (build 16.0.1+0-adhoc..source, mixed mode, sharing)

参考: Guix Profiles in Practice — 2019 — Blog — GNU Guix

マニフェスト

Guix のパッケージ構成は、マニフェストで宣言的に記述することもできる。

(specifications->manifest
  '("package-1"
     ;; package-2 のバージョン 1.3
     "package-2@1.3"
     ;; package-3 の "lib" output
     "package-3:lib"
     "package-N"))

マニフェストを使用してパッケージをインストールしたり、現在のパッケージ構成をマニフェストとしてエクスポートしたりもできる。

# マニフェストを使用してパッケージをインストールする
$ guix package --install --manifest=MANIFEST
# 現在の構成をマニフェストとしてエクスポートする
$ guix package --export-manifest > MANIFEST

マニフェストを Git リポジトリなどで管理しておけば、同じパッケージを、どの環境にも簡単に導入できる。

ディストリビューションとしての Guix

ディストリビューションとしての Guix の利用に関しては、まだ私自身の経験が浅く、言及できることは少ないのだが、簡単に紹介する。

現在、私の個人用端末では、Guix をディストリビューションとして利用している。

ただ、これは二度目の挑戦で、実は過去に一度挫折している。

つい最近になって、パッケージマネージャとしての Guix の利用にこなれてきたため、再挑戦することにした。

ディストリビューションとしての Guix は、GNU のサイトで自由な GNU/Linux ディストリビューションとして掲載されている数少ない自由なディストリビューションのひとつとなっている。

Guix は、カーネルにプロプライエタリなファームウェアを含まない Linux-libre を使用している。

Guix にはグラフィカルインストーラも用意されているので、インストール自体は難しくはない。

グラフィカルインストーラの中で、デスクトップで使用するウィンドウマネージャも選択できる。

Guix らしいと言えるのだが、選択できるウィンドウマネージャには、EXWM が含まれていたりもする。

私が最初に Guix をディストリビューションとして利用した際は、ウィンドウマネージャとして EXWM を選択した。

Emacs で全てをコントロールできるというのは、快適な部分もあったのだが、オリジナルの作者がコミットしなくなってしまい先行きに不安を感じたのと、Wi-Fi の設定やサウンドの設定のような基本的な設定にアレコレ苦労するのが辛かったので、今はおとなしく GNOME を利用している。

宣言的なシステム構成

パッケージのマニフェストと同様に OS の構成も Scheme の DSL を利用して宣言的に記述できる。

記述例は以下だ。

(use-modules (gnu)
  (nongnu packages linux)
  (nongnu system linux-initrd))
(use-service-modules desktop networking ssh xorg)

(define %xorg-libinput-config
  "Section \"InputClass\"
    Identifier \"TouchPad\"
    MatchIsTouchpad \"on\"
    Driver \"libinput\"
    Option \"Tapping\" \"on\"
EndSection")

(operating-system
  (kernel linux)
  (initrd microcode-initrd)
  (firmware (cons* iwlwifi-firmware
              %base-firmware))
  (locale "en_US.utf8")
  (timezone "Asia/Tokyo")
  (keyboard-layout
    (keyboard-layout
      "jp"
      #:options
      '("ctrl:nocaps")))
  (host-name "Taix")
  (users (cons* (user-account
                  (name "taiju")
                  (comment "Taiju HIGASHI")
                  (group "users")
                  (home-directory "/home/taiju")
                  (supplementary-groups
                    '("wheel" "netdev" "audio" "video")))
           %base-user-accounts))
  (packages
    (append
      (list (specification->package "nss-certs"))
      %base-packages))
  (services
    (append
      (list (service gnome-desktop-service-type)
        (set-xorg-configuration
          (xorg-configuration
            (keyboard-layout keyboard-layout)
        (extra-config (list %xorg-libinput-config)))))
      %desktop-services))
  (bootloader
    (bootloader-configuration
      (bootloader grub-efi-bootloader)
      (target "/boot/efi")
      (keyboard-layout keyboard-layout)))
  (mapped-devices
    (list (mapped-device
            (source
              (uuid "74cca602-a8d8-4e2c-a863-0cd727e5f8fc"))
            (target "cryptroot")
            (type luks-device-mapping))
      (mapped-device
        (source
          (uuid "025d4860-aa73-4659-8e66-a75881e7b2b0"))
        (target "crypthome")
        (type luks-device-mapping))))
  (file-systems
    (cons* (file-system
             (mount-point "/boot/efi")
             (device (uuid "4187-5483" 'fat32))
             (type "vfat"))
      (file-system
        (mount-point "/")
        (device "/dev/mapper/cryptroot")
        (type "ext4")
        (dependencies mapped-devices))
      (file-system
        (mount-point "/home")
        (device "/dev/mapper/crypthome")
        (type "ext4")
        (dependencies mapped-devices))
      %base-file-systems)))

これは私の個人用端末にグラフィカルインストーラで Guix をインストールした後、少しだけ記述を追加・変更したものだ。

何が記述されているかはおおよそ見当が付くのではないだろうか。

サービスの設定をもっと活用した方が良いような気もしているのだが、現在はグラフィカルインストーラが自動で設定してくれた Desktop Service の設定しか記述できていない。

デスクトップ用途であればあまり活用しないのかもしれないが、それ以上言及するには知識不足だ。

参考: Services (GNU Guix Reference Manual)

とにかく、このように宣言的にシステム構成が書けるので、上記のシステム構成ファイルを使用して別のマシンをセットアップすれば、同じシステム構成の Guix ディストリビューションが簡単に手に入る。(はずだ。)

途中でシステム構成を更新したい場合は、システム構成ファイルを更新した後、以下のコマンドを実行してシステムを再構成できる。

$ sudo guix system reconfigure CONFIGFILE

余談になるが、現在、個人用端末の入れ替えを予定していて、システム構成ファイルをさらに充実させたいと思っている。

上記のシステム構成ファイルとパッケージのマニフェストを使用すれば、現在の個人用端末を新しい個人用端末に比較的容易に移行できると思っているが、できればホームディレクトリ以下の個人用設定も Guix である程度コントロールしたい。

まだ開発中の機能のようで、Guix の安定版ドキュメントには記載がないが、Guix の開発版ドキュメントには、Home Configuration というセクションが新設されている。

これを利用すればやりたいことが実現できるのではないかと期待している。

参考: Home Configuration (GNU Guix Reference Manual)

今回が Guix での始めてのマシン移行作業になるが、これがうまくいけば、他のディストリビューションにはもう戻れなくなるだろう。5

宣言的な記述によって、自分専用にカスタマイズしたシステムをいつでもすぐに構築できるようになったら、そのコンフォートゾーンから抜け出せなくなりそうだ。

ディストリビューションとしての Guix の辛さ

いろいろと読者の期待の高まることを書いてはいたものの、正直なところ、ディストリビューションとしての Guix には辛さがあるのも事実だ。

一番の辛さは、単純にインストールしただけでは、日本語入力もままならないのだが、日本人のトラブルシューティング記事がほとんどないことだ。

現状、公式のチャンネルで利用できる日本語入力システムは、ibus + ibus-anthy のみで、これらをインストールして、ArchWiki などに書かれている設定をしただけでは、日本語入力ができるようにはならなかった。6

日本語を入力したくて困っている外国の方は希少だろう。

この問題について解決方法が記載されていた記事は以下の記事のみだった。

上記を参考にすれば、ローマ字での日本語入力はできるようになるものの、私の環境では、ibus-anthy の設定が保存できないという事象が発生したため、使い物にならなかった。

特に私は、JIS かな入力使いなので、かな入力に切り替える設定が保存できないことは、日本語入力ができないことに等しい。(そこまで言うと言い過ぎかもしれないが、自分が快適に利用できる入力メソッドを、自分専用の個人用端末で使えないのは苦痛で仕方がない。)

幸い、ibus-anthy のバージョンが低いことが原因だったことがわかったため、ibus-anthy の最新版が使用できるパッケージを書いて事なきを得た。

先日、upstream にパッチを投げたのだが、しばらく応答がなく、今朝、ようやく応答があった。

指摘対応にまだ時間がかかりそうだ。

また、公式チャンネルには Mozc が収録されていないため、Emacs での日本語入力も厳しい状態だった。(anthy.el ってどこから入手するんだろうか?)

これに関しては、DDSKK の Nicola バージョンのパッケージを書いて対応したのだが、まだ DDSKK に慣れていないのと、そもそもローマ字入力の入力方式に比べると、Nicola 方式はあまり効率が良いとは思えないので、改善はしたいと思っている。

こちらの方は、upstream に投げたパッチが公式チャンネルにすでに取り込まれている。

日本語環境においては、このような基本的なユースケースですら、人柱が足りていないので、今の段階で Guix をディストリビューションとして利用する場合は、自分が人柱になる覚悟も必要だ。

ただ、英語圏の Guix ユーザーは多く、インターネット上に様々な情報が転がっているので、日本人が困る問題だけが解決が難しかっただけの可能性はある。

上記で挙げた問題の他、自由なソフトウェアだけを利用するという縛りも、(個人的には目指したい理想ではあるものの) 厳しい部分があったりはするのだが、これにはある程度の回避策があるので後述する。

Guix の避難ハッチ - Nonguix

現在利用している個人用端末には、Intel 製の Wi-Fi モジュールが組み込まれている。

このモジュールのファームウェアは、プロプライエタリなファームウェアのため、Guix では利用できない。

流石に Guix のために Wi-Fi アダプタを買うことはしたくないし、すでに所有している周辺機器が Guix に対応できないというのも辛いため、プロプライエタリなファームウェアやドライバ、ソフトウェアをインストールしないという誓いは今はしないことにした。

そのような場合は、Nonguix というチャンネルを追加することが一つの解決策だ。

Nonguix は、Guix の公式のチャンネルに含めることのできないパッケージを集約し、メンテナンスしている非公式チャンネルで、シェアも高く、よくメンテナンスされている。

前述のシステム構成ファイルを見てもわかるとおり、私の個人用端末では、Nonguix で提供されている Linux-libre ではない (バイナリ・ブロブを含む) 普通の Linux カーネルや、プロプライエタリなファームウェアである Iwlwifi を使用している。

Guix の避難ハッチ - その他のパッケージマネージャ

Nonguix には、Guix でインストールできないパッケージが必要十分に揃っているわけではない。

なので、Nonguix だけでソフトウェア入手問題のすべてが解決できるわけではない。

私は、変な先入観があったため気づくのが遅かったのだが、Guix の公式チャンネルからインストールできるパッケージには、Flatpak や Nix などの他のパッケージマネージャが含まれている。

そのため、Guix にも Nonguix にも存在しないソフトウェアは、例外的に Flatpak や Nix などの他のパッケージマネージャでインストールするということができる。7

例えば私の場合は、Flatpak を利用して、Steam や VSCodium などをインストールしている。8 9

Steam は鬼門かもしれないと考えていたが、Pop!_OS を使っていた時と同じように、Windows 用のゲームも Proton を利用して今のところは普通に遊べている。

Flatpak などのパッケージマネージャでインストールしたソフトウェアが、Guix の公式チャンネルにラインナップされていない自由ソフトウェアであれば、可能な範囲で Guix のパッケージを書いて、upstream にパッチを投げたいとは考えている。

公式のチャンネルや、Nonguix のチャンネル以外をまともにリサーチできていないので、もしかしたら、上記で挙げた問題は、それらのチャンネルを追加して利用するだけで解決できる可能性はある。

libgccjit バージョンの Emacs パッケージをメンテしているチャンネルもあるらしいので、システム構成が一段落したら、その辺りから試していきたい。

結論になるが、ディストリビューションとしての Guix についてまとめると、今の段階では少し苦労する部分はあるものの、自分でパッケージをカスタマイズしたり、必要に応じて別の手段でパッケージを導入すれば、ディストリビューションとしての利用も十分実用に耐えられると思っている。

まとめ

Guix が、なぜ自由ソフトウェアを愛する人たちを中心に支持されているのか、自分で利用してみると理解ができた気がする。

何かの問題に直面した際に、自分で問題解決しないとならないことはまだまだ多いかもしれないが、自分のマシン構成をほぼ掌握しているという安心感や全能感を多少なり感じられて、使っていて楽しいソフトウェアだと思う。10

Emacs と同様に、今後も末永くお世話になる予定だ。

この記事を読んだ誰かが、この記事をキッカケに Guix に興味を持ち、利用し始めたら嬉しい。11

以上。12


  1. この記事の内容は、現在の仕事にまったく関係ない内容だが、この記事は所属する会社の ESM Advent Calendar 2021 の 23 日目の記事として書いた。何かの技術に夢中になれることは、プログラマが持つべき特性のひとつだと思うので、記事の内容が仕事に関係なくても何の問題もないし、働く組織にそういう人達がもっと増えれば喜ばしい。と、勝手に考えている。 

  2. Nix は日本のコミュニティもあるようで、Guix に比べると日本語情報も多いが、もっと評価されても良い気がしている。 

  3. パッケージ自体が副作用によって壊れることはないが、プロファイルに紐付けた際に、あるパッケージとあるパッケージのファイルの生成物のパスが衝突して、パッケージを共存できなくなることは普通に起こる。 

  4. Emacs のパッケージも揃っているので、Emacs のパッケージ管理システムに依らず、Guix にパッケージ管理を任せるという使い方もできる。私はそうしている。 

  5. すべてのパッケージをソースコードからビルドしてインストールする Guix は、現在使用している個人用端末の性能的に少し辛いのだが、性能の良いマシンになることでさらに快適になることを期待している。 

  6. 日本語入力システムは、Guix に頼らず、他のパッケージマネージャで整えればあまり苦労しなかったのかもしれない。 

  7. 必ずしもパッケージマネージャを使用する必要はないが、システムの状態を正確に把握したいと思った場合、Flatpak や Nix のような安全に使用できるパッケージマネージャの利用が好ましいと思った。 

  8. Nix は使わないことにした。Nix を使うと Guix と Nix の境界が曖昧になってしまいそうなのと、あくまで例外的に使うのであってそこに純粋性までは求めてはいないため。 

  9. Nonguix にも Steam があるが、現在使用しているマシンが非力でビルドが厳しく、ストレージのサイズも潤沢ではなく、さらに、導入してみようとした際に、ちょうど既知の不具合が未解決だったため、Flatpak でインストールした。 

  10. Kubernetes に対してもこれと近い感情を抱いた気がする。 

  11. この記事を読んだ結果、「これは良いことを聞いた!私もNixOS 使おう!」と思われてしまったら悲しいものがあるが、少なくとも Guix の魅力も伝えることができたと肯定的に捉えることにする。 

  12. 読み返してみると、この記事はやたらと余談が多い。コロナ禍の会話不足によるストレスか…。