Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ocamlbuild does not give correct switches to ocamldep when running menhir #4572

vicuna opened this Issue Jun 30, 2008 · 1 comment


None yet
1 participant
Copy link

commented Jun 30, 2008

Original bug ID: 4572
Reporter: inalan
Assigned to: ertai
Status: closed (set by ertai on 2008-07-25T14:50:18Z)
Resolution: fixed
Priority: normal
Severity: block
Version: 3.10.1
Fixed in version: 3.11+dev
Category: ~DO NOT USE (was: OCaml general)
Monitored by: kanig inalan

Bug description

Generally, ocamlbuild finds dependencies for menhir .mly files by invoking menhir with the switch: --ocamldep '<ocamldep_options>'. The ocamldep options are however taken from the same list of options as are given to menhir itself during the dependency check. Thus, if menhir requires options that ocamldep does not support, an error is thrown.

Suppose, for example, I have written a parser using menhir and it uses an external token file. Thus, my files are:

To make this compile, I define a tags file:
"tokens.mly": only-tokens

Then, I define a file with:
let parserFlags =

let _ = dispatch begin function
| After_rules ->
flag ["ocaml"; "menhir_ocamldep"; "only-tokens"] (A "--only-tokens");
flag ["ocaml"; "parser"; "menhir"; "only-tokens"] (A "--only-tokens");

flag ["ocaml"; "menhir_ocamldep"; "parser.mly"] parserFlags
flag ["ocaml"; "parser"; "menhir"; "parser.mly"] parserFlags

(* plus some dep lines, not shown *)

When running a Make with this file, ocamlbuild ends up giving both menhir and ocamldep the --base and --external-tokens arguments, like so:

menhir --base Parser --external-tokens Tokens --raw-depends --ocamldep '--base Parser --external-tokens Tokens' etc.

Then ocamldep throws an error and we can't proceed any further. Actually, the switches are given three times in the same command; once to menhir, once to ocamldep, and then once to pp. The real issue here is that when figuring out the dependencies, menhir requires a different set of arguments than does ocamldep. There is no easy way to hack around this using tags.

Additional information

The only quick workaround I've found is to copy the menhir dependencies rule into along with its supporting functions, and then throw out the tags when passed to ocamldep. A full, working example (of just the file) is attached. Here is the short version:

let notags=Ocamlbuild_pack.Tags.of_list []

(* copied and modified from ocamlbuild sources: *)
let ocamldep_command' tags spec =
let tags' = tags++"ocaml"++"ocamldep" in
S [!Options.ocamldep; T tags'; Ocamlbuild_pack.Ocaml_utils.ocaml_ppflags (tags++"pp:dep");
spec; A "-modules"]

let menhir_ocamldep_command' tags ~menhir_spec ~ocamldep_spec out =
let menhir = if !Options.ocamlyacc = N then V"MENHIR" else !Options.ocamlyacc
in Cmd(S[menhir; T tags; A"--raw-depend";
(A"--ocamldep"; Quote (ocamldep_command' tags ocamldep_spec);)
A"--ocamldep"; Quote (ocamldep_command' notags ocamldep_spec);
menhir_spec ; Sh ">"; Px out])

let menhir_ocamldep_command arg out env _build =
let arg = env arg and out = env out in
let tags = tags_of_pathname arg++"ocaml"++"menhir_ocamldep" in
let ocamldep_spec = ignore (Ocamlbuild_pack.Tools.flags_of_pathname arg) in
menhir_ocamldep_command' tags ~menhir_spec:(P arg) ~ocamldep_spec out

| After_rules ->
rule "ocaml: menhir dependencies0"
~prod: "%.mly.depends"
~dep: "%.mly"
~insert: (`before "ocaml: menhir dependencies")
(menhir_ocamldep_command "%.mly" "%.mly.depends");

File attachments


This comment has been minimized.

Copy link
Collaborator Author

commented Jul 25, 2008

Comment author: ertai

Fixed in CVS trunk, thanks for the report.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.