tests: abort on failure
[sqlgg.git] / setup.ml
blob64c51d527e840f8a742d14a4a9c5d6fc1965aa37
1 (* setup.ml generated for the first time by OASIS v0.4.4 *)
3 (* OASIS_START *)
4 (* DO NOT EDIT (digest: f55c42a432dba945721fbef9c77fbc59) *)
5 (*
6 Regenerated by OASIS v0.4.11
7 Visit http://oasis.forge.ocamlcore.org for more information and
8 documentation about functions used in this file.
9 *)
10 module OASISGettext = struct
11 (* # 22 "src/oasis/OASISGettext.ml" *)
14 let ns_ str = str
15 let s_ str = str
16 let f_ (str: ('a, 'b, 'c, 'd) format4) = str
19 let fn_ fmt1 fmt2 n =
20 if n = 1 then
21 fmt1^^""
22 else
23 fmt2^^""
26 let init = []
27 end
29 module OASISString = struct
30 (* # 22 "src/oasis/OASISString.ml" *)
33 (** Various string utilities.
35 Mostly inspired by extlib and batteries ExtString and BatString libraries.
37 @author Sylvain Le Gall
41 let nsplitf str f =
42 if str = "" then
44 else
45 let buf = Buffer.create 13 in
46 let lst = ref [] in
47 let push () =
48 lst := Buffer.contents buf :: !lst;
49 Buffer.clear buf
51 let str_len = String.length str in
52 for i = 0 to str_len - 1 do
53 if f str.[i] then
54 push ()
55 else
56 Buffer.add_char buf str.[i]
57 done;
58 push ();
59 List.rev !lst
62 (** [nsplit c s] Split the string [s] at char [c]. It doesn't include the
63 separator.
65 let nsplit str c =
66 nsplitf str ((=) c)
69 let find ~what ?(offset=0) str =
70 let what_idx = ref 0 in
71 let str_idx = ref offset in
72 while !str_idx < String.length str &&
73 !what_idx < String.length what do
74 if str.[!str_idx] = what.[!what_idx] then
75 incr what_idx
76 else
77 what_idx := 0;
78 incr str_idx
79 done;
80 if !what_idx <> String.length what then
81 raise Not_found
82 else
83 !str_idx - !what_idx
86 let sub_start str len =
87 let str_len = String.length str in
88 if len >= str_len then
90 else
91 String.sub str len (str_len - len)
94 let sub_end ?(offset=0) str len =
95 let str_len = String.length str in
96 if len >= str_len then
98 else
99 String.sub str 0 (str_len - len)
102 let starts_with ~what ?(offset=0) str =
103 let what_idx = ref 0 in
104 let str_idx = ref offset in
105 let ok = ref true in
106 while !ok &&
107 !str_idx < String.length str &&
108 !what_idx < String.length what do
109 if str.[!str_idx] = what.[!what_idx] then
110 incr what_idx
111 else
112 ok := false;
113 incr str_idx
114 done;
115 !what_idx = String.length what
118 let strip_starts_with ~what str =
119 if starts_with ~what str then
120 sub_start str (String.length what)
121 else
122 raise Not_found
125 let ends_with ~what ?(offset=0) str =
126 let what_idx = ref ((String.length what) - 1) in
127 let str_idx = ref ((String.length str) - 1) in
128 let ok = ref true in
129 while !ok &&
130 offset <= !str_idx &&
131 0 <= !what_idx do
132 if str.[!str_idx] = what.[!what_idx] then
133 decr what_idx
134 else
135 ok := false;
136 decr str_idx
137 done;
138 !what_idx = -1
141 let strip_ends_with ~what str =
142 if ends_with ~what str then
143 sub_end str (String.length what)
144 else
145 raise Not_found
148 let replace_chars f s =
149 let buf = Buffer.create (String.length s) in
150 String.iter (fun c -> Buffer.add_char buf (f c)) s;
151 Buffer.contents buf
153 let lowercase_ascii =
154 replace_chars
155 (fun c ->
156 if (c >= 'A' && c <= 'Z') then
157 Char.chr (Char.code c + 32)
158 else
161 let uncapitalize_ascii s =
162 if s <> "" then
163 (lowercase_ascii (String.sub s 0 1)) ^ (String.sub s 1 ((String.length s) - 1))
164 else
167 let uppercase_ascii =
168 replace_chars
169 (fun c ->
170 if (c >= 'a' && c <= 'z') then
171 Char.chr (Char.code c - 32)
172 else
175 let capitalize_ascii s =
176 if s <> "" then
177 (uppercase_ascii (String.sub s 0 1)) ^ (String.sub s 1 ((String.length s) - 1))
178 else
183 module OASISUtils = struct
184 (* # 22 "src/oasis/OASISUtils.ml" *)
187 open OASISGettext
190 module MapExt =
191 struct
192 module type S =
194 include Map.S
195 val add_list: 'a t -> (key * 'a) list -> 'a t
196 val of_list: (key * 'a) list -> 'a t
197 val to_list: 'a t -> (key * 'a) list
200 module Make (Ord: Map.OrderedType) =
201 struct
202 include Map.Make(Ord)
204 let rec add_list t =
205 function
206 | (k, v) :: tl -> add_list (add k v t) tl
207 | [] -> t
209 let of_list lst = add_list empty lst
211 let to_list t = fold (fun k v acc -> (k, v) :: acc) t []
216 module MapString = MapExt.Make(String)
219 module SetExt =
220 struct
221 module type S =
223 include Set.S
224 val add_list: t -> elt list -> t
225 val of_list: elt list -> t
226 val to_list: t -> elt list
229 module Make (Ord: Set.OrderedType) =
230 struct
231 include Set.Make(Ord)
233 let rec add_list t =
234 function
235 | e :: tl -> add_list (add e t) tl
236 | [] -> t
238 let of_list lst = add_list empty lst
240 let to_list = elements
245 module SetString = SetExt.Make(String)
248 let compare_csl s1 s2 =
249 String.compare (OASISString.lowercase_ascii s1) (OASISString.lowercase_ascii s2)
252 module HashStringCsl =
253 Hashtbl.Make
254 (struct
255 type t = string
256 let equal s1 s2 = (compare_csl s1 s2) = 0
257 let hash s = Hashtbl.hash (OASISString.lowercase_ascii s)
258 end)
260 module SetStringCsl =
261 SetExt.Make
262 (struct
263 type t = string
264 let compare = compare_csl
265 end)
268 let varname_of_string ?(hyphen='_') s =
269 if String.length s = 0 then
270 begin
271 invalid_arg "varname_of_string"
273 else
274 begin
275 let buf =
276 OASISString.replace_chars
277 (fun c ->
278 if ('a' <= c && c <= 'z')
280 ('A' <= c && c <= 'Z')
282 ('0' <= c && c <= '9') then
284 else
285 hyphen)
288 let buf =
289 (* Start with a _ if digit *)
290 if '0' <= s.[0] && s.[0] <= '9' then
291 "_"^buf
292 else
295 OASISString.lowercase_ascii buf
299 let varname_concat ?(hyphen='_') p s =
300 let what = String.make 1 hyphen in
301 let p =
303 OASISString.strip_ends_with ~what p
304 with Not_found ->
307 let s =
309 OASISString.strip_starts_with ~what s
310 with Not_found ->
313 p^what^s
316 let is_varname str =
317 str = varname_of_string str
320 let failwithf fmt = Printf.ksprintf failwith fmt
323 let rec file_location ?pos1 ?pos2 ?lexbuf () =
324 match pos1, pos2, lexbuf with
325 | Some p, None, _ | None, Some p, _ ->
326 file_location ~pos1:p ~pos2:p ?lexbuf ()
327 | Some p1, Some p2, _ ->
328 let open Lexing in
329 let fn, lineno = p1.pos_fname, p1.pos_lnum in
330 let c1 = p1.pos_cnum - p1.pos_bol in
331 let c2 = c1 + (p2.pos_cnum - p1.pos_cnum) in
332 Printf.sprintf (f_ "file %S, line %d, characters %d-%d") fn lineno c1 c2
333 | _, _, Some lexbuf ->
334 file_location
335 ~pos1:(Lexing.lexeme_start_p lexbuf)
336 ~pos2:(Lexing.lexeme_end_p lexbuf)
338 | None, None, None ->
339 s_ "<position undefined>"
342 let failwithpf ?pos1 ?pos2 ?lexbuf fmt =
343 let loc = file_location ?pos1 ?pos2 ?lexbuf () in
344 Printf.ksprintf (fun s -> failwith (Printf.sprintf "%s: %s" loc s)) fmt
349 module OASISUnixPath = struct
350 (* # 22 "src/oasis/OASISUnixPath.ml" *)
353 type unix_filename = string
354 type unix_dirname = string
357 type host_filename = string
358 type host_dirname = string
361 let current_dir_name = "."
364 let parent_dir_name = ".."
367 let is_current_dir fn =
368 fn = current_dir_name || fn = ""
371 let concat f1 f2 =
372 if is_current_dir f1 then
374 else
375 let f1' =
376 try OASISString.strip_ends_with ~what:"/" f1 with Not_found -> f1
378 f1'^"/"^f2
381 let make =
382 function
383 | hd :: tl ->
384 List.fold_left
385 (fun f p -> concat f p)
388 | [] ->
389 invalid_arg "OASISUnixPath.make"
392 let dirname f =
394 String.sub f 0 (String.rindex f '/')
395 with Not_found ->
396 current_dir_name
399 let basename f =
401 let pos_start =
402 (String.rindex f '/') + 1
404 String.sub f pos_start ((String.length f) - pos_start)
405 with Not_found ->
409 let chop_extension f =
411 let last_dot =
412 String.rindex f '.'
414 let sub =
415 String.sub f 0 last_dot
418 let last_slash =
419 String.rindex f '/'
421 if last_slash < last_dot then
423 else
425 with Not_found ->
428 with Not_found ->
432 let capitalize_file f =
433 let dir = dirname f in
434 let base = basename f in
435 concat dir (OASISString.capitalize_ascii base)
438 let uncapitalize_file f =
439 let dir = dirname f in
440 let base = basename f in
441 concat dir (OASISString.uncapitalize_ascii base)
446 module OASISHostPath = struct
447 (* # 22 "src/oasis/OASISHostPath.ml" *)
450 open Filename
451 open OASISGettext
454 module Unix = OASISUnixPath
457 let make =
458 function
459 | [] ->
460 invalid_arg "OASISHostPath.make"
461 | hd :: tl ->
462 List.fold_left Filename.concat hd tl
465 let of_unix ufn =
466 match Sys.os_type with
467 | "Unix" | "Cygwin" -> ufn
468 | "Win32" ->
469 make
470 (List.map
471 (fun p ->
472 if p = Unix.current_dir_name then
473 current_dir_name
474 else if p = Unix.parent_dir_name then
475 parent_dir_name
476 else
478 (OASISString.nsplit ufn '/'))
479 | os_type ->
480 OASISUtils.failwithf
481 (f_ "Don't know the path format of os_type %S when translating unix \
482 filename. %S")
483 os_type ufn
488 module OASISFileSystem = struct
489 (* # 22 "src/oasis/OASISFileSystem.ml" *)
491 (** File System functions
493 @author Sylvain Le Gall
496 type 'a filename = string
498 class type closer =
499 object
500 method close: unit
503 class type reader =
504 object
505 inherit closer
506 method input: Buffer.t -> int -> unit
509 class type writer =
510 object
511 inherit closer
512 method output: Buffer.t -> unit
515 class type ['a] fs =
516 object
517 method string_of_filename: 'a filename -> string
518 method open_out: ?mode:(open_flag list) -> ?perm:int -> 'a filename -> writer
519 method open_in: ?mode:(open_flag list) -> ?perm:int -> 'a filename -> reader
520 method file_exists: 'a filename -> bool
521 method remove: 'a filename -> unit
525 module Mode =
526 struct
527 let default_in = [Open_rdonly]
528 let default_out = [Open_wronly; Open_creat; Open_trunc]
530 let text_in = Open_text :: default_in
531 let text_out = Open_text :: default_out
533 let binary_in = Open_binary :: default_in
534 let binary_out = Open_binary :: default_out
537 let std_length = 4096 (* Standard buffer/read length. *)
538 let binary_out = Mode.binary_out
539 let binary_in = Mode.binary_in
541 let of_unix_filename ufn = (ufn: 'a filename)
542 let to_unix_filename fn = (fn: string)
545 let defer_close o f =
547 let r = f o in o#close; r
548 with e ->
549 o#close; raise e
552 let stream_of_reader rdr =
553 let buf = Buffer.create std_length in
554 let pos = ref 0 in
555 let eof = ref false in
556 let rec next idx =
557 let bpos = idx - !pos in
558 if !eof then begin
559 None
560 end else if bpos < Buffer.length buf then begin
561 Some (Buffer.nth buf bpos)
562 end else begin
563 pos := !pos + Buffer.length buf;
564 Buffer.clear buf;
565 begin
567 rdr#input buf std_length;
568 with End_of_file ->
569 if Buffer.length buf = 0 then
570 eof := true
571 end;
572 next idx
575 Stream.from next
578 let read_all buf rdr =
580 while true do
581 rdr#input buf std_length
582 done
583 with End_of_file ->
586 class ['a] host_fs rootdir : ['a] fs =
587 object (self)
588 method private host_filename fn = Filename.concat rootdir fn
589 method string_of_filename = self#host_filename
591 method open_out ?(mode=Mode.text_out) ?(perm=0o666) fn =
592 let chn = open_out_gen mode perm (self#host_filename fn) in
593 object
594 method close = close_out chn
595 method output buf = Buffer.output_buffer chn buf
598 method open_in ?(mode=Mode.text_in) ?(perm=0o666) fn =
599 (* TODO: use Buffer.add_channel when minimal version of OCaml will
600 * be >= 4.03.0 (previous version was discarding last chars).
602 let chn = open_in_gen mode perm (self#host_filename fn) in
603 let strm = Stream.of_channel chn in
604 object
605 method close = close_in chn
606 method input buf len =
607 let read = ref 0 in
609 for _i = 0 to len do
610 Buffer.add_char buf (Stream.next strm);
611 incr read
612 done
613 with Stream.Failure ->
614 if !read = 0 then
615 raise End_of_file
618 method file_exists fn = Sys.file_exists (self#host_filename fn)
619 method remove fn = Sys.remove (self#host_filename fn)
624 module OASISContext = struct
625 (* # 22 "src/oasis/OASISContext.ml" *)
628 open OASISGettext
631 type level =
632 [ `Debug
633 | `Info
634 | `Warning
635 | `Error]
638 type source
639 type source_filename = source OASISFileSystem.filename
642 let in_srcdir ufn = OASISFileSystem.of_unix_filename ufn
645 type t =
647 (* TODO: replace this by a proplist. *)
648 quiet: bool;
649 info: bool;
650 debug: bool;
651 ignore_plugins: bool;
652 ignore_unknown_fields: bool;
653 printf: level -> string -> unit;
654 srcfs: source OASISFileSystem.fs;
655 load_oasis_plugin: string -> bool;
659 let printf lvl str =
660 let beg =
661 match lvl with
662 | `Error -> s_ "E: "
663 | `Warning -> s_ "W: "
664 | `Info -> s_ "I: "
665 | `Debug -> s_ "D: "
667 prerr_endline (beg^str)
670 let default =
673 quiet = false;
674 info = false;
675 debug = false;
676 ignore_plugins = false;
677 ignore_unknown_fields = false;
678 printf = printf;
679 srcfs = new OASISFileSystem.host_fs(Sys.getcwd ());
680 load_oasis_plugin = (fun _ -> false);
684 let quiet =
685 {!default with quiet = true}
688 let fspecs () =
689 (* TODO: don't act on default. *)
690 let ignore_plugins = ref false in
691 ["-quiet",
692 Arg.Unit (fun () -> default := {!default with quiet = true}),
693 s_ " Run quietly";
695 "-info",
696 Arg.Unit (fun () -> default := {!default with info = true}),
697 s_ " Display information message";
700 "-debug",
701 Arg.Unit (fun () -> default := {!default with debug = true}),
702 s_ " Output debug message";
704 "-ignore-plugins",
705 Arg.Set ignore_plugins,
706 s_ " Ignore plugin's field.";
708 "-C",
709 Arg.String
710 (fun str ->
711 Sys.chdir str;
712 default := {!default with srcfs = new OASISFileSystem.host_fs str}),
713 s_ "dir Change directory before running (affects setup.{data,log})."],
714 fun () -> {!default with ignore_plugins = !ignore_plugins}
717 module PropList = struct
718 (* # 22 "src/oasis/PropList.ml" *)
721 open OASISGettext
724 type name = string
727 exception Not_set of name * string option
728 exception No_printer of name
729 exception Unknown_field of name * name
732 let () =
733 Printexc.register_printer
734 (function
735 | Not_set (nm, Some rsn) ->
736 Some
737 (Printf.sprintf (f_ "Field '%s' is not set: %s") nm rsn)
738 | Not_set (nm, None) ->
739 Some
740 (Printf.sprintf (f_ "Field '%s' is not set") nm)
741 | No_printer nm ->
742 Some
743 (Printf.sprintf (f_ "No default printer for value %s") nm)
744 | Unknown_field (nm, schm) ->
745 Some
746 (Printf.sprintf
747 (f_ "Field %s is not defined in schema %s") nm schm)
748 | _ ->
749 None)
752 module Data =
753 struct
754 type t =
755 (name, unit -> unit) Hashtbl.t
757 let create () =
758 Hashtbl.create 13
760 let clear t =
761 Hashtbl.clear t
764 (* # 77 "src/oasis/PropList.ml" *)
768 module Schema =
769 struct
770 type ('ctxt, 'extra) value =
772 get: Data.t -> string;
773 set: Data.t -> ?context:'ctxt -> string -> unit;
774 help: (unit -> string) option;
775 extra: 'extra;
778 type ('ctxt, 'extra) t =
780 name: name;
781 fields: (name, ('ctxt, 'extra) value) Hashtbl.t;
782 order: name Queue.t;
783 name_norm: string -> string;
786 let create ?(case_insensitive=false) nm =
788 name = nm;
789 fields = Hashtbl.create 13;
790 order = Queue.create ();
791 name_norm =
792 (if case_insensitive then
793 OASISString.lowercase_ascii
794 else
795 fun s -> s);
798 let add t nm set get extra help =
799 let key =
800 t.name_norm nm
803 if Hashtbl.mem t.fields key then
804 failwith
805 (Printf.sprintf
806 (f_ "Field '%s' is already defined in schema '%s'")
807 nm t.name);
808 Hashtbl.add
809 t.fields
812 set = set;
813 get = get;
814 help = help;
815 extra = extra;
817 Queue.add nm t.order
819 let mem t nm =
820 Hashtbl.mem t.fields nm
822 let find t nm =
824 Hashtbl.find t.fields (t.name_norm nm)
825 with Not_found ->
826 raise (Unknown_field (nm, t.name))
828 let get t data nm =
829 (find t nm).get data
831 let set t data nm ?context x =
832 (find t nm).set
833 data
834 ?context
837 let fold f acc t =
838 Queue.fold
839 (fun acc k ->
840 let v =
841 find t k
843 f acc k v.extra v.help)
845 t.order
847 let iter f t =
848 fold
849 (fun () -> f)
853 let name t =
854 t.name
858 module Field =
859 struct
860 type ('ctxt, 'value, 'extra) t =
862 set: Data.t -> ?context:'ctxt -> 'value -> unit;
863 get: Data.t -> 'value;
864 sets: Data.t -> ?context:'ctxt -> string -> unit;
865 gets: Data.t -> string;
866 help: (unit -> string) option;
867 extra: 'extra;
870 let new_id =
871 let last_id =
872 ref 0
874 fun () -> incr last_id; !last_id
876 let create ?schema ?name ?parse ?print ?default ?update ?help extra =
877 (* Default value container *)
878 let v =
879 ref None
882 (* If name is not given, create unique one *)
883 let nm =
884 match name with
885 | Some s -> s
886 | None -> Printf.sprintf "_anon_%d" (new_id ())
889 (* Last chance to get a value: the default *)
890 let default () =
891 match default with
892 | Some d -> d
893 | None -> raise (Not_set (nm, Some (s_ "no default value")))
896 (* Get data *)
897 let get data =
898 (* Get value *)
900 (Hashtbl.find data nm) ();
901 match !v with
902 | Some x -> x
903 | None -> default ()
904 with Not_found ->
905 default ()
908 (* Set data *)
909 let set data ?context x =
910 let x =
911 match update with
912 | Some f ->
913 begin
915 f ?context (get data) x
916 with Not_set _ ->
919 | None ->
922 Hashtbl.replace
923 data
925 (fun () -> v := Some x)
928 (* Parse string value, if possible *)
929 let parse =
930 match parse with
931 | Some f ->
933 | None ->
934 fun ?context s ->
935 failwith
936 (Printf.sprintf
937 (f_ "Cannot parse field '%s' when setting value %S")
942 (* Set data, from string *)
943 let sets data ?context s =
944 set ?context data (parse ?context s)
947 (* Output value as string, if possible *)
948 let print =
949 match print with
950 | Some f ->
952 | None ->
953 fun _ -> raise (No_printer nm)
956 (* Get data, as a string *)
957 let gets data =
958 print (get data)
961 begin
962 match schema with
963 | Some t ->
964 Schema.add t nm sets gets extra help
965 | None ->
967 end;
970 set = set;
971 get = get;
972 sets = sets;
973 gets = gets;
974 help = help;
975 extra = extra;
978 let fset data t ?context x =
979 t.set data ?context x
981 let fget data t =
982 t.get data
984 let fsets data t ?context s =
985 t.sets data ?context s
987 let fgets data t =
988 t.gets data
992 module FieldRO =
993 struct
994 let create ?schema ?name ?parse ?print ?default ?update ?help extra =
995 let fld =
996 Field.create ?schema ?name ?parse ?print ?default ?update ?help extra
998 fun data -> Field.fget data fld
1002 module OASISMessage = struct
1003 (* # 22 "src/oasis/OASISMessage.ml" *)
1006 open OASISGettext
1007 open OASISContext
1010 let generic_message ~ctxt lvl fmt =
1011 let cond =
1012 if ctxt.quiet then
1013 false
1014 else
1015 match lvl with
1016 | `Debug -> ctxt.debug
1017 | `Info -> ctxt.info
1018 | _ -> true
1020 Printf.ksprintf
1021 (fun str ->
1022 if cond then
1023 begin
1024 ctxt.printf lvl str
1025 end)
1029 let debug ~ctxt fmt =
1030 generic_message ~ctxt `Debug fmt
1033 let info ~ctxt fmt =
1034 generic_message ~ctxt `Info fmt
1037 let warning ~ctxt fmt =
1038 generic_message ~ctxt `Warning fmt
1041 let error ~ctxt fmt =
1042 generic_message ~ctxt `Error fmt
1046 module OASISVersion = struct
1047 (* # 22 "src/oasis/OASISVersion.ml" *)
1050 open OASISGettext
1053 type t = string
1056 type comparator =
1057 | VGreater of t
1058 | VGreaterEqual of t
1059 | VEqual of t
1060 | VLesser of t
1061 | VLesserEqual of t
1062 | VOr of comparator * comparator
1063 | VAnd of comparator * comparator
1066 (* Range of allowed characters *)
1067 let is_digit c = '0' <= c && c <= '9'
1068 let is_alpha c = ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z')
1069 let is_special = function | '.' | '+' | '-' | '~' -> true | _ -> false
1072 let rec version_compare v1 v2 =
1073 if v1 <> "" || v2 <> "" then
1074 begin
1075 (* Compare ascii string, using special meaning for version
1076 * related char
1078 let val_ascii c =
1079 if c = '~' then -1
1080 else if is_digit c then 0
1081 else if c = '\000' then 0
1082 else if is_alpha c then Char.code c
1083 else (Char.code c) + 256
1086 let len1 = String.length v1 in
1087 let len2 = String.length v2 in
1089 let p = ref 0 in
1091 (** Compare ascii part *)
1092 let compare_vascii () =
1093 let cmp = ref 0 in
1094 while !cmp = 0 &&
1095 !p < len1 && !p < len2 &&
1096 not (is_digit v1.[!p] && is_digit v2.[!p]) do
1097 cmp := (val_ascii v1.[!p]) - (val_ascii v2.[!p]);
1098 incr p
1099 done;
1100 if !cmp = 0 && !p < len1 && !p = len2 then
1101 val_ascii v1.[!p]
1102 else if !cmp = 0 && !p = len1 && !p < len2 then
1103 - (val_ascii v2.[!p])
1104 else
1105 !cmp
1108 (** Compare digit part *)
1109 let compare_digit () =
1110 let extract_int v p =
1111 let start_p = !p in
1112 while !p < String.length v && is_digit v.[!p] do
1113 incr p
1114 done;
1115 let substr =
1116 String.sub v !p ((String.length v) - !p)
1118 let res =
1119 match String.sub v start_p (!p - start_p) with
1120 | "" -> 0
1121 | s -> int_of_string s
1123 res, substr
1125 let i1, tl1 = extract_int v1 (ref !p) in
1126 let i2, tl2 = extract_int v2 (ref !p) in
1127 i1 - i2, tl1, tl2
1130 match compare_vascii () with
1131 | 0 ->
1132 begin
1133 match compare_digit () with
1134 | 0, tl1, tl2 ->
1135 if tl1 <> "" && is_digit tl1.[0] then
1137 else if tl2 <> "" && is_digit tl2.[0] then
1139 else
1140 version_compare tl1 tl2
1141 | n, _, _ ->
1144 | n ->
1147 else begin
1152 let version_of_string str = str
1155 let string_of_version t = t
1158 let chop t =
1160 let pos =
1161 String.rindex t '.'
1163 String.sub t 0 pos
1164 with Not_found ->
1168 let rec comparator_apply v op =
1169 match op with
1170 | VGreater cv ->
1171 (version_compare v cv) > 0
1172 | VGreaterEqual cv ->
1173 (version_compare v cv) >= 0
1174 | VLesser cv ->
1175 (version_compare v cv) < 0
1176 | VLesserEqual cv ->
1177 (version_compare v cv) <= 0
1178 | VEqual cv ->
1179 (version_compare v cv) = 0
1180 | VOr (op1, op2) ->
1181 (comparator_apply v op1) || (comparator_apply v op2)
1182 | VAnd (op1, op2) ->
1183 (comparator_apply v op1) && (comparator_apply v op2)
1186 let rec string_of_comparator =
1187 function
1188 | VGreater v -> "> "^(string_of_version v)
1189 | VEqual v -> "= "^(string_of_version v)
1190 | VLesser v -> "< "^(string_of_version v)
1191 | VGreaterEqual v -> ">= "^(string_of_version v)
1192 | VLesserEqual v -> "<= "^(string_of_version v)
1193 | VOr (c1, c2) ->
1194 (string_of_comparator c1)^" || "^(string_of_comparator c2)
1195 | VAnd (c1, c2) ->
1196 (string_of_comparator c1)^" && "^(string_of_comparator c2)
1199 let rec varname_of_comparator =
1200 let concat p v =
1201 OASISUtils.varname_concat
1203 (OASISUtils.varname_of_string
1204 (string_of_version v))
1206 function
1207 | VGreater v -> concat "gt" v
1208 | VLesser v -> concat "lt" v
1209 | VEqual v -> concat "eq" v
1210 | VGreaterEqual v -> concat "ge" v
1211 | VLesserEqual v -> concat "le" v
1212 | VOr (c1, c2) ->
1213 (varname_of_comparator c1)^"_or_"^(varname_of_comparator c2)
1214 | VAnd (c1, c2) ->
1215 (varname_of_comparator c1)^"_and_"^(varname_of_comparator c2)
1220 module OASISLicense = struct
1221 (* # 22 "src/oasis/OASISLicense.ml" *)
1224 (** License for _oasis fields
1225 @author Sylvain Le Gall
1229 type license = string
1230 type license_exception = string
1233 type license_version =
1234 | Version of OASISVersion.t
1235 | VersionOrLater of OASISVersion.t
1236 | NoVersion
1239 type license_dep_5_unit =
1241 license: license;
1242 excption: license_exception option;
1243 version: license_version;
1247 type license_dep_5 =
1248 | DEP5Unit of license_dep_5_unit
1249 | DEP5Or of license_dep_5 list
1250 | DEP5And of license_dep_5 list
1253 type t =
1254 | DEP5License of license_dep_5
1255 | OtherLicense of string (* URL *)
1260 module OASISExpr = struct
1261 (* # 22 "src/oasis/OASISExpr.ml" *)
1264 open OASISGettext
1265 open OASISUtils
1268 type test = string
1269 type flag = string
1272 type t =
1273 | EBool of bool
1274 | ENot of t
1275 | EAnd of t * t
1276 | EOr of t * t
1277 | EFlag of flag
1278 | ETest of test * string
1281 type 'a choices = (t * 'a) list
1284 let eval var_get t =
1285 let rec eval' =
1286 function
1287 | EBool b ->
1290 | ENot e ->
1291 not (eval' e)
1293 | EAnd (e1, e2) ->
1294 (eval' e1) && (eval' e2)
1296 | EOr (e1, e2) ->
1297 (eval' e1) || (eval' e2)
1299 | EFlag nm ->
1300 let v =
1301 var_get nm
1303 assert(v = "true" || v = "false");
1304 (v = "true")
1306 | ETest (nm, vl) ->
1307 let v =
1308 var_get nm
1310 (v = vl)
1312 eval' t
1315 let choose ?printer ?name var_get lst =
1316 let rec choose_aux =
1317 function
1318 | (cond, vl) :: tl ->
1319 if eval var_get cond then
1321 else
1322 choose_aux tl
1323 | [] ->
1324 let str_lst =
1325 if lst = [] then
1326 s_ "<empty>"
1327 else
1328 String.concat
1329 (s_ ", ")
1330 (List.map
1331 (fun (cond, vl) ->
1332 match printer with
1333 | Some p -> p vl
1334 | None -> s_ "<no printer>")
1335 lst)
1337 match name with
1338 | Some nm ->
1339 failwith
1340 (Printf.sprintf
1341 (f_ "No result for the choice list '%s': %s")
1342 nm str_lst)
1343 | None ->
1344 failwith
1345 (Printf.sprintf
1346 (f_ "No result for a choice list: %s")
1347 str_lst)
1349 choose_aux (List.rev lst)
1354 module OASISText = struct
1355 (* # 22 "src/oasis/OASISText.ml" *)
1357 type elt =
1358 | Para of string
1359 | Verbatim of string
1360 | BlankLine
1362 type t = elt list
1366 module OASISSourcePatterns = struct
1367 (* # 22 "src/oasis/OASISSourcePatterns.ml" *)
1369 open OASISUtils
1370 open OASISGettext
1372 module Templater =
1373 struct
1374 (* TODO: use this module in BaseEnv.var_expand and BaseFileAB, at least. *)
1375 type t =
1377 atoms: atom list;
1378 origin: string
1380 and atom =
1381 | Text of string
1382 | Expr of expr
1383 and expr =
1384 | Ident of string
1385 | String of string
1386 | Call of string * expr
1389 type env =
1391 variables: string MapString.t;
1392 functions: (string -> string) MapString.t;
1396 let eval env t =
1397 let rec eval_expr env =
1398 function
1399 | String str -> str
1400 | Ident nm ->
1401 begin
1403 MapString.find nm env.variables
1404 with Not_found ->
1405 (* TODO: add error location within the string. *)
1406 failwithf
1407 (f_ "Unable to find variable %S in source pattern %S")
1408 nm t.origin
1411 | Call (fn, expr) ->
1412 begin
1414 (MapString.find fn env.functions) (eval_expr env expr)
1415 with Not_found ->
1416 (* TODO: add error location within the string. *)
1417 failwithf
1418 (f_ "Unable to find function %S in source pattern %S")
1419 fn t.origin
1422 String.concat ""
1423 (List.map
1424 (function
1425 | Text str -> str
1426 | Expr expr -> eval_expr env expr)
1427 t.atoms)
1430 let parse env s =
1431 let lxr = Genlex.make_lexer [] in
1432 let parse_expr s =
1433 let st = lxr (Stream.of_string s) in
1434 match Stream.npeek 3 st with
1435 | [Genlex.Ident fn; Genlex.Ident nm] -> Call(fn, Ident nm)
1436 | [Genlex.Ident fn; Genlex.String str] -> Call(fn, String str)
1437 | [Genlex.String str] -> String str
1438 | [Genlex.Ident nm] -> Ident nm
1439 (* TODO: add error location within the string. *)
1440 | _ -> failwithf (f_ "Unable to parse expression %S") s
1442 let parse s =
1443 let lst_exprs = ref [] in
1444 let ss =
1445 let buff = Buffer.create (String.length s) in
1446 Buffer.add_substitute
1447 buff
1448 (fun s -> lst_exprs := (parse_expr s) :: !lst_exprs; "\000")
1450 Buffer.contents buff
1452 let rec join =
1453 function
1454 | hd1 :: tl1, hd2 :: tl2 -> Text hd1 :: Expr hd2 :: join (tl1, tl2)
1455 | [], tl -> List.map (fun e -> Expr e) tl
1456 | tl, [] -> List.map (fun e -> Text e) tl
1458 join (OASISString.nsplit ss '\000', List.rev (!lst_exprs))
1460 let t = {atoms = parse s; origin = s} in
1461 (* We rely on a simple evaluation for checking variables/functions.
1462 It works because there is no if/loop statement.
1464 let _s : string = eval env t in
1467 (* # 144 "src/oasis/OASISSourcePatterns.ml" *)
1471 type t = Templater.t
1474 let env ~modul () =
1476 Templater.
1477 variables = MapString.of_list ["module", modul];
1478 functions = MapString.of_list
1480 "capitalize_file", OASISUnixPath.capitalize_file;
1481 "uncapitalize_file", OASISUnixPath.uncapitalize_file;
1485 let all_possible_files lst ~path ~modul =
1486 let eval = Templater.eval (env ~modul ()) in
1487 List.fold_left
1488 (fun acc pat -> OASISUnixPath.concat path (eval pat) :: acc)
1489 [] lst
1492 let to_string t = t.Templater.origin
1497 module OASISTypes = struct
1498 (* # 22 "src/oasis/OASISTypes.ml" *)
1501 type name = string
1502 type package_name = string
1503 type url = string
1504 type unix_dirname = string
1505 type unix_filename = string (* TODO: replace everywhere. *)
1506 type host_dirname = string (* TODO: replace everywhere. *)
1507 type host_filename = string (* TODO: replace everywhere. *)
1508 type prog = string
1509 type arg = string
1510 type args = string list
1511 type command_line = (prog * arg list)
1514 type findlib_name = string
1515 type findlib_full = string
1518 type compiled_object =
1519 | Byte
1520 | Native
1521 | Best
1524 type dependency =
1525 | FindlibPackage of findlib_full * OASISVersion.comparator option
1526 | InternalLibrary of name
1529 type tool =
1530 | ExternalTool of name
1531 | InternalExecutable of name
1534 type vcs =
1535 | Darcs
1536 | Git
1537 | Svn
1538 | Cvs
1539 | Hg
1540 | Bzr
1541 | Arch
1542 | Monotone
1543 | OtherVCS of url
1546 type plugin_kind =
1547 [ `Configure
1548 | `Build
1549 | `Doc
1550 | `Test
1551 | `Install
1552 | `Extra
1556 type plugin_data_purpose =
1557 [ `Configure
1558 | `Build
1559 | `Install
1560 | `Clean
1561 | `Distclean
1562 | `Install
1563 | `Uninstall
1564 | `Test
1565 | `Doc
1566 | `Extra
1567 | `Other of string
1571 type 'a plugin = 'a * name * OASISVersion.t option
1574 type all_plugin = plugin_kind plugin
1577 type plugin_data = (all_plugin * plugin_data_purpose * (unit -> unit)) list
1580 type 'a conditional = 'a OASISExpr.choices
1583 type custom =
1585 pre_command: (command_line option) conditional;
1586 post_command: (command_line option) conditional;
1590 type common_section =
1592 cs_name: name;
1593 cs_data: PropList.Data.t;
1594 cs_plugin_data: plugin_data;
1598 type build_section =
1600 bs_build: bool conditional;
1601 bs_install: bool conditional;
1602 bs_path: unix_dirname;
1603 bs_compiled_object: compiled_object;
1604 bs_build_depends: dependency list;
1605 bs_build_tools: tool list;
1606 bs_interface_patterns: OASISSourcePatterns.t list;
1607 bs_implementation_patterns: OASISSourcePatterns.t list;
1608 bs_c_sources: unix_filename list;
1609 bs_data_files: (unix_filename * unix_filename option) list;
1610 bs_findlib_extra_files: unix_filename list;
1611 bs_ccopt: args conditional;
1612 bs_cclib: args conditional;
1613 bs_dlllib: args conditional;
1614 bs_dllpath: args conditional;
1615 bs_byteopt: args conditional;
1616 bs_nativeopt: args conditional;
1620 type library =
1622 lib_modules: string list;
1623 lib_pack: bool;
1624 lib_internal_modules: string list;
1625 lib_findlib_parent: findlib_name option;
1626 lib_findlib_name: findlib_name option;
1627 lib_findlib_directory: unix_dirname option;
1628 lib_findlib_containers: findlib_name list;
1632 type object_ =
1634 obj_modules: string list;
1635 obj_findlib_fullname: findlib_name list option;
1636 obj_findlib_directory: unix_dirname option;
1640 type executable =
1642 exec_custom: bool;
1643 exec_main_is: unix_filename;
1647 type flag =
1649 flag_description: string option;
1650 flag_default: bool conditional;
1654 type source_repository =
1656 src_repo_type: vcs;
1657 src_repo_location: url;
1658 src_repo_browser: url option;
1659 src_repo_module: string option;
1660 src_repo_branch: string option;
1661 src_repo_tag: string option;
1662 src_repo_subdir: unix_filename option;
1666 type test =
1668 test_type: [`Test] plugin;
1669 test_command: command_line conditional;
1670 test_custom: custom;
1671 test_working_directory: unix_filename option;
1672 test_run: bool conditional;
1673 test_tools: tool list;
1677 type doc_format =
1678 | HTML of unix_filename (* TODO: source filename. *)
1679 | DocText
1680 | PDF
1681 | PostScript
1682 | Info of unix_filename (* TODO: source filename. *)
1683 | DVI
1684 | OtherDoc
1687 type doc =
1689 doc_type: [`Doc] plugin;
1690 doc_custom: custom;
1691 doc_build: bool conditional;
1692 doc_install: bool conditional;
1693 doc_install_dir: unix_filename; (* TODO: dest filename ?. *)
1694 doc_title: string;
1695 doc_authors: string list;
1696 doc_abstract: string option;
1697 doc_format: doc_format;
1698 (* TODO: src filename. *)
1699 doc_data_files: (unix_filename * unix_filename option) list;
1700 doc_build_tools: tool list;
1704 type section =
1705 | Library of common_section * build_section * library
1706 | Object of common_section * build_section * object_
1707 | Executable of common_section * build_section * executable
1708 | Flag of common_section * flag
1709 | SrcRepo of common_section * source_repository
1710 | Test of common_section * test
1711 | Doc of common_section * doc
1714 type section_kind =
1715 [ `Library | `Object | `Executable | `Flag | `SrcRepo | `Test | `Doc ]
1718 type package =
1720 oasis_version: OASISVersion.t;
1721 ocaml_version: OASISVersion.comparator option;
1722 findlib_version: OASISVersion.comparator option;
1723 alpha_features: string list;
1724 beta_features: string list;
1725 name: package_name;
1726 version: OASISVersion.t;
1727 license: OASISLicense.t;
1728 license_file: unix_filename option; (* TODO: source filename. *)
1729 copyrights: string list;
1730 maintainers: string list;
1731 authors: string list;
1732 homepage: url option;
1733 bugreports: url option;
1734 synopsis: string;
1735 description: OASISText.t option;
1736 tags: string list;
1737 categories: url list;
1739 conf_type: [`Configure] plugin;
1740 conf_custom: custom;
1742 build_type: [`Build] plugin;
1743 build_custom: custom;
1745 install_type: [`Install] plugin;
1746 install_custom: custom;
1747 uninstall_custom: custom;
1749 clean_custom: custom;
1750 distclean_custom: custom;
1752 files_ab: unix_filename list; (* TODO: source filename. *)
1753 sections: section list;
1754 plugins: [`Extra] plugin list;
1755 disable_oasis_section: unix_filename list; (* TODO: source filename. *)
1756 schema_data: PropList.Data.t;
1757 plugin_data: plugin_data;
1763 module OASISFeatures = struct
1764 (* # 22 "src/oasis/OASISFeatures.ml" *)
1766 open OASISTypes
1767 open OASISUtils
1768 open OASISGettext
1769 open OASISVersion
1771 module MapPlugin =
1772 Map.Make
1773 (struct
1774 type t = plugin_kind * name
1775 let compare = Pervasives.compare
1776 end)
1778 module Data =
1779 struct
1780 type t =
1782 oasis_version: OASISVersion.t;
1783 plugin_versions: OASISVersion.t option MapPlugin.t;
1784 alpha_features: string list;
1785 beta_features: string list;
1788 let create oasis_version alpha_features beta_features =
1790 oasis_version = oasis_version;
1791 plugin_versions = MapPlugin.empty;
1792 alpha_features = alpha_features;
1793 beta_features = beta_features
1796 let of_package pkg =
1797 create
1798 pkg.OASISTypes.oasis_version
1799 pkg.OASISTypes.alpha_features
1800 pkg.OASISTypes.beta_features
1802 let add_plugin (plugin_kind, plugin_name, plugin_version) t =
1803 {t with
1804 plugin_versions = MapPlugin.add
1805 (plugin_kind, plugin_name)
1806 plugin_version
1807 t.plugin_versions}
1809 let plugin_version plugin_kind plugin_name t =
1810 MapPlugin.find (plugin_kind, plugin_name) t.plugin_versions
1812 let to_string t =
1813 Printf.sprintf
1814 "oasis_version: %s; alpha_features: %s; beta_features: %s; \
1815 plugins_version: %s"
1816 (OASISVersion.string_of_version (t:t).oasis_version)
1817 (String.concat ", " t.alpha_features)
1818 (String.concat ", " t.beta_features)
1819 (String.concat ", "
1820 (MapPlugin.fold
1821 (fun (_, plg) ver_opt acc ->
1822 (plg^
1823 (match ver_opt with
1824 | Some v ->
1825 " "^(OASISVersion.string_of_version v)
1826 | None -> ""))
1827 :: acc)
1828 t.plugin_versions []))
1831 type origin =
1832 | Field of string * string
1833 | Section of string
1834 | NoOrigin
1836 type stage = Alpha | Beta
1839 let string_of_stage =
1840 function
1841 | Alpha -> "alpha"
1842 | Beta -> "beta"
1845 let field_of_stage =
1846 function
1847 | Alpha -> "AlphaFeatures"
1848 | Beta -> "BetaFeatures"
1850 type publication = InDev of stage | SinceVersion of OASISVersion.t
1852 type t =
1854 name: string;
1855 plugin: all_plugin option;
1856 publication: publication;
1857 description: unit -> string;
1860 (* TODO: mutex protect this. *)
1861 let all_features = Hashtbl.create 13
1864 let since_version ver_str = SinceVersion (version_of_string ver_str)
1865 let alpha = InDev Alpha
1866 let beta = InDev Beta
1869 let to_string t =
1870 Printf.sprintf
1871 "feature: %s; plugin: %s; publication: %s"
1872 (t:t).name
1873 (match t.plugin with
1874 | None -> "<none>"
1875 | Some (_, nm, _) -> nm)
1876 (match t.publication with
1877 | InDev stage -> string_of_stage stage
1878 | SinceVersion ver -> ">= "^(OASISVersion.string_of_version ver))
1880 let data_check t data origin =
1881 let no_message = "no message" in
1883 let check_feature features stage =
1884 let has_feature = List.mem (t:t).name features in
1885 if not has_feature then
1886 match (origin:origin) with
1887 | Field (fld, where) ->
1888 Some
1889 (Printf.sprintf
1890 (f_ "Field %s in %s is only available when feature %s \
1891 is in field %s.")
1892 fld where t.name (field_of_stage stage))
1893 | Section sct ->
1894 Some
1895 (Printf.sprintf
1896 (f_ "Section %s is only available when features %s \
1897 is in field %s.")
1898 sct t.name (field_of_stage stage))
1899 | NoOrigin ->
1900 Some no_message
1901 else
1902 None
1905 let version_is_good ~min_version version fmt =
1906 let version_is_good =
1907 OASISVersion.comparator_apply
1908 version (OASISVersion.VGreaterEqual min_version)
1910 Printf.ksprintf
1911 (fun str -> if version_is_good then None else Some str)
1915 match origin, t.plugin, t.publication with
1916 | _, _, InDev Alpha -> check_feature data.Data.alpha_features Alpha
1917 | _, _, InDev Beta -> check_feature data.Data.beta_features Beta
1918 | Field(fld, where), None, SinceVersion min_version ->
1919 version_is_good ~min_version data.Data.oasis_version
1920 (f_ "Field %s in %s is only valid since OASIS v%s, update \
1921 OASISFormat field from '%s' to '%s' after checking \
1922 OASIS changelog.")
1923 fld where (string_of_version min_version)
1924 (string_of_version data.Data.oasis_version)
1925 (string_of_version min_version)
1927 | Field(fld, where), Some(plugin_knd, plugin_name, _),
1928 SinceVersion min_version ->
1929 begin
1931 let plugin_version_current =
1933 match Data.plugin_version plugin_knd plugin_name data with
1934 | Some ver -> ver
1935 | None ->
1936 failwithf
1937 (f_ "Field %s in %s is only valid for the OASIS \
1938 plugin %s since v%s, but no plugin version is \
1939 defined in the _oasis file, change '%s' to \
1940 '%s (%s)' in your _oasis file.")
1941 fld where plugin_name (string_of_version min_version)
1942 plugin_name
1943 plugin_name (string_of_version min_version)
1944 with Not_found ->
1945 failwithf
1946 (f_ "Field %s in %s is only valid when the OASIS plugin %s \
1947 is defined.")
1948 fld where plugin_name
1950 version_is_good ~min_version plugin_version_current
1951 (f_ "Field %s in %s is only valid for the OASIS plugin %s \
1952 since v%s, update your plugin from '%s (%s)' to \
1953 '%s (%s)' after checking the plugin's changelog.")
1954 fld where plugin_name (string_of_version min_version)
1955 plugin_name (string_of_version plugin_version_current)
1956 plugin_name (string_of_version min_version)
1957 with Failure msg ->
1958 Some msg
1961 | Section sct, None, SinceVersion min_version ->
1962 version_is_good ~min_version data.Data.oasis_version
1963 (f_ "Section %s is only valid for since OASIS v%s, update \
1964 OASISFormat field from '%s' to '%s' after checking OASIS \
1965 changelog.")
1966 sct (string_of_version min_version)
1967 (string_of_version data.Data.oasis_version)
1968 (string_of_version min_version)
1970 | Section sct, Some(plugin_knd, plugin_name, _),
1971 SinceVersion min_version ->
1972 begin
1974 let plugin_version_current =
1976 match Data.plugin_version plugin_knd plugin_name data with
1977 | Some ver -> ver
1978 | None ->
1979 failwithf
1980 (f_ "Section %s is only valid for the OASIS \
1981 plugin %s since v%s, but no plugin version is \
1982 defined in the _oasis file, change '%s' to \
1983 '%s (%s)' in your _oasis file.")
1984 sct plugin_name (string_of_version min_version)
1985 plugin_name
1986 plugin_name (string_of_version min_version)
1987 with Not_found ->
1988 failwithf
1989 (f_ "Section %s is only valid when the OASIS plugin %s \
1990 is defined.")
1991 sct plugin_name
1993 version_is_good ~min_version plugin_version_current
1994 (f_ "Section %s is only valid for the OASIS plugin %s \
1995 since v%s, update your plugin from '%s (%s)' to \
1996 '%s (%s)' after checking the plugin's changelog.")
1997 sct plugin_name (string_of_version min_version)
1998 plugin_name (string_of_version plugin_version_current)
1999 plugin_name (string_of_version min_version)
2000 with Failure msg ->
2001 Some msg
2004 | NoOrigin, None, SinceVersion min_version ->
2005 version_is_good ~min_version data.Data.oasis_version "%s" no_message
2007 | NoOrigin, Some(plugin_knd, plugin_name, _), SinceVersion min_version ->
2008 begin
2010 let plugin_version_current =
2011 match Data.plugin_version plugin_knd plugin_name data with
2012 | Some ver -> ver
2013 | None -> raise Not_found
2015 version_is_good ~min_version plugin_version_current
2016 "%s" no_message
2017 with Not_found ->
2018 Some no_message
2022 let data_assert t data origin =
2023 match data_check t data origin with
2024 | None -> ()
2025 | Some str -> failwith str
2028 let data_test t data =
2029 match data_check t data NoOrigin with
2030 | None -> true
2031 | Some _ -> false
2034 let package_test t pkg =
2035 data_test t (Data.of_package pkg)
2038 let create ?plugin name publication description =
2039 let () =
2040 if Hashtbl.mem all_features name then
2041 failwithf "Feature '%s' is already declared." name
2043 let t =
2045 name = name;
2046 plugin = plugin;
2047 publication = publication;
2048 description = description;
2051 Hashtbl.add all_features name t;
2055 let get_stage name =
2057 (Hashtbl.find all_features name).publication
2058 with Not_found ->
2059 failwithf (f_ "Feature %s doesn't exist.") name
2062 let list () =
2063 Hashtbl.fold (fun _ v acc -> v :: acc) all_features []
2066 * Real flags.
2070 let features =
2071 create "features_fields"
2072 (since_version "0.4")
2073 (fun () ->
2074 s_ "Enable to experiment not yet official features.")
2077 let flag_docs =
2078 create "flag_docs"
2079 (since_version "0.3")
2080 (fun () ->
2081 s_ "Make building docs require '-docs' flag at configure.")
2084 let flag_tests =
2085 create "flag_tests"
2086 (since_version "0.3")
2087 (fun () ->
2088 s_ "Make running tests require '-tests' flag at configure.")
2091 let pack =
2092 create "pack"
2093 (since_version "0.3")
2094 (fun () ->
2095 s_ "Allow to create packed library.")
2098 let section_object =
2099 create "section_object" beta
2100 (fun () ->
2101 s_ "Implement an object section.")
2104 let dynrun_for_release =
2105 create "dynrun_for_release" alpha
2106 (fun () ->
2107 s_ "Make '-setup-update dynamic' suitable for releasing project.")
2110 let compiled_setup_ml =
2111 create "compiled_setup_ml" alpha
2112 (fun () ->
2113 s_ "Compile the setup.ml and speed-up actions done with it.")
2115 let disable_oasis_section =
2116 create "disable_oasis_section" alpha
2117 (fun () ->
2118 s_ "Allow the OASIS section comments and digests to be omitted in \
2119 generated files.")
2121 let no_automatic_syntax =
2122 create "no_automatic_syntax" alpha
2123 (fun () ->
2124 s_ "Disable the automatic inclusion of -syntax camlp4o for packages \
2125 that matches the internal heuristic (if a dependency ends with \
2126 a .syntax or is a well known syntax).")
2128 let findlib_directory =
2129 create "findlib_directory" beta
2130 (fun () ->
2131 s_ "Allow to install findlib libraries in sub-directories of the target \
2132 findlib directory.")
2134 let findlib_extra_files =
2135 create "findlib_extra_files" beta
2136 (fun () ->
2137 s_ "Allow to install extra files for findlib libraries.")
2139 let source_patterns =
2140 create "source_patterns" alpha
2141 (fun () ->
2142 s_ "Customize mapping between module name and source file.")
2145 module OASISSection = struct
2146 (* # 22 "src/oasis/OASISSection.ml" *)
2149 open OASISTypes
2152 let section_kind_common =
2153 function
2154 | Library (cs, _, _) ->
2155 `Library, cs
2156 | Object (cs, _, _) ->
2157 `Object, cs
2158 | Executable (cs, _, _) ->
2159 `Executable, cs
2160 | Flag (cs, _) ->
2161 `Flag, cs
2162 | SrcRepo (cs, _) ->
2163 `SrcRepo, cs
2164 | Test (cs, _) ->
2165 `Test, cs
2166 | Doc (cs, _) ->
2167 `Doc, cs
2170 let section_common sct =
2171 snd (section_kind_common sct)
2174 let section_common_set cs =
2175 function
2176 | Library (_, bs, lib) -> Library (cs, bs, lib)
2177 | Object (_, bs, obj) -> Object (cs, bs, obj)
2178 | Executable (_, bs, exec) -> Executable (cs, bs, exec)
2179 | Flag (_, flg) -> Flag (cs, flg)
2180 | SrcRepo (_, src_repo) -> SrcRepo (cs, src_repo)
2181 | Test (_, tst) -> Test (cs, tst)
2182 | Doc (_, doc) -> Doc (cs, doc)
2185 (** Key used to identify section
2187 let section_id sct =
2188 let k, cs =
2189 section_kind_common sct
2191 k, cs.cs_name
2194 let string_of_section_kind =
2195 function
2196 | `Library -> "library"
2197 | `Object -> "object"
2198 | `Executable -> "executable"
2199 | `Flag -> "flag"
2200 | `SrcRepo -> "src repository"
2201 | `Test -> "test"
2202 | `Doc -> "doc"
2205 let string_of_section sct =
2206 let k, nm = section_id sct in
2207 (string_of_section_kind k)^" "^nm
2210 let section_find id scts =
2211 List.find
2212 (fun sct -> id = section_id sct)
2213 scts
2216 module CSection =
2217 struct
2218 type t = section
2220 let id = section_id
2222 let compare t1 t2 =
2223 compare (id t1) (id t2)
2225 let equal t1 t2 =
2226 (id t1) = (id t2)
2228 let hash t =
2229 Hashtbl.hash (id t)
2233 module MapSection = Map.Make(CSection)
2234 module SetSection = Set.Make(CSection)
2239 module OASISBuildSection = struct
2240 (* # 22 "src/oasis/OASISBuildSection.ml" *)
2242 open OASISTypes
2244 (* Look for a module file, considering capitalization or not. *)
2245 let find_module source_file_exists bs modul =
2246 let possible_lst =
2247 OASISSourcePatterns.all_possible_files
2248 (bs.bs_interface_patterns @ bs.bs_implementation_patterns)
2249 ~path:bs.bs_path
2250 ~modul
2252 match List.filter source_file_exists possible_lst with
2253 | (fn :: _) as fn_lst -> `Sources (OASISUnixPath.chop_extension fn, fn_lst)
2254 | [] ->
2255 let open OASISUtils in
2256 let _, rev_lst =
2257 List.fold_left
2258 (fun (set, acc) fn ->
2259 let base_fn = OASISUnixPath.chop_extension fn in
2260 if SetString.mem base_fn set then
2261 set, acc
2262 else
2263 SetString.add base_fn set, base_fn :: acc)
2264 (SetString.empty, []) possible_lst
2266 `No_sources (List.rev rev_lst)
2271 module OASISExecutable = struct
2272 (* # 22 "src/oasis/OASISExecutable.ml" *)
2275 open OASISTypes
2278 let unix_exec_is (cs, bs, exec) is_native ext_dll suffix_program =
2279 let dir =
2280 OASISUnixPath.concat
2281 bs.bs_path
2282 (OASISUnixPath.dirname exec.exec_main_is)
2284 let is_native_exec =
2285 match bs.bs_compiled_object with
2286 | Native -> true
2287 | Best -> is_native ()
2288 | Byte -> false
2291 OASISUnixPath.concat
2293 (cs.cs_name^(suffix_program ())),
2295 if not is_native_exec &&
2296 not exec.exec_custom &&
2297 bs.bs_c_sources <> [] then
2298 Some (dir^"/dll"^cs.cs_name^"_stubs"^(ext_dll ()))
2299 else
2300 None
2305 module OASISLibrary = struct
2306 (* # 22 "src/oasis/OASISLibrary.ml" *)
2309 open OASISTypes
2310 open OASISGettext
2312 let find_module ~ctxt source_file_exists cs bs modul =
2313 match OASISBuildSection.find_module source_file_exists bs modul with
2314 | `Sources _ as res -> res
2315 | `No_sources _ as res ->
2316 OASISMessage.warning
2317 ~ctxt
2318 (f_ "Cannot find source file matching module '%s' in library %s.")
2319 modul cs.cs_name;
2320 OASISMessage.warning
2321 ~ctxt
2322 (f_ "Use InterfacePatterns or ImplementationPatterns to define \
2323 this file with feature %S.")
2324 (OASISFeatures.source_patterns.OASISFeatures.name);
2327 let source_unix_files ~ctxt (cs, bs, lib) source_file_exists =
2328 List.fold_left
2329 (fun acc modul ->
2330 match find_module ~ctxt source_file_exists cs bs modul with
2331 | `Sources (base_fn, lst) -> (base_fn, lst) :: acc
2332 | `No_sources _ -> acc)
2334 (lib.lib_modules @ lib.lib_internal_modules)
2337 let generated_unix_files
2338 ~ctxt
2339 ~is_native
2340 ~has_native_dynlink
2341 ~ext_lib
2342 ~ext_dll
2343 ~source_file_exists
2344 (cs, bs, lib) =
2346 let find_modules lst ext =
2347 let find_module modul =
2348 match find_module ~ctxt source_file_exists cs bs modul with
2349 | `Sources (_, [fn]) when ext <> "cmi"
2350 && Filename.check_suffix fn ".mli" ->
2351 None (* No implementation files for pure interface. *)
2352 | `Sources (base_fn, _) -> Some [base_fn]
2353 | `No_sources lst -> Some lst
2355 List.fold_left
2356 (fun acc nm ->
2357 match find_module nm with
2358 | None -> acc
2359 | Some base_fns ->
2360 List.map (fun base_fn -> base_fn ^"."^ext) base_fns :: acc)
2365 (* The .cmx that be compiled along *)
2366 let cmxs =
2367 let should_be_built =
2368 match bs.bs_compiled_object with
2369 | Native -> true
2370 | Best -> is_native
2371 | Byte -> false
2373 if should_be_built then
2374 if lib.lib_pack then
2375 find_modules
2376 [cs.cs_name]
2377 "cmx"
2378 else
2379 find_modules
2380 (lib.lib_modules @ lib.lib_internal_modules)
2381 "cmx"
2382 else
2386 let acc_nopath =
2390 (* The headers and annot/cmt files that should be compiled along *)
2391 let headers =
2392 let sufx =
2393 if lib.lib_pack
2394 then [".cmti"; ".cmt"; ".annot"]
2395 else [".cmi"; ".cmti"; ".cmt"; ".annot"]
2397 List.map
2398 (List.fold_left
2399 (fun accu s ->
2400 let dot = String.rindex s '.' in
2401 let base = String.sub s 0 dot in
2402 List.map ((^) base) sufx @ accu)
2404 (find_modules lib.lib_modules "cmi")
2407 (* Compute what libraries should be built *)
2408 let acc_nopath =
2409 (* Add the packed header file if required *)
2410 let add_pack_header acc =
2411 if lib.lib_pack then
2412 [cs.cs_name^".cmi"; cs.cs_name^".cmti"; cs.cs_name^".cmt"] :: acc
2413 else
2416 let byte acc =
2417 add_pack_header ([cs.cs_name^".cma"] :: acc)
2419 let native acc =
2420 let acc =
2421 add_pack_header
2422 (if has_native_dynlink then
2423 [cs.cs_name^".cmxs"] :: acc
2424 else acc)
2426 [cs.cs_name^".cmxa"] :: [cs.cs_name^ext_lib] :: acc
2428 match bs.bs_compiled_object with
2429 | Native -> byte (native acc_nopath)
2430 | Best when is_native -> byte (native acc_nopath)
2431 | Byte | Best -> byte acc_nopath
2434 (* Add C library to be built *)
2435 let acc_nopath =
2436 if bs.bs_c_sources <> [] then begin
2437 ["lib"^cs.cs_name^"_stubs"^ext_lib]
2439 if has_native_dynlink then
2440 ["dll"^cs.cs_name^"_stubs"^ext_dll] :: acc_nopath
2441 else
2442 acc_nopath
2443 end else begin
2444 acc_nopath
2448 (* All the files generated *)
2449 List.rev_append
2450 (List.rev_map
2451 (List.rev_map
2452 (OASISUnixPath.concat bs.bs_path))
2453 acc_nopath)
2454 (headers @ cmxs)
2459 module OASISObject = struct
2460 (* # 22 "src/oasis/OASISObject.ml" *)
2463 open OASISTypes
2464 open OASISGettext
2467 let find_module ~ctxt source_file_exists cs bs modul =
2468 match OASISBuildSection.find_module source_file_exists bs modul with
2469 | `Sources _ as res -> res
2470 | `No_sources _ as res ->
2471 OASISMessage.warning
2472 ~ctxt
2473 (f_ "Cannot find source file matching module '%s' in object %s.")
2474 modul cs.cs_name;
2475 OASISMessage.warning
2476 ~ctxt
2477 (f_ "Use InterfacePatterns or ImplementationPatterns to define \
2478 this file with feature %S.")
2479 (OASISFeatures.source_patterns.OASISFeatures.name);
2482 let source_unix_files ~ctxt (cs, bs, obj) source_file_exists =
2483 List.fold_left
2484 (fun acc modul ->
2485 match find_module ~ctxt source_file_exists cs bs modul with
2486 | `Sources (base_fn, lst) -> (base_fn, lst) :: acc
2487 | `No_sources _ -> acc)
2489 obj.obj_modules
2492 let generated_unix_files
2493 ~ctxt
2494 ~is_native
2495 ~source_file_exists
2496 (cs, bs, obj) =
2498 let find_module ext modul =
2499 match find_module ~ctxt source_file_exists cs bs modul with
2500 | `Sources (base_fn, _) -> [base_fn ^ ext]
2501 | `No_sources lst -> lst
2504 let header, byte, native, c_object, f =
2505 match obj.obj_modules with
2506 | [ m ] -> (find_module ".cmi" m,
2507 find_module ".cmo" m,
2508 find_module ".cmx" m,
2509 find_module ".o" m,
2510 fun x -> x)
2511 | _ -> ([cs.cs_name ^ ".cmi"],
2512 [cs.cs_name ^ ".cmo"],
2513 [cs.cs_name ^ ".cmx"],
2514 [cs.cs_name ^ ".o"],
2515 OASISUnixPath.concat bs.bs_path)
2517 List.map (List.map f) (
2518 match bs.bs_compiled_object with
2519 | Native ->
2520 native :: c_object :: byte :: header :: []
2521 | Best when is_native ->
2522 native :: c_object :: byte :: header :: []
2523 | Byte | Best ->
2524 byte :: header :: [])
2529 module OASISFindlib = struct
2530 (* # 22 "src/oasis/OASISFindlib.ml" *)
2533 open OASISTypes
2534 open OASISUtils
2535 open OASISGettext
2538 type library_name = name
2539 type findlib_part_name = name
2540 type 'a map_of_findlib_part_name = 'a OASISUtils.MapString.t
2543 exception InternalLibraryNotFound of library_name
2544 exception FindlibPackageNotFound of findlib_name
2547 type group_t =
2548 | Container of findlib_name * group_t list
2549 | Package of (findlib_name *
2550 common_section *
2551 build_section *
2552 [`Library of library | `Object of object_] *
2553 unix_dirname option *
2554 group_t list)
2557 type data = common_section *
2558 build_section *
2559 [`Library of library | `Object of object_]
2560 type tree =
2561 | Node of (data option) * (tree MapString.t)
2562 | Leaf of data
2565 let findlib_mapping pkg =
2566 (* Map from library name to either full findlib name or parts + parent. *)
2567 let fndlb_parts_of_lib_name =
2568 let fndlb_parts cs lib =
2569 let name =
2570 match lib.lib_findlib_name with
2571 | Some nm -> nm
2572 | None -> cs.cs_name
2574 let name =
2575 String.concat "." (lib.lib_findlib_containers @ [name])
2577 name
2579 List.fold_left
2580 (fun mp ->
2581 function
2582 | Library (cs, _, lib) ->
2583 begin
2584 let lib_name = cs.cs_name in
2585 let fndlb_parts = fndlb_parts cs lib in
2586 if MapString.mem lib_name mp then
2587 failwithf
2588 (f_ "The library name '%s' is used more than once.")
2589 lib_name;
2590 match lib.lib_findlib_parent with
2591 | Some lib_name_parent ->
2592 MapString.add
2593 lib_name
2594 (`Unsolved (lib_name_parent, fndlb_parts))
2596 | None ->
2597 MapString.add
2598 lib_name
2599 (`Solved fndlb_parts)
2603 | Object (cs, _, obj) ->
2604 begin
2605 let obj_name = cs.cs_name in
2606 if MapString.mem obj_name mp then
2607 failwithf
2608 (f_ "The object name '%s' is used more than once.")
2609 obj_name;
2610 let findlib_full_name = match obj.obj_findlib_fullname with
2611 | Some ns -> String.concat "." ns
2612 | None -> obj_name
2614 MapString.add
2615 obj_name
2616 (`Solved findlib_full_name)
2620 | Executable _ | Test _ | Flag _ | SrcRepo _ | Doc _ ->
2622 MapString.empty
2623 pkg.sections
2626 (* Solve the above graph to be only library name to full findlib name. *)
2627 let fndlb_name_of_lib_name =
2628 let rec solve visited mp lib_name lib_name_child =
2629 if SetString.mem lib_name visited then
2630 failwithf
2631 (f_ "Library '%s' is involved in a cycle \
2632 with regard to findlib naming.")
2633 lib_name;
2634 let visited = SetString.add lib_name visited in
2636 match MapString.find lib_name mp with
2637 | `Solved fndlb_nm ->
2638 fndlb_nm, mp
2639 | `Unsolved (lib_nm_parent, post_fndlb_nm) ->
2640 let pre_fndlb_nm, mp =
2641 solve visited mp lib_nm_parent lib_name
2643 let fndlb_nm = pre_fndlb_nm^"."^post_fndlb_nm in
2644 fndlb_nm, MapString.add lib_name (`Solved fndlb_nm) mp
2645 with Not_found ->
2646 failwithf
2647 (f_ "Library '%s', which is defined as the findlib parent of \
2648 library '%s', doesn't exist.")
2649 lib_name lib_name_child
2651 let mp =
2652 MapString.fold
2653 (fun lib_name status mp ->
2654 match status with
2655 | `Solved _ ->
2656 (* Solved initialy, no need to go further *)
2658 | `Unsolved _ ->
2659 let _, mp = solve SetString.empty mp lib_name "<none>" in
2661 fndlb_parts_of_lib_name
2662 fndlb_parts_of_lib_name
2664 MapString.map
2665 (function
2666 | `Solved fndlb_nm -> fndlb_nm
2667 | `Unsolved _ -> assert false)
2671 (* Convert an internal library name to a findlib name. *)
2672 let findlib_name_of_library_name lib_nm =
2674 MapString.find lib_nm fndlb_name_of_lib_name
2675 with Not_found ->
2676 raise (InternalLibraryNotFound lib_nm)
2679 (* Add a library to the tree.
2681 let add sct mp =
2682 let fndlb_fullname =
2683 let cs, _, _ = sct in
2684 let lib_name = cs.cs_name in
2685 findlib_name_of_library_name lib_name
2687 let rec add_children nm_lst (children: tree MapString.t) =
2688 match nm_lst with
2689 | (hd :: tl) ->
2690 begin
2691 let node =
2693 add_node tl (MapString.find hd children)
2694 with Not_found ->
2695 (* New node *)
2696 new_node tl
2698 MapString.add hd node children
2700 | [] ->
2701 (* Should not have a nameless library. *)
2702 assert false
2703 and add_node tl node =
2704 if tl = [] then
2705 begin
2706 match node with
2707 | Node (None, children) ->
2708 Node (Some sct, children)
2709 | Leaf (cs', _, _) | Node (Some (cs', _, _), _) ->
2710 (* TODO: allow to merge Package, i.e.
2711 * archive(byte) = "foo.cma foo_init.cmo"
2713 let cs, _, _ = sct in
2714 failwithf
2715 (f_ "Library '%s' and '%s' have the same findlib name '%s'")
2716 cs.cs_name cs'.cs_name fndlb_fullname
2718 else
2719 begin
2720 match node with
2721 | Leaf data ->
2722 Node (Some data, add_children tl MapString.empty)
2723 | Node (data_opt, children) ->
2724 Node (data_opt, add_children tl children)
2726 and new_node =
2727 function
2728 | [] ->
2729 Leaf sct
2730 | hd :: tl ->
2731 Node (None, MapString.add hd (new_node tl) MapString.empty)
2733 add_children (OASISString.nsplit fndlb_fullname '.') mp
2736 let unix_directory dn lib =
2737 let directory =
2738 match lib with
2739 | `Library lib -> lib.lib_findlib_directory
2740 | `Object obj -> obj.obj_findlib_directory
2742 match dn, directory with
2743 | None, None -> None
2744 | None, Some dn | Some dn, None -> Some dn
2745 | Some dn1, Some dn2 -> Some (OASISUnixPath.concat dn1 dn2)
2748 let rec group_of_tree dn mp =
2749 MapString.fold
2750 (fun nm node acc ->
2751 let cur =
2752 match node with
2753 | Node (Some (cs, bs, lib), children) ->
2754 let current_dn = unix_directory dn lib in
2755 Package (nm, cs, bs, lib, current_dn, group_of_tree current_dn children)
2756 | Node (None, children) ->
2757 Container (nm, group_of_tree dn children)
2758 | Leaf (cs, bs, lib) ->
2759 let current_dn = unix_directory dn lib in
2760 Package (nm, cs, bs, lib, current_dn, [])
2762 cur :: acc)
2763 mp []
2766 let group_mp =
2767 List.fold_left
2768 (fun mp ->
2769 function
2770 | Library (cs, bs, lib) ->
2771 add (cs, bs, `Library lib) mp
2772 | Object (cs, bs, obj) ->
2773 add (cs, bs, `Object obj) mp
2774 | _ ->
2776 MapString.empty
2777 pkg.sections
2780 let groups = group_of_tree None group_mp in
2782 let library_name_of_findlib_name =
2783 lazy begin
2784 (* Revert findlib_name_of_library_name. *)
2785 MapString.fold
2786 (fun k v mp -> MapString.add v k mp)
2787 fndlb_name_of_lib_name
2788 MapString.empty
2791 let library_name_of_findlib_name fndlb_nm =
2793 MapString.find fndlb_nm (Lazy.force library_name_of_findlib_name)
2794 with Not_found ->
2795 raise (FindlibPackageNotFound fndlb_nm)
2798 groups,
2799 findlib_name_of_library_name,
2800 library_name_of_findlib_name
2803 let findlib_of_group =
2804 function
2805 | Container (fndlb_nm, _)
2806 | Package (fndlb_nm, _, _, _, _, _) -> fndlb_nm
2809 let root_of_group grp =
2810 let rec root_lib_aux =
2811 (* We do a DFS in the group. *)
2812 function
2813 | Container (_, children) ->
2814 List.fold_left
2815 (fun res grp ->
2816 if res = None then
2817 root_lib_aux grp
2818 else
2819 res)
2820 None
2821 children
2822 | Package (_, cs, bs, lib, _, _) ->
2823 Some (cs, bs, lib)
2825 match root_lib_aux grp with
2826 | Some res ->
2828 | None ->
2829 failwithf
2830 (f_ "Unable to determine root library of findlib library '%s'")
2831 (findlib_of_group grp)
2836 module OASISFlag = struct
2837 (* # 22 "src/oasis/OASISFlag.ml" *)
2842 module OASISPackage = struct
2843 (* # 22 "src/oasis/OASISPackage.ml" *)
2848 module OASISSourceRepository = struct
2849 (* # 22 "src/oasis/OASISSourceRepository.ml" *)
2854 module OASISTest = struct
2855 (* # 22 "src/oasis/OASISTest.ml" *)
2860 module OASISDocument = struct
2861 (* # 22 "src/oasis/OASISDocument.ml" *)
2866 module OASISExec = struct
2867 (* # 22 "src/oasis/OASISExec.ml" *)
2870 open OASISGettext
2871 open OASISUtils
2872 open OASISMessage
2875 (* TODO: I don't like this quote, it is there because $(rm) foo expands to
2876 * 'rm -f' foo...
2878 let run ~ctxt ?f_exit_code ?(quote=true) cmd args =
2879 let cmd =
2880 if quote then
2881 if Sys.os_type = "Win32" then
2882 if String.contains cmd ' ' then
2883 (* Double the 1st double quote... win32... sigh *)
2884 "\""^(Filename.quote cmd)
2885 else
2887 else
2888 Filename.quote cmd
2889 else
2892 let cmdline =
2893 String.concat " " (cmd :: args)
2895 info ~ctxt (f_ "Running command '%s'") cmdline;
2896 match f_exit_code, Sys.command cmdline with
2897 | None, 0 -> ()
2898 | None, i ->
2899 failwithf
2900 (f_ "Command '%s' terminated with error code %d")
2901 cmdline i
2902 | Some f, i ->
2906 let run_read_output ~ctxt ?f_exit_code cmd args =
2907 let fn =
2908 Filename.temp_file "oasis-" ".txt"
2911 begin
2912 let () =
2913 run ~ctxt ?f_exit_code cmd (args @ [">"; Filename.quote fn])
2915 let chn =
2916 open_in fn
2918 let routput =
2919 ref []
2921 begin
2923 while true do
2924 routput := (input_line chn) :: !routput
2925 done
2926 with End_of_file ->
2928 end;
2929 close_in chn;
2930 Sys.remove fn;
2931 List.rev !routput
2933 with e ->
2934 (try Sys.remove fn with _ -> ());
2935 raise e
2938 let run_read_one_line ~ctxt ?f_exit_code cmd args =
2939 match run_read_output ~ctxt ?f_exit_code cmd args with
2940 | [fst] ->
2942 | lst ->
2943 failwithf
2944 (f_ "Command return unexpected output %S")
2945 (String.concat "\n" lst)
2948 module OASISFileUtil = struct
2949 (* # 22 "src/oasis/OASISFileUtil.ml" *)
2952 open OASISGettext
2955 let file_exists_case fn =
2956 let dirname = Filename.dirname fn in
2957 let basename = Filename.basename fn in
2958 if Sys.file_exists dirname then
2959 if basename = Filename.current_dir_name then
2960 true
2961 else
2962 List.mem
2963 basename
2964 (Array.to_list (Sys.readdir dirname))
2965 else
2966 false
2969 let find_file ?(case_sensitive=true) paths exts =
2971 (* Cardinal product of two list *)
2972 let ( * ) lst1 lst2 =
2973 List.flatten
2974 (List.map
2975 (fun a ->
2976 List.map
2977 (fun b -> a, b)
2978 lst2)
2979 lst1)
2982 let rec combined_paths lst =
2983 match lst with
2984 | p1 :: p2 :: tl ->
2985 let acc =
2986 (List.map
2987 (fun (a, b) -> Filename.concat a b)
2988 (p1 * p2))
2990 combined_paths (acc :: tl)
2991 | [e] ->
2993 | [] ->
2997 let alternatives =
2998 List.map
2999 (fun (p, e) ->
3000 if String.length e > 0 && e.[0] <> '.' then
3001 p ^ "." ^ e
3002 else
3003 p ^ e)
3004 ((combined_paths paths) * exts)
3006 List.find (fun file ->
3007 (if case_sensitive then
3008 file_exists_case file
3009 else
3010 Sys.file_exists file)
3011 && not (Sys.is_directory file)
3012 ) alternatives
3015 let which ~ctxt prg =
3016 let path_sep =
3017 match Sys.os_type with
3018 | "Win32" ->
3020 | _ ->
3023 let path_lst = OASISString.nsplit (Sys.getenv "PATH") path_sep in
3024 let exec_ext =
3025 match Sys.os_type with
3026 | "Win32" ->
3027 "" :: (OASISString.nsplit (Sys.getenv "PATHEXT") path_sep)
3028 | _ ->
3029 [""]
3031 find_file ~case_sensitive:false [path_lst; [prg]] exec_ext
3034 (**/**)
3035 let rec fix_dir dn =
3036 (* Windows hack because Sys.file_exists "src\\" = false when
3037 * Sys.file_exists "src" = true
3039 let ln =
3040 String.length dn
3042 if Sys.os_type = "Win32" && ln > 0 && dn.[ln - 1] = '\\' then
3043 fix_dir (String.sub dn 0 (ln - 1))
3044 else
3048 let q = Filename.quote
3049 (**/**)
3052 let cp ~ctxt ?(recurse=false) src tgt =
3053 if recurse then
3054 match Sys.os_type with
3055 | "Win32" ->
3056 OASISExec.run ~ctxt
3057 "xcopy" [q src; q tgt; "/E"]
3058 | _ ->
3059 OASISExec.run ~ctxt
3060 "cp" ["-r"; q src; q tgt]
3061 else
3062 OASISExec.run ~ctxt
3063 (match Sys.os_type with
3064 | "Win32" -> "copy"
3065 | _ -> "cp")
3066 [q src; q tgt]
3069 let mkdir ~ctxt tgt =
3070 OASISExec.run ~ctxt
3071 (match Sys.os_type with
3072 | "Win32" -> "md"
3073 | _ -> "mkdir")
3074 [q tgt]
3077 let rec mkdir_parent ~ctxt f tgt =
3078 let tgt =
3079 fix_dir tgt
3081 if Sys.file_exists tgt then
3082 begin
3083 if not (Sys.is_directory tgt) then
3084 OASISUtils.failwithf
3085 (f_ "Cannot create directory '%s', a file of the same name already \
3086 exists")
3089 else
3090 begin
3091 mkdir_parent ~ctxt f (Filename.dirname tgt);
3092 if not (Sys.file_exists tgt) then
3093 begin
3094 f tgt;
3095 mkdir ~ctxt tgt
3100 let rmdir ~ctxt tgt =
3101 if Sys.readdir tgt = [||] then begin
3102 match Sys.os_type with
3103 | "Win32" ->
3104 OASISExec.run ~ctxt "rd" [q tgt]
3105 | _ ->
3106 OASISExec.run ~ctxt "rm" ["-r"; q tgt]
3107 end else begin
3108 OASISMessage.error ~ctxt
3109 (f_ "Cannot remove directory '%s': not empty.")
3114 let glob ~ctxt fn =
3115 let basename =
3116 Filename.basename fn
3118 if String.length basename >= 2 &&
3119 basename.[0] = '*' &&
3120 basename.[1] = '.' then
3121 begin
3122 let ext_len =
3123 (String.length basename) - 2
3125 let ext =
3126 String.sub basename 2 ext_len
3128 let dirname =
3129 Filename.dirname fn
3131 Array.fold_left
3132 (fun acc fn ->
3134 let fn_ext =
3135 String.sub
3137 ((String.length fn) - ext_len)
3138 ext_len
3140 if fn_ext = ext then
3141 (Filename.concat dirname fn) :: acc
3142 else
3144 with Invalid_argument _ ->
3145 acc)
3147 (Sys.readdir dirname)
3149 else
3150 begin
3151 if file_exists_case fn then
3152 [fn]
3153 else
3159 # 3159 "setup.ml"
3160 module BaseEnvLight = struct
3161 (* # 22 "src/base/BaseEnvLight.ml" *)
3164 module MapString = Map.Make(String)
3167 type t = string MapString.t
3170 let default_filename = Filename.concat (Sys.getcwd ()) "setup.data"
3173 let load ?(allow_empty=false) ?(filename=default_filename) ?stream () =
3174 let line = ref 1 in
3175 let lexer st =
3176 let st_line =
3177 Stream.from
3178 (fun _ ->
3180 match Stream.next st with
3181 | '\n' -> incr line; Some '\n'
3182 | c -> Some c
3183 with Stream.Failure -> None)
3185 Genlex.make_lexer ["="] st_line
3187 let rec read_file lxr mp =
3188 match Stream.npeek 3 lxr with
3189 | [Genlex.Ident nm; Genlex.Kwd "="; Genlex.String value] ->
3190 Stream.junk lxr; Stream.junk lxr; Stream.junk lxr;
3191 read_file lxr (MapString.add nm value mp)
3192 | [] -> mp
3193 | _ ->
3194 failwith
3195 (Printf.sprintf "Malformed data file '%s' line %d" filename !line)
3197 match stream with
3198 | Some st -> read_file (lexer st) MapString.empty
3199 | None ->
3200 if Sys.file_exists filename then begin
3201 let chn = open_in_bin filename in
3202 let st = Stream.of_channel chn in
3204 let mp = read_file (lexer st) MapString.empty in
3205 close_in chn; mp
3206 with e ->
3207 close_in chn; raise e
3208 end else if allow_empty then begin
3209 MapString.empty
3210 end else begin
3211 failwith
3212 (Printf.sprintf
3213 "Unable to load environment, the file '%s' doesn't exist."
3214 filename)
3217 let rec var_expand str env =
3218 let buff = Buffer.create ((String.length str) * 2) in
3219 Buffer.add_substitute
3220 buff
3221 (fun var ->
3223 var_expand (MapString.find var env) env
3224 with Not_found ->
3225 failwith
3226 (Printf.sprintf
3227 "No variable %s defined when trying to expand %S."
3229 str))
3230 str;
3231 Buffer.contents buff
3234 let var_get name env = var_expand (MapString.find name env) env
3235 let var_choose lst env = OASISExpr.choose (fun nm -> var_get nm env) lst
3239 # 3239 "setup.ml"
3240 module BaseContext = struct
3241 (* # 22 "src/base/BaseContext.ml" *)
3243 (* TODO: get rid of this module. *)
3244 open OASISContext
3247 let args () = fst (fspecs ())
3250 let default = default
3254 module BaseMessage = struct
3255 (* # 22 "src/base/BaseMessage.ml" *)
3258 (** Message to user, overrid for Base
3259 @author Sylvain Le Gall
3261 open OASISMessage
3262 open BaseContext
3265 let debug fmt = debug ~ctxt:!default fmt
3268 let info fmt = info ~ctxt:!default fmt
3271 let warning fmt = warning ~ctxt:!default fmt
3274 let error fmt = error ~ctxt:!default fmt
3278 module BaseEnv = struct
3279 (* # 22 "src/base/BaseEnv.ml" *)
3281 open OASISGettext
3282 open OASISUtils
3283 open OASISContext
3284 open PropList
3287 module MapString = BaseEnvLight.MapString
3290 type origin_t =
3291 | ODefault
3292 | OGetEnv
3293 | OFileLoad
3294 | OCommandLine
3297 type cli_handle_t =
3298 | CLINone
3299 | CLIAuto
3300 | CLIWith
3301 | CLIEnable
3302 | CLIUser of (Arg.key * Arg.spec * Arg.doc) list
3305 type definition_t =
3307 hide: bool;
3308 dump: bool;
3309 cli: cli_handle_t;
3310 arg_help: string option;
3311 group: string option;
3315 let schema = Schema.create "environment"
3318 (* Environment data *)
3319 let env = Data.create ()
3322 (* Environment data from file *)
3323 let env_from_file = ref MapString.empty
3326 (* Lexer for var *)
3327 let var_lxr = Genlex.make_lexer []
3330 let rec var_expand str =
3331 let buff =
3332 Buffer.create ((String.length str) * 2)
3334 Buffer.add_substitute
3335 buff
3336 (fun var ->
3338 (* TODO: this is a quick hack to allow calling Test.Command
3339 * without defining executable name really. I.e. if there is
3340 * an exec Executable toto, then $(toto) should be replace
3341 * by its real name. It is however useful to have this function
3342 * for other variable that depend on the host and should be
3343 * written better than that.
3345 let st =
3346 var_lxr (Stream.of_string var)
3348 match Stream.npeek 3 st with
3349 | [Genlex.Ident "utoh"; Genlex.Ident nm] ->
3350 OASISHostPath.of_unix (var_get nm)
3351 | [Genlex.Ident "utoh"; Genlex.String s] ->
3352 OASISHostPath.of_unix s
3353 | [Genlex.Ident "ocaml_escaped"; Genlex.Ident nm] ->
3354 String.escaped (var_get nm)
3355 | [Genlex.Ident "ocaml_escaped"; Genlex.String s] ->
3356 String.escaped s
3357 | [Genlex.Ident nm] ->
3358 var_get nm
3359 | _ ->
3360 failwithf
3361 (f_ "Unknown expression '%s' in variable expansion of %s.")
3364 with
3365 | Unknown_field (_, _) ->
3366 failwithf
3367 (f_ "No variable %s defined when trying to expand %S.")
3370 | Stream.Error e ->
3371 failwithf
3372 (f_ "Syntax error when parsing '%s' when trying to \
3373 expand %S: %s")
3377 str;
3378 Buffer.contents buff
3381 and var_get name =
3382 let vl =
3384 Schema.get schema env name
3385 with Unknown_field _ as e ->
3386 begin
3388 MapString.find name !env_from_file
3389 with Not_found ->
3390 raise e
3393 var_expand vl
3396 let var_choose ?printer ?name lst =
3397 OASISExpr.choose
3398 ?printer
3399 ?name
3400 var_get
3404 let var_protect vl =
3405 let buff =
3406 Buffer.create (String.length vl)
3408 String.iter
3409 (function
3410 | '$' -> Buffer.add_string buff "\\$"
3411 | c -> Buffer.add_char buff c)
3413 Buffer.contents buff
3416 let var_define
3417 ?(hide=false)
3418 ?(dump=true)
3419 ?short_desc
3420 ?(cli=CLINone)
3421 ?arg_help
3422 ?group
3423 name (* TODO: type constraint on the fact that name must be a valid OCaml
3424 id *)
3425 dflt =
3427 let default =
3429 OFileLoad, (fun () -> MapString.find name !env_from_file);
3430 ODefault, dflt;
3431 OGetEnv, (fun () -> Sys.getenv name);
3435 let extra =
3437 hide = hide;
3438 dump = dump;
3439 cli = cli;
3440 arg_help = arg_help;
3441 group = group;
3445 (* Try to find a value that can be defined
3447 let var_get_low lst =
3448 let errors, res =
3449 List.fold_left
3450 (fun (errors, res) (_, v) ->
3451 if res = None then
3452 begin
3454 errors, Some (v ())
3455 with
3456 | Not_found ->
3457 errors, res
3458 | Failure rsn ->
3459 (rsn :: errors), res
3460 | e ->
3461 (Printexc.to_string e) :: errors, res
3463 else
3464 errors, res)
3465 ([], None)
3466 (List.sort
3467 (fun (o1, _) (o2, _) ->
3468 Pervasives.compare o2 o1)
3469 lst)
3471 match res, errors with
3472 | Some v, _ ->
3474 | None, [] ->
3475 raise (Not_set (name, None))
3476 | None, lst ->
3477 raise (Not_set (name, Some (String.concat (s_ ", ") lst)))
3480 let help =
3481 match short_desc with
3482 | Some fs -> Some fs
3483 | None -> None
3486 let var_get_lst =
3487 FieldRO.create
3488 ~schema
3489 ~name
3490 ~parse:(fun ?(context=ODefault) s -> [context, fun () -> s])
3491 ~print:var_get_low
3492 ~default
3493 ~update:(fun ?context:_ x old_x -> x @ old_x)
3494 ?help
3495 extra
3498 fun () ->
3499 var_expand (var_get_low (var_get_lst env))
3502 let var_redefine
3503 ?hide
3504 ?dump
3505 ?short_desc
3506 ?cli
3507 ?arg_help
3508 ?group
3509 name
3510 dflt =
3511 if Schema.mem schema name then
3512 begin
3513 (* TODO: look suspsicious, we want to memorize dflt not dflt () *)
3514 Schema.set schema env ~context:ODefault name (dflt ());
3515 fun () -> var_get name
3517 else
3518 begin
3519 var_define
3520 ?hide
3521 ?dump
3522 ?short_desc
3523 ?cli
3524 ?arg_help
3525 ?group
3526 name
3527 dflt
3531 let var_ignore (_: unit -> string) = ()
3534 let print_hidden =
3535 var_define
3536 ~hide:true
3537 ~dump:false
3538 ~cli:CLIAuto
3539 ~arg_help:"Print even non-printable variable. (debug)"
3540 "print_hidden"
3541 (fun () -> "false")
3544 let var_all () =
3545 List.rev
3546 (Schema.fold
3547 (fun acc nm def _ ->
3548 if not def.hide || bool_of_string (print_hidden ()) then
3549 nm :: acc
3550 else
3551 acc)
3553 schema)
3556 let default_filename = in_srcdir "setup.data"
3559 let load ~ctxt ?(allow_empty=false) ?(filename=default_filename) () =
3560 let open OASISFileSystem in
3561 env_from_file :=
3562 let repr_filename = ctxt.srcfs#string_of_filename filename in
3563 if ctxt.srcfs#file_exists filename then begin
3564 let buf = Buffer.create 13 in
3565 defer_close
3566 (ctxt.srcfs#open_in ~mode:binary_in filename)
3567 (read_all buf);
3568 defer_close
3569 (ctxt.srcfs#open_in ~mode:binary_in filename)
3570 (fun rdr ->
3571 OASISMessage.info ~ctxt "Loading environment from %S." repr_filename;
3572 BaseEnvLight.load ~allow_empty
3573 ~filename:(repr_filename)
3574 ~stream:(stream_of_reader rdr)
3576 end else if allow_empty then begin
3577 BaseEnvLight.MapString.empty
3578 end else begin
3579 failwith
3580 (Printf.sprintf
3581 (f_ "Unable to load environment, the file '%s' doesn't exist.")
3582 repr_filename)
3586 let unload () =
3587 env_from_file := MapString.empty;
3588 Data.clear env
3591 let dump ~ctxt ?(filename=default_filename) () =
3592 let open OASISFileSystem in
3593 defer_close
3594 (ctxt.OASISContext.srcfs#open_out ~mode:binary_out filename)
3595 (fun wrtr ->
3596 let buf = Buffer.create 63 in
3597 let output nm value =
3598 Buffer.add_string buf (Printf.sprintf "%s=%S\n" nm value)
3600 let mp_todo =
3601 (* Dump data from schema *)
3602 Schema.fold
3603 (fun mp_todo nm def _ ->
3604 if def.dump then begin
3606 output nm (Schema.get schema env nm)
3607 with Not_set _ ->
3609 end;
3610 MapString.remove nm mp_todo)
3611 !env_from_file
3612 schema
3614 (* Dump data defined outside of schema *)
3615 MapString.iter output mp_todo;
3616 wrtr#output buf)
3618 let print () =
3619 let printable_vars =
3620 Schema.fold
3621 (fun acc nm def short_descr_opt ->
3622 if not def.hide || bool_of_string (print_hidden ()) then
3623 begin
3625 let value = Schema.get schema env nm in
3626 let txt =
3627 match short_descr_opt with
3628 | Some s -> s ()
3629 | None -> nm
3631 (txt, value) :: acc
3632 with Not_set _ ->
3635 else
3636 acc)
3638 schema
3640 let max_length =
3641 List.fold_left max 0
3642 (List.rev_map String.length
3643 (List.rev_map fst printable_vars))
3645 let dot_pad str = String.make ((max_length - (String.length str)) + 3) '.' in
3646 Printf.printf "\nConfiguration:\n";
3647 List.iter
3648 (fun (name, value) ->
3649 Printf.printf "%s: %s" name (dot_pad name);
3650 if value = "" then
3651 Printf.printf "\n"
3652 else
3653 Printf.printf " %s\n" value)
3654 (List.rev printable_vars);
3655 Printf.printf "\n%!"
3658 let args () =
3659 let arg_concat = OASISUtils.varname_concat ~hyphen:'-' in
3661 "--override",
3662 Arg.Tuple
3664 let rvr = ref ""
3666 let rvl = ref ""
3669 Arg.Set_string rvr;
3670 Arg.Set_string rvl;
3671 Arg.Unit
3672 (fun () ->
3673 Schema.set
3674 schema
3676 ~context:OCommandLine
3677 !rvr
3678 !rvl)
3681 "var+val Override any configuration variable.";
3685 List.flatten
3686 (Schema.fold
3687 (fun acc name def short_descr_opt ->
3688 let var_set s =
3689 Schema.set
3690 schema
3692 ~context:OCommandLine
3693 name
3697 let arg_name =
3698 OASISUtils.varname_of_string ~hyphen:'-' name
3701 let hlp =
3702 match short_descr_opt with
3703 | Some txt -> txt ()
3704 | None -> ""
3707 let arg_hlp =
3708 match def.arg_help with
3709 | Some s -> s
3710 | None -> "str"
3713 let default_value =
3715 Printf.sprintf
3716 (f_ " [%s]")
3717 (Schema.get
3718 schema
3720 name)
3721 with Not_set _ ->
3725 let args =
3726 match def.cli with
3727 | CLINone ->
3729 | CLIAuto ->
3731 arg_concat "--" arg_name,
3732 Arg.String var_set,
3733 Printf.sprintf (f_ "%s %s%s") arg_hlp hlp default_value
3735 | CLIWith ->
3737 arg_concat "--with-" arg_name,
3738 Arg.String var_set,
3739 Printf.sprintf (f_ "%s %s%s") arg_hlp hlp default_value
3741 | CLIEnable ->
3742 let dflt =
3743 if default_value = " [true]" then
3744 s_ " [default: enabled]"
3745 else
3746 s_ " [default: disabled]"
3749 arg_concat "--enable-" arg_name,
3750 Arg.Unit (fun () -> var_set "true"),
3751 Printf.sprintf (f_ " %s%s") hlp dflt;
3753 arg_concat "--disable-" arg_name,
3754 Arg.Unit (fun () -> var_set "false"),
3755 Printf.sprintf (f_ " %s%s") hlp dflt
3757 | CLIUser lst ->
3760 args :: acc)
3762 schema)
3765 module BaseArgExt = struct
3766 (* # 22 "src/base/BaseArgExt.ml" *)
3769 open OASISUtils
3770 open OASISGettext
3773 let parse argv args =
3774 (* Simulate command line for Arg *)
3775 let current =
3776 ref 0
3780 Arg.parse_argv
3781 ~current:current
3782 (Array.concat [[|"none"|]; argv])
3783 (Arg.align args)
3784 (failwithf (f_ "Don't know what to do with arguments: '%s'"))
3785 (s_ "configure options:")
3786 with
3787 | Arg.Help txt ->
3788 print_endline txt;
3789 exit 0
3790 | Arg.Bad txt ->
3791 prerr_endline txt;
3792 exit 1
3795 module BaseCheck = struct
3796 (* # 22 "src/base/BaseCheck.ml" *)
3799 open BaseEnv
3800 open BaseMessage
3801 open OASISUtils
3802 open OASISGettext
3805 let prog_best prg prg_lst =
3806 var_redefine
3808 (fun () ->
3809 let alternate =
3810 List.fold_left
3811 (fun res e ->
3812 match res with
3813 | Some _ ->
3815 | None ->
3817 Some (OASISFileUtil.which ~ctxt:!BaseContext.default e)
3818 with Not_found ->
3819 None)
3820 None
3821 prg_lst
3823 match alternate with
3824 | Some prg -> prg
3825 | None -> raise Not_found)
3828 let prog prg =
3829 prog_best prg [prg]
3832 let prog_opt prg =
3833 prog_best prg [prg^".opt"; prg]
3836 let ocamlfind =
3837 prog "ocamlfind"
3840 let version
3841 var_prefix
3843 fversion
3844 () =
3845 (* Really compare version provided *)
3846 let var =
3847 var_prefix^"_version_"^(OASISVersion.varname_of_comparator cmp)
3849 var_redefine
3850 ~hide:true
3852 (fun () ->
3853 let version_str =
3854 match fversion () with
3855 | "[Distributed with OCaml]" ->
3856 begin
3858 (var_get "ocaml_version")
3859 with Not_found ->
3860 warning
3861 (f_ "Variable ocaml_version not defined, fallback \
3862 to default");
3863 Sys.ocaml_version
3865 | res ->
3868 let version =
3869 OASISVersion.version_of_string version_str
3871 if OASISVersion.comparator_apply version cmp then
3872 version_str
3873 else
3874 failwithf
3875 (f_ "Cannot satisfy version constraint on %s: %s (version: %s)")
3876 var_prefix
3877 (OASISVersion.string_of_comparator cmp)
3878 version_str)
3882 let package_version pkg =
3883 OASISExec.run_read_one_line ~ctxt:!BaseContext.default
3884 (ocamlfind ())
3885 ["query"; "-format"; "%v"; pkg]
3888 let package ?version_comparator pkg () =
3889 let var =
3890 OASISUtils.varname_concat
3891 "pkg_"
3892 (OASISUtils.varname_of_string pkg)
3894 let findlib_dir pkg =
3895 let dir =
3896 OASISExec.run_read_one_line ~ctxt:!BaseContext.default
3897 (ocamlfind ())
3898 ["query"; "-format"; "%d"; pkg]
3900 if Sys.file_exists dir && Sys.is_directory dir then
3902 else
3903 failwithf
3904 (f_ "When looking for findlib package %s, \
3905 directory %s return doesn't exist")
3906 pkg dir
3908 let vl =
3909 var_redefine
3911 (fun () -> findlib_dir pkg)
3915 match version_comparator with
3916 | Some ver_cmp ->
3917 ignore
3918 (version
3920 ver_cmp
3921 (fun _ -> package_version pkg)
3923 | None ->
3929 module BaseOCamlcConfig = struct
3930 (* # 22 "src/base/BaseOCamlcConfig.ml" *)
3933 open BaseEnv
3934 open OASISUtils
3935 open OASISGettext
3938 module SMap = Map.Make(String)
3941 let ocamlc =
3942 BaseCheck.prog_opt "ocamlc"
3945 let ocamlc_config_map =
3946 (* Map name to value for ocamlc -config output
3947 (name ^": "^value)
3949 let rec split_field mp lst =
3950 match lst with
3951 | line :: tl ->
3952 let mp =
3954 let pos_semicolon =
3955 String.index line ':'
3957 if pos_semicolon > 1 then
3959 let name =
3960 String.sub line 0 pos_semicolon
3962 let linelen =
3963 String.length line
3965 let value =
3966 if linelen > pos_semicolon + 2 then
3967 String.sub
3968 line
3969 (pos_semicolon + 2)
3970 (linelen - pos_semicolon - 2)
3971 else
3974 SMap.add name value mp
3976 else
3980 with Not_found ->
3985 split_field mp tl
3986 | [] ->
3990 let cache =
3991 lazy
3992 (var_protect
3993 (Marshal.to_string
3994 (split_field
3995 SMap.empty
3996 (OASISExec.run_read_output
3997 ~ctxt:!BaseContext.default
3998 (ocamlc ()) ["-config"]))
3999 []))
4001 var_redefine
4002 "ocamlc_config_map"
4003 ~hide:true
4004 ~dump:false
4005 (fun () ->
4006 (* TODO: update if ocamlc change !!! *)
4007 Lazy.force cache)
4010 let var_define nm =
4011 (* Extract data from ocamlc -config *)
4012 let avlbl_config_get () =
4013 Marshal.from_string
4014 (ocamlc_config_map ())
4017 let chop_version_suffix s =
4019 String.sub s 0 (String.index s '+')
4020 with _ ->
4024 let nm_config, value_config =
4025 match nm with
4026 | "ocaml_version" ->
4027 "version", chop_version_suffix
4028 | _ -> nm, (fun x -> x)
4030 var_redefine
4032 (fun () ->
4034 let map =
4035 avlbl_config_get ()
4037 let value =
4038 SMap.find nm_config map
4040 value_config value
4041 with Not_found ->
4042 failwithf
4043 (f_ "Cannot find field '%s' in '%s -config' output")
4045 (ocamlc ()))
4049 module BaseStandardVar = struct
4050 (* # 22 "src/base/BaseStandardVar.ml" *)
4053 open OASISGettext
4054 open OASISTypes
4055 open BaseCheck
4056 open BaseEnv
4059 let ocamlfind = BaseCheck.ocamlfind
4060 let ocamlc = BaseOCamlcConfig.ocamlc
4061 let ocamlopt = prog_opt "ocamlopt"
4062 let ocamlbuild = prog "ocamlbuild"
4065 (**/**)
4066 let rpkg =
4067 ref None
4070 let pkg_get () =
4071 match !rpkg with
4072 | Some pkg -> pkg
4073 | None -> failwith (s_ "OASIS Package is not set")
4076 let var_cond = ref []
4079 let var_define_cond ~since_version f dflt =
4080 let holder = ref (fun () -> dflt) in
4081 let since_version =
4082 OASISVersion.VGreaterEqual (OASISVersion.version_of_string since_version)
4084 var_cond :=
4085 (fun ver ->
4086 if OASISVersion.comparator_apply ver since_version then
4087 holder := f ()) :: !var_cond;
4088 fun () -> !holder ()
4091 (**/**)
4094 let pkg_name =
4095 var_define
4096 ~short_desc:(fun () -> s_ "Package name")
4097 "pkg_name"
4098 (fun () -> (pkg_get ()).name)
4101 let pkg_version =
4102 var_define
4103 ~short_desc:(fun () -> s_ "Package version")
4104 "pkg_version"
4105 (fun () ->
4106 (OASISVersion.string_of_version (pkg_get ()).version))
4109 let c = BaseOCamlcConfig.var_define
4112 let os_type = c "os_type"
4113 let system = c "system"
4114 let architecture = c "architecture"
4115 let ccomp_type = c "ccomp_type"
4116 let ocaml_version = c "ocaml_version"
4119 (* TODO: Check standard variable presence at runtime *)
4122 let standard_library_default = c "standard_library_default"
4123 let standard_library = c "standard_library"
4124 let standard_runtime = c "standard_runtime"
4125 let bytecomp_c_compiler = c "bytecomp_c_compiler"
4126 let native_c_compiler = c "native_c_compiler"
4127 let model = c "model"
4128 let ext_obj = c "ext_obj"
4129 let ext_asm = c "ext_asm"
4130 let ext_lib = c "ext_lib"
4131 let ext_dll = c "ext_dll"
4132 let default_executable_name = c "default_executable_name"
4133 let systhread_supported = c "systhread_supported"
4136 let flexlink =
4137 BaseCheck.prog "flexlink"
4140 let flexdll_version =
4141 var_define
4142 ~short_desc:(fun () -> "FlexDLL version (Win32)")
4143 "flexdll_version"
4144 (fun () ->
4145 let lst =
4146 OASISExec.run_read_output ~ctxt:!BaseContext.default
4147 (flexlink ()) ["-help"]
4149 match lst with
4150 | line :: _ ->
4151 Scanf.sscanf line "FlexDLL version %s" (fun ver -> ver)
4152 | [] ->
4153 raise Not_found)
4156 (**/**)
4157 let p name hlp dflt =
4158 var_define
4159 ~short_desc:hlp
4160 ~cli:CLIAuto
4161 ~arg_help:"dir"
4162 name
4163 dflt
4166 let (/) a b =
4167 if os_type () = Sys.os_type then
4168 Filename.concat a b
4169 else if os_type () = "Unix" || os_type () = "Cygwin" then
4170 OASISUnixPath.concat a b
4171 else
4172 OASISUtils.failwithf (f_ "Cannot handle os_type %s filename concat")
4173 (os_type ())
4174 (**/**)
4177 let prefix =
4178 p "prefix"
4179 (fun () -> s_ "Install architecture-independent files dir")
4180 (fun () ->
4181 match os_type () with
4182 | "Win32" ->
4183 let program_files =
4184 Sys.getenv "PROGRAMFILES"
4186 program_files/(pkg_name ())
4187 | _ ->
4188 "/usr/local")
4191 let exec_prefix =
4192 p "exec_prefix"
4193 (fun () -> s_ "Install architecture-dependent files in dir")
4194 (fun () -> "$prefix")
4197 let bindir =
4198 p "bindir"
4199 (fun () -> s_ "User executables")
4200 (fun () -> "$exec_prefix"/"bin")
4203 let sbindir =
4204 p "sbindir"
4205 (fun () -> s_ "System admin executables")
4206 (fun () -> "$exec_prefix"/"sbin")
4209 let libexecdir =
4210 p "libexecdir"
4211 (fun () -> s_ "Program executables")
4212 (fun () -> "$exec_prefix"/"libexec")
4215 let sysconfdir =
4216 p "sysconfdir"
4217 (fun () -> s_ "Read-only single-machine data")
4218 (fun () -> "$prefix"/"etc")
4221 let sharedstatedir =
4222 p "sharedstatedir"
4223 (fun () -> s_ "Modifiable architecture-independent data")
4224 (fun () -> "$prefix"/"com")
4227 let localstatedir =
4228 p "localstatedir"
4229 (fun () -> s_ "Modifiable single-machine data")
4230 (fun () -> "$prefix"/"var")
4233 let libdir =
4234 p "libdir"
4235 (fun () -> s_ "Object code libraries")
4236 (fun () -> "$exec_prefix"/"lib")
4239 let datarootdir =
4240 p "datarootdir"
4241 (fun () -> s_ "Read-only arch-independent data root")
4242 (fun () -> "$prefix"/"share")
4245 let datadir =
4246 p "datadir"
4247 (fun () -> s_ "Read-only architecture-independent data")
4248 (fun () -> "$datarootdir")
4251 let infodir =
4252 p "infodir"
4253 (fun () -> s_ "Info documentation")
4254 (fun () -> "$datarootdir"/"info")
4257 let localedir =
4258 p "localedir"
4259 (fun () -> s_ "Locale-dependent data")
4260 (fun () -> "$datarootdir"/"locale")
4263 let mandir =
4264 p "mandir"
4265 (fun () -> s_ "Man documentation")
4266 (fun () -> "$datarootdir"/"man")
4269 let docdir =
4270 p "docdir"
4271 (fun () -> s_ "Documentation root")
4272 (fun () -> "$datarootdir"/"doc"/"$pkg_name")
4275 let htmldir =
4276 p "htmldir"
4277 (fun () -> s_ "HTML documentation")
4278 (fun () -> "$docdir")
4281 let dvidir =
4282 p "dvidir"
4283 (fun () -> s_ "DVI documentation")
4284 (fun () -> "$docdir")
4287 let pdfdir =
4288 p "pdfdir"
4289 (fun () -> s_ "PDF documentation")
4290 (fun () -> "$docdir")
4293 let psdir =
4294 p "psdir"
4295 (fun () -> s_ "PS documentation")
4296 (fun () -> "$docdir")
4299 let destdir =
4300 p "destdir"
4301 (fun () -> s_ "Prepend a path when installing package")
4302 (fun () ->
4303 raise
4304 (PropList.Not_set
4305 ("destdir",
4306 Some (s_ "undefined by construct"))))
4309 let findlib_version =
4310 var_define
4311 "findlib_version"
4312 (fun () ->
4313 BaseCheck.package_version "findlib")
4316 let is_native =
4317 var_define
4318 "is_native"
4319 (fun () ->
4321 let _s: string =
4322 ocamlopt ()
4324 "true"
4325 with PropList.Not_set _ ->
4326 let _s: string =
4327 ocamlc ()
4329 "false")
4332 let ext_program =
4333 var_define
4334 "suffix_program"
4335 (fun () ->
4336 match os_type () with
4337 | "Win32" | "Cygwin" -> ".exe"
4338 | _ -> "")
4341 let rm =
4342 var_define
4343 ~short_desc:(fun () -> s_ "Remove a file.")
4344 "rm"
4345 (fun () ->
4346 match os_type () with
4347 | "Win32" -> "del"
4348 | _ -> "rm -f")
4351 let rmdir =
4352 var_define
4353 ~short_desc:(fun () -> s_ "Remove a directory.")
4354 "rmdir"
4355 (fun () ->
4356 match os_type () with
4357 | "Win32" -> "rd"
4358 | _ -> "rm -rf")
4361 let debug =
4362 var_define
4363 ~short_desc:(fun () -> s_ "Turn ocaml debug flag on")
4364 ~cli:CLIEnable
4365 "debug"
4366 (fun () -> "true")
4369 let profile =
4370 var_define
4371 ~short_desc:(fun () -> s_ "Turn ocaml profile flag on")
4372 ~cli:CLIEnable
4373 "profile"
4374 (fun () -> "false")
4377 let tests =
4378 var_define_cond ~since_version:"0.3"
4379 (fun () ->
4380 var_define
4381 ~short_desc:(fun () ->
4382 s_ "Compile tests executable and library and run them")
4383 ~cli:CLIEnable
4384 "tests"
4385 (fun () -> "false"))
4386 "true"
4389 let docs =
4390 var_define_cond ~since_version:"0.3"
4391 (fun () ->
4392 var_define
4393 ~short_desc:(fun () -> s_ "Create documentations")
4394 ~cli:CLIEnable
4395 "docs"
4396 (fun () -> "true"))
4397 "true"
4400 let native_dynlink =
4401 var_define
4402 ~short_desc:(fun () -> s_ "Compiler support generation of .cmxs.")
4403 ~cli:CLINone
4404 "native_dynlink"
4405 (fun () ->
4406 let res =
4407 let ocaml_lt_312 () =
4408 OASISVersion.comparator_apply
4409 (OASISVersion.version_of_string (ocaml_version ()))
4410 (OASISVersion.VLesser
4411 (OASISVersion.version_of_string "3.12.0"))
4413 let flexdll_lt_030 () =
4414 OASISVersion.comparator_apply
4415 (OASISVersion.version_of_string (flexdll_version ()))
4416 (OASISVersion.VLesser
4417 (OASISVersion.version_of_string "0.30"))
4419 let has_native_dynlink =
4420 let ocamlfind = ocamlfind () in
4422 let fn =
4423 OASISExec.run_read_one_line
4424 ~ctxt:!BaseContext.default
4425 ocamlfind
4426 ["query"; "-predicates"; "native"; "dynlink";
4427 "-format"; "%d/%a"]
4429 Sys.file_exists fn
4430 with _ ->
4431 false
4433 if not has_native_dynlink then
4434 false
4435 else if ocaml_lt_312 () then
4436 false
4437 else if (os_type () = "Win32" || os_type () = "Cygwin")
4438 && flexdll_lt_030 () then
4439 begin
4440 BaseMessage.warning
4441 (f_ ".cmxs generation disabled because FlexDLL needs to be \
4442 at least 0.30. Please upgrade FlexDLL from %s to 0.30.")
4443 (flexdll_version ());
4444 false
4446 else
4447 true
4449 string_of_bool res)
4452 let init pkg =
4453 rpkg := Some pkg;
4454 List.iter (fun f -> f pkg.oasis_version) !var_cond
4458 module BaseFileAB = struct
4459 (* # 22 "src/base/BaseFileAB.ml" *)
4462 open BaseEnv
4463 open OASISGettext
4464 open BaseMessage
4465 open OASISContext
4468 let to_filename fn =
4469 if not (Filename.check_suffix fn ".ab") then
4470 warning (f_ "File '%s' doesn't have '.ab' extension") fn;
4471 OASISFileSystem.of_unix_filename (Filename.chop_extension fn)
4474 let replace ~ctxt fn_lst =
4475 let open OASISFileSystem in
4476 let ibuf, obuf = Buffer.create 13, Buffer.create 13 in
4477 List.iter
4478 (fun fn ->
4479 Buffer.clear ibuf; Buffer.clear obuf;
4480 defer_close
4481 (ctxt.srcfs#open_in (of_unix_filename fn))
4482 (read_all ibuf);
4483 Buffer.add_string obuf (var_expand (Buffer.contents ibuf));
4484 defer_close
4485 (ctxt.srcfs#open_out (to_filename fn))
4486 (fun wrtr -> wrtr#output obuf))
4487 fn_lst
4490 module BaseLog = struct
4491 (* # 22 "src/base/BaseLog.ml" *)
4494 open OASISUtils
4495 open OASISContext
4496 open OASISGettext
4497 open OASISFileSystem
4500 let default_filename = in_srcdir "setup.log"
4503 let load ~ctxt () =
4504 let module SetTupleString =
4505 Set.Make
4506 (struct
4507 type t = string * string
4508 let compare (s11, s12) (s21, s22) =
4509 match String.compare s11 s21 with
4510 | 0 -> String.compare s12 s22
4511 | n -> n
4512 end)
4514 if ctxt.srcfs#file_exists default_filename then begin
4515 defer_close
4516 (ctxt.srcfs#open_in default_filename)
4517 (fun rdr ->
4518 let line = ref 1 in
4519 let lxr = Genlex.make_lexer [] (stream_of_reader rdr) in
4520 let rec read_aux (st, lst) =
4521 match Stream.npeek 2 lxr with
4522 | [Genlex.String e; Genlex.String d] ->
4523 let t = e, d in
4524 Stream.junk lxr; Stream.junk lxr;
4525 if SetTupleString.mem t st then
4526 read_aux (st, lst)
4527 else
4528 read_aux (SetTupleString.add t st, t :: lst)
4529 | [] -> List.rev lst
4530 | _ ->
4531 failwithf
4532 (f_ "Malformed log file '%s' at line %d")
4533 (ctxt.srcfs#string_of_filename default_filename)
4534 !line
4536 read_aux (SetTupleString.empty, []))
4537 end else begin
4542 let register ~ctxt event data =
4543 defer_close
4544 (ctxt.srcfs#open_out
4545 ~mode:[Open_append; Open_creat; Open_text]
4546 ~perm:0o644
4547 default_filename)
4548 (fun wrtr ->
4549 let buf = Buffer.create 13 in
4550 Printf.bprintf buf "%S %S\n" event data;
4551 wrtr#output buf)
4554 let unregister ~ctxt event data =
4555 let lst = load ~ctxt () in
4556 let buf = Buffer.create 13 in
4557 List.iter
4558 (fun (e, d) ->
4559 if e <> event || d <> data then
4560 Printf.bprintf buf "%S %S\n" e d)
4561 lst;
4562 if Buffer.length buf > 0 then
4563 defer_close
4564 (ctxt.srcfs#open_out default_filename)
4565 (fun wrtr -> wrtr#output buf)
4566 else
4567 ctxt.srcfs#remove default_filename
4570 let filter ~ctxt events =
4571 let st_events = SetString.of_list events in
4572 List.filter
4573 (fun (e, _) -> SetString.mem e st_events)
4574 (load ~ctxt ())
4577 let exists ~ctxt event data =
4578 List.exists
4579 (fun v -> (event, data) = v)
4580 (load ~ctxt ())
4583 module BaseBuilt = struct
4584 (* # 22 "src/base/BaseBuilt.ml" *)
4587 open OASISTypes
4588 open OASISGettext
4589 open BaseStandardVar
4590 open BaseMessage
4593 type t =
4594 | BExec (* Executable *)
4595 | BExecLib (* Library coming with executable *)
4596 | BLib (* Library *)
4597 | BObj (* Library *)
4598 | BDoc (* Document *)
4601 let to_log_event_file t nm =
4602 "built_"^
4603 (match t with
4604 | BExec -> "exec"
4605 | BExecLib -> "exec_lib"
4606 | BLib -> "lib"
4607 | BObj -> "obj"
4608 | BDoc -> "doc")^
4609 "_"^nm
4612 let to_log_event_done t nm =
4613 "is_"^(to_log_event_file t nm)
4616 let register ~ctxt t nm lst =
4617 BaseLog.register ~ctxt (to_log_event_done t nm) "true";
4618 List.iter
4619 (fun alt ->
4620 let registered =
4621 List.fold_left
4622 (fun registered fn ->
4623 if OASISFileUtil.file_exists_case fn then begin
4624 BaseLog.register ~ctxt
4625 (to_log_event_file t nm)
4626 (if Filename.is_relative fn then
4627 Filename.concat (Sys.getcwd ()) fn
4628 else
4629 fn);
4630 true
4631 end else begin
4632 registered
4633 end)
4634 false
4637 if not registered then
4638 warning
4639 (f_ "Cannot find an existing alternative files among: %s")
4640 (String.concat (s_ ", ") alt))
4644 let unregister ~ctxt t nm =
4645 List.iter
4646 (fun (e, d) -> BaseLog.unregister ~ctxt e d)
4647 (BaseLog.filter ~ctxt [to_log_event_file t nm; to_log_event_done t nm])
4650 let fold ~ctxt t nm f acc =
4651 List.fold_left
4652 (fun acc (_, fn) ->
4653 if OASISFileUtil.file_exists_case fn then begin
4654 f acc fn
4655 end else begin
4656 warning
4657 (f_ "File '%s' has been marked as built \
4658 for %s but doesn't exist")
4660 (Printf.sprintf
4661 (match t with
4662 | BExec | BExecLib -> (f_ "executable %s")
4663 | BLib -> (f_ "library %s")
4664 | BObj -> (f_ "object %s")
4665 | BDoc -> (f_ "documentation %s"))
4666 nm);
4668 end)
4670 (BaseLog.filter ~ctxt [to_log_event_file t nm])
4673 let is_built ~ctxt t nm =
4674 List.fold_left
4675 (fun _ (_, d) -> try bool_of_string d with _ -> false)
4676 false
4677 (BaseLog.filter ~ctxt [to_log_event_done t nm])
4680 let of_executable ffn (cs, bs, exec) =
4681 let unix_exec_is, unix_dll_opt =
4682 OASISExecutable.unix_exec_is
4683 (cs, bs, exec)
4684 (fun () ->
4685 bool_of_string
4686 (is_native ()))
4687 ext_dll
4688 ext_program
4690 let evs =
4691 (BExec, cs.cs_name, [[ffn unix_exec_is]])
4693 (match unix_dll_opt with
4694 | Some fn ->
4695 [BExecLib, cs.cs_name, [[ffn fn]]]
4696 | None ->
4699 evs,
4700 unix_exec_is,
4701 unix_dll_opt
4704 let of_library ffn (cs, bs, lib) =
4705 let unix_lst =
4706 OASISLibrary.generated_unix_files
4707 ~ctxt:!BaseContext.default
4708 ~source_file_exists:(fun fn ->
4709 OASISFileUtil.file_exists_case (OASISHostPath.of_unix fn))
4710 ~is_native:(bool_of_string (is_native ()))
4711 ~has_native_dynlink:(bool_of_string (native_dynlink ()))
4712 ~ext_lib:(ext_lib ())
4713 ~ext_dll:(ext_dll ())
4714 (cs, bs, lib)
4716 let evs =
4717 [BLib,
4718 cs.cs_name,
4719 List.map (List.map ffn) unix_lst]
4721 evs, unix_lst
4724 let of_object ffn (cs, bs, obj) =
4725 let unix_lst =
4726 OASISObject.generated_unix_files
4727 ~ctxt:!BaseContext.default
4728 ~source_file_exists:(fun fn ->
4729 OASISFileUtil.file_exists_case (OASISHostPath.of_unix fn))
4730 ~is_native:(bool_of_string (is_native ()))
4731 (cs, bs, obj)
4733 let evs =
4734 [BObj,
4735 cs.cs_name,
4736 List.map (List.map ffn) unix_lst]
4738 evs, unix_lst
4742 module BaseCustom = struct
4743 (* # 22 "src/base/BaseCustom.ml" *)
4746 open BaseEnv
4747 open BaseMessage
4748 open OASISTypes
4749 open OASISGettext
4752 let run cmd args extra_args =
4753 OASISExec.run ~ctxt:!BaseContext.default ~quote:false
4754 (var_expand cmd)
4755 (List.map
4756 var_expand
4757 (args @ (Array.to_list extra_args)))
4760 let hook ?(failsafe=false) cstm f e =
4761 let optional_command lst =
4762 let printer =
4763 function
4764 | Some (cmd, args) -> String.concat " " (cmd :: args)
4765 | None -> s_ "No command"
4767 match
4768 var_choose
4769 ~name:(s_ "Pre/Post Command")
4770 ~printer
4771 lst with
4772 | Some (cmd, args) ->
4773 begin
4775 run cmd args [||]
4776 with e when failsafe ->
4777 warning
4778 (f_ "Command '%s' fail with error: %s")
4779 (String.concat " " (cmd :: args))
4780 (match e with
4781 | Failure msg -> msg
4782 | e -> Printexc.to_string e)
4784 | None ->
4787 let res =
4788 optional_command cstm.pre_command;
4791 optional_command cstm.post_command;
4795 module BaseDynVar = struct
4796 (* # 22 "src/base/BaseDynVar.ml" *)
4799 open OASISTypes
4800 open OASISGettext
4801 open BaseEnv
4802 open BaseBuilt
4805 let init ~ctxt pkg =
4806 (* TODO: disambiguate exec vs other variable by adding exec_VARNAME. *)
4807 (* TODO: provide compile option for library libary_byte_args_VARNAME... *)
4808 List.iter
4809 (function
4810 | Executable (cs, bs, _) ->
4811 if var_choose bs.bs_build then
4812 var_ignore
4813 (var_redefine
4814 (* We don't save this variable *)
4815 ~dump:false
4816 ~short_desc:(fun () ->
4817 Printf.sprintf
4818 (f_ "Filename of executable '%s'")
4819 cs.cs_name)
4820 (OASISUtils.varname_of_string cs.cs_name)
4821 (fun () ->
4822 let fn_opt =
4823 fold ~ctxt BExec cs.cs_name (fun _ fn -> Some fn) None
4825 match fn_opt with
4826 | Some fn -> fn
4827 | None ->
4828 raise
4829 (PropList.Not_set
4830 (cs.cs_name,
4831 Some (Printf.sprintf
4832 (f_ "Executable '%s' not yet built.")
4833 cs.cs_name)))))
4835 | Library _ | Object _ | Flag _ | Test _ | SrcRepo _ | Doc _ ->
4837 pkg.sections
4840 module BaseTest = struct
4841 (* # 22 "src/base/BaseTest.ml" *)
4844 open BaseEnv
4845 open BaseMessage
4846 open OASISTypes
4847 open OASISGettext
4850 let test ~ctxt lst pkg extra_args =
4852 let one_test (failure, n) (test_plugin, cs, test) =
4853 if var_choose
4854 ~name:(Printf.sprintf
4855 (f_ "test %s run")
4856 cs.cs_name)
4857 ~printer:string_of_bool
4858 test.test_run then
4859 begin
4860 let () = info (f_ "Running test '%s'") cs.cs_name in
4861 let back_cwd =
4862 match test.test_working_directory with
4863 | Some dir ->
4864 let cwd = Sys.getcwd () in
4865 let chdir d =
4866 info (f_ "Changing directory to '%s'") d;
4867 Sys.chdir d
4869 chdir dir;
4870 fun () -> chdir cwd
4872 | None ->
4873 fun () -> ()
4876 let failure_percent =
4877 BaseCustom.hook
4878 test.test_custom
4879 (test_plugin ~ctxt pkg (cs, test))
4880 extra_args
4882 back_cwd ();
4883 (failure_percent +. failure, n + 1)
4884 with e ->
4885 begin
4886 back_cwd ();
4887 raise e
4890 else
4891 begin
4892 info (f_ "Skipping test '%s'") cs.cs_name;
4893 (failure, n)
4896 let failed, n = List.fold_left one_test (0.0, 0) lst in
4897 let failure_percent = if n = 0 then 0.0 else failed /. (float_of_int n) in
4898 let msg =
4899 Printf.sprintf
4900 (f_ "Tests had a %.2f%% failure rate")
4901 (100. *. failure_percent)
4903 if failure_percent > 0.0 then
4904 failwith msg
4905 else
4906 info "%s" msg;
4908 (* Possible explanation why the tests where not run. *)
4909 if OASISFeatures.package_test OASISFeatures.flag_tests pkg &&
4910 not (bool_of_string (BaseStandardVar.tests ())) &&
4911 lst <> [] then
4912 BaseMessage.warning
4913 "Tests are turned off, consider enabling with \
4914 'ocaml setup.ml -configure --enable-tests'"
4917 module BaseDoc = struct
4918 (* # 22 "src/base/BaseDoc.ml" *)
4921 open BaseEnv
4922 open BaseMessage
4923 open OASISTypes
4924 open OASISGettext
4927 let doc ~ctxt lst pkg extra_args =
4929 let one_doc (doc_plugin, cs, doc) =
4930 if var_choose
4931 ~name:(Printf.sprintf
4932 (f_ "documentation %s build")
4933 cs.cs_name)
4934 ~printer:string_of_bool
4935 doc.doc_build then
4936 begin
4937 info (f_ "Building documentation '%s'") cs.cs_name;
4938 BaseCustom.hook
4939 doc.doc_custom
4940 (doc_plugin ~ctxt pkg (cs, doc))
4941 extra_args
4944 List.iter one_doc lst;
4946 if OASISFeatures.package_test OASISFeatures.flag_docs pkg &&
4947 not (bool_of_string (BaseStandardVar.docs ())) &&
4948 lst <> [] then
4949 BaseMessage.warning
4950 "Docs are turned off, consider enabling with \
4951 'ocaml setup.ml -configure --enable-docs'"
4954 module BaseSetup = struct
4955 (* # 22 "src/base/BaseSetup.ml" *)
4957 open OASISContext
4958 open BaseEnv
4959 open BaseMessage
4960 open OASISTypes
4961 open OASISGettext
4962 open OASISUtils
4965 type std_args_fun =
4966 ctxt:OASISContext.t -> package -> string array -> unit
4969 type ('a, 'b) section_args_fun =
4970 name *
4971 (ctxt:OASISContext.t ->
4972 package ->
4973 (common_section * 'a) ->
4974 string array ->
4978 type t =
4980 configure: std_args_fun;
4981 build: std_args_fun;
4982 doc: ((doc, unit) section_args_fun) list;
4983 test: ((test, float) section_args_fun) list;
4984 install: std_args_fun;
4985 uninstall: std_args_fun;
4986 clean: std_args_fun list;
4987 clean_doc: (doc, unit) section_args_fun list;
4988 clean_test: (test, unit) section_args_fun list;
4989 distclean: std_args_fun list;
4990 distclean_doc: (doc, unit) section_args_fun list;
4991 distclean_test: (test, unit) section_args_fun list;
4992 package: package;
4993 oasis_fn: string option;
4994 oasis_version: string;
4995 oasis_digest: Digest.t option;
4996 oasis_exec: string option;
4997 oasis_setup_args: string list;
4998 setup_update: bool;
5002 (* Associate a plugin function with data from package *)
5003 let join_plugin_sections filter_map lst =
5004 List.rev
5005 (List.fold_left
5006 (fun acc sct ->
5007 match filter_map sct with
5008 | Some e ->
5009 e :: acc
5010 | None ->
5011 acc)
5013 lst)
5016 (* Search for plugin data associated with a section name *)
5017 let lookup_plugin_section plugin action nm lst =
5019 List.assoc nm lst
5020 with Not_found ->
5021 failwithf
5022 (f_ "Cannot find plugin %s matching section %s for %s action")
5023 plugin
5025 action
5028 let configure ~ctxt t args =
5029 (* Run configure *)
5030 BaseCustom.hook
5031 t.package.conf_custom
5032 (fun () ->
5033 (* Reload if preconf has changed it *)
5034 begin
5036 unload ();
5037 load ~ctxt ();
5038 with _ ->
5040 end;
5042 (* Run plugin's configure *)
5043 t.configure ~ctxt t.package args;
5045 (* Dump to allow postconf to change it *)
5046 dump ~ctxt ())
5049 (* Reload environment *)
5050 unload ();
5051 load ~ctxt ();
5053 (* Save environment *)
5054 print ();
5056 (* Replace data in file *)
5057 BaseFileAB.replace ~ctxt t.package.files_ab
5060 let build ~ctxt t args =
5061 BaseCustom.hook
5062 t.package.build_custom
5063 (t.build ~ctxt t.package)
5064 args
5067 let doc ~ctxt t args =
5068 BaseDoc.doc
5069 ~ctxt
5070 (join_plugin_sections
5071 (function
5072 | Doc (cs, e) ->
5073 Some
5074 (lookup_plugin_section
5075 "documentation"
5076 (s_ "build")
5077 cs.cs_name
5078 t.doc,
5081 | _ ->
5082 None)
5083 t.package.sections)
5084 t.package
5085 args
5088 let test ~ctxt t args =
5089 BaseTest.test
5090 ~ctxt
5091 (join_plugin_sections
5092 (function
5093 | Test (cs, e) ->
5094 Some
5095 (lookup_plugin_section
5096 "test"
5097 (s_ "run")
5098 cs.cs_name
5099 t.test,
5102 | _ ->
5103 None)
5104 t.package.sections)
5105 t.package
5106 args
5109 let all ~ctxt t args =
5110 let rno_doc = ref false in
5111 let rno_test = ref false in
5112 let arg_rest = ref [] in
5113 Arg.parse_argv
5114 ~current:(ref 0)
5115 (Array.of_list
5116 ((Sys.executable_name^" all") ::
5117 (Array.to_list args)))
5119 "-no-doc",
5120 Arg.Set rno_doc,
5121 s_ "Don't run doc target";
5123 "-no-test",
5124 Arg.Set rno_test,
5125 s_ "Don't run test target";
5127 "--",
5128 Arg.Rest (fun arg -> arg_rest := arg :: !arg_rest),
5129 s_ "All arguments for configure.";
5131 (failwithf (f_ "Don't know what to do with '%s'"))
5134 info "Running configure step";
5135 configure ~ctxt t (Array.of_list (List.rev !arg_rest));
5137 info "Running build step";
5138 build ~ctxt t [||];
5140 (* Load setup.log dynamic variables *)
5141 BaseDynVar.init ~ctxt t.package;
5143 if not !rno_doc then begin
5144 info "Running doc step";
5145 doc ~ctxt t [||]
5146 end else begin
5147 info "Skipping doc step"
5148 end;
5149 if not !rno_test then begin
5150 info "Running test step";
5151 test ~ctxt t [||]
5152 end else begin
5153 info "Skipping test step"
5157 let install ~ctxt t args =
5158 BaseCustom.hook t.package.install_custom (t.install ~ctxt t.package) args
5161 let uninstall ~ctxt t args =
5162 BaseCustom.hook t.package.uninstall_custom (t.uninstall ~ctxt t.package) args
5165 let reinstall ~ctxt t args =
5166 uninstall ~ctxt t args;
5167 install ~ctxt t args
5170 let clean, distclean =
5171 let failsafe f a =
5174 with e ->
5175 warning
5176 (f_ "Action fail with error: %s")
5177 (match e with
5178 | Failure msg -> msg
5179 | e -> Printexc.to_string e)
5182 let generic_clean ~ctxt t cstm mains docs tests args =
5183 BaseCustom.hook
5184 ~failsafe:true
5185 cstm
5186 (fun () ->
5187 (* Clean section *)
5188 List.iter
5189 (function
5190 | Test (cs, test) ->
5191 let f =
5193 List.assoc cs.cs_name tests
5194 with Not_found ->
5195 fun ~ctxt:_ _ _ _ -> ()
5197 failsafe (f ~ctxt t.package (cs, test)) args
5198 | Doc (cs, doc) ->
5199 let f =
5201 List.assoc cs.cs_name docs
5202 with Not_found ->
5203 fun ~ctxt:_ _ _ _ -> ()
5205 failsafe (f ~ctxt t.package (cs, doc)) args
5206 | Library _ | Object _ | Executable _ | Flag _ | SrcRepo _ -> ())
5207 t.package.sections;
5208 (* Clean whole package *)
5209 List.iter (fun f -> failsafe (f ~ctxt t.package) args) mains)
5213 let clean ~ctxt t args =
5214 generic_clean
5215 ~ctxt
5217 t.package.clean_custom
5218 t.clean
5219 t.clean_doc
5220 t.clean_test
5221 args
5224 let distclean ~ctxt t args =
5225 (* Call clean *)
5226 clean ~ctxt t args;
5228 (* Call distclean code *)
5229 generic_clean
5230 ~ctxt
5232 t.package.distclean_custom
5233 t.distclean
5234 t.distclean_doc
5235 t.distclean_test
5236 args;
5238 (* Remove generated source files. *)
5239 List.iter
5240 (fun fn ->
5241 if ctxt.srcfs#file_exists fn then begin
5242 info (f_ "Remove '%s'") (ctxt.srcfs#string_of_filename fn);
5243 ctxt.srcfs#remove fn
5244 end)
5245 ([BaseEnv.default_filename; BaseLog.default_filename]
5246 @ (List.rev_map BaseFileAB.to_filename t.package.files_ab))
5249 clean, distclean
5252 let version ~ctxt:_ (t: t) _ = print_endline t.oasis_version
5255 let update_setup_ml, no_update_setup_ml_cli =
5256 let b = ref true in
5258 ("-no-update-setup-ml",
5259 Arg.Clear b,
5260 s_ " Don't try to update setup.ml, even if _oasis has changed.")
5262 (* TODO: srcfs *)
5263 let default_oasis_fn = "_oasis"
5266 let update_setup_ml t =
5267 let oasis_fn =
5268 match t.oasis_fn with
5269 | Some fn -> fn
5270 | None -> default_oasis_fn
5272 let oasis_exec =
5273 match t.oasis_exec with
5274 | Some fn -> fn
5275 | None -> "oasis"
5277 let ocaml =
5278 Sys.executable_name
5280 let setup_ml, args =
5281 match Array.to_list Sys.argv with
5282 | setup_ml :: args ->
5283 setup_ml, args
5284 | [] ->
5285 failwith
5286 (s_ "Expecting non-empty command line arguments.")
5288 let ocaml, setup_ml =
5289 if Sys.executable_name = Sys.argv.(0) then
5290 (* We are not running in standard mode, probably the script
5291 * is precompiled.
5293 "ocaml", "setup.ml"
5294 else
5295 ocaml, setup_ml
5297 let no_update_setup_ml_cli, _, _ = no_update_setup_ml_cli in
5298 let do_update () =
5299 let oasis_exec_version =
5300 OASISExec.run_read_one_line
5301 ~ctxt:!BaseContext.default
5302 ~f_exit_code:
5303 (function
5304 | 0 ->
5306 | 1 ->
5307 failwithf
5308 (f_ "Executable '%s' is probably an old version \
5309 of oasis (< 0.3.0), please update to version \
5310 v%s.")
5311 oasis_exec t.oasis_version
5312 | 127 ->
5313 failwithf
5314 (f_ "Cannot find executable '%s', please install \
5315 oasis v%s.")
5316 oasis_exec t.oasis_version
5317 | n ->
5318 failwithf
5319 (f_ "Command '%s version' exited with code %d.")
5320 oasis_exec n)
5321 oasis_exec ["version"]
5323 if OASISVersion.comparator_apply
5324 (OASISVersion.version_of_string oasis_exec_version)
5325 (OASISVersion.VGreaterEqual
5326 (OASISVersion.version_of_string t.oasis_version)) then
5327 begin
5328 (* We have a version >= for the executable oasis, proceed with
5329 * update.
5331 (* TODO: delegate this check to 'oasis setup'. *)
5332 if Sys.os_type = "Win32" then
5333 failwithf
5334 (f_ "It is not possible to update the running script \
5335 setup.ml on Windows. Please update setup.ml by \
5336 running '%s'.")
5337 (String.concat " " (oasis_exec :: "setup" :: t.oasis_setup_args))
5338 else
5339 begin
5340 OASISExec.run
5341 ~ctxt:!BaseContext.default
5342 ~f_exit_code:
5343 (fun n ->
5344 if n <> 0 then
5345 failwithf
5346 (f_ "Unable to update setup.ml using '%s', \
5347 please fix the problem and retry.")
5348 oasis_exec)
5349 oasis_exec ("setup" :: t.oasis_setup_args);
5350 OASISExec.run ~ctxt:!BaseContext.default ocaml (setup_ml :: args)
5353 else
5354 failwithf
5355 (f_ "The version of '%s' (v%s) doesn't match the version of \
5356 oasis used to generate the %s file. Please install at \
5357 least oasis v%s.")
5358 oasis_exec oasis_exec_version setup_ml t.oasis_version
5361 if !update_setup_ml then
5362 begin
5364 match t.oasis_digest with
5365 | Some dgst ->
5366 if Sys.file_exists oasis_fn &&
5367 dgst <> Digest.file default_oasis_fn then
5368 begin
5369 do_update ();
5370 true
5372 else
5373 false
5374 | None ->
5375 false
5376 with e ->
5377 error
5378 (f_ "Error when updating setup.ml. If you want to avoid this error, \
5379 you can bypass the update of %s by running '%s %s %s %s'")
5380 setup_ml ocaml setup_ml no_update_setup_ml_cli
5381 (String.concat " " args);
5382 raise e
5384 else
5385 false
5388 let setup t =
5389 let catch_exn = ref true in
5390 let act_ref =
5391 ref (fun ~ctxt:_ _ ->
5392 failwithf
5393 (f_ "No action defined, run '%s %s -help'")
5394 Sys.executable_name
5395 Sys.argv.(0))
5398 let extra_args_ref = ref [] in
5399 let allow_empty_env_ref = ref false in
5400 let arg_handle ?(allow_empty_env=false) act =
5401 Arg.Tuple
5403 Arg.Rest (fun str -> extra_args_ref := str :: !extra_args_ref);
5404 Arg.Unit
5405 (fun () ->
5406 allow_empty_env_ref := allow_empty_env;
5407 act_ref := act);
5411 let () =
5412 Arg.parse
5413 (Arg.align
5415 "-configure",
5416 arg_handle ~allow_empty_env:true configure,
5417 s_ "[options*] Configure the whole build process.";
5419 "-build",
5420 arg_handle build,
5421 s_ "[options*] Build executables and libraries.";
5423 "-doc",
5424 arg_handle doc,
5425 s_ "[options*] Build documents.";
5427 "-test",
5428 arg_handle test,
5429 s_ "[options*] Run tests.";
5431 "-all",
5432 arg_handle ~allow_empty_env:true all,
5433 s_ "[options*] Run configure, build, doc and test targets.";
5435 "-install",
5436 arg_handle install,
5437 s_ "[options*] Install libraries, data, executables \
5438 and documents.";
5440 "-uninstall",
5441 arg_handle uninstall,
5442 s_ "[options*] Uninstall libraries, data, executables \
5443 and documents.";
5445 "-reinstall",
5446 arg_handle reinstall,
5447 s_ "[options*] Uninstall and install libraries, data, \
5448 executables and documents.";
5450 "-clean",
5451 arg_handle ~allow_empty_env:true clean,
5452 s_ "[options*] Clean files generated by a build.";
5454 "-distclean",
5455 arg_handle ~allow_empty_env:true distclean,
5456 s_ "[options*] Clean files generated by a build and configure.";
5458 "-version",
5459 arg_handle ~allow_empty_env:true version,
5460 s_ " Display version of OASIS used to generate this setup.ml.";
5462 "-no-catch-exn",
5463 Arg.Clear catch_exn,
5464 s_ " Don't catch exception, useful for debugging.";
5467 (if t.setup_update then
5468 [no_update_setup_ml_cli]
5469 else
5471 @ (BaseContext.args ())))
5472 (failwithf (f_ "Don't know what to do with '%s'"))
5473 (s_ "Setup and run build process current package\n")
5476 (* Instantiate the context. *)
5477 let ctxt = !BaseContext.default in
5479 (* Build initial environment *)
5480 load ~ctxt ~allow_empty:!allow_empty_env_ref ();
5482 (** Initialize flags *)
5483 List.iter
5484 (function
5485 | Flag (cs, {flag_description = hlp;
5486 flag_default = choices}) ->
5487 begin
5488 let apply ?short_desc () =
5489 var_ignore
5490 (var_define
5491 ~cli:CLIEnable
5492 ?short_desc
5493 (OASISUtils.varname_of_string cs.cs_name)
5494 (fun () ->
5495 string_of_bool
5496 (var_choose
5497 ~name:(Printf.sprintf
5498 (f_ "default value of flag %s")
5499 cs.cs_name)
5500 ~printer:string_of_bool
5501 choices)))
5503 match hlp with
5504 | Some hlp -> apply ~short_desc:(fun () -> hlp) ()
5505 | None -> apply ()
5507 | _ ->
5509 t.package.sections;
5511 BaseStandardVar.init t.package;
5513 BaseDynVar.init ~ctxt t.package;
5515 if not (t.setup_update && update_setup_ml t) then
5516 !act_ref ~ctxt t (Array.of_list (List.rev !extra_args_ref))
5518 with e when !catch_exn ->
5519 error "%s" (Printexc.to_string e);
5520 exit 1
5525 module BaseCompat = struct
5526 (* # 22 "src/base/BaseCompat.ml" *)
5528 (** Compatibility layer to provide a stable API inside setup.ml.
5529 This layer allows OASIS to change in between minor versions
5530 (e.g. 0.4.6 -> 0.4.7) but still provides a stable API inside setup.ml. This
5531 enables to write functions that manipulate setup_t inside setup.ml. See
5532 deps.ml for an example.
5534 The module opened by default will depend on the version of the _oasis. E.g.
5535 if we have "OASISFormat: 0.3", the module Compat_0_3 will be opened and
5536 the function Compat_0_3 will be called. If setup.ml is generated with the
5537 -nocompat, no module will be opened.
5539 @author Sylvain Le Gall
5542 module Compat_0_4 =
5543 struct
5544 let rctxt = ref !BaseContext.default
5546 module BaseSetup =
5547 struct
5548 module Original = BaseSetup
5550 open OASISTypes
5552 type std_args_fun = package -> string array -> unit
5553 type ('a, 'b) section_args_fun =
5554 name * (package -> (common_section * 'a) -> string array -> 'b)
5555 type t =
5557 configure: std_args_fun;
5558 build: std_args_fun;
5559 doc: ((doc, unit) section_args_fun) list;
5560 test: ((test, float) section_args_fun) list;
5561 install: std_args_fun;
5562 uninstall: std_args_fun;
5563 clean: std_args_fun list;
5564 clean_doc: (doc, unit) section_args_fun list;
5565 clean_test: (test, unit) section_args_fun list;
5566 distclean: std_args_fun list;
5567 distclean_doc: (doc, unit) section_args_fun list;
5568 distclean_test: (test, unit) section_args_fun list;
5569 package: package;
5570 oasis_fn: string option;
5571 oasis_version: string;
5572 oasis_digest: Digest.t option;
5573 oasis_exec: string option;
5574 oasis_setup_args: string list;
5575 setup_update: bool;
5578 let setup t =
5579 let mk_std_args_fun f =
5580 fun ~ctxt pkg args -> rctxt := ctxt; f pkg args
5582 let mk_section_args_fun l =
5583 List.map
5584 (fun (nm, f) ->
5586 (fun ~ctxt pkg sct args ->
5587 rctxt := ctxt;
5588 f pkg sct args))
5591 let t' =
5593 Original.
5594 configure = mk_std_args_fun t.configure;
5595 build = mk_std_args_fun t.build;
5596 doc = mk_section_args_fun t.doc;
5597 test = mk_section_args_fun t.test;
5598 install = mk_std_args_fun t.install;
5599 uninstall = mk_std_args_fun t.uninstall;
5600 clean = List.map mk_std_args_fun t.clean;
5601 clean_doc = mk_section_args_fun t.clean_doc;
5602 clean_test = mk_section_args_fun t.clean_test;
5603 distclean = List.map mk_std_args_fun t.distclean;
5604 distclean_doc = mk_section_args_fun t.distclean_doc;
5605 distclean_test = mk_section_args_fun t.distclean_test;
5607 package = t.package;
5608 oasis_fn = t.oasis_fn;
5609 oasis_version = t.oasis_version;
5610 oasis_digest = t.oasis_digest;
5611 oasis_exec = t.oasis_exec;
5612 oasis_setup_args = t.oasis_setup_args;
5613 setup_update = t.setup_update;
5616 Original.setup t'
5620 let adapt_setup_t setup_t =
5621 let module O = BaseSetup.Original in
5622 let mk_std_args_fun f = fun pkg args -> f ~ctxt:!rctxt pkg args in
5623 let mk_section_args_fun l =
5624 List.map
5625 (fun (nm, f) -> nm, (fun pkg sct args -> f ~ctxt:!rctxt pkg sct args))
5629 BaseSetup.
5630 configure = mk_std_args_fun setup_t.O.configure;
5631 build = mk_std_args_fun setup_t.O.build;
5632 doc = mk_section_args_fun setup_t.O.doc;
5633 test = mk_section_args_fun setup_t.O.test;
5634 install = mk_std_args_fun setup_t.O.install;
5635 uninstall = mk_std_args_fun setup_t.O.uninstall;
5636 clean = List.map mk_std_args_fun setup_t.O.clean;
5637 clean_doc = mk_section_args_fun setup_t.O.clean_doc;
5638 clean_test = mk_section_args_fun setup_t.O.clean_test;
5639 distclean = List.map mk_std_args_fun setup_t.O.distclean;
5640 distclean_doc = mk_section_args_fun setup_t.O.distclean_doc;
5641 distclean_test = mk_section_args_fun setup_t.O.distclean_test;
5643 package = setup_t.O.package;
5644 oasis_fn = setup_t.O.oasis_fn;
5645 oasis_version = setup_t.O.oasis_version;
5646 oasis_digest = setup_t.O.oasis_digest;
5647 oasis_exec = setup_t.O.oasis_exec;
5648 oasis_setup_args = setup_t.O.oasis_setup_args;
5649 setup_update = setup_t.O.setup_update;
5654 module Compat_0_3 =
5655 struct
5656 include Compat_0_4
5662 # 5662 "setup.ml"
5663 module InternalConfigurePlugin = struct
5664 (* # 22 "src/plugins/internal/InternalConfigurePlugin.ml" *)
5667 (** Configure using internal scheme
5668 @author Sylvain Le Gall
5672 open BaseEnv
5673 open OASISTypes
5674 open OASISUtils
5675 open OASISGettext
5676 open BaseMessage
5679 (** Configure build using provided series of check to be done
5680 and then output corresponding file.
5682 let configure ~ctxt:_ pkg argv =
5683 let var_ignore_eval var = let _s: string = var () in () in
5684 let errors = ref SetString.empty in
5685 let buff = Buffer.create 13 in
5687 let add_errors fmt =
5688 Printf.kbprintf
5689 (fun b ->
5690 errors := SetString.add (Buffer.contents b) !errors;
5691 Buffer.clear b)
5692 buff
5696 let warn_exception e =
5697 warning "%s" (Printexc.to_string e)
5700 (* Check tools *)
5701 let check_tools lst =
5702 List.iter
5703 (function
5704 | ExternalTool tool ->
5705 begin
5707 var_ignore_eval (BaseCheck.prog tool)
5708 with e ->
5709 warn_exception e;
5710 add_errors (f_ "Cannot find external tool '%s'") tool
5712 | InternalExecutable nm1 ->
5713 (* Check that matching tool is built *)
5714 List.iter
5715 (function
5716 | Executable ({cs_name = nm2; _},
5717 {bs_build = build; _},
5718 _) when nm1 = nm2 ->
5719 if not (var_choose build) then
5720 add_errors
5721 (f_ "Cannot find buildable internal executable \
5722 '%s' when checking build depends")
5724 | _ ->
5726 pkg.sections)
5730 let build_checks sct bs =
5731 if var_choose bs.bs_build then
5732 begin
5733 if bs.bs_compiled_object = Native then
5734 begin
5736 var_ignore_eval BaseStandardVar.ocamlopt
5737 with e ->
5738 warn_exception e;
5739 add_errors
5740 (f_ "Section %s requires native compilation")
5741 (OASISSection.string_of_section sct)
5742 end;
5744 (* Check tools *)
5745 check_tools bs.bs_build_tools;
5747 (* Check depends *)
5748 List.iter
5749 (function
5750 | FindlibPackage (findlib_pkg, version_comparator) ->
5751 begin
5753 var_ignore_eval
5754 (BaseCheck.package ?version_comparator findlib_pkg)
5755 with e ->
5756 warn_exception e;
5757 match version_comparator with
5758 | None ->
5759 add_errors
5760 (f_ "Cannot find findlib package %s")
5761 findlib_pkg
5762 | Some ver_cmp ->
5763 add_errors
5764 (f_ "Cannot find findlib package %s (%s)")
5765 findlib_pkg
5766 (OASISVersion.string_of_comparator ver_cmp)
5768 | InternalLibrary nm1 ->
5769 (* Check that matching library is built *)
5770 List.iter
5771 (function
5772 | Library ({cs_name = nm2; _},
5773 {bs_build = build; _},
5774 _) when nm1 = nm2 ->
5775 if not (var_choose build) then
5776 add_errors
5777 (f_ "Cannot find buildable internal library \
5778 '%s' when checking build depends")
5780 | _ ->
5782 pkg.sections)
5783 bs.bs_build_depends
5787 (* Parse command line *)
5788 BaseArgExt.parse argv (BaseEnv.args ());
5790 (* OCaml version *)
5791 begin
5792 match pkg.ocaml_version with
5793 | Some ver_cmp ->
5794 begin
5796 var_ignore_eval
5797 (BaseCheck.version
5798 "ocaml"
5799 ver_cmp
5800 BaseStandardVar.ocaml_version)
5801 with e ->
5802 warn_exception e;
5803 add_errors
5804 (f_ "OCaml version %s doesn't match version constraint %s")
5805 (BaseStandardVar.ocaml_version ())
5806 (OASISVersion.string_of_comparator ver_cmp)
5808 | None ->
5810 end;
5812 (* Findlib version *)
5813 begin
5814 match pkg.findlib_version with
5815 | Some ver_cmp ->
5816 begin
5818 var_ignore_eval
5819 (BaseCheck.version
5820 "findlib"
5821 ver_cmp
5822 BaseStandardVar.findlib_version)
5823 with e ->
5824 warn_exception e;
5825 add_errors
5826 (f_ "Findlib version %s doesn't match version constraint %s")
5827 (BaseStandardVar.findlib_version ())
5828 (OASISVersion.string_of_comparator ver_cmp)
5830 | None ->
5832 end;
5833 (* Make sure the findlib version is fine for the OCaml compiler. *)
5834 begin
5835 let ocaml_ge4 =
5836 OASISVersion.version_compare
5837 (OASISVersion.version_of_string (BaseStandardVar.ocaml_version ()))
5838 (OASISVersion.version_of_string "4.0.0") >= 0 in
5839 if ocaml_ge4 then
5840 let findlib_lt132 =
5841 OASISVersion.version_compare
5842 (OASISVersion.version_of_string (BaseStandardVar.findlib_version()))
5843 (OASISVersion.version_of_string "1.3.2") < 0 in
5844 if findlib_lt132 then
5845 add_errors "OCaml >= 4.0.0 requires Findlib version >= 1.3.2"
5846 end;
5848 (* FlexDLL *)
5849 if BaseStandardVar.os_type () = "Win32" ||
5850 BaseStandardVar.os_type () = "Cygwin" then
5851 begin
5853 var_ignore_eval BaseStandardVar.flexlink
5854 with e ->
5855 warn_exception e;
5856 add_errors (f_ "Cannot find 'flexlink'")
5857 end;
5859 (* Check build depends *)
5860 List.iter
5861 (function
5862 | Executable (_, bs, _)
5863 | Library (_, bs, _) as sct ->
5864 build_checks sct bs
5865 | Doc (_, doc) ->
5866 if var_choose doc.doc_build then
5867 check_tools doc.doc_build_tools
5868 | Test (_, test) ->
5869 if var_choose test.test_run then
5870 check_tools test.test_tools
5871 | _ ->
5873 pkg.sections;
5875 (* Check if we need native dynlink (presence of libraries that compile to
5876 native)
5878 begin
5879 let has_cmxa =
5880 List.exists
5881 (function
5882 | Library (_, bs, _) ->
5883 var_choose bs.bs_build &&
5884 (bs.bs_compiled_object = Native ||
5885 (bs.bs_compiled_object = Best &&
5886 bool_of_string (BaseStandardVar.is_native ())))
5887 | _ ->
5888 false)
5889 pkg.sections
5891 if has_cmxa then
5892 var_ignore_eval BaseStandardVar.native_dynlink
5893 end;
5895 (* Check errors *)
5896 if SetString.empty != !errors then
5897 begin
5898 List.iter
5899 (fun e -> error "%s" e)
5900 (SetString.elements !errors);
5901 failwithf
5902 (fn_
5903 "%d configuration error"
5904 "%d configuration errors"
5905 (SetString.cardinal !errors))
5906 (SetString.cardinal !errors)
5912 module InternalInstallPlugin = struct
5913 (* # 22 "src/plugins/internal/InternalInstallPlugin.ml" *)
5916 (** Install using internal scheme
5917 @author Sylvain Le Gall
5921 (* TODO: rewrite this module with OASISFileSystem. *)
5923 open BaseEnv
5924 open BaseStandardVar
5925 open BaseMessage
5926 open OASISTypes
5927 open OASISFindlib
5928 open OASISGettext
5929 open OASISUtils
5932 let exec_hook = ref (fun (cs, bs, exec) -> cs, bs, exec)
5933 let lib_hook = ref (fun (cs, bs, dn, lib) -> cs, bs, dn, lib, [])
5934 let obj_hook = ref (fun (cs, bs, dn, obj) -> cs, bs, dn, obj, [])
5935 let doc_hook = ref (fun (cs, doc) -> cs, doc)
5937 let install_file_ev = "install-file"
5938 let install_dir_ev = "install-dir"
5939 let install_findlib_ev = "install-findlib"
5942 (* TODO: this can be more generic and used elsewhere. *)
5943 let win32_max_command_line_length = 8000
5946 let split_install_command ocamlfind findlib_name meta files =
5947 if Sys.os_type = "Win32" then
5948 (* Arguments for the first command: *)
5949 let first_args = ["install"; findlib_name; meta] in
5950 (* Arguments for remaining commands: *)
5951 let other_args = ["install"; findlib_name; "-add"] in
5952 (* Extract as much files as possible from [files], [len] is
5953 the current command line length: *)
5954 let rec get_files len acc files =
5955 match files with
5956 | [] ->
5957 (List.rev acc, [])
5958 | file :: rest ->
5959 let len = len + 1 + String.length file in
5960 if len > win32_max_command_line_length then
5961 (List.rev acc, files)
5962 else
5963 get_files len (file :: acc) rest
5965 (* Split the command into several commands. *)
5966 let rec split args files =
5967 match files with
5968 | [] ->
5970 | _ ->
5971 (* Length of "ocamlfind install <lib> [META|-add]" *)
5972 let len =
5973 List.fold_left
5974 (fun len arg ->
5975 len + 1 (* for the space *) + String.length arg)
5976 (String.length ocamlfind)
5977 args
5979 match get_files len [] files with
5980 | ([], _) ->
5981 failwith (s_ "Command line too long.")
5982 | (firsts, others) ->
5983 let cmd = args @ firsts in
5984 (* Use -add for remaining commands: *)
5985 let () =
5986 let findlib_ge_132 =
5987 OASISVersion.comparator_apply
5988 (OASISVersion.version_of_string
5989 (BaseStandardVar.findlib_version ()))
5990 (OASISVersion.VGreaterEqual
5991 (OASISVersion.version_of_string "1.3.2"))
5993 if not findlib_ge_132 then
5994 failwithf
5995 (f_ "Installing the library %s require to use the \
5996 flag '-add' of ocamlfind because the command \
5997 line is too long. This flag is only available \
5998 for findlib 1.3.2. Please upgrade findlib from \
5999 %s to 1.3.2")
6000 findlib_name (BaseStandardVar.findlib_version ())
6002 let cmds = split other_args others in
6003 cmd :: cmds
6005 (* The first command does not use -add: *)
6006 split first_args files
6007 else
6008 ["install" :: findlib_name :: meta :: files]
6011 let install =
6013 let in_destdir fn =
6015 (* Practically speaking destdir is prepended at the beginning of the
6016 target filename
6018 (destdir ())^fn
6019 with PropList.Not_set _ ->
6023 let install_file ~ctxt ?(prepend_destdir=true) ?tgt_fn src_file envdir =
6024 let tgt_dir =
6025 if prepend_destdir then in_destdir (envdir ()) else envdir ()
6027 let tgt_file =
6028 Filename.concat
6029 tgt_dir
6030 (match tgt_fn with
6031 | Some fn ->
6033 | None ->
6034 Filename.basename src_file)
6036 (* Create target directory if needed *)
6037 OASISFileUtil.mkdir_parent
6038 ~ctxt
6039 (fun dn ->
6040 info (f_ "Creating directory '%s'") dn;
6041 BaseLog.register ~ctxt install_dir_ev dn)
6042 (Filename.dirname tgt_file);
6044 (* Really install files *)
6045 info (f_ "Copying file '%s' to '%s'") src_file tgt_file;
6046 OASISFileUtil.cp ~ctxt src_file tgt_file;
6047 BaseLog.register ~ctxt install_file_ev tgt_file
6050 (* Install the files for a library. *)
6052 let install_lib_files ~ctxt findlib_name files =
6053 let findlib_dir =
6054 let dn =
6055 let findlib_destdir =
6056 OASISExec.run_read_one_line ~ctxt (ocamlfind ())
6057 ["printconf" ; "destdir"]
6059 Filename.concat findlib_destdir findlib_name
6061 fun () -> dn
6063 let () =
6064 if not (OASISFileUtil.file_exists_case (findlib_dir ())) then
6065 failwithf
6066 (f_ "Directory '%s' doesn't exist for findlib library %s")
6067 (findlib_dir ()) findlib_name
6069 let f dir file =
6070 let basename = Filename.basename file in
6071 let tgt_fn = Filename.concat dir basename in
6072 (* Destdir is already include in printconf. *)
6073 install_file ~ctxt ~prepend_destdir:false ~tgt_fn file findlib_dir
6075 List.iter (fun (dir, files) -> List.iter (f dir) files) files ;
6078 (* Install data into defined directory *)
6079 let install_data ~ctxt srcdir lst tgtdir =
6080 let tgtdir =
6081 OASISHostPath.of_unix (var_expand tgtdir)
6083 List.iter
6084 (fun (src, tgt_opt) ->
6085 let real_srcs =
6086 OASISFileUtil.glob
6087 ~ctxt:!BaseContext.default
6088 (Filename.concat srcdir src)
6090 if real_srcs = [] then
6091 failwithf
6092 (f_ "Wildcard '%s' doesn't match any files")
6093 src;
6094 List.iter
6095 (fun fn ->
6096 install_file ~ctxt
6098 (fun () ->
6099 match tgt_opt with
6100 | Some s ->
6101 OASISHostPath.of_unix (var_expand s)
6102 | None ->
6103 tgtdir))
6104 real_srcs)
6108 let make_fnames modul sufx =
6109 List.fold_right
6110 begin fun sufx accu ->
6111 (OASISString.capitalize_ascii modul ^ sufx) ::
6112 (OASISString.uncapitalize_ascii modul ^ sufx) ::
6113 accu
6115 sufx
6119 (** Install all libraries *)
6120 let install_libs ~ctxt pkg =
6122 let find_first_existing_files_in_path bs lst =
6123 let path = OASISHostPath.of_unix bs.bs_path in
6124 List.find
6125 OASISFileUtil.file_exists_case
6126 (List.map (Filename.concat path) lst)
6129 let files_of_modules new_files typ cs bs modules =
6130 List.fold_left
6131 (fun acc modul ->
6132 begin
6134 (* Add uncompiled header from the source tree *)
6135 [find_first_existing_files_in_path
6136 bs (make_fnames modul [".mli"; ".ml"])]
6137 with Not_found ->
6138 warning
6139 (f_ "Cannot find source header for module %s \
6140 in %s %s")
6141 typ modul cs.cs_name;
6145 List.fold_left
6146 (fun acc fn ->
6148 find_first_existing_files_in_path bs [fn] :: acc
6149 with Not_found ->
6150 acc)
6151 acc (make_fnames modul [".annot";".cmti";".cmt"]))
6152 new_files
6153 modules
6156 let files_of_build_section (f_data, new_files) typ cs bs =
6157 let extra_files =
6158 List.map
6159 (fun fn ->
6161 find_first_existing_files_in_path bs [fn]
6162 with Not_found ->
6163 failwithf
6164 (f_ "Cannot find extra findlib file %S in %s %s ")
6167 cs.cs_name)
6168 bs.bs_findlib_extra_files
6170 let f_data () =
6171 (* Install data associated with the library *)
6172 install_data
6173 ~ctxt
6174 bs.bs_path
6175 bs.bs_data_files
6176 (Filename.concat
6177 (datarootdir ())
6178 pkg.name);
6179 f_data ()
6181 f_data, new_files @ extra_files
6184 let files_of_library (f_data, acc) data_lib =
6185 let cs, bs, lib, dn, lib_extra = !lib_hook data_lib in
6186 if var_choose bs.bs_install &&
6187 BaseBuilt.is_built ~ctxt BaseBuilt.BLib cs.cs_name then begin
6188 (* Start with lib_extra *)
6189 let new_files = lib_extra in
6190 let new_files =
6191 files_of_modules new_files "library" cs bs lib.lib_modules
6193 let f_data, new_files =
6194 files_of_build_section (f_data, new_files) "library" cs bs
6196 let new_files =
6197 (* Get generated files *)
6198 BaseBuilt.fold
6199 ~ctxt
6200 BaseBuilt.BLib
6201 cs.cs_name
6202 (fun acc fn -> fn :: acc)
6203 new_files
6205 let acc = (dn, new_files) :: acc in
6207 let f_data () =
6208 (* Install data associated with the library *)
6209 install_data
6210 ~ctxt
6211 bs.bs_path
6212 bs.bs_data_files
6213 (Filename.concat
6214 (datarootdir ())
6215 pkg.name);
6216 f_data ()
6219 (f_data, acc)
6220 end else begin
6221 (f_data, acc)
6223 and files_of_object (f_data, acc) data_obj =
6224 let cs, bs, obj, dn, obj_extra = !obj_hook data_obj in
6225 if var_choose bs.bs_install &&
6226 BaseBuilt.is_built ~ctxt BaseBuilt.BObj cs.cs_name then begin
6227 (* Start with obj_extra *)
6228 let new_files = obj_extra in
6229 let new_files =
6230 files_of_modules new_files "object" cs bs obj.obj_modules
6232 let f_data, new_files =
6233 files_of_build_section (f_data, new_files) "object" cs bs
6236 let new_files =
6237 (* Get generated files *)
6238 BaseBuilt.fold
6239 ~ctxt
6240 BaseBuilt.BObj
6241 cs.cs_name
6242 (fun acc fn -> fn :: acc)
6243 new_files
6245 let acc = (dn, new_files) :: acc in
6247 let f_data () =
6248 (* Install data associated with the object *)
6249 install_data
6250 ~ctxt
6251 bs.bs_path
6252 bs.bs_data_files
6253 (Filename.concat (datarootdir ()) pkg.name);
6254 f_data ()
6256 (f_data, acc)
6257 end else begin
6258 (f_data, acc)
6262 (* Install one group of library *)
6263 let install_group_lib grp =
6264 (* Iterate through all group nodes *)
6265 let rec install_group_lib_aux data_and_files grp =
6266 let data_and_files, children =
6267 match grp with
6268 | Container (_, children) ->
6269 data_and_files, children
6270 | Package (_, cs, bs, `Library lib, dn, children) ->
6271 files_of_library data_and_files (cs, bs, lib, dn), children
6272 | Package (_, cs, bs, `Object obj, dn, children) ->
6273 files_of_object data_and_files (cs, bs, obj, dn), children
6275 List.fold_left
6276 install_group_lib_aux
6277 data_and_files
6278 children
6281 (* Findlib name of the root library *)
6282 let findlib_name = findlib_of_group grp in
6284 (* Determine root library *)
6285 let root_lib = root_of_group grp in
6287 (* All files to install for this library *)
6288 let f_data, files = install_group_lib_aux (ignore, []) grp in
6290 (* Really install, if there is something to install *)
6291 if files = [] then begin
6292 warning
6293 (f_ "Nothing to install for findlib library '%s'") findlib_name
6294 end else begin
6295 let meta =
6296 (* Search META file *)
6297 let _, bs, _ = root_lib in
6298 let res = Filename.concat bs.bs_path "META" in
6299 if not (OASISFileUtil.file_exists_case res) then
6300 failwithf
6301 (f_ "Cannot find file '%s' for findlib library %s")
6303 findlib_name;
6306 let files =
6307 (* Make filename shorter to avoid hitting command max line length
6308 * too early, esp. on Windows.
6310 (* TODO: move to OASISHostPath as make_relative. *)
6311 let remove_prefix p n =
6312 let plen = String.length p in
6313 let nlen = String.length n in
6314 if plen <= nlen && String.sub n 0 plen = p then begin
6315 let fn_sep = if Sys.os_type = "Win32" then '\\' else '/' in
6316 let cutpoint =
6317 plen +
6318 (if plen < nlen && n.[plen] = fn_sep then 1 else 0)
6320 String.sub n cutpoint (nlen - cutpoint)
6321 end else begin
6325 List.map
6326 (fun (dir, fn) ->
6327 (dir, List.map (remove_prefix (Sys.getcwd ())) fn))
6328 files
6330 let ocamlfind = ocamlfind () in
6331 let nodir_files, dir_files =
6332 List.fold_left
6333 (fun (nodir, dir) (dn, lst) ->
6334 match dn with
6335 | Some dn -> nodir, (dn, lst) :: dir
6336 | None -> lst @ nodir, dir)
6337 ([], [])
6338 (List.rev files)
6340 info (f_ "Installing findlib library '%s'") findlib_name;
6341 List.iter
6342 (OASISExec.run ~ctxt ocamlfind)
6343 (split_install_command ocamlfind findlib_name meta nodir_files);
6344 install_lib_files ~ctxt findlib_name dir_files;
6345 BaseLog.register ~ctxt install_findlib_ev findlib_name
6346 end;
6348 (* Install data files *)
6349 f_data ();
6352 let group_libs, _, _ = findlib_mapping pkg in
6354 (* We install libraries in groups *)
6355 List.iter install_group_lib group_libs
6358 let install_execs ~ctxt pkg =
6359 let install_exec data_exec =
6360 let cs, bs, _ = !exec_hook data_exec in
6361 if var_choose bs.bs_install &&
6362 BaseBuilt.is_built ~ctxt BaseBuilt.BExec cs.cs_name then begin
6363 let exec_libdir () = Filename.concat (libdir ()) pkg.name in
6364 BaseBuilt.fold
6365 ~ctxt
6366 BaseBuilt.BExec
6367 cs.cs_name
6368 (fun () fn ->
6369 install_file ~ctxt
6370 ~tgt_fn:(cs.cs_name ^ ext_program ())
6372 bindir)
6374 BaseBuilt.fold
6375 ~ctxt
6376 BaseBuilt.BExecLib
6377 cs.cs_name
6378 (fun () fn -> install_file ~ctxt fn exec_libdir)
6380 install_data ~ctxt
6381 bs.bs_path
6382 bs.bs_data_files
6383 (Filename.concat (datarootdir ()) pkg.name)
6386 List.iter
6387 (function
6388 | Executable (cs, bs, exec)-> install_exec (cs, bs, exec)
6389 | _ -> ())
6390 pkg.sections
6393 let install_docs ~ctxt pkg =
6394 let install_doc data =
6395 let cs, doc = !doc_hook data in
6396 if var_choose doc.doc_install &&
6397 BaseBuilt.is_built ~ctxt BaseBuilt.BDoc cs.cs_name then begin
6398 let tgt_dir = OASISHostPath.of_unix (var_expand doc.doc_install_dir) in
6399 BaseBuilt.fold
6400 ~ctxt
6401 BaseBuilt.BDoc
6402 cs.cs_name
6403 (fun () fn -> install_file ~ctxt fn (fun () -> tgt_dir))
6405 install_data ~ctxt
6406 Filename.current_dir_name
6407 doc.doc_data_files
6408 doc.doc_install_dir
6411 List.iter
6412 (function
6413 | Doc (cs, doc) -> install_doc (cs, doc)
6414 | _ -> ())
6415 pkg.sections
6417 fun ~ctxt pkg _ ->
6418 install_libs ~ctxt pkg;
6419 install_execs ~ctxt pkg;
6420 install_docs ~ctxt pkg
6423 (* Uninstall already installed data *)
6424 let uninstall ~ctxt _ _ =
6425 let uninstall_aux (ev, data) =
6426 if ev = install_file_ev then begin
6427 if OASISFileUtil.file_exists_case data then begin
6428 info (f_ "Removing file '%s'") data;
6429 Sys.remove data
6430 end else begin
6431 warning (f_ "File '%s' doesn't exist anymore") data
6433 end else if ev = install_dir_ev then begin
6434 if Sys.file_exists data && Sys.is_directory data then begin
6435 if Sys.readdir data = [||] then begin
6436 info (f_ "Removing directory '%s'") data;
6437 OASISFileUtil.rmdir ~ctxt data
6438 end else begin
6439 warning
6440 (f_ "Directory '%s' is not empty (%s)")
6441 data
6442 (String.concat ", " (Array.to_list (Sys.readdir data)))
6444 end else begin
6445 warning (f_ "Directory '%s' doesn't exist anymore") data
6447 end else if ev = install_findlib_ev then begin
6448 info (f_ "Removing findlib library '%s'") data;
6449 OASISExec.run ~ctxt (ocamlfind ()) ["remove"; data]
6450 end else begin
6451 failwithf (f_ "Unknown log event '%s'") ev;
6452 end;
6453 BaseLog.unregister ~ctxt ev data
6455 (* We process event in reverse order *)
6456 List.iter uninstall_aux
6457 (List.rev
6458 (BaseLog.filter ~ctxt [install_file_ev; install_dir_ev]));
6459 List.iter uninstall_aux
6460 (List.rev (BaseLog.filter ~ctxt [install_findlib_ev]))
6465 # 6465 "setup.ml"
6466 module OCamlbuildCommon = struct
6467 (* # 22 "src/plugins/ocamlbuild/OCamlbuildCommon.ml" *)
6470 (** Functions common to OCamlbuild build and doc plugin
6474 open OASISGettext
6475 open BaseEnv
6476 open BaseStandardVar
6477 open OASISTypes
6480 type args =
6482 plugin_tags: string option;
6483 extra: string list;
6487 let ocamlbuild_clean_ev = "ocamlbuild-clean"
6490 let ocamlbuildflags =
6491 var_define
6492 ~short_desc:(fun () -> "OCamlbuild additional flags")
6493 "ocamlbuildflags"
6494 (fun () -> "")
6497 (** Fix special arguments depending on environment *)
6498 let fix_args args extra_argv =
6499 List.flatten
6501 if (os_type ()) = "Win32" then
6503 "-classic-display";
6504 "-no-log";
6505 "-no-links";
6507 else
6510 if OASISVersion.comparator_apply
6511 (OASISVersion.version_of_string (ocaml_version ()))
6512 (OASISVersion.VLesser (OASISVersion.version_of_string "3.11.1")) then
6514 "-install-lib-dir";
6515 (Filename.concat (standard_library ()) "ocamlbuild")
6517 else
6520 if not (bool_of_string (is_native ())) || (os_type ()) = "Win32" then
6522 "-byte-plugin"
6524 else
6527 args.extra;
6529 begin
6530 match args.plugin_tags with
6531 | Some t -> ["-plugin-tag"; Filename.quote t]
6532 | None -> []
6533 end;
6535 if bool_of_string (debug ()) then
6536 ["-tag"; "debug"]
6537 else
6540 if bool_of_string (tests ()) then
6541 ["-tag"; "tests"]
6542 else
6545 if bool_of_string (profile ()) then
6546 ["-tag"; "profile"]
6547 else
6550 OASISString.nsplit (ocamlbuildflags ()) ' ';
6552 Array.to_list extra_argv;
6556 (** Run 'ocamlbuild -clean' if not already done *)
6557 let run_clean ~ctxt extra_argv =
6558 let extra_cli =
6559 String.concat " " (Array.to_list extra_argv)
6561 (* Run if never called with these args *)
6562 if not (BaseLog.exists ~ctxt ocamlbuild_clean_ev extra_cli) then
6563 begin
6564 OASISExec.run
6565 ~ctxt (ocamlbuild ())
6566 (fix_args {extra = ["-clean"]; plugin_tags = None} extra_argv);
6567 BaseLog.register ~ctxt ocamlbuild_clean_ev extra_cli;
6568 at_exit
6569 (fun () ->
6571 BaseLog.unregister ~ctxt ocamlbuild_clean_ev extra_cli
6572 with _ -> ())
6576 (** Run ocamlbuild, unregister all clean events *)
6577 let run_ocamlbuild ~ctxt args extra_argv =
6578 (* TODO: enforce that target in args must be UNIX encoded i.e. toto/index.html
6580 OASISExec.run ~ctxt (ocamlbuild ()) (fix_args args extra_argv);
6581 (* Remove any clean event, we must run it again *)
6582 List.iter
6583 (fun (e, d) -> BaseLog.unregister ~ctxt e d)
6584 (BaseLog.filter ~ctxt [ocamlbuild_clean_ev])
6587 (** Determine real build directory *)
6588 let build_dir extra_argv =
6589 let rec search_args dir =
6590 function
6591 | "-build-dir" :: dir :: tl ->
6592 search_args dir tl
6593 | _ :: tl ->
6594 search_args dir tl
6595 | [] ->
6598 search_args "_build" (fix_args {extra = []; plugin_tags = None} extra_argv)
6603 module OCamlbuildPlugin = struct
6604 (* # 22 "src/plugins/ocamlbuild/OCamlbuildPlugin.ml" *)
6607 (** Build using ocamlbuild
6608 @author Sylvain Le Gall
6612 open OASISTypes
6613 open OASISGettext
6614 open OASISUtils
6615 open OASISString
6616 open BaseEnv
6617 open OCamlbuildCommon
6618 open BaseStandardVar
6621 let cond_targets_hook = ref (fun lst -> lst)
6624 let build ~ctxt args pkg argv =
6625 (* Return the filename in build directory *)
6626 let in_build_dir fn =
6627 Filename.concat
6628 (build_dir argv)
6632 (* Return the unix filename in host build directory *)
6633 let in_build_dir_of_unix fn =
6634 in_build_dir (OASISHostPath.of_unix fn)
6637 let cond_targets =
6638 List.fold_left
6639 (fun acc ->
6640 function
6641 | Library (cs, bs, lib) when var_choose bs.bs_build ->
6642 begin
6643 let evs, unix_files =
6644 BaseBuilt.of_library
6645 in_build_dir_of_unix
6646 (cs, bs, lib)
6649 let tgts =
6650 List.flatten
6651 (List.filter
6652 (fun l -> l <> [])
6653 (List.map
6654 (List.filter
6655 (fun fn ->
6656 ends_with ~what:".cma" fn
6657 || ends_with ~what:".cmxs" fn
6658 || ends_with ~what:".cmxa" fn
6659 || ends_with ~what:(ext_lib ()) fn
6660 || ends_with ~what:(ext_dll ()) fn))
6661 unix_files))
6664 match tgts with
6665 | _ :: _ ->
6666 (evs, tgts) :: acc
6667 | [] ->
6668 failwithf
6669 (f_ "No possible ocamlbuild targets for library %s")
6670 cs.cs_name
6673 | Object (cs, bs, obj) when var_choose bs.bs_build ->
6674 begin
6675 let evs, unix_files =
6676 BaseBuilt.of_object
6677 in_build_dir_of_unix
6678 (cs, bs, obj)
6681 let tgts =
6682 List.flatten
6683 (List.filter
6684 (fun l -> l <> [])
6685 (List.map
6686 (List.filter
6687 (fun fn ->
6688 ends_with ~what:".cmo" fn
6689 || ends_with ~what:".cmx" fn))
6690 unix_files))
6693 match tgts with
6694 | _ :: _ ->
6695 (evs, tgts) :: acc
6696 | [] ->
6697 failwithf
6698 (f_ "No possible ocamlbuild targets for object %s")
6699 cs.cs_name
6702 | Executable (cs, bs, exec) when var_choose bs.bs_build ->
6703 begin
6704 let evs, _, _ =
6705 BaseBuilt.of_executable in_build_dir_of_unix (cs, bs, exec)
6708 let target ext =
6709 let unix_tgt =
6710 (OASISUnixPath.concat
6711 bs.bs_path
6712 (OASISUnixPath.chop_extension
6713 exec.exec_main_is))^ext
6715 let evs =
6716 (* Fix evs, we want to use the unix_tgt, without copying *)
6717 List.map
6718 (function
6719 | BaseBuilt.BExec, nm, _ when nm = cs.cs_name ->
6720 BaseBuilt.BExec, nm,
6721 [[in_build_dir_of_unix unix_tgt]]
6722 | ev ->
6726 evs, [unix_tgt]
6729 (* Add executable *)
6730 let acc =
6731 match bs.bs_compiled_object with
6732 | Native ->
6733 (target ".native") :: acc
6734 | Best when bool_of_string (is_native ()) ->
6735 (target ".native") :: acc
6736 | Byte
6737 | Best ->
6738 (target ".byte") :: acc
6743 | Library _ | Object _ | Executable _ | Test _
6744 | SrcRepo _ | Flag _ | Doc _ ->
6745 acc)
6747 (* Keep the pkg.sections ordered *)
6748 (List.rev pkg.sections);
6751 (* Check and register built files *)
6752 let check_and_register (bt, bnm, lst) =
6753 List.iter
6754 (fun fns ->
6755 if not (List.exists OASISFileUtil.file_exists_case fns) then
6756 failwithf
6757 (fn_
6758 "Expected built file %s doesn't exist."
6759 "None of expected built files %s exists."
6760 (List.length fns))
6761 (String.concat (s_ " or ") (List.map (Printf.sprintf "'%s'") fns)))
6762 lst;
6763 (BaseBuilt.register ~ctxt bt bnm lst)
6766 (* Run the hook *)
6767 let cond_targets = !cond_targets_hook cond_targets in
6769 (* Run a list of target... *)
6770 run_ocamlbuild
6771 ~ctxt
6772 {args with extra = List.flatten (List.map snd cond_targets) @ args.extra}
6773 argv;
6774 (* ... and register events *)
6775 List.iter check_and_register (List.flatten (List.map fst cond_targets))
6778 let clean ~ctxt pkg args =
6779 run_clean ~ctxt args;
6780 List.iter
6781 (function
6782 | Library (cs, _, _) ->
6783 BaseBuilt.unregister ~ctxt BaseBuilt.BLib cs.cs_name
6784 | Executable (cs, _, _) ->
6785 BaseBuilt.unregister ~ctxt BaseBuilt.BExec cs.cs_name;
6786 BaseBuilt.unregister ~ctxt BaseBuilt.BExecLib cs.cs_name
6787 | _ ->
6789 pkg.sections
6794 module OCamlbuildDocPlugin = struct
6795 (* # 22 "src/plugins/ocamlbuild/OCamlbuildDocPlugin.ml" *)
6798 (* Create documentation using ocamlbuild .odocl files
6799 @author Sylvain Le Gall
6803 open OASISTypes
6804 open OASISGettext
6805 open OCamlbuildCommon
6808 type run_t =
6810 args: args;
6811 run_path: unix_filename;
6815 let doc_build ~ctxt run _ (cs, _) argv =
6816 let index_html =
6817 OASISUnixPath.make
6819 run.run_path;
6820 cs.cs_name^".docdir";
6821 "index.html";
6824 let tgt_dir =
6825 OASISHostPath.make
6827 build_dir argv;
6828 OASISHostPath.of_unix run.run_path;
6829 cs.cs_name^".docdir";
6832 run_ocamlbuild ~ctxt
6833 {run.args with extra = index_html :: run.args.extra} argv;
6834 List.iter
6835 (fun glb ->
6836 match OASISFileUtil.glob ~ctxt (Filename.concat tgt_dir glb) with
6837 | (_ :: _) as filenames ->
6838 BaseBuilt.register ~ctxt BaseBuilt.BDoc cs.cs_name [filenames]
6839 | [] -> ())
6840 ["*.html"; "*.css"]
6843 let doc_clean ~ctxt _ _ (cs, _) argv =
6844 run_clean ~ctxt argv;
6845 BaseBuilt.unregister ~ctxt BaseBuilt.BDoc cs.cs_name
6851 # 6851 "setup.ml"
6852 module CustomPlugin = struct
6853 (* # 22 "src/plugins/custom/CustomPlugin.ml" *)
6856 (** Generate custom configure/build/doc/test/install system
6857 @author
6861 open BaseEnv
6862 open OASISGettext
6863 open OASISTypes
6865 type t =
6867 cmd_main: command_line conditional;
6868 cmd_clean: (command_line option) conditional;
6869 cmd_distclean: (command_line option) conditional;
6873 let run = BaseCustom.run
6876 let main ~ctxt:_ t _ extra_args =
6877 let cmd, args = var_choose ~name:(s_ "main command") t.cmd_main in
6878 run cmd args extra_args
6881 let clean ~ctxt:_ t _ extra_args =
6882 match var_choose t.cmd_clean with
6883 | Some (cmd, args) -> run cmd args extra_args
6884 | _ -> ()
6887 let distclean ~ctxt:_ t _ extra_args =
6888 match var_choose t.cmd_distclean with
6889 | Some (cmd, args) -> run cmd args extra_args
6890 | _ -> ()
6893 module Build =
6894 struct
6895 let main ~ctxt t pkg extra_args =
6896 main ~ctxt t pkg extra_args;
6897 List.iter
6898 (fun sct ->
6899 let evs =
6900 match sct with
6901 | Library (cs, bs, lib) when var_choose bs.bs_build ->
6902 begin
6903 let evs, _ =
6904 BaseBuilt.of_library
6905 OASISHostPath.of_unix
6906 (cs, bs, lib)
6910 | Executable (cs, bs, exec) when var_choose bs.bs_build ->
6911 begin
6912 let evs, _, _ =
6913 BaseBuilt.of_executable
6914 OASISHostPath.of_unix
6915 (cs, bs, exec)
6919 | _ ->
6922 List.iter
6923 (fun (bt, bnm, lst) -> BaseBuilt.register ~ctxt bt bnm lst)
6924 evs)
6925 pkg.sections
6927 let clean ~ctxt t pkg extra_args =
6928 clean ~ctxt t pkg extra_args;
6929 (* TODO: this seems to be pretty generic (at least wrt to ocamlbuild
6930 * considering moving this to BaseSetup?
6932 List.iter
6933 (function
6934 | Library (cs, _, _) ->
6935 BaseBuilt.unregister ~ctxt BaseBuilt.BLib cs.cs_name
6936 | Executable (cs, _, _) ->
6937 BaseBuilt.unregister ~ctxt BaseBuilt.BExec cs.cs_name;
6938 BaseBuilt.unregister ~ctxt BaseBuilt.BExecLib cs.cs_name
6939 | _ ->
6941 pkg.sections
6943 let distclean ~ctxt t pkg extra_args = distclean ~ctxt t pkg extra_args
6947 module Test =
6948 struct
6949 let main ~ctxt t pkg (cs, _) extra_args =
6951 main ~ctxt t pkg extra_args;
6953 with Failure s ->
6954 BaseMessage.warning
6955 (f_ "Test '%s' fails: %s")
6956 cs.cs_name
6960 let clean ~ctxt t pkg _ extra_args = clean ~ctxt t pkg extra_args
6962 let distclean ~ctxt t pkg _ extra_args = distclean ~ctxt t pkg extra_args
6966 module Doc =
6967 struct
6968 let main ~ctxt t pkg (cs, _) extra_args =
6969 main ~ctxt t pkg extra_args;
6970 BaseBuilt.register ~ctxt BaseBuilt.BDoc cs.cs_name []
6972 let clean ~ctxt t pkg (cs, _) extra_args =
6973 clean ~ctxt t pkg extra_args;
6974 BaseBuilt.unregister ~ctxt BaseBuilt.BDoc cs.cs_name
6976 let distclean ~ctxt t pkg _ extra_args = distclean ~ctxt t pkg extra_args
6983 # 6983 "setup.ml"
6984 open OASISTypes;;
6986 let setup_t =
6988 BaseSetup.configure = InternalConfigurePlugin.configure;
6989 build =
6990 OCamlbuildPlugin.build
6992 OCamlbuildCommon.plugin_tags = Some "package(mybuild)";
6993 extra = ["-use-ocamlfind"; "-j"; "0"]
6995 test =
6997 ("main",
6998 CustomPlugin.Test.main
7000 CustomPlugin.cmd_main =
7001 [(OASISExpr.EBool true, ("$sqlgg", ["-test"]))];
7002 cmd_clean = [(OASISExpr.EBool true, None)];
7003 cmd_distclean = [(OASISExpr.EBool true, None)]
7005 ("regression",
7006 CustomPlugin.Test.main
7008 CustomPlugin.cmd_main =
7009 [(OASISExpr.EBool true, ("./run_test", []))];
7010 cmd_clean = [(OASISExpr.EBool true, None)];
7011 cmd_distclean = [(OASISExpr.EBool true, None)]
7014 doc = [];
7015 install = InternalInstallPlugin.install;
7016 uninstall = InternalInstallPlugin.uninstall;
7017 clean = [OCamlbuildPlugin.clean];
7018 clean_test =
7020 ("main",
7021 CustomPlugin.Test.clean
7023 CustomPlugin.cmd_main =
7024 [(OASISExpr.EBool true, ("$sqlgg", ["-test"]))];
7025 cmd_clean = [(OASISExpr.EBool true, None)];
7026 cmd_distclean = [(OASISExpr.EBool true, None)]
7028 ("regression",
7029 CustomPlugin.Test.clean
7031 CustomPlugin.cmd_main =
7032 [(OASISExpr.EBool true, ("./run_test", []))];
7033 cmd_clean = [(OASISExpr.EBool true, None)];
7034 cmd_distclean = [(OASISExpr.EBool true, None)]
7037 clean_doc = [];
7038 distclean = [];
7039 distclean_test =
7041 ("main",
7042 CustomPlugin.Test.distclean
7044 CustomPlugin.cmd_main =
7045 [(OASISExpr.EBool true, ("$sqlgg", ["-test"]))];
7046 cmd_clean = [(OASISExpr.EBool true, None)];
7047 cmd_distclean = [(OASISExpr.EBool true, None)]
7049 ("regression",
7050 CustomPlugin.Test.distclean
7052 CustomPlugin.cmd_main =
7053 [(OASISExpr.EBool true, ("./run_test", []))];
7054 cmd_clean = [(OASISExpr.EBool true, None)];
7055 cmd_distclean = [(OASISExpr.EBool true, None)]
7058 distclean_doc = [];
7059 package =
7061 oasis_version = "0.4";
7062 ocaml_version = Some (OASISVersion.VGreaterEqual "4.02");
7063 version = "0.4.4";
7064 license =
7065 OASISLicense.DEP5License
7066 (OASISLicense.DEP5Unit
7068 OASISLicense.license = "GPL";
7069 excption = None;
7070 version = OASISLicense.Version "2"
7072 findlib_version = None;
7073 alpha_features = ["ocamlbuild_more_args"];
7074 beta_features = [];
7075 name = "sqlgg";
7076 license_file = None;
7077 copyrights = ["(C) 2009 ygrek"];
7078 maintainers = [];
7079 authors = ["ygrek <ygrek@autistici.org>"];
7080 homepage = Some "http://ygrek.org.ua/p/sqlgg/";
7081 bugreports = None;
7082 synopsis = "SQL guided (code) generator";
7083 description = None;
7084 tags = [];
7085 categories = [];
7086 files_ab = ["src/version_release.ml.ab"];
7087 sections =
7089 Library
7091 cs_name = "sqlgg";
7092 cs_data = PropList.Data.create ();
7093 cs_plugin_data = []
7096 bs_build = [(OASISExpr.EBool true, true)];
7097 bs_install = [(OASISExpr.EBool true, true)];
7098 bs_path = "lib/";
7099 bs_compiled_object = Best;
7100 bs_build_depends =
7102 FindlibPackage ("extlib", None);
7103 FindlibPackage ("ppx_deriving.std", None)
7105 bs_build_tools =
7106 [ExternalTool "ocamlbuild"; ExternalTool "menhir"];
7107 bs_interface_patterns =
7110 OASISSourcePatterns.Templater.atoms =
7112 OASISSourcePatterns.Templater.Text "";
7113 OASISSourcePatterns.Templater.Expr
7114 (OASISSourcePatterns.Templater.Call
7115 ("capitalize_file",
7116 OASISSourcePatterns.Templater.Ident
7117 "module"));
7118 OASISSourcePatterns.Templater.Text ".mli"
7120 origin = "${capitalize_file module}.mli"
7123 OASISSourcePatterns.Templater.atoms =
7125 OASISSourcePatterns.Templater.Text "";
7126 OASISSourcePatterns.Templater.Expr
7127 (OASISSourcePatterns.Templater.Call
7128 ("uncapitalize_file",
7129 OASISSourcePatterns.Templater.Ident
7130 "module"));
7131 OASISSourcePatterns.Templater.Text ".mli"
7133 origin = "${uncapitalize_file module}.mli"
7136 bs_implementation_patterns =
7139 OASISSourcePatterns.Templater.atoms =
7141 OASISSourcePatterns.Templater.Text "";
7142 OASISSourcePatterns.Templater.Expr
7143 (OASISSourcePatterns.Templater.Call
7144 ("capitalize_file",
7145 OASISSourcePatterns.Templater.Ident
7146 "module"));
7147 OASISSourcePatterns.Templater.Text ".ml"
7149 origin = "${capitalize_file module}.ml"
7152 OASISSourcePatterns.Templater.atoms =
7154 OASISSourcePatterns.Templater.Text "";
7155 OASISSourcePatterns.Templater.Expr
7156 (OASISSourcePatterns.Templater.Call
7157 ("uncapitalize_file",
7158 OASISSourcePatterns.Templater.Ident
7159 "module"));
7160 OASISSourcePatterns.Templater.Text ".ml"
7162 origin = "${uncapitalize_file module}.ml"
7165 OASISSourcePatterns.Templater.atoms =
7167 OASISSourcePatterns.Templater.Text "";
7168 OASISSourcePatterns.Templater.Expr
7169 (OASISSourcePatterns.Templater.Call
7170 ("capitalize_file",
7171 OASISSourcePatterns.Templater.Ident
7172 "module"));
7173 OASISSourcePatterns.Templater.Text ".mll"
7175 origin = "${capitalize_file module}.mll"
7178 OASISSourcePatterns.Templater.atoms =
7180 OASISSourcePatterns.Templater.Text "";
7181 OASISSourcePatterns.Templater.Expr
7182 (OASISSourcePatterns.Templater.Call
7183 ("uncapitalize_file",
7184 OASISSourcePatterns.Templater.Ident
7185 "module"));
7186 OASISSourcePatterns.Templater.Text ".mll"
7188 origin = "${uncapitalize_file module}.mll"
7191 OASISSourcePatterns.Templater.atoms =
7193 OASISSourcePatterns.Templater.Text "";
7194 OASISSourcePatterns.Templater.Expr
7195 (OASISSourcePatterns.Templater.Call
7196 ("capitalize_file",
7197 OASISSourcePatterns.Templater.Ident
7198 "module"));
7199 OASISSourcePatterns.Templater.Text ".mly"
7201 origin = "${capitalize_file module}.mly"
7204 OASISSourcePatterns.Templater.atoms =
7206 OASISSourcePatterns.Templater.Text "";
7207 OASISSourcePatterns.Templater.Expr
7208 (OASISSourcePatterns.Templater.Call
7209 ("uncapitalize_file",
7210 OASISSourcePatterns.Templater.Ident
7211 "module"));
7212 OASISSourcePatterns.Templater.Text ".mly"
7214 origin = "${uncapitalize_file module}.mly"
7217 bs_c_sources = [];
7218 bs_data_files = [];
7219 bs_findlib_extra_files = [];
7220 bs_ccopt = [(OASISExpr.EBool true, [])];
7221 bs_cclib = [(OASISExpr.EBool true, [])];
7222 bs_dlllib = [(OASISExpr.EBool true, [])];
7223 bs_dllpath = [(OASISExpr.EBool true, [])];
7224 bs_byteopt = [(OASISExpr.EBool true, [])];
7225 bs_nativeopt = [(OASISExpr.EBool true, [])]
7228 lib_modules =
7229 ["Props"; "Sql"; "Stmt"; "Tables"; "Syntax"];
7230 lib_pack = true;
7231 lib_internal_modules = ["Prelude"];
7232 lib_findlib_parent = None;
7233 lib_findlib_name = None;
7234 lib_findlib_directory = None;
7235 lib_findlib_containers = []
7237 Executable
7239 cs_name = "sqlgg";
7240 cs_data = PropList.Data.create ();
7241 cs_plugin_data = []
7244 bs_build = [(OASISExpr.EBool true, true)];
7245 bs_install = [(OASISExpr.EBool true, true)];
7246 bs_path = "src/";
7247 bs_compiled_object = Best;
7248 bs_build_depends =
7250 FindlibPackage ("extlib", None);
7251 FindlibPackage ("ppx_deriving.std", None);
7252 FindlibPackage ("oUnit", None);
7253 InternalLibrary "sqlgg"
7255 bs_build_tools =
7256 [ExternalTool "ocamlbuild"; ExternalTool "menhir"];
7257 bs_interface_patterns =
7260 OASISSourcePatterns.Templater.atoms =
7262 OASISSourcePatterns.Templater.Text "";
7263 OASISSourcePatterns.Templater.Expr
7264 (OASISSourcePatterns.Templater.Call
7265 ("capitalize_file",
7266 OASISSourcePatterns.Templater.Ident
7267 "module"));
7268 OASISSourcePatterns.Templater.Text ".mli"
7270 origin = "${capitalize_file module}.mli"
7273 OASISSourcePatterns.Templater.atoms =
7275 OASISSourcePatterns.Templater.Text "";
7276 OASISSourcePatterns.Templater.Expr
7277 (OASISSourcePatterns.Templater.Call
7278 ("uncapitalize_file",
7279 OASISSourcePatterns.Templater.Ident
7280 "module"));
7281 OASISSourcePatterns.Templater.Text ".mli"
7283 origin = "${uncapitalize_file module}.mli"
7286 bs_implementation_patterns =
7289 OASISSourcePatterns.Templater.atoms =
7291 OASISSourcePatterns.Templater.Text "";
7292 OASISSourcePatterns.Templater.Expr
7293 (OASISSourcePatterns.Templater.Call
7294 ("capitalize_file",
7295 OASISSourcePatterns.Templater.Ident
7296 "module"));
7297 OASISSourcePatterns.Templater.Text ".ml"
7299 origin = "${capitalize_file module}.ml"
7302 OASISSourcePatterns.Templater.atoms =
7304 OASISSourcePatterns.Templater.Text "";
7305 OASISSourcePatterns.Templater.Expr
7306 (OASISSourcePatterns.Templater.Call
7307 ("uncapitalize_file",
7308 OASISSourcePatterns.Templater.Ident
7309 "module"));
7310 OASISSourcePatterns.Templater.Text ".ml"
7312 origin = "${uncapitalize_file module}.ml"
7315 OASISSourcePatterns.Templater.atoms =
7317 OASISSourcePatterns.Templater.Text "";
7318 OASISSourcePatterns.Templater.Expr
7319 (OASISSourcePatterns.Templater.Call
7320 ("capitalize_file",
7321 OASISSourcePatterns.Templater.Ident
7322 "module"));
7323 OASISSourcePatterns.Templater.Text ".mll"
7325 origin = "${capitalize_file module}.mll"
7328 OASISSourcePatterns.Templater.atoms =
7330 OASISSourcePatterns.Templater.Text "";
7331 OASISSourcePatterns.Templater.Expr
7332 (OASISSourcePatterns.Templater.Call
7333 ("uncapitalize_file",
7334 OASISSourcePatterns.Templater.Ident
7335 "module"));
7336 OASISSourcePatterns.Templater.Text ".mll"
7338 origin = "${uncapitalize_file module}.mll"
7341 OASISSourcePatterns.Templater.atoms =
7343 OASISSourcePatterns.Templater.Text "";
7344 OASISSourcePatterns.Templater.Expr
7345 (OASISSourcePatterns.Templater.Call
7346 ("capitalize_file",
7347 OASISSourcePatterns.Templater.Ident
7348 "module"));
7349 OASISSourcePatterns.Templater.Text ".mly"
7351 origin = "${capitalize_file module}.mly"
7354 OASISSourcePatterns.Templater.atoms =
7356 OASISSourcePatterns.Templater.Text "";
7357 OASISSourcePatterns.Templater.Expr
7358 (OASISSourcePatterns.Templater.Call
7359 ("uncapitalize_file",
7360 OASISSourcePatterns.Templater.Ident
7361 "module"));
7362 OASISSourcePatterns.Templater.Text ".mly"
7364 origin = "${uncapitalize_file module}.mly"
7367 bs_c_sources = [];
7368 bs_data_files = [];
7369 bs_findlib_extra_files = [];
7370 bs_ccopt = [(OASISExpr.EBool true, [])];
7371 bs_cclib = [(OASISExpr.EBool true, [])];
7372 bs_dlllib = [(OASISExpr.EBool true, [])];
7373 bs_dllpath = [(OASISExpr.EBool true, [])];
7374 bs_byteopt = [(OASISExpr.EBool true, [])];
7375 bs_nativeopt = [(OASISExpr.EBool true, [])]
7377 {exec_custom = false; exec_main_is = "cli.ml"});
7378 Library
7380 cs_name = "sqlgg_traits";
7381 cs_data = PropList.Data.create ();
7382 cs_plugin_data = []
7385 bs_build = [(OASISExpr.EBool true, true)];
7386 bs_install = [(OASISExpr.EBool true, true)];
7387 bs_path = "impl/ocaml/";
7388 bs_compiled_object = Best;
7389 bs_build_depends = [];
7390 bs_build_tools =
7391 [ExternalTool "ocamlbuild"; ExternalTool "menhir"];
7392 bs_interface_patterns =
7395 OASISSourcePatterns.Templater.atoms =
7397 OASISSourcePatterns.Templater.Text "";
7398 OASISSourcePatterns.Templater.Expr
7399 (OASISSourcePatterns.Templater.Call
7400 ("capitalize_file",
7401 OASISSourcePatterns.Templater.Ident
7402 "module"));
7403 OASISSourcePatterns.Templater.Text ".mli"
7405 origin = "${capitalize_file module}.mli"
7408 OASISSourcePatterns.Templater.atoms =
7410 OASISSourcePatterns.Templater.Text "";
7411 OASISSourcePatterns.Templater.Expr
7412 (OASISSourcePatterns.Templater.Call
7413 ("uncapitalize_file",
7414 OASISSourcePatterns.Templater.Ident
7415 "module"));
7416 OASISSourcePatterns.Templater.Text ".mli"
7418 origin = "${uncapitalize_file module}.mli"
7421 bs_implementation_patterns =
7424 OASISSourcePatterns.Templater.atoms =
7426 OASISSourcePatterns.Templater.Text "";
7427 OASISSourcePatterns.Templater.Expr
7428 (OASISSourcePatterns.Templater.Call
7429 ("capitalize_file",
7430 OASISSourcePatterns.Templater.Ident
7431 "module"));
7432 OASISSourcePatterns.Templater.Text ".ml"
7434 origin = "${capitalize_file module}.ml"
7437 OASISSourcePatterns.Templater.atoms =
7439 OASISSourcePatterns.Templater.Text "";
7440 OASISSourcePatterns.Templater.Expr
7441 (OASISSourcePatterns.Templater.Call
7442 ("uncapitalize_file",
7443 OASISSourcePatterns.Templater.Ident
7444 "module"));
7445 OASISSourcePatterns.Templater.Text ".ml"
7447 origin = "${uncapitalize_file module}.ml"
7450 OASISSourcePatterns.Templater.atoms =
7452 OASISSourcePatterns.Templater.Text "";
7453 OASISSourcePatterns.Templater.Expr
7454 (OASISSourcePatterns.Templater.Call
7455 ("capitalize_file",
7456 OASISSourcePatterns.Templater.Ident
7457 "module"));
7458 OASISSourcePatterns.Templater.Text ".mll"
7460 origin = "${capitalize_file module}.mll"
7463 OASISSourcePatterns.Templater.atoms =
7465 OASISSourcePatterns.Templater.Text "";
7466 OASISSourcePatterns.Templater.Expr
7467 (OASISSourcePatterns.Templater.Call
7468 ("uncapitalize_file",
7469 OASISSourcePatterns.Templater.Ident
7470 "module"));
7471 OASISSourcePatterns.Templater.Text ".mll"
7473 origin = "${uncapitalize_file module}.mll"
7476 OASISSourcePatterns.Templater.atoms =
7478 OASISSourcePatterns.Templater.Text "";
7479 OASISSourcePatterns.Templater.Expr
7480 (OASISSourcePatterns.Templater.Call
7481 ("capitalize_file",
7482 OASISSourcePatterns.Templater.Ident
7483 "module"));
7484 OASISSourcePatterns.Templater.Text ".mly"
7486 origin = "${capitalize_file module}.mly"
7489 OASISSourcePatterns.Templater.atoms =
7491 OASISSourcePatterns.Templater.Text "";
7492 OASISSourcePatterns.Templater.Expr
7493 (OASISSourcePatterns.Templater.Call
7494 ("uncapitalize_file",
7495 OASISSourcePatterns.Templater.Ident
7496 "module"));
7497 OASISSourcePatterns.Templater.Text ".mly"
7499 origin = "${uncapitalize_file module}.mly"
7502 bs_c_sources = [];
7503 bs_data_files = [];
7504 bs_findlib_extra_files = [];
7505 bs_ccopt = [(OASISExpr.EBool true, [])];
7506 bs_cclib = [(OASISExpr.EBool true, [])];
7507 bs_dlllib = [(OASISExpr.EBool true, [])];
7508 bs_dllpath = [(OASISExpr.EBool true, [])];
7509 bs_byteopt = [(OASISExpr.EBool true, [])];
7510 bs_nativeopt = [(OASISExpr.EBool true, [])]
7513 lib_modules = ["Sqlgg_traits"];
7514 lib_pack = false;
7515 lib_internal_modules = [];
7516 lib_findlib_parent = Some "sqlgg";
7517 lib_findlib_name = Some "traits";
7518 lib_findlib_directory = None;
7519 lib_findlib_containers = []
7521 Flag
7523 cs_name = "mysql";
7524 cs_data = PropList.Data.create ();
7525 cs_plugin_data = []
7528 flag_description =
7529 Some "Build mysql traits implementation";
7530 flag_default = [(OASISExpr.EBool true, false)]
7532 Flag
7534 cs_name = "sqlite3";
7535 cs_data = PropList.Data.create ();
7536 cs_plugin_data = []
7539 flag_description =
7540 Some "Build sqlite3 traits implementation";
7541 flag_default = [(OASISExpr.EBool true, false)]
7543 Library
7545 cs_name = "sqlgg_mysql";
7546 cs_data = PropList.Data.create ();
7547 cs_plugin_data = []
7550 bs_build =
7552 (OASISExpr.EBool true, false);
7553 (OASISExpr.EFlag "mysql", true)
7555 bs_install = [(OASISExpr.EBool true, true)];
7556 bs_path = "impl/ocaml/mysql";
7557 bs_compiled_object = Best;
7558 bs_build_depends =
7560 FindlibPackage ("mysql", None);
7561 InternalLibrary "sqlgg_traits"
7563 bs_build_tools =
7564 [ExternalTool "ocamlbuild"; ExternalTool "menhir"];
7565 bs_interface_patterns =
7568 OASISSourcePatterns.Templater.atoms =
7570 OASISSourcePatterns.Templater.Text "";
7571 OASISSourcePatterns.Templater.Expr
7572 (OASISSourcePatterns.Templater.Call
7573 ("capitalize_file",
7574 OASISSourcePatterns.Templater.Ident
7575 "module"));
7576 OASISSourcePatterns.Templater.Text ".mli"
7578 origin = "${capitalize_file module}.mli"
7581 OASISSourcePatterns.Templater.atoms =
7583 OASISSourcePatterns.Templater.Text "";
7584 OASISSourcePatterns.Templater.Expr
7585 (OASISSourcePatterns.Templater.Call
7586 ("uncapitalize_file",
7587 OASISSourcePatterns.Templater.Ident
7588 "module"));
7589 OASISSourcePatterns.Templater.Text ".mli"
7591 origin = "${uncapitalize_file module}.mli"
7594 bs_implementation_patterns =
7597 OASISSourcePatterns.Templater.atoms =
7599 OASISSourcePatterns.Templater.Text "";
7600 OASISSourcePatterns.Templater.Expr
7601 (OASISSourcePatterns.Templater.Call
7602 ("capitalize_file",
7603 OASISSourcePatterns.Templater.Ident
7604 "module"));
7605 OASISSourcePatterns.Templater.Text ".ml"
7607 origin = "${capitalize_file module}.ml"
7610 OASISSourcePatterns.Templater.atoms =
7612 OASISSourcePatterns.Templater.Text "";
7613 OASISSourcePatterns.Templater.Expr
7614 (OASISSourcePatterns.Templater.Call
7615 ("uncapitalize_file",
7616 OASISSourcePatterns.Templater.Ident
7617 "module"));
7618 OASISSourcePatterns.Templater.Text ".ml"
7620 origin = "${uncapitalize_file module}.ml"
7623 OASISSourcePatterns.Templater.atoms =
7625 OASISSourcePatterns.Templater.Text "";
7626 OASISSourcePatterns.Templater.Expr
7627 (OASISSourcePatterns.Templater.Call
7628 ("capitalize_file",
7629 OASISSourcePatterns.Templater.Ident
7630 "module"));
7631 OASISSourcePatterns.Templater.Text ".mll"
7633 origin = "${capitalize_file module}.mll"
7636 OASISSourcePatterns.Templater.atoms =
7638 OASISSourcePatterns.Templater.Text "";
7639 OASISSourcePatterns.Templater.Expr
7640 (OASISSourcePatterns.Templater.Call
7641 ("uncapitalize_file",
7642 OASISSourcePatterns.Templater.Ident
7643 "module"));
7644 OASISSourcePatterns.Templater.Text ".mll"
7646 origin = "${uncapitalize_file module}.mll"
7649 OASISSourcePatterns.Templater.atoms =
7651 OASISSourcePatterns.Templater.Text "";
7652 OASISSourcePatterns.Templater.Expr
7653 (OASISSourcePatterns.Templater.Call
7654 ("capitalize_file",
7655 OASISSourcePatterns.Templater.Ident
7656 "module"));
7657 OASISSourcePatterns.Templater.Text ".mly"
7659 origin = "${capitalize_file module}.mly"
7662 OASISSourcePatterns.Templater.atoms =
7664 OASISSourcePatterns.Templater.Text "";
7665 OASISSourcePatterns.Templater.Expr
7666 (OASISSourcePatterns.Templater.Call
7667 ("uncapitalize_file",
7668 OASISSourcePatterns.Templater.Ident
7669 "module"));
7670 OASISSourcePatterns.Templater.Text ".mly"
7672 origin = "${uncapitalize_file module}.mly"
7675 bs_c_sources = [];
7676 bs_data_files = [];
7677 bs_findlib_extra_files = [];
7678 bs_ccopt = [(OASISExpr.EBool true, [])];
7679 bs_cclib = [(OASISExpr.EBool true, [])];
7680 bs_dlllib = [(OASISExpr.EBool true, [])];
7681 bs_dllpath = [(OASISExpr.EBool true, [])];
7682 bs_byteopt = [(OASISExpr.EBool true, [])];
7683 bs_nativeopt = [(OASISExpr.EBool true, [])]
7686 lib_modules = ["Sqlgg_mysql"];
7687 lib_pack = false;
7688 lib_internal_modules = [];
7689 lib_findlib_parent = Some "sqlgg";
7690 lib_findlib_name = Some "mysql";
7691 lib_findlib_directory = None;
7692 lib_findlib_containers = []
7694 Library
7696 cs_name = "sqlgg_sqlite3";
7697 cs_data = PropList.Data.create ();
7698 cs_plugin_data = []
7701 bs_build =
7703 (OASISExpr.EBool true, false);
7704 (OASISExpr.EFlag "sqlite3", true)
7706 bs_install = [(OASISExpr.EBool true, true)];
7707 bs_path = "impl/ocaml/sqlite3";
7708 bs_compiled_object = Best;
7709 bs_build_depends =
7711 FindlibPackage ("sqlite3", None);
7712 InternalLibrary "sqlgg_traits"
7714 bs_build_tools =
7715 [ExternalTool "ocamlbuild"; ExternalTool "menhir"];
7716 bs_interface_patterns =
7719 OASISSourcePatterns.Templater.atoms =
7721 OASISSourcePatterns.Templater.Text "";
7722 OASISSourcePatterns.Templater.Expr
7723 (OASISSourcePatterns.Templater.Call
7724 ("capitalize_file",
7725 OASISSourcePatterns.Templater.Ident
7726 "module"));
7727 OASISSourcePatterns.Templater.Text ".mli"
7729 origin = "${capitalize_file module}.mli"
7732 OASISSourcePatterns.Templater.atoms =
7734 OASISSourcePatterns.Templater.Text "";
7735 OASISSourcePatterns.Templater.Expr
7736 (OASISSourcePatterns.Templater.Call
7737 ("uncapitalize_file",
7738 OASISSourcePatterns.Templater.Ident
7739 "module"));
7740 OASISSourcePatterns.Templater.Text ".mli"
7742 origin = "${uncapitalize_file module}.mli"
7745 bs_implementation_patterns =
7748 OASISSourcePatterns.Templater.atoms =
7750 OASISSourcePatterns.Templater.Text "";
7751 OASISSourcePatterns.Templater.Expr
7752 (OASISSourcePatterns.Templater.Call
7753 ("capitalize_file",
7754 OASISSourcePatterns.Templater.Ident
7755 "module"));
7756 OASISSourcePatterns.Templater.Text ".ml"
7758 origin = "${capitalize_file module}.ml"
7761 OASISSourcePatterns.Templater.atoms =
7763 OASISSourcePatterns.Templater.Text "";
7764 OASISSourcePatterns.Templater.Expr
7765 (OASISSourcePatterns.Templater.Call
7766 ("uncapitalize_file",
7767 OASISSourcePatterns.Templater.Ident
7768 "module"));
7769 OASISSourcePatterns.Templater.Text ".ml"
7771 origin = "${uncapitalize_file module}.ml"
7774 OASISSourcePatterns.Templater.atoms =
7776 OASISSourcePatterns.Templater.Text "";
7777 OASISSourcePatterns.Templater.Expr
7778 (OASISSourcePatterns.Templater.Call
7779 ("capitalize_file",
7780 OASISSourcePatterns.Templater.Ident
7781 "module"));
7782 OASISSourcePatterns.Templater.Text ".mll"
7784 origin = "${capitalize_file module}.mll"
7787 OASISSourcePatterns.Templater.atoms =
7789 OASISSourcePatterns.Templater.Text "";
7790 OASISSourcePatterns.Templater.Expr
7791 (OASISSourcePatterns.Templater.Call
7792 ("uncapitalize_file",
7793 OASISSourcePatterns.Templater.Ident
7794 "module"));
7795 OASISSourcePatterns.Templater.Text ".mll"
7797 origin = "${uncapitalize_file module}.mll"
7800 OASISSourcePatterns.Templater.atoms =
7802 OASISSourcePatterns.Templater.Text "";
7803 OASISSourcePatterns.Templater.Expr
7804 (OASISSourcePatterns.Templater.Call
7805 ("capitalize_file",
7806 OASISSourcePatterns.Templater.Ident
7807 "module"));
7808 OASISSourcePatterns.Templater.Text ".mly"
7810 origin = "${capitalize_file module}.mly"
7813 OASISSourcePatterns.Templater.atoms =
7815 OASISSourcePatterns.Templater.Text "";
7816 OASISSourcePatterns.Templater.Expr
7817 (OASISSourcePatterns.Templater.Call
7818 ("uncapitalize_file",
7819 OASISSourcePatterns.Templater.Ident
7820 "module"));
7821 OASISSourcePatterns.Templater.Text ".mly"
7823 origin = "${uncapitalize_file module}.mly"
7826 bs_c_sources = [];
7827 bs_data_files = [];
7828 bs_findlib_extra_files = [];
7829 bs_ccopt = [(OASISExpr.EBool true, [])];
7830 bs_cclib = [(OASISExpr.EBool true, [])];
7831 bs_dlllib = [(OASISExpr.EBool true, [])];
7832 bs_dllpath = [(OASISExpr.EBool true, [])];
7833 bs_byteopt = [(OASISExpr.EBool true, [])];
7834 bs_nativeopt = [(OASISExpr.EBool true, [])]
7837 lib_modules = ["Sqlgg_sqlite3"];
7838 lib_pack = false;
7839 lib_internal_modules = [];
7840 lib_findlib_parent = Some "sqlgg";
7841 lib_findlib_name = Some "sqlite3";
7842 lib_findlib_directory = None;
7843 lib_findlib_containers = []
7845 Test
7847 cs_name = "main";
7848 cs_data = PropList.Data.create ();
7849 cs_plugin_data = []
7852 test_type = (`Test, "custom", Some "0.4");
7853 test_command =
7854 [(OASISExpr.EBool true, ("$sqlgg", ["-test"]))];
7855 test_custom =
7857 pre_command = [(OASISExpr.EBool true, None)];
7858 post_command = [(OASISExpr.EBool true, None)]
7860 test_working_directory = None;
7861 test_run =
7863 (OASISExpr.ENot (OASISExpr.EFlag "tests"), false);
7864 (OASISExpr.EFlag "tests", true)
7866 test_tools =
7868 ExternalTool "ocamlbuild";
7869 ExternalTool "menhir";
7870 InternalExecutable "sqlgg"
7873 Test
7875 cs_name = "regression";
7876 cs_data = PropList.Data.create ();
7877 cs_plugin_data = []
7880 test_type = (`Test, "custom", Some "0.4");
7881 test_command =
7882 [(OASISExpr.EBool true, ("./run_test", []))];
7883 test_custom =
7885 pre_command = [(OASISExpr.EBool true, None)];
7886 post_command = [(OASISExpr.EBool true, None)]
7888 test_working_directory = None;
7889 test_run =
7891 (OASISExpr.ENot (OASISExpr.EFlag "tests"), false);
7892 (OASISExpr.EFlag "tests", true)
7894 test_tools =
7896 ExternalTool "ocamlbuild";
7897 ExternalTool "menhir";
7898 InternalExecutable "sqlgg"
7901 SrcRepo
7903 cs_name = "head";
7904 cs_data = PropList.Data.create ();
7905 cs_plugin_data = []
7908 src_repo_type = Git;
7909 src_repo_location = "git://github.com/ygrek/sqlgg.git";
7910 src_repo_browser = None;
7911 src_repo_module = None;
7912 src_repo_branch = None;
7913 src_repo_tag = None;
7914 src_repo_subdir = None
7917 disable_oasis_section = [];
7918 conf_type = (`Configure, "internal", Some "0.4");
7919 conf_custom =
7921 pre_command = [(OASISExpr.EBool true, None)];
7922 post_command = [(OASISExpr.EBool true, None)]
7924 build_type = (`Build, "ocamlbuild", Some "0.4");
7925 build_custom =
7927 pre_command = [(OASISExpr.EBool true, None)];
7928 post_command = [(OASISExpr.EBool true, None)]
7930 install_type = (`Install, "internal", Some "0.4");
7931 install_custom =
7933 pre_command = [(OASISExpr.EBool true, None)];
7934 post_command = [(OASISExpr.EBool true, None)]
7936 uninstall_custom =
7938 pre_command = [(OASISExpr.EBool true, None)];
7939 post_command = [(OASISExpr.EBool true, None)]
7941 clean_custom =
7943 pre_command = [(OASISExpr.EBool true, None)];
7944 post_command = [(OASISExpr.EBool true, None)]
7946 distclean_custom =
7948 pre_command = [(OASISExpr.EBool true, None)];
7949 post_command = [(OASISExpr.EBool true, None)]
7951 plugins =
7952 [(`Extra, "DevFiles", Some "0.4"); (`Extra, "META", Some "0.4")];
7953 schema_data = PropList.Data.create ();
7954 plugin_data = []
7956 oasis_fn = Some "_oasis";
7957 oasis_version = "0.4.11";
7958 oasis_digest = Some "B\252\172\167C\198\227\191\200\2498\170\174\195TI";
7959 oasis_exec = None;
7960 oasis_setup_args = [];
7961 setup_update = false
7964 let setup () = BaseSetup.setup setup_t;;
7966 # 7967 "setup.ml"
7967 let setup_t = BaseCompat.Compat_0_4.adapt_setup_t setup_t
7968 open BaseCompat.Compat_0_4
7969 (* OASIS_STOP *)
7970 let () = setup ();;