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
190
❄️ NixOS/nixpkgsにSATySFiサポートを実装する
Nix meetup #2
Mutsuha Asada
March 09, 2025
Tweet
Share
More Decks by Mutsuha Asada
See All by Mutsuha Asada
Wasmで拡張できる軽量マークアップ言語 Brack
momeemt
0
65
Intel系FPGA上へのRISC-Vプロセッサの実装
momeemt
0
130
情報科学若手の会 2024 LT「WebAssemblyで拡張可能な軽量マークアップ言語の開発」
momeemt
0
35
Nixでつくるdotfiles
momeemt
1
28
情報特別演習I 最終発表「理工学の紙書籍を用いた学習の効率を向上させるインタフェース」
momeemt
0
27
SATySFi Conf 2023「SATySFiを使って学類新歓冊子を発行した」
momeemt
0
19
主専攻実験(深層学習を用いたCG・画像処理)最終成果報告
momeemt
0
24
情報科学類新歓2023 履修の組み方
momeemt
0
110
情報科学特別演習 最終発表「動画編集ソフトウェアフレームワーク: mock up」
momeemt
0
28
Other Decks in Programming
See All in Programming
PHPバージョンアップから始めるOSSコントリビュート / how2oss-contribute
dmnlk
1
1.1k
七輪ライブラリー: Claude AI で作る Next.js アプリ
suneo3476
1
120
Dissecting and Reconstructing Ruby Syntactic Structures
ydah
2
1.2k
Golangci-lint v2爆誕: 君たちはどうすべきか
logica0419
1
160
Qiita Bash
mercury_dev0517
2
210
Building a macOS screen saver with Kotlin (Android Makers 2025)
zsmb
1
160
メモリウォールを超えて:キャッシュメモリ技術の進歩
kawayu
0
1.9k
Optimizing JRuby 10
headius
0
490
SwiftUI API Design Lessons
niw
1
300
エンジニア向けCursor勉強会 @ SmartHR
yukisnow1823
2
3.4k
RubyKaigi Dev Meeting 2025
tenderlove
1
390
On-the-fly Suggestions of Rewriting Method Deprecations
ohbarye
1
3.4k
Featured
See All Featured
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
31
1.1k
4 Signs Your Business is Dying
shpigford
183
22k
Agile that works and the tools we love
rasmusluckow
328
21k
Navigating Team Friction
lara
185
15k
Building Adaptive Systems
keathley
41
2.5k
Optimizing for Happiness
mojombo
377
70k
What’s in a name? Adding method to the madness
productmarketing
PRO
22
3.4k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
47
5.3k
Building a Scalable Design System with Sketch
lauravandoore
462
33k
Git: the NoSQL Database
bkeepers
PRO
430
65k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
29
9.4k
Build The Right Thing And Hit Your Dates
maggiecrowley
35
2.6k
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