I am using the --compile-errors
functionality of menhir
and I'm quite happy with it. I'm also using ocamlbuild
to manage the compilation of my project. Since the project is quite basic, the build infrastructure has remained trivial so far.
I have a single _tags
file and a simple Makefile
at the root of the project. I don't have a myocamlbuild.ml
file yet. The _tags
file contains just one line:
<src/*>: package(ppx_deriving.std)
The relevant part of the Makefile is
all: src/ParsingErrors.ml
ocamlbuild $(OPTIONS) src/Main.native
src/ParsingErrors.ml: src/Handcrafted.messages src/Parser.mly
menhir --compile-errors src/Handcrafted.messages src/Parser.mly > src/ParsingErrors.ml
OPTIONS = -j 4 -use-menhir -use-ocamlfind -yaccflag --table -pkgs menhirLib,str,unix
OCamlbuild and Menhir are usually well integrated, but --compile-errors
seems to be a fairly new functionality. My setup is not ideal because I dislike having an automatically generated file, src/ParsingErrors.ml
, in my source directory instead of the build directory. What would be the best way to explain to OCamlbuild that I want Menhir to build this error messages file? Changing the naming convention of my files (into src/Parser.messages
and src/Parser.ml
, for example) does not bother me if it simplifies things.
NB: although I have myocamlbuild.ml
files in other projects, I copied them from online sources. I find them hard to decipher and I don't really understand how to write these things.
The best place to look for an answer to this question is in Menhir's distribution, since Menhir uses "menhir --compile-errors" and ocamlbuild in its own compilation process.
The file to look for is src/myocamlbuild.ml
in the source tarball .
Here is a relevant excerpt:
(* This rule generates an .ml file [target] from an .mly file [grammar] and a
.messages file [messages]. *)
(* If the name of a witness file is passed, it is made an additional
dependency. This triggers a separate rule (see below) which performs a
completeness check, that is, which checks that the .messages file lists
every possible syntax error. *)
let compile_errors grammar messages (witness : string list) target =
rule
"menhir/compile_errors"
~prod:target
~deps:([ grammar; messages ] @ witness)
(fun env _ ->
let grammar = env grammar in
let tags = tags_of_pathname grammar ++ "ocaml" ++ "menhir" in
Cmd(S[
!Options.ocamlyacc; (* menhir *)
T tags;
P grammar;
A "--compile-errors"; P (env messages);
Sh ">"; Px (env target);
]))
(* A generic version of the above rule, with uniform naming. *)
let generic_compile_errors (check_completeness : bool) =
compile_errors
(* sources: *)
"%.mly" "%Messages.messages"
(* if present, this dependency forces a completeness check: *)
(if check_completeness then [ "%Messages.witness" ] else [])
(* target: *)
"%Messages.ml"
I would be happy to discuss with the ocamlbuild maintainers whether some parts of Menhir's myocamlbuild.ml could be moved into ocamlbuild's standard set of rules. (Hi Gabriel!)
The feature is indeed not supported in current ocamlbuild versions. To add it in your myocamlbuild.ml
plugin, you would have to define a new build rule. If you are scared by what is inside myocamlbuild.ml
, you may be interested in the new ocamlbuild manual , in particular its section on plugins .
I just opened an issue report #121 on the ocamlbuild repository to track this missing feature. Are you interested in learning enough about ocamlbuild to write a proper rule for this and contribute it to the next ocamlbuild version? If yes, feel free to the github issue and start asking questions about how to implement it, I would be glad to help. If not, I'll try to implement it myself when I have some time.
In the meantime, note that it's much easier to define a one-shot rule for specific files than a generic rule. If you are ready to hardcode the sourcefiles you use, you could have something that would look very similar to the Makefile rule. I don't have the time today to write and check this rule, but I'll try to come back tomorrow if someone else hasn't done it in between.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.