ドキュメントをソースの一部として書く意義
みなさん開発する時一つのディレクトリにソースをまとめますよね?そこに説明書もまとめちゃってください!以下の利点があります。
- ソースコードのすぐそばにドキュメントの原稿があるのでドキュメントをすぐみてすぐ直すことが簡単になります
- ライブラリ等でディレクトリごとコピペすればそのライブラリの説明書も一緒に取り込むことができるようになります
TypstとCMakeの強さ
Wordやメモ帳でやるとWordは他のファイルを参照することがめんどかったりフォントの指定を一括でできない(変更してほしくない箇所がある)ことなどがありますよね?
TypstとCMakeはコマンドラインツールであるとともにコンパイラ型ツールキットなのでこの組み合わせでは以下のような利点があります。
- このページだけフォントを変更みたいなことがプログラミング言語のような記法でできます(Typst)
- プログラミング言語のfor文のような記法で繰り返し表記を行うことができます(Typst)
- ドキュメントが大量にできても入れ子構造で整理できます(Typst)
- pdf形式で出力できます(Typst)
- ドキュメントをビルドしないことでビルド時間を選択的に短縮できます(CMake)
- 実行ファイルのビルド設定とドキュメントのビルド設定を一緒のファイルにまとめられます(UseTYPST.cmake)
実際の使い方
ここではUseTYPST.cmakeというCMakeサブモジュールを使ってCMakeを活用したドキュメント生成を試しにやってみましょう!
サンプルプロジェクトのソースコードはここにあります。
ここではCMakeなのでC++を使ってみますがSwiftやRust、あるいはTypescript&Node.jsでもCMakeを使いこなせばどうにかなるんじゃないですかね(適当)
サンプルプロジェクトは大体こんな感じのソースツリーになっています。
CMakeユーザーの方にはお馴染みなのではないでしょうか。
で、CMakeLists.txtはこんな感じになっています。
project(sample_project CXX)
set(USETYPST_DEFAULT_ALL_TARGET ON)
include(UseTYPST.cmake)
add_executable(sample_executable main.cpp)
add_typst_document(sample_document doc.typ)
add_executableのノリ(出力ファイル名にスペースを開けてソースファイルを入れる)でドキュメント生成をかけられることがお分かりかと思います。(add_documentとしても良かったのですがMarkdownやUseLaTeX.cmake等とかちあいそうなので辞めました。)
Typstでソースが綺麗なドキュメントを作れる時代が来たぞ!
Typstがついにドキュメントの依存関係をmakeのような形式で出力する--make-deps機能をサポートしました!これによってCMakeやMakeのビルドツールを組み合わせてドキュメントのrootとなる.typファイルを指定するだけで自動的に依存するファイルを列挙およびドキュメントの再生成を自動化することができるようになりました!Unix Makefilesでは--make-depsで出力されるファイルをインクルードするだけで依存関係を考慮した再ビルドが可能になるみたいです(Make使ってないので確実なことを言えなくてごめんなさい)
CMakeでも活用したい!
CMakeで使えるようになればNinjaビルドシステムでも--make-depsを活用できるようになり、高速なビルドやドキュメントビルドの無効化が容易になります(最重要)
ここでは、--make-depsの仕様を確認し、CMakeにおいてどのように処理すればいいかを少し深掘りします。
--make-depsの出力を確認
私の環境の場合、--make-depsでsample_docの依存関係を出力した場合、次のようになります。(macOSを使ってます)
/Users/User/GitHub/UseTYPST.cmake/build/SampleProject/sample_document.pdf: ../../SampleProject/doc.typ
これはmakeの依存関係ファイルと同じフォーマットらしいです。なのでこれをそのままmakeやninjaに渡せればいいということになります。
CMakeで渡す方法
add_custom_commandを使って依存関係を構築します。add_custom_commandのDEPFILE機能(下で解説)によって依存関係を登録します。
add_custom_command(
OUTPUT ${DOC_NAME}.pdf
COMMAND typst compile ${CMAKE_CURRENT_SOURCE_DIR}/${ROOT_TYP_DOCUMENT} ${CMAKE_CURRENT_BINARY_DIR}/${DOC_NAME}.pdf --make-deps ${CMAKE_CURRENT_BINARY_DIR}/${DOC_NAME}.d
DEPFILE ${CMAKE_CURRENT_BINARY_DIR}/${DOC_NAME}.d)
余談ですがadd_custom_commandのOUTPUTをadd_custom_targetのSOURCESで渡せばadd_executableみたいにできます。詳しくはこの記事を見ればある程度はわかるかもしれません...
DEPFILEって何
add_custom_commandのDEPFILE機能はまさにmakeやninjaに依存関係ファイルを渡してくれるものです。ただ、DEPFILEは複数のジェネレーターに対応するため少し高機能です。
超ざっくり言うと、依存関係ファイルが変更されていないか確かめるcmakeコマンドを裏で実行し、変更があればmakeやninjaにリビルドを要請するための記述をMakefileやbuild.ninjaに書いてくれます。だからDEPFILEに渡すだけであとはCMakeがいい感じに処理してくれます。(正直拍子抜けでした...)
まとめ
Typstが--make-depsに対応したことで、大規模なプロジェクトツリーでもCMake等と併用して必要最低限なビルドを行うことが可能になりました。
CMakeその他ビルドエコシステムの機能をフル活用することができるのでビルドツールの作成コストが圧倒的に低くなりました(個人的にはかなり拍子抜け...ジェネレータ式に格闘したあの頃が懐かしい...)
みんなもTypstを使った整理されたドキュメント作成ライフをお楽しみください!