Linux カーネルでの Sphinx 利用法を見てみよう
年末カウントダウン Sphinx 連載、第3弾です。
一切下準備をせずに連載を始めたので、早くも息切れをしています。
だれかと約束をしたわけでもないのに急にアドベントカレンダー的なものを始めるのは、なんだか死に急いでいる気がしてきました。
今回は、今年から Sphinx の利用者に加わったある大型プロジェクトについて紹介しましょう。
そのプロジェクトとは、世界最大級の OSS のひとつである Linux カーネルです。
現在の Linux カーネルドキュメント
今年開催された LinuxCon Japan 2016 で Linux カーネルのドキュメントに Sphinx を使うという発表がありました。
Linus Torvalds氏が登壇、「約10週間のリリースサイクルは続く」 - クラウド Watch
それから約 5ヶ月。現在はどうなっているのか見てみましょう。
Linux カーネルのドキュメントは https://www.kernel.org/doc/ で公開されています。
最初に目に入るのは (new sphinx format) という記述が目に入ります。
そして docbook format の方には (deprecated) の文字が。
というわけで、いまでは Linux カーネルのメインのドキュメントには Sphinx が使われています。
リンクをたどると見慣れた readthedocs テーマで生成されたドキュメントが現れます。
カーネルドキュメントに Sphinx が採用された経緯
LinuxCon 2016 のプレゼンを聞いていた @senopen 氏は当時こんな風にツイートしています。
(当時、仕事中にこれが流れてきてかなりびっくりした覚えがあります)
#linuxcon カーネルのドキュメント。
— せのぺん (@senopen) July 14, 2016
・txtファイル:2000+
・DocBook:カーネルの心臓の記述
・Doxygen形式と似たのKerneldocコメント:55000個。
カーネル開発者がシステムを作った。
make htmldocs
#linuxcon 問題点が。
— せのぺん (@senopen) July 14, 2016
・遅い
・brittle
・設定とmakeが難しい
・他のDocumentation/ディレクトリと統合がない。
最近変えた。
markdonwを導入。その後AsciiDocに切り替えた。
#linuxcon
— せのぺん (@senopen) July 14, 2016
AscIiDoc
利点
・汚いDocBookを回避
・よりよい文書
欠点
・パフォーマンス
・文書館のリンク
・Ruby依存
#linuxcon
— せのぺん (@senopen) July 14, 2016
何がやりたいか。DocBookはやめたい。
簡単なマークアップを使いたい(Markdonw,AsciiDoc,Sphinx)。
フォーマットされていない文書にもそのまま使いたい
東道された文書ツリーを作りたい。
#linuxcon それでSphinxに目をつけた。
— せのぺん (@senopen) July 14, 2016
・コードの文書化に特化
・世界的な利用
・DocBookやLaTeXに頼らない。
で,Sphixを使うことで合意が取れた。
kerneldocコメントはいつも動作して,RST指示文を追加できる。
DocBook から移行をするのは理解できるものの、なぜ asciidoc ではダメだったのか、
Ruby 依存とはどういうことかと疑問に思っていたのですが、
その答えは LWN.net への投稿 で説明されていました。
asciidoc と Sphinx のどちらを採用するかの判断理由として、次のように説明されています。
But it seemed that neither tool would work as-is, or at least we wouldn't be able to get their full potential without extending the tools ourselves. In the kernel tree, there are no tools written in Ruby, but there are plenty of tools written in Python. It was fairly easy to lean towards Sphinx in this regard.
超訳:
Grant Likely summed it up this way: "Honestly, in the end I think we could make either tool do what is needed of it. However, my impression after trying to do a document that needs to have nice publishable output with both tools is that Sphinx is easier to work with, simpler to extend, better supported.”
超訳:
- どちらのツールでも要求は満たせた
- 両方試した結果、Sphinx の方が使いやすく、簡単に拡張できて、サポートがよかった
どうやら、既にカーネルの構成管理ツールとして Python が使われていたので、どちらかといえば Python を使ったほうが楽だろうという判断のようですね。また、Sphinx の方を気に入ってくれたようです。
(サポートが良かった、というのはどういうことなんでしょうかね。特に何かをした覚えはないのですが)
ちなみに Part.2 では移行や、あたらしいドキュメントの書き方について説明しています。
個人的にツボった所だけ抜粋しておきます。
grepping and reading reStructuredText is much easier than the angle-bracketed mess that is DocBook.
reST を grep したり読んだりするのは、DocBook のタグよりはるかにかんたんです。
It's a nice vision, I hear angels singing when I think about it and so on, it's where I want to go.
(数年後、包括的で読みやすいドキュメントができることについて)
そう考えると天使の歌声が聞こえます。
カーネルドキュメントはどのような設定になっているのか
カーネルドキュメントの設定は ここ から参照できます。
読み進めていくと、極めて一般的な、Sphinx の基本設定だけで構築されていることがわかります。
primary_domain が C になっているのは、やはり Linux カーネルですね。
primary_domain = 'C' highlight_language = 'none'
LaTeX のプリアンブル部には、いくつかの設定が指定されています。
- 色やスタイルなどの指定
- landscape 出力の準備
- XeLaTeX 用のフォント設定
また、巨大なドキュメントであるため、PDF もいくつかに分冊して出力するようになっています。
このあたりは Python のドキュメントでも培われた、ドキュメントを小分けにするテクニックをうまく使っているようですね。
latex_documents = [ ('doc-guide/index', 'kernel-doc-guide.tex', 'Linux Kernel Documentation Guide', 'The kernel development community', 'manual'), ('admin-guide/index', 'linux-user.tex', 'Linux Kernel User Documentation', 'The kernel development community', 'manual'), ('core-api/index', 'core-api.tex', 'The kernel core API manual', 'The kernel development community', 'manual'), ('driver-api/index', 'driver-api.tex', 'The kernel driver API manual', 'The kernel development community', 'manual'), ('kernel-documentation', 'kernel-documentation.tex', 'The Linux Kernel Documentation', 'The kernel development community', 'manual'), ('process/index', 'development-process.tex', 'Linux Kernel Development Documentation', 'The kernel development community', 'manual'), ('gpu/index', 'gpu.tex', 'Linux GPU Driver Developer\'s Guide', 'The kernel development community', 'manual'), ('media/index', 'media.tex', 'Linux Media Subsystem Documentation', 'The kernel development community', 'manual'), ('security/index', 'security.tex', 'The kernel security subsystem manual', 'The kernel development community', 'manual'), ]
また、カーネル特有の設定として、いくつかの拡張を利用するようになっています。
extensions = ['kerneldoc', 'rstFlatTable', 'kernel_include', 'cdomain']
ここで指定されている kerneldoc, rstFlatTable, kernel_include, cdomain という4つの拡張はドキュメントと一緒にコミットされている
カーネル専用の Sphinx 拡張です。
それぞれどういう効果のある拡張なのか、ひとつずつ見ていってみます。
カーネルドキュメント専用の拡張
kerneldoc
外部スクリプトである kernel-doc コマンドを呼び出して、カーネルのソースコードからコメントを抽出するディレクティブ kernel-doc を提供します。
抽出したコメントは reST として解釈され、ドキュメントに埋め込まれるようです。
rstFlatTable
list-table のようなリストベースの記法で、なおかつセル結合に対応したテーブル系ディレクティブです。
このページ のサンプルでわかるように :rspan: と :cspan: というふたつのロールを使ってセル結合を行います。
また、セルが足りない場合は自動的に補ってくれる autospan 機能もついています。
やや ad-hoc なマークアップではあるものの、複雑な表を作りたい場合は便利そうです。
kernel_include
環境変数などを含んだパスに対応した include ディレクティブである、kernel-include ディレクティブを提供しています。
おまけ
Linus が reStructuredText を書いているのか気になって調べてみたら、
過去半年で彼が Documentation/ ディレクトリ以下にコミットしたの、これだけだった。
https://github.com/torvalds/linux/commit/852d21ae1fcdf0e4de6b5bfa730d29cb013c7ff3
(その他はすべてマージコミット)
.rst ファイルに symlink を貼ったのも、Sphinx を使ったの一部、ですよね? (弱気)