Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
❄️ NixOS/nixpkgsにSATySFiサポートを実装する
Search
Mutsuha Asada
March 09, 2025
Programming
2
250
❄️ NixOS/nixpkgsにSATySFiサポートを実装する
Nix meetup #2
Mutsuha Asada
March 09, 2025
Tweet
Share
More Decks by Mutsuha Asada
See All by Mutsuha Asada
🔨 小さなビルドシステムを作る
momeemt
0
290
情報科学類で学べる専門科目38選
momeemt
0
570
❄️ tmux-nixの実装を通して学ぶNixOSモジュール
momeemt
1
240
Wasmで拡張できる軽量マークアップ言語 Brack
momeemt
0
100
Intel系FPGA上へのRISC-Vプロセッサの実装
momeemt
0
140
情報科学若手の会 2024 LT「WebAssemblyで拡張可能な軽量マークアップ言語の開発」
momeemt
0
45
Nixでつくるdotfiles
momeemt
1
57
情報特別演習I 最終発表「理工学の紙書籍を用いた学習の効率を向上させるインタフェース」
momeemt
0
36
SATySFi Conf 2023「SATySFiを使って学類新歓冊子を発行した」
momeemt
0
26
Other Decks in Programming
See All in Programming
Dart 参戦!!静的型付き言語界の隠れた実力者
kno3a87
0
200
ゲームの物理
fadis
5
1.5k
CEDEC 2025 『ゲームにおけるリアルタイム通信への QUIC導入事例の紹介』
segadevtech
3
960
ワープロって実は計算機で
pepepper
2
1.4k
フロントエンドのmonorepo化と責務分離のリアーキテクト
kajitack
2
130
Kiroの仕様駆動開発から見えてきたAIコーディングとの正しい付き合い方
clshinji
1
130
Claude Codeで実装以外の開発フロー、どこまで自動化できるか?失敗と成功
ndadayo
2
760
Langfuseと歩む生成AI活用推進
licux
3
290
技術的負債で信頼性が限界だったWordPress運用をShifterで完全復活させた話
rvirus0817
1
2k
Google I/O recap web編 大分Web祭り2025
kponda
0
2.9k
新世界の理解
koriym
0
140
Claude Code と OpenAI o3 で メタデータ情報を作る
laket
0
140
Featured
See All Featured
The Cult of Friendly URLs
andyhume
79
6.5k
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.4k
A designer walks into a library…
pauljervisheath
207
24k
Music & Morning Musume
bryan
46
6.7k
jQuery: Nuts, Bolts and Bling
dougneiner
64
7.9k
Principles of Awesome APIs and How to Build Them.
keavy
126
17k
Automating Front-end Workflow
addyosmani
1370
200k
The Cost Of JavaScript in 2023
addyosmani
53
8.8k
Unsuck your backbone
ammeep
671
58k
Side Projects
sachag
455
43k
Visualization
eitanlees
146
16k
GitHub's CSS Performance
jonrohan
1031
460k
Transcript
NixOS/nixpkgsに SATySFiサポートを実装する Nix meetup #2 2025.03.09 浅田睦葉 @mutsuha_asada
🎓 所属 ・筑波大学情報学群情報科学類 B3 🐣 興味 ・コンパイラやそのツールチェーン、ビルドシステム ・2年くらいNixOSとNixを利用している (2022/12~) ・ちょっとOSS活動
・NixOS/nix: 1 PR merged ・NixOS/nixpkgs: 36 PRs merged, 197 PRs reviewed ・nixpkgs用のLinterを作りたいな〜と思っています ・興味がある方、ぜひお話ししましょう! 自己紹介 @momeemt @mutsuha_asada https://momee.mt 2
概要 ・組版処理システムであるSATySFiのパッケージビルドをnixpkgsでサポートしたい ・そのためのderivationを追加する作業をしているので今日はそれについて話す ・NixOS/nixpkgs #372555 ( 🚧 WIP 🚧) 📚
目次 nixpkgsにおけるSATySFiサポートの現状 1. NixによるSATySFiビルドの先行研究 2. satyrographosInstallHookの実装(パッケージビルドのサポート) 3. パッケージの依存解決の実装(パッケージを利用可能にする) 4. 今後の課題・展望 5. まとめ 6. 3
1. nixpkgsにおけるSATySFiサポートの現状 4
SATySFi ・gfngfn氏によって開発された静的型付き組版処理システム ・ 🐪 OCamlで実装されている ・LaTeXとは異なり可読性が高く、詳細なエラー報告が実現されている ・SATySFiパッケージの多くはOCamlのソースコードは含まれないが、 Opamパッケージとして配布されている ・公式のパッケージマネージャやビルドツールは存在しないが、 Satyrographosという有志により開発されたパッケージマネージャがある
→ ~/.opam/<ocaml-version>/share/satysfi/<package> にインストールされた SATySFiパッケージを、~/.satysfi/dist にコピーする 5
現状 ・ 🙆♀️ nixpkgs 24.11ではSATySFiとemacsのSATySFiプラグインが利用可能 ・ 😞 third-party製のパッケージ、LSPなどの周辺ツールはなく、実用的ではない ▲ 寂しい
6
動機 ・個人的な経験として、SATySFiは環境構築が複雑 → 1年生の頃、新歓パンフレットの組版に利用したが Dockerイメージを作って環境を配布した ・opam installでコケたり、依存関係でコケたり... ・mt-caret氏によりnixpkgsにSATySFiが追加されている → PythonやOCamlのようにパッケージやLSPも入れれば
気軽にSATySFiで文書を書ける! 7
2. NixによるSATySFiビルドの先行研究 8
・ ・2つのderivationを提供 ・文書をビルドするための`buildDocument` ・パッケージをビルドするための`buildPackage` 先行研究① (AumyF/satyxin) 9
先行研究① (AumyF/satyxin) 10
先行研究① (AumyF/satyxin) 11
先行研究① (AumyF/satyxin) ・パッケージをビルドするときに、setupHookにより環境変数SATYSFI_LIBPATHに 当該パッケージのパス($1/lib/satysfi)が追加される ・ドキュメントをビルドする際には、SATYSFI_LIBPATHをコンパイラに渡すことで コンパイラがパッケージを見つけられるようにする ・ 👏 良い点 ・パッケージ名とパス、ソースを渡すだけでパッケージングができる
・わかりやすく明快 ・ ☹️ 機能不足な点 ・フォントやハッシュファイルなど、lib/satysfi/dist/packages 以外に配置するべきファイル をコピーすることができない ・複数のファイルを含むパッケージに対応できない ・devShell環境ではコンパイラからパッケージが見えていない 12
先行研究② (SnO2WMaN/satyxin) ・AumyF/satyxinのフォーク ・既にパッケージング済みのパッケージを多数提供していて、簡単に始められる ・フォーク元で不足していたpackages以外のファイル/ディレクトリや複数ファイルを含む パッケージにも対応している 13
先行研究② (SnO2WMaN/satyxin) ・installPhaseで、packages以外の パッケージ要素(フォント、ハッシュなど)の 存在をチェックしてコピーすることで、 適切にファイルを配置できる◎ ・フォントハッシュのマージにも対応(後述) 14
先行研究② (SnO2WMaN/satyxin) ・フォーク元とは異なり、`buildSatysfiDist`を提供 ・これは依存パッケージをプロジェクトルートに生成するためのderivation ・SATySFiコンパイラはパッケージパスとしてプロジェクトルートを参照する → devShell環境でコンパイラがパッケージを見つけられる 15
先行研究② (SnO2WMaN/satyxin) ・satysfi-zrbaseのパッケージング ・依存パッケージがなく最もシンプル ・`build-package`を利用して、 コピー対象のファイルを明示的に`copyfrom`へ指定 16
先行研究② (SnO2WMaN/satyxin) ・ 👏 良い点 ・パッケージ名とパス、ソースを渡すだけでパッケージングができる ・フォントやハッシュファイルなども含めてビルドできるので、 全てのSatyrographosに対応したSATySFiパッケージをパッケージングできる ・複数のファイルを含むパッケージに対応◎ ・devShell環境でもコンパイラからパッケージが見える
・ ☹️ 機能不足な点 ・ハッシュファイルのマージスクリプトにバグがあり、ときおり壊れる ・Satyrographosのビルドファイル(Satyristes)に コピー対象のファイルが与えられている(library.source)が、明示的に記述する必要がある ・ローカルに.satysfiDistを生成する必要がある(nix-direnvが実質的には必要) 17
3. satyrographosInstallHookの実装 18
インストール工程の共通化 ・SATySFiパッケージをパッケージングする際に複雑なのはインストール工程 ・たとえば... ・satyファイルやフォントファイルなどのソースをコピーする ・フォントファイルが複数ある場合にはハッシュファイルをマージする ・実は(`buildSATySFiPackage`のような)ビルダーから提供する必要はない ・ビルドやパッチなど他の工程も複雑だったり、特殊な工程のAPIを提供したりしたい場合は ビルダーを実装する価値があるが、今回のケースはそうではない ・インストール工程のみをスクリプトとして括り出してフックとして提供すれば 🆗
→ 既存のフックの実装はどうなっているだろうか...? 19
pip-install-hook ・たとえば、Pythonのパッケージマネージャであるpipのインストールフックを眺めてみる ・スクリプトの処理 ・pipを利用して、distは以下のwheelを出力先に展開する ・環境変数`PYTHONPATH="$out/@pythonSitePackages@"`を設定することで、 `prefix=”$out”`のようにpipからライブラリが見えるように実行できる 20
pkgs.makeSetupHook ・ここで、`pkgs.makeSetupHook` によってフックを作成している ・フックとして定義されたderivationは、`stdenv`側で自動的に呼び出される ・したがって、`nativeBuildInputs`に追加しておくだけで`installPhase`を書き換えられ、 結果的にwheelを出力先に展開することができる 21
Satyrographos ・SATySFiのデファクトスタンダードなパッケージマネージャ ・Satyristesというビルドファイルを読んでビルドを代行する ・多くのSATySFiパッケージはSatyrographosを利用して開発されている → これを利用したインストールフックを実装すればビルド工程を共通化できる ・実際、Satyrographosはそのようなソフトウェアであり、 インストールフックの実装はエミュレートするスクリプトを実装することと同じ → では、Satyristesの仕様を見てみよう
💪 22
Satyristes https://github.com/na4zagin3/satyrographos/blob/master/README.md#satyristes-file-syntax 23
Satyristes ・library宣言の、特に sources が重要 ・ここに配置するべきソースとパスが記述されている ・例えば、mypackageという名前のパッケージにおいて (font “/dst” “/src”) は、/src
配下のファイルを dist/fonts/mypackage/ 以下に配置する ・name はパスを特定するために必要 ・version, opam, dependencies, compatibility は無視できる ・そもそもこのファイルはS式によって記述されている ・S式をパースできるライブラリを利用して該当の処理を行えば良さそう ・今回はsexpdataというライブラリを用いてPythonスクリプトを書く 24
satyrographosInstallHook ・実装したPythonスクリプトを用いて インストールフックを定義する ・このフックを利用することで、 nativeBuildInputs = [ satyrographosInstallHook ]; だけでインストール工程が行われる
25
satysfi-zrbaseのパッケージング 26 記述量が多く、 パッケージごとの差異もあってかなり大変 😕
フックを利用したsatysfi-zrbaseのパッケージング 27 処理が共通化されて すっきりまとまるようになった! 🌟
satyxinによるsatysfi-zrbaseのパッケージング (再掲) 28 satyxinと比べても、Satyristesを用いた インストールフックの恩恵は大きい
29 4. パッケージの依存解決の実装
/nix/store /nix/store/xxx-satysfi-0.0.11 bin シェル環境でコンパイラからパッケージが見えない ・各パッケージは /nix/store 以下に結果が作成されるので、 何らかの方法でパスを渡さなければコンパイラからパッケージが見えない 30 lib
share ~/.satysfi ~/doc/nix-meetup (プロジェクトルート) /nix/store/xxx-satysfi- zrbase-0.4.0 /nix/store/xxx-satysfi- fss-0.2.0 利用したいパッケージはここにいるのに... 👀
/nix/store /nix/store/xxx-satysfi-0.0.11 bin lib share ~/.satysfi ~/doc/nix-meetup (プロジェクトルート) /nix/store/xxx-satysfi- zrbase-0.4.0
/nix/store/xxx-satysfi- fss-0.2.0 $SATYSFI_LIBRARY シェル環境でコンパイラからパッケージが見えない ・AumyF/satyxinでは、セットアップフックで環境変数 SATYSFI_LIBRARY にパッケージの パスが追記されるようにした上で、ビルド時にコンパイラにパスを渡していた → この方法ではシェル環境ではいちいちコンパイラに引数を渡す必要があるし、 LSPなどのツールチェーンにも同様の手間が発生する 31 --config
シェル環境でコンパイラからパッケージが見えない ・SnO2WMaN/satyxinでは、プロジェクトルートにパッケージがコピーされるような derivationを提供していた → この方法だとコンパイラのデフォルトの探索先なので手間が必要ない◎ → 一方で、nix-direnvの利用が必須になる 32 /nix/store /nix/store/xxx-satysfi-0.0.11
bin lib share ~/.satysfi ~/doc/nix-meetup /nix/store/xxx-satysfi- zrbase-0.4.0 /nix/store/xxx-satysfi- fss-0.2.0 $SATYSFI_LIBRARY --config /nix/store/xxx-satysfi- zrbase-0.4.0 /nix/store/xxx-satysfi- fss-0.2.0 link link
シェル環境でコンパイラからパッケージが見えない ・できればどちらの問題も解決した上でシェル環境で扱えるようにしたい... 😖 ・つまり、コンパイラがデフォルトで探索するパスに環境に入った時点でパッケージを配置したい → SATySFiの $out/share/satysfi/dist にパッケージをコピーすれば良いのでは? 33 /nix/store
/nix/store/xxx-satysfi-0.0.11 bin lib share ~/.satysfi ~/doc/nix-meetup (プロジェクトルート) /nix/store/xxx-satysfi- zrbase-0.4.0 /nix/store/xxx-satysfi- fss-0.2.0 zrbase fss copy copy
SATySFiがパッケージセットを受け取るようにする ・SATySFiのderivationを見て、パッケージセットを受け取って配置するようにする → パッケージを使いたいときは、override してパッケージを渡す ・override は、derivationの引数を書き換えることができる機能 34 ▲ このような使い方を想定
依存パッケージの解決をする ・SATySFiのパッケージには依存関係がある ・たとえば、fssはbaseに依存しており、baseはfonts-dejavuとtestに依存している ・パッケージの依存は dependencies に記述する(規約)ことにして、 畳み込み関数を使って再帰的に依存するパッケージを集めてくる 35
集めたパッケージをshare/satysfi/distに配置 ・基本的には $out/share/satysfi/dist を再配置するだけ ・しかし、フォントのハッシュファイルを適切にマージする必要がある 36
フォントハッシュファイルのマージ ・フォントハッシュファイルは、フォント名に対してメタデータを引くためのファイル ・JSONではなく、Yojsonによって記述されている → https://mjambon.github.io/mjambon2016/yojson.html ・普通のJSONパーサではパースできない記法が含まれている... 😞 ・実はYojsonに対する複雑な操作が行われることはなく、2つのYojsonを結合するだけ → 同様にPythonで正規表現を使った結合スクリプトを書いてderivationを定義
・1ページ前のスクリプトにあるように、すでにハッシュファイルが存在している場合には 結合スクリプトを呼び出して適切にマージされるように実装した 37
パッケージセットをトップレベルに定義する ・定義したSATySFiのパッケージは、pkgs.satysfiPackages.xxx のように アクセスできると便利!☺️ → pkgs/top-level/satysfi-packages.nix にパッケージのエイリアスを張って、 pkgs/top-level/all-packages.nix で satysfiPackages
にまとめる 38 ▲ さっきのshell.nixが使えるように! ✊
次のリポジトリで試すことができます ・momeemt/nix-satysfi-sandbox ・興味があれば触ってみてください 🙌 39
40 5. 今後の課題・展望
・パッケージのドキュメント(libraryDoc属性)について全く実装していない ・最終的にはドキュメントを $out/share/doc に生成するようにしたい ・パッケージドキュメントはパッケージに依存するので工夫しないと循環する ・Yojsonを真面目にパースしていないので壊れる可能性がある(前例があるため) ・SatyristesをパースするPythonスクリプトをシェルスクリプトに埋め込んでいるため 保守性に不安がある ・SATySFi、Nixについて経験があるそこのあなた! 🫵
・レビューにご協力いただけるとありがたいです! ・指摘、ご意見などどんなことでも構いません ・NixOS/nixpkgs #372555 です! 現在わかっている課題点 41
展望 ・目下の目標はmasterにマージされてunstableで利用できるようにすること ・中期的には以下のようなツールもnixpkgsに入れたい ・SATySFiパッケージ(約80個ある) ・satysfi-language-server, satysfi-formatter ・SATySFi v0.1.0で新しく入るエコシステム(プロトタイプはSapheと呼ばれている)が 実用されるようになったらそちらのサポートも行う ・テストへの対応
・SATySFiは全然関係ないですが、nixpkgsを支えるインフラや自動化ツールについて もっと解像度を深めて有用なツールを作ることができればいいなと思っています 🪄 42
43 6. まとめ
まとめ ・現在取り組んでいる、NixOS/nixpkgsへのSATySFiビルドサポートについて紹介した ・現状(nixpkgs 24.11)ではSATySFi本体とemacsの拡張機能のみが存在している状態であり、 環境構築を容易にするためにはSATySFiパッケージや周辺ツールの拡充が必要 ・特にSATySFiパッケージのパッケージングをサポートするderivationをnixpkgsに導入したい ・過去の事例としては、セットアップフックと環境変数を組み合わせてパッケージビルド、 ドキュメントビルドを提供するAumyF/satyxinや、より高度なビルダーや パッケージセットを含むdistを生成する機能を提供するSnO2WMaN/satyxinなどがあった ・今回の発表では、Satyrographosのビルドファイルを用いてパッケージのインストール工程を
共通化するフックであるsatyrographosInstallHookの実装と、 SATySFiへのパッケージオーバーロードを拡張する方法について説明した ・シェル環境でコンパイラからパッケージが見えるようにするために、SATySFiの share/satysfi/distに依存パッケージを集めてきて、マージハッシュを行った上で格納した ・パッケージのドキュメントビルド、derivationが循環することの解消、YojsonやSatyristesの 仕様に適切に則った堅牢なスクリプトに修正していくことなどが今後の課題 44