Date Tags ocaml

Recently I tried to answer to a problem posed on the OCaml mailing list. Basically the problem is how to compile using ocamlbuild using ocamlfind and camlp4. The Camlp4 wiki has already all the ingredients. Here I mix them up in a short example.

_tags : is the ocamlbuild dep file

bar.ml : is a ml file that uses the syntax extension pa_float to

compile.

foo.ml : is a ml file that depends on bar.ml and the str module

(fetched via ocamlfind)

pa_float.ml : is the source code of the camlp4 syntax extension.

The code

_tags

"pa_float.ml": use_camlp4, pp(camlp4of)
"bar.ml": camlp4o, use_float

bar.ml

let x = Float.( 3/2 - sqrt (1/3) )
let f x =
  Float.(
    let pi = acos(-1) in
    x/(2*pi) - x**(2/3)
  )

foo.ml

open Str
let x = Bar.x

myocamlbuild.ml

open Ocamlbuild_plugin;;
open Command;;

let packages = "str";;

let ocamlfind x = S[A"ocamlfind"; x; A"-package"; A packages];;

dispatch begin function
| Before_options ->
    Options.ocamlc := ocamlfind& A"ocamlc";
    Options.ocamlopt := ocamlfind& A"ocamlopt";

| After_rules ->
    flag ["ocaml"; "pp"; "use_float"] (A"pa_float.cmo");
    flag ["ocaml"; "link"] (A"-linkpkg");
    dep  ["ocaml"; "ocamldep"; "use_float"] ["pa_float.cmo"];
| _ -> ()
end;;

pa_float.ml

module Id = struct
  let name = "pa_float"
  let version = "1.0"
end

open Camlp4

module Make (Syntax : Sig.Camlp4Syntax) = struct
  open Sig
  include Syntax

  class float_subst _loc = object
    inherit Ast.map as super
    method _Loc_t _ = _loc
    method expr =
      function
      | <:expr< ( + ) >> -> <:expr< ( +. ) >>
      | <:expr< ( - ) >> -> <:expr< ( -. ) >>
      | <:expr< ( * ) >> -> <:expr< ( *. ) >>
      | <:expr< ( / ) >> -> <:expr< ( /. ) >>
      | <:expr< $int:i$ >> ->
        let f = float(int_of_string i) in <:expr< $`flo:f$ >>
      | e -> super#expr e
  end;;

  EXTEND Gram
    GLOBAL: expr;

    expr: LEVEL "simple"
    [ [ "Float"; "."; "("; e = SELF; ")" -> (new float_subst _loc)#expr e ]
    ]
    ;
  END
end

let module M = Register.OCamlSyntaxExtension Id Make in ()

To Compile

$ocamlbuild foo.byte -classic-display
/usr/bin/ocamlopt -I /usr/lib/ocaml/3.10.0/ocamlbuild unix.cmxa /usr/lib/ocaml/3.10.0/ocamlbuild/ocamlbuildlib.cmxa myocamlbuild.ml
+/usr/lib/ocaml/3.10.0/ocamlbuild/ocamlbuild.cmx -o myocamlbuild
/usr/bin/ocamldep -modules foo.ml > foo.ml.depends
/usr/bin/ocamldep -pp camlp4of -modules pa_float.ml > pa_float.ml.depends
ocamlfind ocamlc -package str -c -I +camlp4 -pp camlp4of -o pa_float.cmo pa_float.ml
/usr/bin/ocamldep -pp 'camlp4o pa_float.cmo' -modules bar.ml > bar.ml.depends
ocamlfind ocamlc -package str -c -pp 'camlp4o pa_float.cmo' -o bar.cmo bar.ml
ocamlfind ocamlc -package str -c -o foo.cmo foo.ml
ocamlfind ocamlc -package str -linkpkg bar.cmo foo.cmo -o foo.byte