~ubuntu-branches/ubuntu/wily/coq-doc/wily

« back to all changes in this revision

Viewing changes to scripts/coqmktop.ml

  • Committer: Bazaar Package Importer
  • Author(s): Stéphane Glondu, Stéphane Glondu, Samuel Mimram
  • Date: 2010-01-07 22:50:39 UTC
  • mfrom: (1.2.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20100107225039-n3cq82589u0qt0s2
Tags: 8.2pl1-1
[ Stéphane Glondu ]
* New upstream release (Closes: #563669)
  - remove patches
* Packaging overhaul:
  - use git, advertise it in Vcs-* fields of debian/control
  - use debhelper 7 and dh with override
  - use source format 3.0 (quilt)
* debian/control:
  - set Maintainer to d-o-m, set Uploaders to Sam and myself
  - add Homepage field
  - bump Standards-Version to 3.8.3
* Register PDF documentation into doc-base
* Add debian/watch
* Update debian/copyright

[ Samuel Mimram ]
* Change coq-doc's description to mention that it provides documentation in
  pdf format, not postscript, closes: #543545.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
(************************************************************************)
 
2
(*  v      *   The Coq Proof Assistant  /  The Coq Development Team     *)
 
3
(* <O___,, * CNRS-Ecole Polytechnique-INRIA Futurs-Universite Paris Sud *)
 
4
(*   \VV/  **************************************************************)
 
5
(*    //   *      This file is distributed under the terms of the       *)
 
6
(*         *       GNU Lesser General Public License Version 2.1        *)
 
7
(************************************************************************)
 
8
 
 
9
(* $Id: coqmktop.ml 11784 2009-01-14 11:36:32Z herbelin $ *)
 
10
 
 
11
(* coqmktop is a script to link Coq, analogous to ocamlmktop.
 
12
   The command line contains options specific to coqmktop, options for the
 
13
   Ocaml linker and files to link (in addition to the default Coq files). *)
 
14
 
 
15
open Unix
 
16
 
 
17
(* Objects to link *)
 
18
 
 
19
(* 1. Core objects *)
 
20
let ocamlobjs = ["str.cma";"unix.cma";"nums.cma"]
 
21
let dynobjs = ["dynlink.cma"]
 
22
let camlp4objs = ["gramlib.cma"]
 
23
let libobjs = ocamlobjs @ camlp4objs
 
24
 
 
25
let spaces = Str.regexp "[ \t\n]+"
 
26
let split_list l = Str.split spaces l
 
27
 
 
28
let copts     = split_list Tolink.copts
 
29
let core_objs = split_list Tolink.core_objs
 
30
let core_libs = split_list Tolink.core_libs
 
31
let ide       = split_list Tolink.ide 
 
32
 
 
33
(* 3. Toplevel objects *)
 
34
let camlp4topobjs =
 
35
  if Coq_config.camlp4 = "camlp5" then
 
36
    ["camlp5_top.cma"; "pa_o.cmo"; "pa_extend.cmo"]
 
37
  else
 
38
    ["camlp4_top.cma"; "pa_o.cmo"; "pa_op.cmo"; "pa_extend.cmo"]
 
39
let topobjs = camlp4topobjs
 
40
 
 
41
let gramobjs = []
 
42
let notopobjs = gramobjs
 
43
 
 
44
(* 4. High-level tactics objects *)
 
45
 
 
46
(* environment *)
 
47
let opt        = ref false
 
48
let full       = ref false
 
49
let top        = ref false
 
50
let searchisos = ref false
 
51
let coqide     = ref false
 
52
let echo       = ref false
 
53
 
 
54
let src_dirs () = 
 
55
  [ []; ["kernel";"byterun"]; [ "config" ]; [ "toplevel" ] ] @
 
56
  if !coqide then [[ "ide" ]] else []
 
57
 
 
58
let includes () = 
 
59
  let coqlib = Envars.coqlib () in
 
60
  let camlp4lib = Envars.camlp4lib () in
 
61
    List.fold_right
 
62
      (fun d l -> "-I" :: ("\"" ^ List.fold_left Filename.concat coqlib d ^ "\"") :: l)
 
63
      (src_dirs ())
 
64
      (["-I"; "\"" ^ camlp4lib ^ "\""] @ 
 
65
         ["-I"; "\"" ^ coqlib ^ "\""] @
 
66
         (if !coqide then ["-thread"; "-I"; "+lablgtk2"] else []))
 
67
 
 
68
(* Transform bytecode object file names in native object file names *)
 
69
let native_suffix f =
 
70
  if Filename.check_suffix f ".cmo" then 
 
71
    (Filename.chop_suffix f ".cmo") ^ ".cmx"
 
72
  else if Filename.check_suffix f ".cma" then 
 
73
    (Filename.chop_suffix f ".cma") ^ ".cmxa"
 
74
  else  
 
75
    if Filename.check_suffix f ".a" then f 
 
76
    else
 
77
      failwith ("File "^f^" has not extension .cmo, .cma or .a")
 
78
 
 
79
(* Transforms a file name in the corresponding Caml module name. *)
 
80
let rem_ext_regexpr = Str.regexp "\\(.*\\)\\.\\(cm..?\\|ml\\)"
 
81
 
 
82
let module_of_file name =
 
83
  let s = Str.replace_first rem_ext_regexpr "\\1" (Filename.basename name) in
 
84
  String.capitalize s
 
85
 
 
86
(* Build the list of files to link and the list of modules names *)
 
87
let files_to_link userfiles =
 
88
  let dyn_objs =
 
89
    if not !opt || Coq_config.has_natdynlink then dynobjs else [] in
 
90
  let toplevel_objs =
 
91
    if !top then topobjs else if !opt then notopobjs else [] in
 
92
  let ide_objs = if !coqide then 
 
93
    "threads.cma"::"lablgtk.cma"::"gtkThread.cmo"::ide 
 
94
  else [] 
 
95
  in
 
96
  let ide_libs = if !coqide then 
 
97
    ["threads.cma" ; "lablgtk.cma" ; "gtkThread.cmo" ;
 
98
     "ide/ide.cma" ]
 
99
  else [] 
 
100
  in
 
101
  let objs = dyn_objs @ libobjs @ core_objs @ toplevel_objs @ ide_objs
 
102
  and libs = dyn_objs @ libobjs @ core_libs @ toplevel_objs @ ide_libs in
 
103
  let objstolink,libstolink =
 
104
    if !opt then 
 
105
      ((List.map native_suffix objs) @ userfiles,
 
106
       (List.map native_suffix libs) @ userfiles)
 
107
    else 
 
108
      (objs @ userfiles, libs @ userfiles )
 
109
  in
 
110
  let modules = List.map module_of_file objstolink in
 
111
  (modules, libstolink)
 
112
 
 
113
(* Gives the list of all the directories under [dir].
 
114
   Uses [Unix] (it is hard to do without it). *)
 
115
let all_subdirs dir =
 
116
  let l = ref [dir] in
 
117
  let add f = l := f :: !l in
 
118
  let rec traverse dir =
 
119
    let dirh = 
 
120
      try opendir dir with Unix_error _ -> invalid_arg "all_subdirs" 
 
121
    in
 
122
    try
 
123
      while true do
 
124
        let f = readdir dirh in
 
125
        if f <> "." && f <> ".." then
 
126
          let file = Filename.concat dir f in
 
127
          if (stat file).st_kind = S_DIR then begin
 
128
            add file;
 
129
            traverse file
 
130
          end
 
131
      done
 
132
    with End_of_file ->
 
133
      closedir dirh
 
134
  in
 
135
  traverse dir; List.rev !l
 
136
 
 
137
(* usage *)
 
138
let usage () =
 
139
  prerr_endline "Usage: coqmktop <options> <ocaml options> files
 
140
Flags.are:
 
141
  -coqlib dir    Specify where the Coq object files are
 
142
  -camlbin dir   Specify where the OCaml binaries are
 
143
  -camlp4bin dir Specify where the CAmp4/5 binaries are
 
144
  -o exec-file   Specify the name of the resulting toplevel
 
145
  -boot          Run in boot mode
 
146
  -opt           Compile in native code
 
147
  -full          Link high level tactics
 
148
  -top           Build Coq on a ocaml toplevel (incompatible with -opt)
 
149
  -searchisos    Build a toplevel for SearchIsos
 
150
  -ide           Build a toplevel for the Coq IDE
 
151
  -R dir         Specify recursively directories for Ocaml\n";
 
152
  exit 1
 
153
 
 
154
(* parsing of the command line *)
 
155
let parse_args () =
 
156
  let rec parse (op,fl) = function
 
157
    | [] -> List.rev op, List.rev fl
 
158
    | "-coqlib" :: d :: rem -> 
 
159
        Flags.coqlib_spec := true; Flags.coqlib := d ; parse (op,fl) rem
 
160
    | "-coqlib" :: _        -> usage ()
 
161
    | "-camlbin" :: d :: rem -> 
 
162
        Flags.camlbin_spec := true; Flags.camlbin := d ; parse (op,fl) rem
 
163
    | "-camlbin" :: _        -> usage ()
 
164
    | "-camlp4bin" :: d :: rem -> 
 
165
        Flags.camlp4bin_spec := true; Flags.camlp4bin := d ; parse (op,fl) rem
 
166
    | "-camlp4bin" :: _        -> usage ()
 
167
    | "-boot" :: rem -> Flags.boot := true; parse (op,fl) rem
 
168
    | "-opt" :: rem -> opt := true ; parse (op,fl) rem
 
169
    | "-full" :: rem -> full := true ; parse (op,fl) rem
 
170
    | "-top" :: rem -> top := true ; parse (op,fl) rem
 
171
    | "-ide" :: rem ->
 
172
        coqide := true; parse (op,fl) rem
 
173
    | "-v8" :: rem -> 
 
174
        Printf.eprintf "warning: option -v8 deprecated";
 
175
        parse (op,fl) rem
 
176
    | "-echo" :: rem -> echo := true ; parse (op,fl) rem
 
177
    | ("-cclib"|"-ccopt"|"-I"|"-o"|"-w" as o) :: rem' ->
 
178
        begin
 
179
          match rem' with
 
180
            | a :: rem -> parse (a::o::op,fl) rem
 
181
            | []       -> usage ()
 
182
        end
 
183
    | "-R" :: a :: rem ->
 
184
        parse ((List.rev(List.flatten (List.map (fun d -> ["-I";d])
 
185
                                         (all_subdirs a))))@op,fl) rem
 
186
    | "-R" :: [] -> usage ()
 
187
    | ("-noassert"|"-compact"|"-g"|"-p"|"-thread"|"-dtypes" as o) :: rem ->
 
188
        parse (o::op,fl) rem
 
189
    | ("-h"|"--help") :: _ -> usage ()
 
190
    | f :: rem ->
 
191
        if Filename.check_suffix f ".ml" 
 
192
          or Filename.check_suffix f ".cmx" 
 
193
          or Filename.check_suffix f ".cmo"
 
194
          or Filename.check_suffix f ".cmxa"
 
195
          or Filename.check_suffix f ".cma" then
 
196
            parse (op,f::fl) rem
 
197
        else begin
 
198
          prerr_endline ("Don't know what to do with " ^ f);
 
199
          exit 1
 
200
        end
 
201
  in
 
202
  parse ([Coq_config.osdeplibs],[]) (List.tl (Array.to_list Sys.argv))
 
203
 
 
204
let clean file =
 
205
  let rm f = if Sys.file_exists f then Sys.remove f in
 
206
  let basename = Filename.chop_suffix file ".ml" in
 
207
  if not !echo then begin
 
208
    rm file;
 
209
    rm (basename ^ ".o");
 
210
    rm (basename ^ ".cmi");
 
211
    rm (basename ^ ".cmo");
 
212
    rm (basename ^ ".cmx")
 
213
  end
 
214
 
 
215
(* Creates another temporary file for Dynlink if needed *)
 
216
let tmp_dynlink()=
 
217
  let tmp = Filename.temp_file "coqdynlink" ".ml" in
 
218
  let _ = Sys.command ("echo \"Dynlink.init();;\" > "^tmp) in
 
219
  tmp
 
220
 
 
221
(* Initializes the kind of loading in the main program *)
 
222
let declare_loading_string () =
 
223
  if not !top then
 
224
    "Mltop.remove ();;"
 
225
  else
 
226
    "let ppf = Format.std_formatter;;
 
227
     Mltop.set_top
 
228
       {Mltop.load_obj=Topdirs.dir_load ppf;
 
229
        Mltop.use_file=Topdirs.dir_use ppf;
 
230
        Mltop.add_dir=Topdirs.dir_directory;
 
231
        Mltop.ml_loop=(fun () -> Toploop.loop ppf) };;\n"
 
232
 
 
233
(* create a temporary main file to link *)
 
234
let create_tmp_main_file modules =
 
235
  let main_name = Filename.temp_file "coqmain" ".ml" in
 
236
  let oc = open_out main_name in
 
237
  try
 
238
    (* Add the pre-linked modules *)    
 
239
    output_string oc "List.iter Mltop.add_known_module [\"";
 
240
    output_string oc (String.concat "\";\"" modules);
 
241
    output_string oc "\"];;\n";
 
242
    (* Initializes the kind of loading *)
 
243
    output_string oc (declare_loading_string());
 
244
    (* Start the right toplevel loop: Coq or Coq_searchisos *)
 
245
    if !searchisos then 
 
246
      output_string oc "Cmd_searchisos_line.start();;\n"
 
247
    else if !coqide then
 
248
      output_string oc "Coqide.start();;\n"
 
249
    else
 
250
      output_string oc "Coqtop.start();;\n";
 
251
    close_out oc;
 
252
    main_name
 
253
  with e -> 
 
254
    clean main_name; raise e
 
255
 
 
256
(* main part *)
 
257
let main () =
 
258
  let (options, userfiles) = parse_args () in
 
259
  (* which ocaml command to invoke *)
 
260
  let camlbin = Envars.camlbin () in
 
261
  let prog =
 
262
    if !opt then begin
 
263
      (* native code *)
 
264
      if !top then failwith "no custom toplevel in native code !";
 
265
      let ocamloptexec = Filename.concat camlbin "ocamlopt" in
 
266
        ocamloptexec^" -linkall"
 
267
    end else
 
268
      (* bytecode (we shunt ocamlmktop script which fails on win32) *)
 
269
      let ocamlmktoplib = " toplevellib.cma" in
 
270
      let ocamlcexec = Filename.concat camlbin "ocamlc" in
 
271
      let ocamlccustom = Printf.sprintf "%s %s -linkall "
 
272
        ocamlcexec Coq_config.coqrunbyteflags in
 
273
      (if !top then ocamlccustom^ocamlmktoplib else ocamlccustom)
 
274
  in
 
275
  (* files to link *)
 
276
  let (modules, tolink) = files_to_link userfiles in
 
277
  (*file for dynlink *)
 
278
  let dynlink=
 
279
    if not (!opt || !top) then
 
280
      [(print_int 2; tmp_dynlink())]
 
281
    else
 
282
      []
 
283
  in
 
284
  (* the list of the loaded modules *)
 
285
  let main_file = create_tmp_main_file modules in
 
286
  try
 
287
    let args =
 
288
      options @ (includes ()) @ copts @ tolink @ dynlink @ [ main_file ] in
 
289
      (* add topstart.cmo explicitly because we shunted ocamlmktop wrapper *)
 
290
    let args = if !top then args @ [ "topstart.cmo" ] else args in
 
291
      (* Now, with the .cma, we MUST use the -linkall option *)
 
292
    let command = String.concat " " (prog::"-rectypes"::args) in
 
293
      if !echo then 
 
294
        begin 
 
295
          print_endline command; 
 
296
          print_endline 
 
297
            ("(command length is " ^ 
 
298
               (string_of_int (String.length command)) ^ " characters)");
 
299
          flush Pervasives.stdout 
 
300
        end;
 
301
      let retcode = Sys.command command in
 
302
        clean main_file;
 
303
        (* command gives the exit code in HSB, and signal in LSB !!! *)
 
304
        if retcode > 255 then retcode lsr 8 else retcode 
 
305
  with e -> 
 
306
    clean main_file; raise e
 
307
 
 
308
let retcode =
 
309
  try Printexc.print main () with _ -> 1
 
310
 
 
311
let _ = exit retcode