summaryrefslogtreecommitdiff
path: root/ocaml-binary-annot/ocamlbuild/ocaml_utils.ml
diff options
context:
space:
mode:
Diffstat (limited to 'ocaml-binary-annot/ocamlbuild/ocaml_utils.ml')
-rw-r--r--ocaml-binary-annot/ocamlbuild/ocaml_utils.ml171
1 files changed, 171 insertions, 0 deletions
diff --git a/ocaml-binary-annot/ocamlbuild/ocaml_utils.ml b/ocaml-binary-annot/ocamlbuild/ocaml_utils.ml
new file mode 100644
index 0000000000..3dafe25a41
--- /dev/null
+++ b/ocaml-binary-annot/ocamlbuild/ocaml_utils.ml
@@ -0,0 +1,171 @@
+(***********************************************************************)
+(* ocamlbuild *)
+(* *)
+(* Nicolas Pouillard, Berke Durak, projet Gallium, INRIA Rocquencourt *)
+(* *)
+(* Copyright 2007 Institut National de Recherche en Informatique et *)
+(* en Automatique. All rights reserved. This file is distributed *)
+(* under the terms of the Q Public License version 1.0. *)
+(* *)
+(***********************************************************************)
+
+
+(* Original author: Nicolas Pouillard *)
+open My_std
+open Format
+open Log
+open Pathname.Operators
+open Tags.Operators
+open Tools
+open Flags
+open Command;;
+
+
+module S = Set.Make(String)
+
+let flag_and_dep tags cmd_spec =
+ flag tags cmd_spec;
+ let ps = Command.fold_pathnames (fun p ps -> p :: ps) (Cmd cmd_spec) [] in
+ dep tags ps
+
+let stdlib_dir = lazy begin
+ (* FIXME *)
+ let ocamlc_where = sprintf "%s/ocamlc.where" (Pathname.pwd / !Options.build_dir) in
+ let () = Command.execute ~quiet:true (Cmd(S[!Options.ocamlc; A"-where"; Sh">"; P ocamlc_where])) in
+ String.chomp (read_file ocamlc_where)
+end
+
+let pflag_and_dep tags ptag cmd_spec =
+ Param_tags.declare ptag
+ (fun param ->
+ flag_and_dep (Param_tags.make ptag param :: tags) (cmd_spec param))
+
+let module_name_of_filename f = String.capitalize (Pathname.remove_extensions f)
+let module_name_of_pathname x =
+ module_name_of_filename (Pathname.to_string (Pathname.basename x))
+
+let ignore_stdlib x =
+ if !Options.nostdlib then false
+ else
+ let x' = !*stdlib_dir/((String.uncapitalize x)-.-"cmi") in
+ Pathname.exists x'
+
+let non_dependencies = ref []
+let non_dependency m1 m2 =
+ (* non_dependency was not supposed to accept pathnames without extension. *)
+ if String.length (Pathname.get_extensions m1) = 0 then
+ invalid_arg "non_dependency: no extension";
+ non_dependencies := (m1, m2) :: !non_dependencies
+
+let path_importance path x =
+ if List.mem (path, x) !non_dependencies
+ || (List.mem x !Options.ignore_list) then begin
+ let () = dprintf 3 "This module (%s) is ignored by %s" x path in
+ `ignored
+ end
+ else if ignore_stdlib x then `just_try else `mandatory
+
+let expand_module include_dirs module_name exts =
+ let dirname = Pathname.dirname module_name in
+ let basename = Pathname.basename module_name in
+ let module_name_cap = dirname/(String.capitalize basename) in
+ let module_name_uncap = dirname/(String.uncapitalize basename) in
+ List.fold_right begin fun include_dir ->
+ List.fold_right begin fun ext acc ->
+ include_dir/(module_name_uncap-.-ext) ::
+ include_dir/(module_name_cap-.-ext) :: acc
+ end exts
+ end include_dirs []
+
+let string_list_of_file file =
+ with_input_file file begin fun ic ->
+ Lexers.blank_sep_strings (Lexing.from_channel ic)
+ end
+let print_path_list = Pathname.print_path_list
+
+let ocaml_ppflags tags =
+ let flags = Flags.of_tags (tags++"ocaml"++"pp") in
+ let reduced = Command.reduce flags in
+ if reduced = N then N else S[A"-pp"; Quote reduced]
+
+let ocaml_add_include_flag x acc =
+ if x = Pathname.current_dir_name then acc else A"-I" :: A x :: acc
+
+let ocaml_include_flags path =
+ S (List.fold_right ocaml_add_include_flag (Pathname.include_dirs_of (Pathname.dirname path)) [])
+
+let info_libraries = Hashtbl.create 103
+
+let libraries = Hashtbl.create 103
+let libraries_of m =
+ try Hashtbl.find libraries m with Not_found -> []
+let use_lib m lib = Hashtbl.replace libraries m (lib :: libraries_of m)
+
+let ocaml_lib ?(extern=false) ?(byte=true) ?(native=true) ?dir ?tag_name libpath =
+ let add_dir x =
+ match dir with
+ | Some dir -> S[A"-I"; P dir; x]
+ | None -> x
+ in
+ let tag_name =
+ match tag_name with
+ | Some x -> x
+ | None -> "use_" ^ Pathname.basename libpath
+ in
+ let flag_and_dep tags lib =
+ flag tags (add_dir (A lib));
+ if not extern then dep tags [lib] (* cannot happen? *)
+ in
+ Hashtbl.replace info_libraries tag_name (libpath, extern);
+ if extern then begin
+ if byte then
+ flag_and_dep ["ocaml"; tag_name; "link"; "byte"] (libpath^".cma");
+ if native then
+ flag_and_dep ["ocaml"; tag_name; "link"; "native"] (libpath^".cmxa");
+ end else begin
+ if not byte && not native then
+ invalid_arg "ocaml_lib: ~byte:false or ~native:false only works with ~extern:true";
+ end;
+ match dir with
+ | None -> ()
+ | Some dir ->
+ List.iter
+ (fun x -> flag ["ocaml"; tag_name; x] (S[A"-I"; P dir]))
+ ["compile"; "doc"; "infer_interface"]
+
+let cmi_of = Pathname.update_extensions "cmi"
+
+exception Ocamldep_error of string
+
+let read_path_dependencies =
+ let path_dependencies = Hashtbl.create 103 in
+ let read path =
+ let module_name = module_name_of_pathname path in
+ let depends = path-.-"depends" in
+ with_input_file depends begin fun ic ->
+ let ocamldep_output =
+ try Lexers.ocamldep_output (Lexing.from_channel ic)
+ with Lexers.Error msg -> raise (Ocamldep_error(Printf.sprintf "Ocamldep.ocamldep: bad output (%s)" msg)) in
+ let deps =
+ List.fold_right begin fun (path, deps) acc ->
+ let module_name' = module_name_of_pathname path in
+ if module_name' = module_name
+ then List.union deps acc
+ else raise (Ocamldep_error(Printf.sprintf "Ocamldep.ocamldep: multiple files in ocamldep output (%s not expected)" path))
+ end ocamldep_output [] in
+ let deps =
+ if !Options.nostdlib && not (Tags.mem "nopervasives" (tags_of_pathname path)) then
+ "Pervasives" :: deps
+ else deps in
+ let deps' = List.fold_right begin fun dep acc ->
+ match path_importance path dep with
+ | `ignored -> acc
+ | (`just_try | `mandatory) as importance -> (importance, dep) :: acc
+ end deps [] in
+ Hashtbl.replace path_dependencies path
+ (List.union (try Hashtbl.find path_dependencies path with Not_found -> []) deps');
+ deps'
+ end
+ in read
+
+let path_dependencies_of = memo read_path_dependencies