Replace the Hashtbl.t used for mapping nodes to state-sets by an
[tatoo.git] / myocamlbuild.ml
index 7a792d1..0ea5ff0 100644 (file)
 open Ocamlbuild_plugin
 open Command
-open Myocamlbuild_config
-open Format
 
-let print_list l =
-  eprintf "%![%s]%!\n" (String.concat ", " l)
-
-let _A x = A x
-let _S ?(extra=N) l = S (List.map (fun e -> (S [extra; _A e] )) l)
-;;
-let cxx_flags_for_ml = [ _S ~extra:(_A "-ccopt") cxx_flags ]
-let cxx_flags = ref [ _S cxx_flags ]
-let project_dirs = [ src_path; include_path ]
-let cxx_include_flags = _S cxx_includes
-let cxx_link_flags = ref  [ _S cxx_lpaths; _S cxx_libs]
-let native_link_flags = ref (List.map (fun s -> s ^ ".cmxa") ocaml_link)
-let byte_link_flags =  ref ("-custom" :: (List.map (fun s -> s ^ ".cma") ocaml_link))
-let link_flags = [ A"-linkpkg" ]
-let libs_files = List.map (fun s -> "file:" ^ s) cxx_libs_objects
-
-
-let native_compile_flags = ref [A"-fno-PIC"]
-let compile_flags = ref []
-
-let dwsize = sprintf "-DWORDSIZE%i" Sys.word_size
-
-(* Utils *)
-let ( @= ) r l = r := !r @ l
-let ( =:: ) r e = r := e :: !r
-
-(* Pre-processed files *)
-let pp_macro_options = ref
-  [ A "-parser"; A "macro"; A dwsize; A "-I"; P include_path ]
-
-let include_full_path =  Pathname.pwd / include_path
-module Depends =
-struct
-open Scanf
-let scan_include ml =
-  let ic = open_in ml and includes = ref [] in
-  begin
-    try
-      while true do
-       let s = input_line ic in
-       if String.length s > 0 then
-         try
-           sscanf s " INCLUDE \"%s@\"" (fun s -> includes =:: include_path /s)
-         with Scan_failure _ -> ()
-      done
-    with End_of_file -> close_in ic
-  end;
-  !includes
-
-let ocaml ml =
-  let rec loop file =
-    let includes = scan_include file in
-    List.fold_left (fun a i -> (loop i) @ a) includes includes
-  in
-  let includes = loop ml in
-    dep [ "file:" ^ ml ] includes
-
-let parse_depends depfile =
-  let ichan = open_in depfile in
-  let iscan = Scanning.from_channel ichan in
-  let includes = ref [] in
-  bscanf iscan " %_s@: %s " ignore;
-  try
-    while true do
-      bscanf iscan " %s " (
-       function "" -> raise End_of_file
-         | "\\" -> ()
-         | s ->  includes =::s)
-    done; []
-  with
-    _ -> close_in ichan;!includes
-
-let cxx cpp =
-  let depfile = !Options.build_dir /" __cxx_depends.tmp" in
-  let cmd = Cmd (S[ A cxx_cmd ; S !cxx_flags; cxx_include_flags ; A"-MM";
-                   A "-MF";  P depfile; P cpp])
-  in
-  let () = Command.execute ~quiet:true ~pretend:false cmd in
-  let includes = parse_depends depfile in
-  let includes' = (List.filter (Pathname.is_relative) includes) in
-  dep [ "compile"; "file:" ^ cpp ] includes'
-end
-
-let cxx_compile env _build =
-  let cpp = env "%.cpp" and obj = env "%.o" in
-  let tags = (tags_of_pathname cpp) ++ "compile" ++ "c++" in
-  Cmd(S[T tags; A cxx_cmd; A "-o" ; P obj; A "-c";  S !cxx_flags; cxx_include_flags; P cpp])
-
-(* Native compile and link action *)
-
-let ocamlfind x = S[ T (Tags.singleton "ocamlfind"); A"ocamlfind"; x ; A "-package"; A ocamlfind_packages ]
-
-let ppopt l = List.map (fun e -> S[ A"-ppopt"; e ]) l
+let includes = ref StringSet.empty
+
+let register_include dir =
+  if not (StringSet.mem dir !includes) then begin
+    includes := StringSet.add dir !includes;
+    dep [ "extension:ml" ]
+      (List.map (fun s -> dir ^ "/" ^ s )
+         (Array.to_list (Pathname.readdir dir)))
+  end
+
+let set_flags tag_list action_list =
+  List.iter (fun s ->
+    List.iter (fun (fl, fu) ->
+      pflag s fl fu)
+      action_list
+  ) tag_list
+
+let macro_flags = [
+  "macro_include",
+  (fun s -> register_include s; S [A"-ppopt"; A "-I"; A"-ppopt"; A s]);
+  "macro_define", (fun s -> S [A"-ppopt"; A ("-D"^s)]);
+]
 
 let () = dispatch begin
   function
-    | Before_rules ->
-
-      Options.ocamlc := ocamlfind  (A"ocamlc");
-      Options.ocamlopt := ocamlfind (A"ocamlopt");
-      Options.ocamldep := ocamlfind (A"ocamldep");
-      Options.ocamldoc := ocamlfind (A"ocamldoc");
-      Options.ocamlmktop := ocamlfind (A"ocamlmktop");
-
-      if not (List.mem "log" !Options.tags) then begin
-       pp_macro_options @= [ A "-DNLOG" ];
-      end;
-      if (List.mem "profile" !Options.tags) then begin
-       pp_macro_options @= [ A "-DPROFILE" ];
-       native_compile_flags @= [A "-p" ];
-       native_link_flags @= [ "-p" ];
-       cxx_flags @= [ A "-pg" ];
-       cxx_link_flags @= [ A "-pg" ];
-      end;
-
-      if (List.mem "debug" !Options.tags) then begin
-       pp_macro_options @= [ A "-DDEBUG" ];
-       cxx_flags @= [ A "-O0"; A "-g" ];
-       cxx_link_flags @= [ A "-g" ];
-      end
-      else begin
-       compile_flags @= [A "-noassert"];
-       pp_macro_options @= [ A "-unsafe" ];
-       native_compile_flags @= [ A "-inline"; A ocaml_inline ];
-       cxx_flags @= [ A "-O3" ]
-      end;
-
-      let dir_path = Pathname.pwd / src_path in
-      let dir = Pathname.readdir dir_path in
-
-      Array.iter (fun entry ->
-       if Pathname.check_extension entry "ml" then
-         Depends.ocaml (src_path / entry)
-       else if Pathname.check_extension entry "cpp" then
-         Depends.cxx (src_path / entry)
-      ) dir;
-
+    | Before_rules -> ()
     | After_rules ->
-      dep [ "link" ] cstub_lib;
-      rule "c++: cpp & depends -> o" ~prod:"%.o" ~deps:[ "%.cpp" ] cxx_compile;
-      let syntax_flags = S ([ A "-syntax"; A "camlp4o";
-                           S (ppopt [A "-printer" ; A"Camlp4OCamlAstDumper"]);
-                           S (ppopt !pp_macro_options) ])
-      in
-      flag [ "ocaml"; "ocamldep"] syntax_flags;
-      flag [ "ocaml"; "compile" ] (S[ A "-cc"; A cxx_cmd; S cxx_flags_for_ml ;  syntax_flags; S !compile_flags ]);
-      flag [ "ocaml"; "native"; "compile" ] (S !native_compile_flags);
-      flag [ "ocaml"; "link" ]
-       (S [ S link_flags ; A "-cc"; A cxx_cmd; S cxx_flags_for_ml; A "-cclib" ;
-            Quote (S [ _S cstub_lib;  S !cxx_link_flags]) ]);
-      flag [ "ocaml"; "byte"; "link" ] (_S !byte_link_flags);
-      flag [ "ocaml"; "native"; "link" ] (_S !native_link_flags);
-      flag [ "c"; "ocamlmklib"] (S[ A "-custom"; ])
+        set_flags [["ocaml";"compile"]; ["ocaml";"ocamldep"] ] macro_flags;
+        pflag [ "ocaml"; "compile" ] "warning"   (fun s -> (S[ A"-w"; A s]));
+        flag [ "ocaml"; "compile"; "debug" ] (S[ A"-g"; A"-ppopt"; A"-DDEBUG"]);
+        flag [ "ocaml"; "link"; "debug" ] (A"-g");
+        flag [ "ocaml"; "compile"; "profile"] (S[A"-ppopt"; A"-DPROFILE"]);
+        flag [ "ocaml"; "compile"; "profile"; "native"] (A"-p");
+        flag [ "ocaml"; "link"; "profile"; "native"] (A"-p");
+        pflag [ "ocaml"; "compile"; "native" ] "inline" (fun i -> (S[ A"-inline"; A i ]));
+        pflag [ "ocaml"; "compile" ] "unsafe" (fun s -> (if s = "true" then S[A"-ppopt";A "-unsafe"] else N));
+
+
+         rule "Java compilation"
+        ~prod:"%.class"
+        ~dep:"%.java"
+        begin fun env _build ->
+          let java = env "%.java" in
+          let tags = tags_of_pathname java ++ "compile" in
+          Cmd( S[ A"javac" ; P java; T tags ])
+        end
     | _ -> ()
 end