LoginSignup
2
0

More than 1 year has passed since last update.

シングル Makefile で簡単 SATySFi サンドボックス環境を使おう!

Last updated at Posted at 2022-12-04

これは「SATySFi Advent Caleandar 2022」の4日目の記事です。
(3日目は zr_tex8r さん、5日目は yozu さんです。)

SATySFiの環境を整備するのは、ちょっと厄介です。例えば

  • インストールしないといけないものが多い。例えば、opam, ocaml, satysfi, satyrographos, 各種パッケージ, ...
  • インストール手順が煩雑。例えばopamリポジトリの設定、satyrographosの実行、...
  • 各ドキュメント毎にパッケージを管理したい(仮想環境)のに、通常のパッケージ管理ではユーザー全体のパッケージデータベースに影響を与えてしまう
  • satysfiやsatyrographos、各種パッケージのバージョンをドキュメント毎に変えるのが大変
  • SATySFiパッケージとOCamlのパッケージが混ざるので管理しづらい

このような点を解決するMakefileを作成しました。

$ wget https://gist.githubusercontent.com/yasuo-ozu/ef3134dbc80f657a9f476de4c80df113/raw/00f972c64113c7b94dbb6af14649e8398a230dab/Makefile

使い方

  1. まずシステムに opam をインストールします。
  2. ドキュメント用のディレクトリを作成し、そこに移動します。
  3. Makefileをダウンロードして配置します。
  4. make を実行します。 Satyristes ファイルが無い状態で実行するとサンプルの *.saty ファイルを作成しpdfを生成します。

例えば、 satysfi_doc という空ディレクトリの中で上の手順を行うと、以下のようなファイルが生成されます。

$ ls
.gitignore  Makefile  Satyristes  _build  _opam  satysfi-satysfi_doc.opam  satysfi_doc.pdf  satysfi_doc.saty  satysfi_doc.satysfi-aux

ファイルの説明

Satyristes

satyrographosが読み込むファイルで、*.satyファイルのコンパイルに必要なSATySFiパッケージをリストアップします。同じフォルダに複数の *.saty ファイルが存在する場合、 Satyristes にも対応する doc エントリが存在する必要があります。
このファイルが存在しない場合、 make 実行時にサンプルのファイル構成が生成されます。

サンプル

(lang 0.0.3)
(doc
  (name "satysfi_doc")
  (workingDirectory "./")
  (build (
    (make-with-env-var "satysfi_doc.pdf")
  ))
  (dependencies (dist))
  (autogen ($today))
)

satysfi-ドキュメント名.opam

opamが読み込むファイルで、ドキュメント名.saty で使われるパッケージとそのバージョンをリストアップします。 Satyristesファイルで指定されたパッケージはすべてこのファイルにも含まれる必要があります。
SATySFiのパッケージ管理では、パッケージをインストールするのはsatyrographosですが、ダウンロードやバージョンの解決のためにopamが使われるため、Satyrographos*.opam の両方が必要になっています。

サンプル

satysfi-satysfi_doc.opam
opam-version: "2.0"
depends: ["satysfi" { >= "0.0.5" & < "0.0.7" } "satysfi-dist" "satyrographos"]

ドキュメント名.saty

メインのファイルです。

サンプル

satysfi_doc.saty
@require: stdjabook
@require: $today
let-inline ctx \today = Today.datetime |> embed-string |> read-inline ctx
in
document (|
  title = {\SATySFi;};
  author = {};
  show-title = true;
  show-toc = false;
|) '<
	+p { Today is \today; }
>

ドキュメント名.d

Makeが読み込むファイルで、ドキュメント名.saty内に画像ファイルが使われていた場合、make 実行時にそのパスがドキュメント名.dファイル内にリストアップされます。
そのため、実際にその画像が存在しない場合でも、*.pdf を生成する前に make 画像ファイル名 が実行されるため、予め Makefile 内に適切なルールを書いておくことで*.satyファイル内で使用している画像を別のソフトウェアで生成することができます。(make cleanで削除される)

_build

satyrographosが作成する仮想環境用のディレクトリです。(make cleanで削除される)

_opam

satysfi, satyrographos 等のバイナリや satysfi-dist 等のパッケージのファイルがインストールされる仮想環境です。(make cleanで削除される)

*.satysfi-aux

SATySFi が生成する一時ファイルです。(make clean で削除される)

解説

仮想環境について

このMakefileでは、ユーザーの環境に対して影響を与えないため、ドキュメントのディレクトリに閉じた仮想環境を作成します。
ここでいう仮想環境には、以下の2つが存在します。

  • opamの仮想環境 ... opam switchコマンドによって_opam以下に作成される。
  • satyrographosの仮想環境 ... satyrographos buildコマンドによって _build 以下に作成される。

パッケージをインストールするのになぜ2つも仮想環境が必要になるのが疑問に思うでしょうが、それはSATySFiのパッケージをインストールする際に以下のような2段階の処理が行われるからです。

  • opam install パッケージ名 コマンドでSATySFiのパッケージ(に satysfi- というプレフィクスをつけたもの)を satyrographos-repo というopamリポジトリからダウンロードしてインストールする。インストールされたファイルはopamレポジトリ(仮想環境の場合は_opam)で管理される。
  • satyrographos installコマンドを実行すると opam リポジトリを探索してsatysfiパッケージを探し出し、必要なファイルを dist ディレクトリにインストールする。
  • satysfi コマンドはコンパイル中 @require: を処理する際、 dist ディレクトリを参照する

そのため本Makefile では opam switch 及び satyrographos build を活用することで2つの仮想環境を管理しています。

make build コマンドの動作

make (もしくは make build) を実行すると以下の処理が行われます。

  • 存在しない場合、opamの仮想環境 _opam を作成する。
  • Satyristesが存在しない場合、サンプルファイルを生成する。
  • 仮想環境_opam内に satysfi, satyrographosをインストールする。(この際、*.opam内に書かれたバージョン制約を反映)
  • satyrographos buildコマンドを用いて、Satyristes内に記述されたドキュメントを全てコンパイルする

satyrographos buildコマンドが参照するSatyristesは例えば次のようになっています。

(lang 0.0.3)
(doc
  (name "satysfi_doc")
  (workingDirectory "./")
  (build (
    (make-with-env-var "satysfi_doc.pdf")
  ))
  (dependencies (dist))
  (autogen ($today))
)

ここでは make-with-env-var が使われており、これはsatysfi_doc.pdf生成時にmakeコマンドを使用することを意味します。この場合 satyrographos buildコマンドは以下のことをします。

  • ドキュメント毎に仮想環境を作る。(_build)
  • Satyristes内に指示された依存パッケージを_opamから探し出し、仮想環境にインストールする。
  • make satysfi_doc.pdf を実行する。

ここでmake satysfi_doc.pdf が実行された時に呼ばれる部分は以下のようになっています。

%.pdf:	%.saty $(SATYSFI_BIN) Makefile
	@if [ -n "$$SATYSFI_RUNTIME" ]; then \
		eval $$(opam env) && satysfi -C "$$SATYSFI_RUNTIME" --no-default-config "$<" -o "$@" ; \
	fi

$SATYSFI_RUNTIME には satyrographos build が作成した仮想環境のディレクトリが与えられます。これを -Cオプションを界してsatysfiに与えています。
ここでpdfを作成するためにわざわざMakefileを呼び出している理由なのですが、それは*.satyが依存しているファイルをMakefile内で同時に生成することを想定しているからです。例えば、satysfi_doc.satyファイルの中でexample.pdfファイルを使用している場合、最初のmake build実行時に以下のファイルが自動的に生成されます。

satysfi_doc.d
satysfi_doc.pdf:    example.pdf

このファイルはsatysfi_doc.pdfを生成するためにはexample.pdfが必要であるという事実を述べており、make satysfi_doc.pdfを実行したときに読み込まれます。
example.pdf が存在しない場合、自動的にmake example.pdfが実行され、Makefile が画像ファイルを生成しようとします。

例えば、example.svgから自動的にexample.pdfを生成したい時は、Makefileに以下の内容を追記(もしくはinclude.amというファイルを作成)すればよいです。
(なお、この場合example.pdfmake cleanで自動的に削除されないので注意してください。このような中間ファイルは一時ディレクトリを作成し、その中に生成させるのがおすすめです。)

%.jpg:   %.svg
    inkscape "--export-filename=$@" "$<"
2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0