TaPLの公式実装をduneでビルドする時にハマったこと
非常に限定された一部界隈では非常に有名なことで有名なTypes and Programming Languagesの公式サイトから、本に出てくる型システムの実装がダウンロードできる:
以前も気になった部分を落として実装を覗いてみたりはしたのだが、コンパイルして走らせてみたりはしなかった。
最近個人的な型システム熱が強まってきたので、自分でも実装してみようと思ってまずは公式実装をコンパイルして使ってみることにした。
公式はocamlcを使ったMakefileを提供しているが、私は自分のコードはいつもduneでコンパイルしているのでとりあえずそっちを使ってみることにした。
見たところocamllex/menhir以外では依存するライブラリもないようだし・・・というわけでこんなduneファイルを用意:
(menhir (modules parser)) (ocamllex lexer) (executable (name main))
dune build ./main.exe
とやってみたところ、コンパイルエラー。
「昔のコードだろうからね、最近のocamlcでコンパイルできなくても仕方ないね」と思いつつmakeを走らせてみると普通にコンパイルできてしまった。
Makefileの中身を覗いてみるとOCaml 4.02以降はコンパイラフラグとして-unsafe-string
を渡しているようだ。これで「StringじゃなくてByteだよ」といったエラーは消えるのだが、それでもduneのほうは大量にエラーが出る。主に使われていない変数、openされたモジュール、非再帰的なlet rec
関数定義などについてのようだ。
Makefileではこれらに対して特にフラグを渡しているようでもないのだが、仕方なく手動で黙らせていく:
(menhir (modules parser)) (ocamllex lexer) (env (dev (flags (:standard -w -3 -w -27 -w -32 -w -33 -w -34 -w -39 -unsafe-string)))) (executable (name main))
ちなみにこれは-w -3-27-32-33-34-39
のように書けるようだ。
ちなみにOCaml 4.12.0から -w -unused-var-strict みたいに名前でwarningを指定できるようになったぞい(ただし -w-27-32-33 みたいな一括指定は数字でないとできないhttps://t.co/CLcJByY0UI
— でこれき (@dico_leque) March 2, 2021
しかし
ただ、makeだとocamlcに-unsafe-string以外のフラグは渡していないようなんだよな・・・
— zehnpaard (@zehnpaard) March 2, 2021
と不思議に思っていたところ:
たぶんduneが裏で -w @A を渡していてwarningをエラーにしているからではないかとhttps://t.co/ecaCIrheJb
— でこれき (@dico_leque) March 2, 2021
と教えていただいた。
dune makes all warnings fatal by default. This can be a challenge when porting a codebase to dune.
というところだ。
dune build --profile release ./main.exe
とするとwarningでコンパイルが止まらないらしいが、実際にはdev目的のビルドなのにreleaseフラグを使うのもなんだし、ということで
(menhir (modules parser)) (ocamllex lexer) (env (dev (flags (:standard -unsafe-string -warn-error -A)))) (executable (name main))
こういうduneファイルでwarningがエラーにならないように設定する。
これで(山のようにwarningは出るが)ちゃんとコンパイルできる。
arith$ ./_build/default/main.exe test.f true false 0 1 false
実行もちゃんとできた。めでたしめでたし。@dico_lequeさんありがとうございます!