ocaml_monad_io / myocamlbuild.ml

open Ocamlbuild_plugin;;



(**********************)

(* these functions are not really officially exported *)
let run_and_read = Ocamlbuild_pack.My_unix.run_and_read
let blank_sep_strings = Ocamlbuild_pack.Lexers.blank_sep_strings

let split s ch =
  let x = ref [] in
  let rec go s =
    let pos = String.index s ch in
    x := (String.before s pos)::!x;
    go (String.after s (pos + 1))
  in
  try
    go s
  with Not_found -> !x

let split_nl s = split s '\n'

let before_space s =
  try
    String.before s (String.index s ' ')
  with Not_found -> s

(* this lists all supported packages *)
let find_packages () =
  List.map before_space (split_nl & run_and_read "ocamlfind list")

(* this is supposed to list available syntaxes,
   but I don't know how to do it. *)
let find_syntaxes () = ["camlp4o"; "camlp4r"]

(* ocamlfind command *)
let ocamlfind x = S[A"ocamlfind"; x]
;;

let disp_ocamlfind = begin function
   | Before_options ->
       (* by using Before_options one let command line options have an higher priority *)
       (* on the contrary using After_options will guarantee to have the higher priority *)

       (* override default commands by ocamlfind ones *)

(*
       Options.ocamlc     := ocamlfind & A"ocamlc";
*)
       Options.ocamlc     := ocamlfind & S[A"ocamlc"; A"-verbose"];

       Options.ocamlopt   := ocamlfind & A"ocamlopt";
       Options.ocamldep   := ocamlfind & A"ocamldep" (* S[A"ocamldep"; A"-verbose"] *) ;
       Options.ocamldoc   := ocamlfind & A"ocamldoc";
       Options.ocamlmktop := ocamlfind & A"ocamlmktop"

   | After_rules ->

       (* When one link an OCaml library/binary/package, one should use -linkpkg *)
       flag ["ocaml"; "link"] & A"-linkpkg";

       (* For each ocamlfind package one inject the -package option when
       	* compiling, computing dependencies, generating documentation and
       	* linking. *)
       List.iter begin fun pkg ->
         flag ["ocaml"; "compile";  "pkg_"^pkg] & S[A"-package"; A pkg];
         flag ["ocaml"; "ocamldep"; "pkg_"^pkg] & S[A"-package"; A pkg];
         flag ["ocaml"; "doc";      "pkg_"^pkg] & S[A"-package"; A pkg];
         flag ["ocaml"; "link";     "pkg_"^pkg] & S[A"-package"; A pkg];
         flag ["ocaml"; "infer_interface"; "pkg_"^pkg] & S[A"-package"; A pkg];
       end (find_packages ());

       (* Like -package but for extensions syntax. Morover -syntax is useless
       	* when linking. *)
       List.iter begin fun syntax ->
         flag ["ocaml"; "compile";  "syntax_"^syntax] & S[A"-syntax"; A syntax];
         flag ["ocaml"; "ocamldep"; "syntax_"^syntax] & S[A"-syntax"; A syntax];
         flag ["ocaml"; "doc";      "syntax_"^syntax] & S[A"-syntax"; A syntax];
         flag ["ocaml"; "infer_interface"; "syntax_"^syntax] & S[A"-syntax"; A syntax];
       end (find_syntaxes ());
       
       (* The default "thread" tag is not compatible with ocamlfind.
          Indeed, the default rules add the "threads.cma" or "threads.cmxa"
          options when using this tag. When using the "-linkpkg" option with
          ocamlfind, this module will then be added twice on the command line.
       
          To solve this, one approach is to add the "-thread" option when using
          the "threads" package using the previous plugin.
        *)
       flag ["ocaml"; "pkg_threads"; "compile"] (S[A "-thread"]);
       flag ["ocaml"; "pkg_threads"; "link"] (S[A "-thread"]);
       flag ["ocaml"; "pkg_threads"; "infer_interface"] (S[A "-thread"])
       
   | _ -> ()
end

(**********************)



(*
List.iter begin fun class_name ->
  flag ["ocaml"; "pp"; "classes"^class_name] (S[A"-classes"; A class_name])
end ["Show"; "Typeable"]
;;
*)

let libdir = !Ocamlbuild_pack.Ocamlbuild_where.libdir
;;

(*
Printf.printf "%!\n\n\nlibdir: %S\n\n\n%!"
   !Ocamlbuild_pack.Ocamlbuild_where.libdir
   !libdir
   !Ocamlbuild_where.libdir
   !Myocamlbuild_config.libdir
   !Ocamlbuild_Myocamlbuild_config.libdir
*)

let stdlib_dir = Ocamlbuild_pack.Ocaml_utils.stdlib_dir;;


let str_replace_char str cfrom cto =
  let str = String.copy str in
  let () =
    for i = 0 to String.length str - 1 do
      ( if str.[i] = cfrom
        then str.[i] <- cto
        else ()
      )
      done
  in
  str
;;


let disp_deriving = (function
| After_rules ->
    let stdlib_dir = Lazy.force stdlib_dir in
    let syn_dir = stdlib_dir / "deriving" / "syntax" in
(*
    let syn_dir =
      if Sys.os_type = "Win32"
      then str_replace_char syn_dir '/' '\\'
      else syn_dir
    in
*)
    ( flag ["ocaml"; "pp"; "deriving"]
        (S[A"-I"; P(syn_dir);
          S(List.map
              (fun m -> A(m^".cmo"))
              ["utils"; "type"; "base"; "id"; "extend"; "show_class"]
           )
          ]
        )
    ; flag ["ocaml"; "compile"; "deriving"]
        (S[A"-I"; P("+deriving" / "lib")])
    ; flag ["ocaml"; "link"; "deriving"; "byte"]
        (S[A"-I"; P("+deriving" / "lib"); A"deriving.cma"])
    ; flag ["ocaml"; "link"; "deriving"; "native"]
        (S[A"-I"; P("+deriving" / "lib"); A"deriving.cmxa"])
    )
|  _ -> ()
);;


dispatch
(fun x -> (disp_ocamlfind x; disp_deriving x))
;;
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.