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

« back to all changes in this revision

Viewing changes to tools/coq_makefile.ml4

  • 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: coq_makefile.ml4 12176 2009-06-09 09:44:40Z notin $ *)
 
10
 
 
11
(* cr�er un Makefile pour un d�veloppement Coq automatiquement *)
 
12
 
 
13
type target =
 
14
  | ML of string (* ML file : foo.ml -> (ML "foo") *)
 
15
  | V of string  (* V file : foo.v -> (V "foo") *)
 
16
  | Special of string * string * string (* file, dependencies, command *)
 
17
  | Subdir of string
 
18
  | Def of string * string (* X=foo -> Def ("X","foo") *)
 
19
  | Include of string
 
20
  | RInclude of string * string (* -R physicalpath logicalpath *)
 
21
 
 
22
let output_channel = ref stdout
 
23
let makefile_name = ref "Makefile"
 
24
let make_name = ref ""
 
25
 
 
26
let some_file = ref false
 
27
let some_vfile = ref false
 
28
let some_mlfile = ref false
 
29
 
 
30
let opt = ref "-opt"
 
31
let impredicative_set = ref false
 
32
let no_install = ref false
 
33
 
 
34
let print x = output_string !output_channel x
 
35
let printf x = Printf.fprintf !output_channel x
 
36
 
 
37
let rec print_list sep = function
 
38
  | [ x ] -> print x
 
39
  | x :: l -> print x; print sep; print_list sep l
 
40
  | [] -> ()
 
41
 
 
42
let list_iter_i f =
 
43
  let rec aux i = function [] -> () | a::l -> f i a; aux (i+1) l in aux 1
 
44
 
 
45
let best_ocamlc = 
 
46
  if Coq_config.best = "opt" then "ocamlc.opt" else "ocamlc"
 
47
let best_ocamlopt =
 
48
  if Coq_config.best = "opt" then "ocamlopt.opt" else "ocamlopt"
 
49
 
 
50
let section s =
 
51
  let l = String.length s in
 
52
  let sep = String.make (l+5) '#'
 
53
  and sep2 = String.make (l+5) ' ' in
 
54
  String.set sep (l+4) '\n';
 
55
  String.set sep2 0 '#';
 
56
  String.set sep2 (l+3) '#';
 
57
  String.set sep2 (l+4) '\n';
 
58
  print sep;
 
59
  print sep2;
 
60
  print "# "; print s; print " #\n";
 
61
  print sep2;
 
62
  print sep;
 
63
  print "\n"
 
64
 
 
65
let usage () =
 
66
  output_string stderr "Usage summary:
 
67
 
 
68
coq_makefile [subdirectory] .... [file.v] ... [file.ml] ... [-custom
 
69
  command dependencies file] ... [-I dir] ... [-R physicalpath logicalpath]
 
70
  ... [VARIABLE = value] ...  [-opt|-byte] [-impredicative-set] [-no-install]
 
71
  [-f file] [-o file] [-h] [--help]
 
72
 
 
73
[file.v]: Coq file to be compiled
 
74
[file.ml]: Objective Caml file to be compiled
 
75
[subdirectory] : subdirectory that should be \"made\"
 
76
[-custom command dependencies file]: add target \"file\" with command
 
77
  \"command\" and dependencies \"dependencies\"
 
78
[-I dir]: look for dependencies in \"dir\"
 
79
[-R physicalpath logicalpath]: look for dependencies resursively starting from
 
80
 \"physicalpath\". The logical path associated to the physical path is
 
81
 \"logicalpath\".
 
82
[VARIABLE = value]: Add the variable definition \"VARIABLE=value\"
 
83
[-byte]: compile with byte-code version of coq
 
84
[-opt]: compile with native-code version of coq
 
85
[-impredicative-set]: compile with option -impredicative-set of coq
 
86
[-no-install]: build a makefile with no install target
 
87
[-f file]: take the contents of file as arguments
 
88
[-o file]: output should go in file file 
 
89
[-h]: print this usage summary
 
90
[--help]: equivalent to [-h]\n";
 
91
  exit 1
 
92
 
 
93
let is_genrule r =
 
94
    let genrule = Str.regexp("%") in
 
95
      Str.string_match genrule r 0
 
96
 
 
97
let absolute_dir dir =
 
98
  let current = Sys.getcwd () in
 
99
    Sys.chdir dir;
 
100
    let dir' = Sys.getcwd () in
 
101
      Sys.chdir current;
 
102
      dir'
 
103
 
 
104
let is_prefix dir1 dir2 =
 
105
  let l1 = String.length dir1 in
 
106
  let l2 = String.length dir2 in
 
107
    dir1 = dir2 or (l1 < l2 & String.sub dir2 0 l1 = dir1 & dir2.[l1] = '/')
 
108
 
 
109
let canonize f =
 
110
  let l = String.length f in
 
111
  if l > 2 && f.[0] = '.' && f.[1] = '/' then
 
112
    let n = let i = ref 2 in while !i < l && f.[!i] = '/' do incr i done; !i in
 
113
    String.sub f n (l-n)
 
114
  else f
 
115
 
 
116
let is_absolute_prefix dir dir' =
 
117
  is_prefix (absolute_dir dir) (absolute_dir dir')
 
118
 
 
119
let is_included dir = function
 
120
  | RInclude (dir',_) -> is_absolute_prefix dir' dir
 
121
  | Include dir' -> absolute_dir dir = absolute_dir dir'
 
122
  | _ -> false
 
123
 
 
124
let has_top_file = function
 
125
  | ML s | V s -> s = Filename.basename s
 
126
  | _ -> false
 
127
 
 
128
let physical_dir_of_logical_dir ldir =
 
129
  let pdir = String.copy ldir in
 
130
  for i = 0 to String.length ldir - 1 do
 
131
    if pdir.[i] = '.' then pdir.[i] <- '/';
 
132
  done;
 
133
  pdir
 
134
 
 
135
let standard ()=
 
136
  print "byte:\n";
 
137
  print "\t$(MAKE) all \"OPT:=-byte\"\n\n";
 
138
  print "opt:\n";
 
139
  if !opt = "" then print "\t@echo \"WARNING: opt is disabled\"\n";
 
140
  print "\t$(MAKE) all \"OPT:="; print !opt; print "\"\n\n"
 
141
 
 
142
let is_prefix_of_file dir f =
 
143
  is_prefix dir (absolute_dir (Filename.dirname f))
 
144
 
 
145
let classify_files_by_root var files (inc_i,inc_r) =
 
146
  if not (List.exists (fun (pdir,_,_) -> pdir = ".") inc_r) then
 
147
    begin
 
148
      (* Files in the scope of a -R option (assuming they are disjoint) *)
 
149
      list_iter_i (fun i (pdir,ldir,abspdir) ->
 
150
        if List.exists (is_prefix_of_file abspdir) files then
 
151
          printf "%s%d:=$(patsubst %s/%%,%%,$(filter %s/%%,$(%s)))\n"
 
152
            var i pdir pdir var)
 
153
        inc_r;
 
154
      (* Files not in the scope of a -R option *)
 
155
      let pat_of_dir (pdir,_,_) = pdir^"/%" in
 
156
      let pdir_patterns = String.concat " " (List.map pat_of_dir inc_r) in
 
157
      printf "%s0:=$(filter-out %s,$(%s))\n" var pdir_patterns var
 
158
    end
 
159
 
 
160
let install_include_by_root var files (_,inc_r) =
 
161
  try
 
162
    (* All files caught by a -R . option (assuming it is the only one) *)
 
163
    let ldir = List.assoc "." (List.map (fun (p,l,_) -> (p,l)) inc_r) in
 
164
    let pdir = physical_dir_of_logical_dir ldir in
 
165
    printf "\t(for i in $(%s); do \\\n" var;
 
166
    printf "\t install -D $$i $(COQLIB)/user-contrib/%s/$$i; \\\n" pdir;
 
167
    printf "\t done)\n"
 
168
  with Not_found ->
 
169
    (* Files in the scope of a -R option (assuming they are disjoint) *)
 
170
    list_iter_i (fun i (pdir,ldir,abspdir) ->
 
171
      if List.exists (is_prefix_of_file abspdir) files then
 
172
        begin
 
173
          let pdir' = physical_dir_of_logical_dir ldir in
 
174
          printf "\t(cd %s; for i in $(%s%d); do \\\n" pdir var i;
 
175
          printf "\t install -D $$i $(COQLIB)/user-contrib/%s/$$i; \\\n" pdir';
 
176
          printf "\t done)\n"
 
177
        end) inc_r;
 
178
    (* Files not in the scope of a -R option *)
 
179
    printf "\t(for i in $(%s0); do \\\n" var;
 
180
    printf "\t install -D $$i $(COQLIB)/user-contrib/$(INSTALLDEFAULTROOT)/$$i; \\\n";
 
181
    printf "\t done)\n"
 
182
 
 
183
let install (vfiles,mlfiles,_,sds) inc =
 
184
  print "install:\n";
 
185
  print "\tmkdir -p $(COQLIB)/user-contrib\n";
 
186
  if !some_vfile then install_include_by_root "VOFILES" vfiles inc;
 
187
  if !some_mlfile then install_include_by_root "CMOFILES" mlfiles inc;
 
188
  if !some_mlfile then install_include_by_root "CMIFILES" mlfiles inc;
 
189
  if Coq_config.has_natdynlink && !some_mlfile then
 
190
    install_include_by_root "CMXSFILES" mlfiles inc;
 
191
  List.iter
 
192
    (fun x ->
 
193
      printf "\t(cd %s; $(MAKE) INSTALLDEFAULTROOT=$(INSTALLDEFAULTROOT)/%s install)\n" x x)
 
194
    sds;
 
195
  print "\n"
 
196
 
 
197
let make_makefile sds =
 
198
  if !make_name <> "" then begin
 
199
    printf "%s: %s\n" !makefile_name !make_name;
 
200
    printf "\tmv -f %s %s.bak\n" !makefile_name !makefile_name;
 
201
    printf "\t$(COQBIN)coq_makefile -f %s -o %s\n" !make_name !makefile_name;
 
202
    print "\n";
 
203
    List.iter
 
204
      (fun x -> print "\t(cd "; print x; print " ; $(MAKE) Makefile)\n")
 
205
      sds;
 
206
    print "\n";
 
207
  end
 
208
 
 
209
let clean sds sps =
 
210
  print "clean:\n";
 
211
  print "\trm -f $(VOFILES) $(VIFILES) $(GFILES) *~\n";
 
212
  print "\trm -f all.ps all-gal.ps all.pdf all-gal.pdf all.glob $(VFILES:.v=.glob) $(HTMLFILES) \
 
213
         $(GHTMLFILES) $(VFILES:.v=.tex) $(VFILES:.v=.g.tex) $(VFILES:.v=.v.d)\n";
 
214
  if !some_mlfile then
 
215
    print "\trm -f $(CMOFILES) $(MLFILES:.ml=.cmi) $(MLFILES:.ml=.ml.d) $(MLFILES:.ml=.cmx) $(MLFILES:.ml=.o)\n";
 
216
  if Coq_config.has_natdynlink && !some_mlfile then
 
217
    print "\trm -f $(CMXSFILES) $(CMXSFILES:.cmxs=.o)\n";
 
218
  print "\t- rm -rf html\n";
 
219
  List.iter
 
220
    (fun (file,_,_) -> 
 
221
       if not (is_genrule file) then
 
222
         (print "\t- rm -f "; print file; print "\n"))
 
223
    sps;
 
224
  List.iter
 
225
    (fun x -> print "\t(cd "; print x; print " ; $(MAKE) clean)\n")
 
226
    sds;
 
227
  print "\n";
 
228
  print "archclean:\n";
 
229
  print "\trm -f *.cmx *.o\n";
 
230
  List.iter
 
231
    (fun x -> print "\t(cd "; print x; print " ; $(MAKE) archclean)\n")
 
232
    sds;
 
233
  print "\n\n";
 
234
  print "printenv: \n\t@echo CAMLC =\t$(CAMLC)\n\t@echo CAMLOPTC =\t$(CAMLOPTC)\n";
 
235
  print "\t@echo CAMLP4LIB =\t$(CAMLP4LIB)\n\n"
 
236
 
 
237
let header_includes () = ()
 
238
  
 
239
let footer_includes () = 
 
240
  if !some_vfile then print "-include $(VFILES:.v=.v.d)\n.SECONDARY: $(VFILES:.v=.v.d)\n\n";
 
241
  if !some_mlfile then print "-include $(MLFILES:.ml=.ml.d)\n.SECONDARY: $(MLFILES:.ml=.ml.d)\n\n"
 
242
 
 
243
let implicit () =
 
244
  let ml_rules () =
 
245
    print "%.cmi: %.mli\n\t$(CAMLC) $(ZDEBUG) $(ZFLAGS) $<\n\n";
 
246
    print "%.cmo: %.ml\n\t$(CAMLC) $(ZDEBUG) $(ZFLAGS) $(PP) $<\n\n";
 
247
    print "%.cmx: %.ml\n\t$(CAMLOPTC) $(ZDEBUG) $(ZFLAGS) $(PP) $<\n\n";
 
248
    print "%.cmxs: %.ml\n\t$(CAMLOPTLINK) $(ZDEBUG) $(ZFLAGS) -shared -o $@ $(PP) $<\n\n";
 
249
    print "%.cmo: %.ml4\n\t$(CAMLC) $(ZDEBUG) $(ZFLAGS) $(PP) -impl $<\n\n";
 
250
    print "%.cmx: %.ml4\n\t$(CAMLOPTC) $(ZDEBUG) $(ZFLAGS) $(PP) -impl $<\n\n";
 
251
    print "%.cmxs: %.ml4\n\t$(CAMLOPTLINK) $(ZDEBUG) $(ZFLAGS) -shared -o $@ $(PP) -impl $<\n\n";
 
252
    print "%.ml.d: %.ml\n";
 
253
    print "\t$(CAMLBIN)ocamldep -slash $(COQSRCLIBS) $(OCAMLLIBS) $(PP) \"$<\" > \"$@\"\n\n"
 
254
  and v_rule () =
 
255
    print "%.vo %.glob: %.v\n\t$(COQC) -dump-glob $*.glob $(COQDEBUG) $(COQFLAGS) $*\n\n";
 
256
    print "%.vi: %.v\n\t$(COQC) -i $(COQDEBUG) $(COQFLAGS) $*\n\n";
 
257
    print "%.g: %.v\n\t$(GALLINA) $<\n\n";
 
258
    print "%.tex: %.v\n\t$(COQDOC) -latex $< -o $@\n\n";
 
259
    print "%.html: %.v %.glob\n\t$(COQDOC) -glob-from $*.glob  -html $< -o $@\n\n";
 
260
    print "%.g.tex: %.v\n\t$(COQDOC) -latex -g $< -o $@\n\n";
 
261
    print "%.g.html: %.v %.glob\n\t$(COQDOC) -glob-from $*.glob -html -g $< -o $@\n\n";
 
262
    print "%.v.d: %.v\n";
 
263
    print "\t$(COQDEP) -glob -slash $(COQLIBS) \"$<\" > \"$@\" || ( RV=$$?; rm -f \"$@\"; exit $${RV} )\n\n"
 
264
  in
 
265
    if !some_mlfile then ml_rules ();
 
266
    if !some_vfile then v_rule ()
 
267
 
 
268
let variables defs =
 
269
  let var_aux (v,def) = print v; print "="; print def; print "\n" in
 
270
    section "Variables definitions.";
 
271
    print "ZFLAGS=$(OCAMLLIBS) $(COQSRCLIBS) -I $(CAMLP4LIB)\n";
 
272
    if !opt = "-byte" then 
 
273
      print "override OPT:=-byte\n"
 
274
    else
 
275
      print "OPT:=\n";
 
276
    if !impredicative_set = true then print "OTHERFLAGS=-impredicative-set\n";
 
277
    (* Coq executables and relative variables *)
 
278
    print "COQFLAGS:=-q $(OPT) $(COQLIBS) $(OTHERFLAGS) $(COQ_XML)\n";
 
279
    print "ifdef CAMLBIN\n  COQMKTOPFLAGS:=-camlbin $(CAMLBIN) -camlp4bin $(CAMLP4BIN)\nendif\n";
 
280
    print "COQC:=$(COQBIN)coqc\n";
 
281
    print "COQDEP:=$(COQBIN)coqdep -c\n";
 
282
    print "GALLINA:=$(COQBIN)gallina\n";
 
283
    print "COQDOC:=$(COQBIN)coqdoc\n";
 
284
    print "COQMKTOP:=$(COQBIN)coqmktop\n";
 
285
    (* Caml executables and relative variables *)
 
286
    printf "CAMLC:=$(CAMLBIN)%s -c -rectypes\n" best_ocamlc;
 
287
    printf "CAMLOPTC:=$(CAMLBIN)%s -c -rectypes\n" best_ocamlopt;
 
288
    printf "CAMLLINK:=$(CAMLBIN)%s -rectypes\n" best_ocamlc;
 
289
    printf "CAMLOPTLINK:=$(CAMLBIN)%s -rectypes\n" best_ocamlopt;
 
290
    print "GRAMMARS:=grammar.cma\n";
 
291
    print "CAMLP4EXTEND:=pa_extend.cmo pa_macro.cmo q_MLast.cmo\n";
 
292
    print "CAMLP4OPTIONS:=\n";
 
293
    List.iter var_aux defs;
 
294
    print "PP:=-pp \"$(CAMLP4BIN)$(CAMLP4)o -I . $(COQSRCLIBS) $(CAMLP4EXTEND) $(GRAMMARS) $(CAMLP4OPTIONS) -impl\"\n";
 
295
    print "\n"
 
296
 
 
297
let parameters () =
 
298
  print "# \n";
 
299
  print "# This Makefile may take 3 arguments passed as environment variables:\n";
 
300
  print "#   - COQBIN to specify the directory where Coq binaries resides;\n";
 
301
  print "#   - CAMLBIN and CAMLP4BIN to give the path for the OCaml and Camlp4/5 binaries.\n";
 
302
  print "COQLIB:=$(shell $(COQBIN)coqtop -where | sed -e 's/\\\\/\\\\\\\\/g')\n"; 
 
303
  print "CAMLP4:=\"$(shell $(COQBIN)coqtop -config | awk -F = '/CAMLP4=/{print $$2}')\"\n"; 
 
304
  print "ifndef CAMLP4BIN\n  CAMLP4BIN:=$(CAMLBIN)\nendif\n\n";
 
305
  print "CAMLP4LIB:=$(shell $(CAMLP4BIN)$(CAMLP4) -where)\n\n"
 
306
 
 
307
let include_dirs (inc_i,inc_r) =
 
308
  let parse_includes l = List.map (fun (x,_) -> "-I " ^ x) l in
 
309
  let parse_rec_includes l =
 
310
    List.map (fun (p,l,_) ->
 
311
      let l' = if l = "" then "\"\"" else l in "-R " ^ p ^ " " ^ l')
 
312
      l in
 
313
  let inc_i' = List.filter (fun (i,_) -> not (List.exists (fun (i',_,_) -> is_absolute_prefix i' i) inc_r)) inc_i in
 
314
  let str_i = parse_includes inc_i in
 
315
  let str_i' = parse_includes inc_i' in
 
316
  let str_r = parse_rec_includes inc_r in
 
317
    section "Libraries definitions.";
 
318
    print "OCAMLLIBS:="; print_list "\\\n  " str_i; print "\n";
 
319
    print "COQSRCLIBS:=-I $(COQLIB)/kernel -I $(COQLIB)/lib \\
 
320
  -I $(COQLIB)/library -I $(COQLIB)/parsing \\
 
321
  -I $(COQLIB)/pretyping -I $(COQLIB)/interp \\
 
322
  -I $(COQLIB)/proofs -I $(COQLIB)/tactics \\
 
323
  -I $(COQLIB)/toplevel -I $(COQLIB)/contrib/cc -I $(COQLIB)/contrib/dp \\
 
324
  -I $(COQLIB)/contrib/extraction -I $(COQLIB)/contrib/field \\
 
325
  -I $(COQLIB)/contrib/firstorder -I $(COQLIB)/contrib/fourier \\
 
326
  -I $(COQLIB)/contrib/funind -I $(COQLIB)/contrib/interface \\
 
327
  -I $(COQLIB)/contrib/micromega -I $(COQLIB)/contrib/omega \\
 
328
  -I $(COQLIB)/contrib/ring -I $(COQLIB)/contrib/romega \\
 
329
  -I $(COQLIB)/contrib/rtauto -I $(COQLIB)/contrib/setoid_ring \\
 
330
  -I $(COQLIB)/contrib/subtac -I $(COQLIB)/contrib/xml\n";
 
331
    print "COQLIBS:="; print_list "\\\n  " str_i'; print " "; print_list "\\\n  " str_r; print "\n";
 
332
    print "COQDOCLIBS:=";   print_list "\\\n  " str_r; print "\n\n"
 
333
 
 
334
 
 
335
let rec special = function
 
336
  | [] -> []
 
337
  | Special (file,deps,com) :: r -> (file,deps,com) :: (special r)
 
338
  | _ :: r -> special r
 
339
      
 
340
let custom sps =
 
341
  let pr_sp (file,dependencies,com) =
 
342
    print file; print ": "; print dependencies; print "\n";
 
343
    print "\t"; print com; print "\n\n"
 
344
  in
 
345
    if sps <> [] then section "Custom targets.";
 
346
    List.iter pr_sp sps
 
347
 
 
348
let subdirs sds =
 
349
  let pr_subdir s =
 
350
    print s; print ":\n\tcd "; print s; print " ; $(MAKE) all\n\n"
 
351
  in
 
352
    if sds <> [] then section "Subdirectories.";
 
353
    List.iter pr_subdir sds;
 
354
    section "Special targets.";
 
355
    print ".PHONY: ";
 
356
    print_list " "
 
357
      ("all" ::  "opt" :: "byte" :: "archclean" :: "clean" :: "install" 
 
358
        :: "depend" :: "html" :: sds);
 
359
    print "\n\n"
 
360
 
 
361
let rec split_arguments = function
 
362
  | V n :: r ->
 
363
      let (v,m,o,s),i,d = split_arguments r in ((canonize n::v,m,o,s),i,d)
 
364
  | ML n :: r ->
 
365
      let (v,m,o,s),i,d = split_arguments r in ((v,canonize n::m,o,s),i,d)
 
366
  | Special (n,dep,c) :: r -> 
 
367
      let (v,m,o,s),i,d = split_arguments r in ((v,m,(n,dep,c)::o,s),i,d)
 
368
  | Subdir n :: r ->
 
369
      let (v,m,o,s),i,d = split_arguments r in ((v,m,o,n::s),i,d)
 
370
  | Include p :: r ->
 
371
      let t,(i,r),d = split_arguments r in (t,((p,absolute_dir p)::i,r),d)
 
372
  | RInclude (p,l) :: r ->
 
373
      let t,(i,r),d = split_arguments r in (t,(i,(p,l,absolute_dir p)::r),d)
 
374
  | Def (v,def) :: r -> 
 
375
      let t,i,d = split_arguments r in (t,i,(v,def)::d)
 
376
  | [] -> ([],[],[],[]),([],[]),[]
 
377
 
 
378
let main_targets vfiles mlfiles other_targets inc =
 
379
    if !some_vfile then
 
380
      begin
 
381
        print "VFILES:="; print_list "\\\n  " vfiles; print "\n";
 
382
        print "VOFILES:=$(VFILES:.v=.vo)\n";
 
383
        classify_files_by_root "VOFILES" vfiles inc;
 
384
        print "GLOBFILES:=$(VFILES:.v=.glob)\n";
 
385
        print "VIFILES:=$(VFILES:.v=.vi)\n";
 
386
        print "GFILES:=$(VFILES:.v=.g)\n";
 
387
        print "HTMLFILES:=$(VFILES:.v=.html)\n";
 
388
        print "GHTMLFILES:=$(VFILES:.v=.g.html)\n"
 
389
      end;
 
390
    if !some_mlfile then
 
391
      begin
 
392
        print "MLFILES:="; print_list "\\\n  " mlfiles; print "\n";
 
393
        print "CMOFILES:=$(MLFILES:.ml=.cmo)\n";
 
394
        classify_files_by_root "CMOFILES" mlfiles inc;
 
395
        print "CMIFILES:=$(MLFILES:.ml=.cmi)\n";
 
396
        classify_files_by_root "CMIFILES" mlfiles inc;
 
397
        print "CMXFILES:=$(MLFILES:.ml=.cmx)\n";
 
398
        print "CMXSFILES:=$(MLFILES:.ml=.cmxs)\n";
 
399
        classify_files_by_root "CMXSFILES" mlfiles inc;
 
400
        print "OFILES:=$(MLFILES:.ml=.o)\n";
 
401
      end;
 
402
    print "\nall: ";
 
403
    if !some_vfile then print "$(VOFILES) ";
 
404
    if !some_mlfile then print "$(CMOFILES) ";
 
405
    if Coq_config.has_natdynlink && !some_mlfile then print "$(CMXSFILES) ";
 
406
    print_list "\\\n  " other_targets; print "\n";
 
407
    if !some_vfile then 
 
408
      begin
 
409
        print "spec: $(VIFILES)\n\n";
 
410
        print "gallina: $(GFILES)\n\n";
 
411
        print "html: $(GLOBFILES) $(VFILES)\n";
 
412
        print "\t- mkdir html\n"; 
 
413
        print "\t$(COQDOC) -toc -html $(COQDOCLIBS) -d html $(VFILES)\n\n";
 
414
        print "gallinahtml: $(GLOBFILES) $(VFILES)\n";
 
415
        print "\t- mkdir html\n"; 
 
416
        print "\t$(COQDOC) -toc -html -g $(COQDOCLIBS) -d html $(VFILES)\n\n";
 
417
        print "all.ps: $(VFILES)\n";
 
418
        print "\t$(COQDOC) -toc -ps $(COQDOCLIBS) -o $@ `$(COQDEP) -sort -suffix .v $(VFILES)`\n\n";
 
419
        print "all-gal.ps: $(VFILES)\n";
 
420
        print "\t$(COQDOC) -toc -ps -g $(COQDOCLIBS) -o $@ `$(COQDEP) -sort -suffix .v $(VFILES)`\n\n";
 
421
        print "all.pdf: $(VFILES)\n";
 
422
        print "\t$(COQDOC) -toc -pdf $(COQDOCLIBS) -o $@ `$(COQDEP) -sort -suffix .v $(VFILES)`\n\n";
 
423
        print "all-gal.pdf: $(VFILES)\n";
 
424
        print "\t$(COQDOC) -toc -pdf -g $(COQDOCLIBS) -o $@ `$(COQDEP) -sort -suffix .v $(VFILES)`\n\n";
 
425
        print "\n\n"
 
426
      end
 
427
 
 
428
let all_target (vfiles, mlfiles, sps, sds) inc =
 
429
  let special_targets = List.filter (fun (n,_,_) -> not (is_genrule n)) sps in
 
430
  let other_targets = List.map (fun x,_,_ -> x) special_targets @ sds in
 
431
  section "Definition of the \"all\" target.";
 
432
  main_targets vfiles mlfiles other_targets inc;
 
433
  custom sps;
 
434
  subdirs sds
 
435
      
 
436
let parse f =
 
437
  let rec string = parser 
 
438
    | [< '' ' | '\n' | '\t' >] -> ""
 
439
    | [< 'c; s >] -> (String.make 1 c)^(string s)
 
440
    | [< >] -> ""
 
441
  and string2 = parser 
 
442
    | [< ''"' >] -> ""
 
443
    | [< 'c; s >] -> (String.make 1 c)^(string2 s)
 
444
  and skip_comment = parser 
 
445
    | [< ''\n'; s >] -> s
 
446
    | [< 'c; s >] -> skip_comment s
 
447
    | [< >] -> [< >]
 
448
  and args = parser 
 
449
    | [< '' ' | '\n' | '\t'; s >] -> args s
 
450
    | [< ''#'; s >] -> args (skip_comment s)
 
451
    | [< ''"'; str = string2; s >] -> ("" ^ str) :: args s
 
452
    | [< 'c; str = string; s >] -> ((String.make 1 c) ^ str) :: (args s)
 
453
    | [< >] -> []
 
454
  in
 
455
  let c = open_in f in
 
456
  let res = args (Stream.of_channel c) in
 
457
    close_in c;
 
458
    res
 
459
 
 
460
let rec process_cmd_line = function
 
461
  | [] -> 
 
462
      some_file := !some_file or !some_mlfile or !some_vfile; []
 
463
  | ("-h"|"--help") :: _ -> 
 
464
      usage ()
 
465
  | ("-no-opt"|"-byte") :: r -> 
 
466
      opt := "-byte"; process_cmd_line r
 
467
  | ("-full"|"-opt") :: r -> 
 
468
      opt := "-opt"; process_cmd_line r
 
469
  | "-impredicative-set" :: r ->
 
470
      impredicative_set := true; process_cmd_line r
 
471
  | "-no-install" :: r ->
 
472
      no_install := true; process_cmd_line r
 
473
  | "-custom" :: com :: dependencies :: file :: r ->
 
474
      let check_dep f =
 
475
        if Filename.check_suffix f ".v" then
 
476
          some_vfile := true
 
477
        else if (Filename.check_suffix f ".ml") || (Filename.check_suffix f ".ml4") then
 
478
          some_mlfile := true
 
479
      in
 
480
        List.iter check_dep (Str.split (Str.regexp "[ \t]+") dependencies);
 
481
        Special (file,dependencies,com) :: (process_cmd_line r)
 
482
  | "-I" :: d :: r ->
 
483
      Include d :: (process_cmd_line r)
 
484
  | "-R" :: p :: l :: r ->
 
485
      RInclude (p,l) :: (process_cmd_line r)
 
486
  | ("-I"|"-custom") :: _ -> 
 
487
      usage ()
 
488
  | "-f" :: file :: r -> 
 
489
      make_name := file;
 
490
      process_cmd_line ((parse file)@r)
 
491
  | ["-f"] -> 
 
492
      usage ()
 
493
  | "-o" :: file :: r -> 
 
494
      makefile_name := file;
 
495
      output_channel := (open_out file);
 
496
      (process_cmd_line r)
 
497
  | v :: "=" :: def :: r -> 
 
498
      Def (v,def) :: (process_cmd_line r)
 
499
  | f :: r ->
 
500
      if Filename.check_suffix f ".v" then begin
 
501
          some_vfile := true; 
 
502
          V f :: (process_cmd_line r)
 
503
        end else if (Filename.check_suffix f ".ml") || (Filename.check_suffix f ".ml4") then begin
 
504
          some_mlfile := true; 
 
505
          ML f :: (process_cmd_line r)
 
506
        end else if (Filename.check_suffix f ".mli") then begin
 
507
          Printf.eprintf "Warning: no need for .mli files, skipped %s\n" f;
 
508
          process_cmd_line r
 
509
        end else
 
510
          Subdir f :: (process_cmd_line r)
 
511
              
 
512
let banner () =
 
513
  print
 
514
"##########################################################################
 
515
##  v      #                  The Coq Proof Assistant                   ##
 
516
## <O___,, # CNRS-Ecole Polytechnique-INRIA Futurs-Universite Paris Sud ##
 
517
##   \\VV/  #                                                            ##
 
518
##    //   #   Makefile automagically generated by coq_makefile V8.2    ##
 
519
##########################################################################
 
520
 
 
521
"
 
522
 
 
523
let warning () =
 
524
  print "# WARNING\n#\n";
 
525
  print "# This Makefile has been automagically generated\n";
 
526
  print "# Edit at your own risks !\n";
 
527
  print "#\n# END OF WARNING\n\n"
 
528
    
 
529
let print_list l = List.iter (fun x -> print x; print " ") l
 
530
  
 
531
let command_line args =
 
532
  print "#\n# This Makefile was generated by the command line :\n";
 
533
  print "# coq_makefile ";
 
534
  print_list args;
 
535
  print "\n#\n\n"
 
536
    
 
537
let directories_deps l =
 
538
  let print_dep f dep = 
 
539
    if dep <> [] then begin print f; print ": "; print_list dep; print "\n" end
 
540
  in
 
541
  let rec iter ((dirs,before) as acc) = function
 
542
    | [] -> 
 
543
        ()
 
544
    | (Subdir d) :: l -> 
 
545
        print_dep d before; iter (d :: dirs, d :: before) l
 
546
    | (ML f) :: l ->
 
547
        print_dep f dirs; iter (dirs, f :: before) l
 
548
    | (V f) :: l ->
 
549
        print_dep f dirs; iter (dirs, f :: before) l
 
550
    | (Special (f,_,_)) :: l ->
 
551
        print_dep f dirs; iter (dirs, f :: before) l
 
552
    | _ :: l -> 
 
553
        iter acc l
 
554
  in
 
555
    iter ([],[]) l
 
556
 
 
557
let ensure_root_dir l =
 
558
  if List.exists (is_included ".") l or not (List.exists has_top_file l) then
 
559
    l
 
560
  else
 
561
    Include "." :: l
 
562
 
 
563
let warn_install_at_root_directory (vfiles,mlfiles,_,_) (inc_i,inc_r) =
 
564
  let inc_r_top = List.filter (fun (_,ldir,_) -> ldir = "") inc_r in
 
565
  let inc_top = List.map (fun (p,_,a) -> (p,a)) inc_r_top @ inc_i in
 
566
  let files = vfiles @ mlfiles in
 
567
  if not !no_install &&
 
568
    List.exists (fun f -> List.mem_assoc (Filename.dirname f) inc_top) files
 
569
  then
 
570
    Printf.eprintf "Warning: install target will copy files at the first level of the coq contributions installation directory; option -R %sis recommended\n" 
 
571
      (if inc_r_top = [] then "" else "with non trivial logical root ")
 
572
 
 
573
let check_overlapping_include (inc_i,inc_r) =
 
574
  let pwd = Sys.getcwd () in
 
575
  let rec aux = function
 
576
    | [] -> ()
 
577
    | (pdir,_,abspdir)::l ->
 
578
        if not (is_prefix pwd abspdir) then
 
579
          Printf.eprintf "Warning: in option -R, %s is not a subdirectoty of the current directory\n" pdir;
 
580
        List.iter (fun (pdir',_,abspdir') ->
 
581
          if is_prefix abspdir abspdir' or is_prefix abspdir' abspdir then
 
582
            Printf.eprintf "Warning: in options -R, %s and %s overlap\n" pdir pdir') l;
 
583
        List.iter (fun (pdir',abspdir') ->
 
584
          if is_prefix abspdir abspdir' or is_prefix abspdir' abspdir then
 
585
            Printf.eprintf "Warning: in option -I, %s overlap with %s in option -R\n" pdir' pdir) inc_i 
 
586
  in aux inc_r
 
587
 
 
588
let do_makefile args =
 
589
  let l = process_cmd_line args in
 
590
  let l = ensure_root_dir l in
 
591
  let (_,_,sps,sds as targets), inc, defs = split_arguments l in
 
592
  warn_install_at_root_directory targets inc;
 
593
  check_overlapping_include inc;
 
594
  banner ();
 
595
  header_includes ();
 
596
  warning ();
 
597
  command_line args;
 
598
  parameters ();
 
599
  include_dirs inc;
 
600
  variables defs;
 
601
  all_target targets inc;
 
602
  implicit ();
 
603
  standard ();
 
604
  if not !no_install then install targets inc;
 
605
  clean sds sps;
 
606
  make_makefile sds;
 
607
  (* TEST directories_deps l; *)
 
608
  footer_includes ();
 
609
  warning ();
 
610
  if not (!output_channel == stdout) then close_out !output_channel;
 
611
  exit 0
 
612
          
 
613
let main () =
 
614
  let args =
 
615
    if Array.length Sys.argv = 1 then usage ();
 
616
    List.tl (Array.to_list Sys.argv)
 
617
  in
 
618
    do_makefile args
 
619
      
 
620
let _ = Printexc.catch main ()