2

I am looking to add the ability to compile Ragel source files into Ocaml source files in the context of the LLVM Ocaml tutorial. Specifically, for source files with a ".rl" extension I would want it to execute:

ragel -O source.rl

The build system should of course then compile the resulting Ocaml file(s) as usual. What is a straightforward way to do this?

Here is the _tags file:

<{lexer,parser}.ml>: use_camlp4, pp(camlp4of)
<*.{byte,native}>: g++, use_llvm, use_llvm_analysis
<*.{byte,native}>: use_llvm_executionengine, use_llvm_target
<*.{byte,native}>: use_llvm_scalar_opts, use_bindings

And here is the myocamlbuild.ml file:

open Ocamlbuild_plugin;;

ocaml_lib ~extern:true "llvm";;
ocaml_lib ~extern:true "llvm_analysis";;
ocaml_lib ~extern:true "llvm_executionengine";;
ocaml_lib ~extern:true "llvm_target";;
ocaml_lib ~extern:true "llvm_scalar_opts";;

flag ["link"; "ocaml"; "g++"] (S[A"-cc"; A"g++ -rdynamic"]);;
dep ["link"; "ocaml"; "use_bindings"] ["bindings.o"];;
brooks94
  • 3,836
  • 4
  • 30
  • 57

2 Answers2

2

It's hard to determine without the entire source directory to fiddle with, but you'll have to create a rule to call the ragel compiler. the dep tells ocamlbuild to copy those files to the _build directory --the tags for this may be different depending on your needs. Something like,

let ragel_files = ["file1.rl"; ... ]

let () = dispatch begin function
  | After_rules ->
    rule "Build RL files with Ragel"
        ~prod:"%.ml"
        ~dep:"%.rl"
        begin fun env _build ->
            let rl = env "%.rl" in
            Cmd(S[A"ragel"; A"-0"; A rl;])
        end;
    dep ["compile"; "ocaml"] ragel_files;
end

Check out the ocamlbuild source for the rules on OCaml files. That should be a very good start.

nlucaroni
  • 47,556
  • 6
  • 64
  • 86
  • And this would go in the bottom of myocamlbuild.ml, correct? is there anything else i would need to do? it seems to be ignoring it altogether. all my source files are in the same top-level dir. – brooks94 Jan 14 '14 at 21:08
  • It goes in the function passed to `dispatch` when `After_rules` is called. – nlucaroni Jan 14 '14 at 21:15
  • Not necessarily. If the prod and dep arguments satisfy the dependency then you shouldn't. if you're having trouble, could you be more specific? (the commands you'd like run and what they produce). – nlucaroni Jan 15 '14 at 19:57
  • Oh, to "move" files into the '_build' directory you need a dep of all the files, yes. – nlucaroni Jan 15 '14 at 19:59
0

I would suggest distinguishing .rl files by host language i.e. .ml.rl for OCaml code, .c.rl for C code, etc.

rule ("ragel: .ml.rl -> .ml") ~dep:"%.ml.rl" ~prod:"%.ml" begin fun env _ ->
  let dep = env "%.ml.rl" and prod = env "%.ml" in
  Cmd (S[ P"ragel";
    T(tags_of_pathname prod ++ "ragel");
    A "-O";
    A "-F1";
    A dep;
    A"-o"; A prod;
  ])
end;;

The rule can be defined at toplevel before dispatch is called.

Also you will most probably want to switch off warnings 32 and 38 for ragel generated code. In _tags:

"generated.ml": warn(-32-38)
ygrek
  • 6,656
  • 22
  • 29