]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/ocaml/contrib/camlp4/Makefile.ml
update
[l4.git] / l4 / pkg / ocaml / contrib / camlp4 / Makefile.ml
1 (****************************************************************************)
2 (*                                                                          *)
3 (*                              Objective Caml                              *)
4 (*                                                                          *)
5 (*                            INRIA Rocquencourt                            *)
6 (*                                                                          *)
7 (*  Copyright  2006   Institut National de Recherche  en  Informatique et   *)
8 (*  en Automatique.  All rights reserved.  This file is distributed under   *)
9 (*  the terms of the GNU Library General Public License, with the special   *)
10 (*  exception on linking described in LICENSE at the top of the Objective   *)
11 (*  Caml source tree.                                                       *)
12 (*                                                                          *)
13 (****************************************************************************)
14
15 (* Authors:
16  * - Nicolas Pouillard: initial version
17  *)
18 open YaM
19 open Format
20
21 let getenv var default =
22   try Sys.getenv var
23   with Not_found ->
24     default
25
26 let libdir_camlp4 = (getenv "LIBDIR" Camlp4_config.libdir) ^ "/camlp4/."
27
28 let bindir = (getenv "BINDIR" Camlp4_config.bindir) ^ "/."
29
30 (**
31 let unixlib =
32   match Sys.os_type with
33   | "Win32" -> "../otherlibs/win32unix"
34   | _       -> "../otherlibs/unix"
35 **)
36 let ocamlrun = "../boot/ocamlrun" (* " -I " ^ unixlib *)
37 let ocamlrun_os =
38   Filename.concat Filename.parent_dir_name
39                   (Filename.concat "boot" "ocamlrun")
40 (*  ^ " -I " ^ unixlib *)
41
42 let ocaml = ocamlrun ^ " ../ocaml -I ../stdlib" (* "-I " ^ unixlib *)
43
44 let debug_mode =
45   (* true *)
46   false
47
48 let camlp4_modules =
49   [
50     ocamlrun_os;
51     "./boot/camlp4boot";
52   ]
53 let camlp4_modules =
54   if debug_mode then "env STATIC_CAMLP4_DEBUG=\\*" :: camlp4_modules
55   else camlp4_modules
56
57 let debug_opt x = if debug_mode && Sys.file_exists x then [x] else []
58 let filter_opt x = if Sys.file_exists x then [x] else []
59
60 let camlp4boot = "'" ^ String.concat " " camlp4_modules ^ "'"
61 let camlp4boot_may_debug mods =
62   let camlp4_modules = camlp4_modules @
63     debug_opt "./boot/ExceptionTracer.cmo" @
64     filter_opt "./boot/Profiler.cmo" @ mods
65   in "'" ^ String.concat " " camlp4_modules ^ "'"
66
67 let ocamlc =
68   best ["../ocamlc.opt", "../ocamlc.opt";
69         "../ocamlc",     ocamlrun ^^ "../ocamlc";
70         "",              "echo no byte compiler available && false"]
71 let ocamlopt =
72   best ["../ocamlopt.opt", "../ocamlopt.opt";
73         "../ocamlopt",     ocamlrun ^^ "../ocamlopt";
74         "",                "echo no native compiler available && false"]
75
76 let () =
77   !options.ocamlc       := ocamlc ^^ " -nostdlib -I ../stdlib";
78   !options.ocamlopt     := ocamlopt ^^ " -nostdlib -I ../stdlib";
79   !options.ocamldoc     := ocamlrun ^^ "../ocamldoc/ocamldoc";
80   !options.ocamlyacc    := ocamlrun ^^ "../boot/ocamlyacc";
81   !options.ocamllex     := ocamlrun ^^ "../boot/ocamllex";
82   !options.ocamldep     := ocamlrun ^^ "../tools/ocamldep";
83   ()
84
85 let options_without_camlp4 = new_scope (lazy !options)
86
87 let windows = Sys.os_type = "Win32"
88
89 let may_define_unix = if windows then [] else ["-D UNIX"]
90
91 let () =
92   !options.ocaml_Flags ^= "-w Ale -warn-error Ale"^^
93                             (if getenv "DTYPES" "" <> "" then "-annot"
94                              else "");
95   !options.ocaml_P4     := camlp4boot_may_debug may_define_unix;
96   !options.ocaml_P4_opt := camlp4boot_may_debug ("-D OPT" :: may_define_unix);
97   ()
98
99 let options_without_debug () = { (!options) with ocaml_P4     = ref camlp4boot
100                                                ; ocaml_P4_opt = ref camlp4boot }
101
102 let parsing = "../parsing"
103 and typing = "../typing"
104 and toplevel = "../toplevel"
105 and utils = "../utils"
106 and dynlink = "../otherlibs/dynlink"
107 and unix =
108   match Sys.os_type with
109   | "Win32" -> "../otherlibs/win32unix"
110   | _       -> "../otherlibs/unix"
111 and build = "build"
112
113 let ocaml_Module_with_genmap =
114   generic_ocaml_Module_extension ".genmap.ml"
115    (fun _ i o ->
116       "if test ! -e"^^o^^
117          "|| ( test -e ./camlp4boot.run"^^
118              "&& test -e Camlp4Filters/GenerateMap.cmo"^^
119              "&& test -e Camlp4Filters/GenerateFold.cmo"^^
120              "&& test -e Camlp4Filters/MetaGenerator.cmo"^^
121              "&& test -e Camlp4Filters/RemoveTrashModule.cmo ) ;"^^
122       "then ( echo 'module Camlp4FiltersTrash = struct' ;"^^
123              "cat Camlp4/Sig/Camlp4Ast.ml ; echo 'end;' ) > Camlp4/Struct/Camlp4Ast.tmp.ml ;"^^
124              "( echo '(* Generated file! Do not edit by hand *)' ;"^^
125                 "../boot/ocamlrun ./camlp4boot.run"^^
126                    "./Camlp4Filters/GenerateMap.cmo"^^
127                    "./Camlp4Filters/GenerateFold.cmo"^^
128                    "./Camlp4Filters/MetaGenerator.cmo"^^
129                    "./Camlp4Filters/RemoveTrashModule.cmo -printer OCamlr"^^
130                    i^^" -no_comments ) >"^^o^^"; else : ; fi")
131
132 let camlp4_package_as_one_dir =
133   ocaml_PackageDir "Camlp4" (lazy [
134     ocaml_IModule ~includes:[build] "Config";
135     ocaml_IModule ~o:(options_without_debug ()) "Debug";
136     ocaml_IModule "Options";
137     ocaml_PackageDir "Sig" (lazy [
138       ocaml_Interface "Id";
139       ocaml_Interface ~ext_includes:[parsing] "Loc";
140       ocaml_Interface "Error";
141       ocaml_Interface "Warning";
142       ocaml_Interface "Type";
143       ocaml_Interface "Token";
144       ocaml_Interface "Lexer";
145       ocaml_PackageDir "Grammar" (lazy [
146         ocaml_Interface "Action";
147         ocaml_Interface "Structure";
148         ocaml_Interface "Dynamic";
149         ocaml_Interface "Static"
150       ]);
151       ocaml_IModule "Mapper";
152       ocaml_Interface "Ast";
153       ocaml_Module "Camlp4Ast";
154       ocaml_Interface "Quotation";
155       ocaml_Interface "Camlp4Token";
156       ocaml_Interface "DynLoader";
157       ocaml_Interface "AntiquotSyntax";
158       ocaml_Interface "Parser";
159       ocaml_Interface "Printer";
160       ocaml_Interface "Syntax";
161       ocaml_Interface "Camlp4Syntax";
162       ocaml_Interface "AstFilters";
163       ocaml_Interface "SyntaxExtension";
164     ]);
165     ocaml_IModule "ErrorHandler";
166     ocaml_PackageDir "Struct" (lazy [
167       ocaml_IModule ~ext_includes:[parsing] "Loc";
168       ocaml_Module  "Warning";
169       ocaml_IModule "EmptyError";
170       ocaml_IModule "EmptyPrinter";
171       ocaml_IModule "Token";
172       ocaml_Lexer ~includes:[utils] ~ext_includes:[parsing] ~pp:"" "Lexer";
173       ocaml_PackageDir "Grammar" (lazy [
174         ocaml_Module "Context";
175         ocaml_Module "Structure";
176         ocaml_Module "Search";
177         ocaml_Module "Tools";
178         ocaml_IModule "Print";
179         ocaml_Module "Failed";
180         ocaml_Module "Parser";
181         ocaml_IModule "Fold";
182         ocaml_Module "Insert";
183         ocaml_Module "Delete";
184         ocaml_Module "Entry";
185         ocaml_Module "Find";
186         ocaml_Module "Dynamic";
187         ocaml_Module "Static"
188       ]);
189       ocaml_Module "Quotation";
190       ocaml_IModule ~ext_includes:[dynlink] "DynLoader";
191       ocaml_Module_with_genmap ~flags:"-w z -warn-error z" "Camlp4Ast";
192       ocaml_IModule "FreeVars";
193       ocaml_Module "AstFilters";
194       ocaml_IModule ~ext_includes:[parsing] "Camlp4Ast2OCamlAst";
195       ocaml_Module "CleanAst";
196       ocaml_IModule "CommentFilter";
197     ]);
198     ocaml_Module "OCamlInitSyntax";
199     ocaml_PackageDir "Printers" (lazy [
200       ocaml_IModule "Null";
201       ocaml_IModule "DumpOCamlAst";
202       ocaml_IModule "DumpCamlp4Ast";
203       ocaml_IModule "OCaml";
204       ocaml_IModule "OCamlr" ~flags:"-w v -warn-error v";
205       (* ocaml_IModule "OCamlrr"; *)
206     ]);
207     ocaml_IModule "PreCast";
208     ocaml_IModule "Register"
209   ])
210
211 let camlp4_parsers =
212   ocaml_PackageDir "Camlp4Parsers" (lazy [
213     ocaml_Module "OCamlr";
214     ocaml_Module "OCaml";
215     (* ocaml_Module "OCamlrr"; *)
216     ocaml_Module "OCamlQuotationBase";
217     ocaml_Module "OCamlQuotation";
218     ocaml_Module "OCamlRevisedQuotation";
219     ocaml_Module "OCamlOriginalQuotation";
220     ocaml_Module "OCamlRevisedParser";
221     ocaml_Module "OCamlParser";
222     ocaml_Module "Grammar";
223     ocaml_Module "Macro";
224     ocaml_Module ~o:(options_without_debug ()) "Debug";
225     ocaml_Module "LoadCamlp4Ast";
226   ])
227
228 let camlp4_printers =
229   ocaml_PackageDir "Camlp4Printers" (lazy [
230     ocaml_Module "DumpOCamlAst";
231     ocaml_Module "DumpCamlp4Ast";
232     ocaml_Module "OCaml";
233     ocaml_Module "OCamlr";
234     (* ocaml_Module "OCamlrr"; *)
235     ocaml_Module "Null";
236     ocaml_Module ~ext_includes:[unix] "Auto";
237   ])
238
239 let camlp4_filters =
240   ocaml_PackageDir "Camlp4Filters" (lazy [
241     ocaml_Module "ExceptionTracer";
242     ocaml_Module "Tracer";
243     ocaml_Module "StripLocations";
244     ocaml_Module "LiftCamlp4Ast";
245     ocaml_Module "GenerateMap";
246     ocaml_Module "GenerateFold";
247     ocaml_Module "MetaGenerator";
248     ocaml_Module "RemoveTrashModule";
249     ocaml_Module "Profiler";
250   ])
251
252 let camlp4_top =
253   ocaml_PackageDir "Camlp4Top" (lazy [
254     ocaml_Module ~ext_includes:[toplevel; typing; parsing] "Rprint";
255     ocaml_Module ~ext_includes:[toplevel; parsing; utils] "Camlp4Top";
256   ])
257
258 let split c s =
259   let rec self acc s =
260     try
261       let pos = String.rindex s c in
262       let x = String.sub s 0 pos
263       and y = String.sub s (pos + 1) (String.length s - pos - 1)
264       in self (y :: acc) x
265     with Not_found -> s :: acc
266   in self [] s
267 let chop_end c s =
268   let pos = String.rindex s c in
269   String.sub s (pos + 1) (String.length s - pos - 1)
270 let file ppf f =
271   let cin = open_in f in
272   let rec loop () =
273     pp_print_string ppf (input_line cin);
274     fprintf ppf "@\n";
275     loop ()
276   in try loop () with End_of_file -> ()
277 let ext_split f = split '.' f
278   
279   
280 let print_packed_sources ppf ?(skip = fun _ -> false) package_dir =
281   let _ =
282   fold_units_sources [package_dir] (fun name sources k (skip, inside) ->
283     eprintf "%s: [%s] (%b)@." name (String.concat "; " sources) inside;
284     let name = try chop_end '/' name with Not_found -> name in
285     let k () = ignore (k (skip, true)) in
286     if not inside then k () else (
287       if skip name then fprintf ppf "(**/**)@\n" else fprintf ppf "(** *)@\n";
288       fprintf ppf "@[<2>module %s " name;
289       let (mli, ml, mll, k) =
290         List.fold_right
291           (fun x (mli, ml, mll, k) ->
292             match ext_split x with
293             | [_; "mli"] -> (Some x, ml, mll, k)
294             | [_; "ml"]  -> (mli, Some x, mll, k)
295             | [_; "mll"] -> (mli, ml, Some x, k)
296             | [x; "meta"; "ml"] -> (mli, Some (x^".ml"), mll, fun () -> ())
297             | [x; "genmap"; "ml"] -> (mli, Some (x^".ml"), mll, fun () -> ())
298             | [_; ext] -> failwith ("unknown extension " ^ ext)
299             | _ -> failwith ("bad file "^x))
300           sources (None, None, None, k) in
301       (match (ml, mll, mli) with
302       | (None, None, Some mli) -> fprintf ppf "=@ @[<2>struct@\n"
303       | (_, _, Some mli) -> fprintf ppf ":@,@[<2>sig@\n%a@]@\nend@\n" file mli;
304                             fprintf ppf "=@ @[<2>struct@\n"
305       | _ -> fprintf ppf "=@ @[<2>struct@\n");
306       (match (ml, mll, mli) with
307       | (_, Some mll, _) ->
308             fprintf ppf "(*___CAMLP4_LEXER___ %a ___CAMLP4_LEXER___*)@\n();"
309             file (String.sub mll 0 (String.length mll - 1))
310       | (Some ml, _, _) -> k (); fprintf ppf "%a" file ml
311       | (None, _, Some mli) -> k (); fprintf ppf "%a" file mli
312       | _ -> if sources <> [] then () else k ());
313       fprintf ppf "@]@\nend;@]@\n";
314       if skip name then fprintf ppf "(**/**)@\n";
315     );
316     (skip, inside)
317   ) (skip, false) in fprintf ppf "@."
318
319 let run l =
320   let cmd = String.concat " " l in
321   let () = Format.printf "%s@." cmd in
322   let st = YaM.call cmd in
323   if st <> 0 then failwith ("Exit: " ^ string_of_int st)
324
325 let sed re str file =
326   run ["sed"; "-i"; "-e"; "'s/"^re^"/"^str^"/'"; file]
327
328 let pack () =
329   let revised_to_ocaml f =
330     run ["./boot/camlp4boot -printer OCaml -o "^f^".ml -impl "^f^".ml4"] in
331   let ppf_of_file f = formatter_of_out_channel (open_out f) in
332   let skip_struct = function "Struct" -> true | _ -> false in
333   print_packed_sources (ppf_of_file "Camlp4.ml4")
334                        ~skip:skip_struct camlp4_package_as_one_dir;
335   print_packed_sources (ppf_of_file "Camlp4Parsers.ml4") camlp4_parsers;
336   print_packed_sources (ppf_of_file "Camlp4Printers.ml4") camlp4_printers;
337   print_packed_sources (ppf_of_file "Camlp4Filters.ml4") camlp4_filters;
338   print_packed_sources (ppf_of_file "Camlp4Top.ml4") camlp4_top;
339   revised_to_ocaml "Camlp4";
340   sed "(\\*___CAMLP4_LEXER___" "" "Camlp4.ml";
341   sed "___CAMLP4_LEXER___\\*)" "" "Camlp4.ml";
342   sed "^ *# [0-9]\\+.*$" "" "Camlp4.ml";
343   revised_to_ocaml "Camlp4Parsers";
344   revised_to_ocaml "Camlp4Printers";
345   revised_to_ocaml "Camlp4Filters";
346   revised_to_ocaml "Camlp4Top"
347
348 let just_doc () =
349   run ["cd doc && ../../ocamldoc/ocamldoc";
350        "-v -short-functors -html";
351        "-I ../../parsing -I ../build -I ../../utils -I ..";
352        "-dump ocamldoc.out";
353        "-t 'Camlp4 a Pre-Processor-Pretty-Printer for Objective Caml'";
354        "../Camlp4.ml"; "../Camlp4Parsers.ml"; "../Camlp4Printers.ml";
355        "../Camlp4Filters.ml"; "../Camlp4Top.ml"]
356
357 let doc () =
358   pack (); just_doc ()
359