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
68
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
20
主専攻実験(深層学習を用いたCG・画像処理)最終成果報告
momeemt
0
25
情報科学類新歓2023 履修の組み方
momeemt
0
110
情報科学特別演習 最終発表「動画編集ソフトウェアフレームワーク: mock up」
momeemt
0
29
Other Decks in Programming
See All in Programming
generative-ai-use-cases(GenU)の推しポイント ~2025年4月版~
hideg
1
370
fieldalignmentから見るGoの構造体
kuro_kurorrr
0
130
Enterprise Web App. Development (1): Build Tool Training Ver. 5
knakagawa
1
120
オープンソースコントリビュート入門
_katsuma
0
120
状態と共に暮らす:ステートフルへの挑戦
ypresto
3
1.1k
Cline with Amazon Bedrockで爆速開発体験ハンズオン/ 株式会社ブリューアス登壇資料
mhan
0
110
State of Namespace
tagomoris
5
2.4k
ウォンテッドリーの「ココロオドル」モバイル開発 / Wantedly's "kokoro odoru" mobile development
kubode
1
250
note の Elasticsearch 更新系を支える技術
tchov
9
3.4k
Memory API : Patterns, Performance et Cas d'Utilisation
josepaumard
1
160
Bedrock × Confluenceで簡単(?)社内RAG
iharuoru
1
110
Amazon CloudWatchの地味だけど強力な機能紹介!
itotsum
0
230
Featured
See All Featured
The Language of Interfaces
destraynor
157
25k
Docker and Python
trallard
44
3.4k
Producing Creativity
orderedlist
PRO
344
40k
Done Done
chrislema
184
16k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
357
30k
Keith and Marios Guide to Fast Websites
keithpitt
411
22k
GitHub's CSS Performance
jonrohan
1030
460k
Stop Working from a Prison Cell
hatefulcrawdad
268
20k
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.3k
The Straight Up "How To Draw Better" Workshop
denniskardys
233
140k
Thoughts on Productivity
jonyablonski
69
4.6k
Agile that works and the tools we love
rasmusluckow
329
21k
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