Merge commit 'ocaml3102'
[ocaml.git] / ocamlbuild / ocaml_tools.ml
blob20348472d9aeda56027c22fd5fe91da2fd261998
1 (***********************************************************************)
2 (* ocamlbuild *)
3 (* *)
4 (* Nicolas Pouillard, Berke Durak, projet Gallium, INRIA Rocquencourt *)
5 (* *)
6 (* Copyright 2007 Institut National de Recherche en Informatique et *)
7 (* en Automatique. All rights reserved. This file is distributed *)
8 (* under the terms of the Q Public License version 1.0. *)
9 (* *)
10 (***********************************************************************)
12 (* $Id$ *)
13 (* Original author: Nicolas Pouillard *)
14 open My_std
15 open Pathname.Operators
16 open Tags.Operators
17 open Tools
18 open Command
19 open Ocaml_utils
21 let add_suffix s = List.map (fun x -> x -.- s) ;;
23 let ocamldep_command' tags spec =
24 let tags' = tags++"ocaml"++"ocamldep" in
25 S [!Options.ocamldep; T tags'; ocaml_ppflags (tags++"pp:dep");
26 spec; A "-modules"]
28 let menhir_ocamldep_command' tags ~menhir_spec ~ocamldep_spec out =
29 let menhir = if !Options.ocamlyacc = N then V"MENHIR" else !Options.ocamlyacc in
30 Cmd(S[menhir; T tags; A"--raw-depend";
31 A"--ocamldep"; Quote (ocamldep_command' tags ocamldep_spec);
32 menhir_spec ; Sh ">"; Px out])
34 let menhir_ocamldep_command arg out env _build =
35 let arg = env arg and out = env out in
36 let tags = tags_of_pathname arg++"ocaml"++"menhir_ocamldep" in
37 let ocamldep_spec = flags_of_pathname arg in
38 menhir_ocamldep_command' tags ~menhir_spec:(P arg) ~ocamldep_spec out
40 let import_mlypack build mlypack =
41 let tags1 = tags_of_pathname mlypack in
42 let files = string_list_of_file mlypack in
43 let include_dirs = Pathname.include_dirs_of (Pathname.dirname mlypack) in
44 let files_alternatives =
45 List.map begin fun module_name ->
46 expand_module include_dirs module_name ["mly"]
47 end files
49 let files = List.map Outcome.good (build files_alternatives) in
50 let tags2 =
51 List.fold_right
52 (fun file -> Tags.union (tags_of_pathname file))
53 files tags1
55 (tags2, files)
57 let menhir_modular_ocamldep_command mlypack out env build =
58 let mlypack = env mlypack and out = env out in
59 let (tags,files) = import_mlypack build mlypack in
60 let tags = tags++"ocaml"++"menhir_ocamldep" in
61 let menhir_base = Pathname.remove_extensions mlypack in
62 let menhir_spec = S[A "--base" ; P menhir_base ; atomize_paths files] in
63 let ocamldep_spec = N in
64 menhir_ocamldep_command' tags ~menhir_spec ~ocamldep_spec out
66 let menhir_modular menhir_base mlypack mlypack_depends env build =
67 let menhir = if !Options.ocamlyacc = N then V"MENHIR" else !Options.ocamlyacc in
68 let menhir_base = env menhir_base in
69 let mlypack = env mlypack in
70 let mlypack_depends = env mlypack_depends in
71 let (tags,files) = import_mlypack build mlypack in
72 let () = List.iter Outcome.ignore_good (build [[mlypack_depends]]) in
73 Ocaml_compiler.prepare_compile build mlypack;
74 let tags = tags++"ocaml"++"parser"++"menhir" in
75 Cmd(S[menhir ;
76 A "--ocamlc"; Quote(S[!Options.ocamlc; ocaml_include_flags mlypack]);
77 T tags ; A "--infer" ; flags_of_pathname mlypack ;
78 A "--base" ; Px menhir_base ; atomize_paths files])
80 let ocamldep_command arg out env _build =
81 let arg = env arg and out = env out in
82 let spec = flags_of_pathname arg in
83 let tags = tags_of_pathname arg in
84 Cmd(S[ocamldep_command' tags spec; P arg; Sh ">"; Px out])
86 let ocamlyacc mly env _build =
87 let mly = env mly in
88 let ocamlyacc = if !Options.ocamlyacc = N then V"OCAMLYACC" else !Options.ocamlyacc in
89 Cmd(S[ocamlyacc; T(tags_of_pathname mly++"ocaml"++"parser"++"ocamlyacc");
90 flags_of_pathname mly; Px mly])
92 let ocamllex mll env _build =
93 let mll = env mll in
94 Cmd(S[!Options.ocamllex; T(tags_of_pathname mll++"ocaml"++"lexer"++"ocamllex");
95 flags_of_pathname mll; Px mll])
97 let infer_interface ml mli env build =
98 let ml = env ml and mli = env mli in
99 let tags = tags_of_pathname ml++"ocaml" in
100 Ocaml_compiler.prepare_compile build ml;
101 Cmd(S[!Options.ocamlc; ocaml_ppflags tags; ocaml_include_flags ml; A"-i";
102 T(tags++"infer_interface"); P ml; Sh">"; Px mli])
104 let menhir mly env build =
105 let mly = env mly in
106 let menhir = if !Options.ocamlyacc = N then V"MENHIR" else !Options.ocamlyacc in
107 Ocaml_compiler.prepare_compile build mly;
108 Cmd(S[menhir;
109 A"--ocamlc"; Quote(S[!Options.ocamlc; ocaml_include_flags mly]);
110 T(tags_of_pathname mly++"ocaml"++"parser"++"menhir");
111 A"--infer"; flags_of_pathname mly; Px mly])
113 let ocamldoc_c tags arg odoc =
114 let tags = tags++"ocaml" in
115 Cmd (S [!Options.ocamldoc; A"-dump"; Px odoc; T(tags++"doc");
116 ocaml_ppflags (tags++"pp:doc"); flags_of_pathname arg;
117 ocaml_include_flags arg; P arg])
119 let ocamldoc_l_dir tags deps _docout docdir =
120 Seq[Cmd (S[A"rm"; A"-rf"; Px docdir]);
121 Cmd (S[A"mkdir"; A"-p"; Px docdir]);
122 Cmd (S [!Options.ocamldoc;
123 S(List.map (fun a -> S[A"-load"; P a]) deps);
124 T(tags++"doc"++"docdir"); A"-d"; Px docdir])]
126 let ocamldoc_l_file tags deps docout _docdir =
127 Seq[Cmd (S[A"rm"; A"-rf"; Px docout]);
128 Cmd (S[A"mkdir"; A"-p"; Px (Pathname.dirname docout)]);
129 Cmd (S [!Options.ocamldoc;
130 S(List.map (fun a -> S[A"-load"; P a]) deps);
131 T(tags++"doc"++"docfile"); A"-o"; Px docout])]
133 let document_ocaml_interf mli odoc env build =
134 let mli = env mli and odoc = env odoc in
135 Ocaml_compiler.prepare_compile build mli;
136 ocamldoc_c (tags_of_pathname mli++"interf") mli odoc
138 let document_ocaml_implem ml odoc env build =
139 let ml = env ml and odoc = env odoc in
140 Ocaml_compiler.prepare_compile build ml;
141 ocamldoc_c (tags_of_pathname ml++"implem") ml odoc
143 let document_ocaml_project ?(ocamldoc=ocamldoc_l_file) odocl docout docdir env build =
144 let odocl = env odocl and docout = env docout and docdir = env docdir in
145 let contents = string_list_of_file odocl in
146 let include_dirs = Pathname.include_dirs_of (Pathname.dirname odocl) in
147 let to_build =
148 List.map begin fun module_name ->
149 expand_module include_dirs module_name ["odoc"]
150 end contents in
151 let module_paths = List.map Outcome.good (build to_build) in
152 let tags = (Tags.union (tags_of_pathname docout) (tags_of_pathname docdir))++"ocaml" in
153 ocamldoc tags module_paths docout docdir