Sys.Signals module for a Variant type of signals (and a set_signal function that...
[ocaml.git] / myocamlbuild.ml
blob6b0ab371dd6d67657830f5fde8ff1647426807ae
1 open Ocamlbuild_plugin
2 open Command
3 open Arch
4 open Format
6 module C = Myocamlbuild_config
8 let windows = Sys.os_type = "Win32";;
9 if windows then tag_any ["windows"];;
10 let ccomptype = C.ccomptype
11 let () = if ccomptype <> "cc" then eprintf "ccomptype: %s@." ccomptype;;
13 let fp_cat oc f = with_input_file ~bin:true f (fun ic -> copy_chan ic oc)
15 (* Improve using the command module in Myocamlbuild_config
16 with the variant version (`S, `A...) *)
17 let mkdll out implib files opts =
18 let s = Command.string_of_command_spec in
19 Cmd(Sh(C.mkdll out (s implib) (s files) (s opts)))
21 let mkexe out files opts =
22 let s = Command.string_of_command_spec in
23 Cmd(Sh(C.mkexe out (s files) (s opts)))
25 let mklib out files opts =
26 let s = Command.string_of_command_spec in
27 Cmd(Sh(C.mklib out (s files) (s opts)))
29 let syslib x = A(C.syslib x);;
30 let syscamllib x =
31 if ccomptype = "msvc" then A(Printf.sprintf "lib%s.lib" x)
32 else A("-l"^x)
34 let mkobj obj file opts =
35 let obj = obj-.-C.o in
36 if ccomptype = "msvc" then
37 Seq[Cmd(S[Sh C.bytecc; Sh C.bytecccompopts; opts; A"-c"; Px file]);
38 mv (Pathname.basename (Pathname.update_extension C.o file)) obj]
39 else
40 Cmd(S[Sh C.bytecc; Sh C.bytecccompopts; opts; A"-c"; P file; A"-o"; Px obj])
42 let mkdynobj obj file opts =
43 let d_obj = obj-.-"d"-.-C.o in
44 if ccomptype = "msvc" then
45 Seq[Cmd(S[Sh C.bytecc; opts; Sh C.dllcccompopts; A"-c"; Px file]);
46 mv (Pathname.basename (Pathname.update_extension C.o file)) d_obj]
47 else
48 Cmd(S[Sh C.bytecc; opts; Sh C.dllcccompopts; A"-c"; P file; A"-o"; Px d_obj])
50 let mknatobj obj file opts =
51 let obj = obj-.-C.o in
52 if ccomptype = "msvc" then
53 Seq[Cmd(S[Sh C.nativecc; opts; A"-c"; Px file]);
54 mv (Pathname.basename (Pathname.update_extension C.o file)) obj]
55 else
56 Cmd(S[Sh C.nativecc; A"-O"; opts;
57 Sh C.nativecccompopts; A"-c"; P file; A"-o"; Px obj])
59 let add_exe a =
60 if not windows || Pathname.check_extension a "exe" then a
61 else a-.-"exe";;
63 let add_exe_if_exists a =
64 if not windows || Pathname.check_extension a "exe" then a
65 else
66 let exe = a-.-"exe" in
67 if Pathname.exists exe then exe else a;;
69 let convert_command_for_windows_shell spec =
70 if not windows then spec else
71 let rec self specs acc =
72 match specs with
73 | N :: specs -> self specs acc
74 | S[] :: specs -> self specs acc
75 | S[x] :: specs -> self (x :: specs) acc
76 | S specs :: specs' -> self (specs @ specs') acc
77 | (P(a) | A(a)) :: specs ->
78 let dirname = Pathname.dirname a in
79 let basename = Pathname.basename a in
80 let p =
81 if dirname = Pathname.current_dir_name then Sh(add_exe_if_exists basename)
82 else Sh(add_exe_if_exists (dirname ^ "\\" ^ basename)) in
83 if String.contains_string basename 0 "ocamlrun" = None then
84 List.rev (p :: acc) @ specs
85 else
86 self specs (p :: acc)
87 | [] | (Px _ | T _ | V _ | Sh _ | Quote _) :: _ ->
88 invalid_arg "convert_command_for_windows_shell: invalid atom in head position"
89 in S(self [spec] [])
91 let convert_for_windows_shell solver () =
92 convert_command_for_windows_shell (solver ())
94 let ocamlrun = A"boot/ocamlrun"
95 let full_ocamlrun = P((Sys.getcwd ()) / "boot/ocamlrun")
97 let boot_ocamlc = S[ocamlrun; A"boot/ocamlc"; A"-I"; A"boot"; A"-nostdlib"]
99 let partial = bool_of_string (getenv ~default:"false" "OCAMLBUILD_PARTIAL");;
101 let if_partial_dir dir =
102 if partial then ".."/dir else dir;;
104 let unix_dir =
105 match Sys.os_type with
106 | "Win32" -> if_partial_dir "otherlibs/win32unix"
107 | _ -> if_partial_dir "otherlibs/unix";;
109 let threads_dir = if_partial_dir "otherlibs/threads";;
110 let systhreads_dir = if_partial_dir "otherlibs/systhreads";;
111 let dynlink_dir = if_partial_dir "otherlibs/dynlink";;
112 let str_dir = if_partial_dir "otherlibs/str";;
113 let toplevel_dir = if_partial_dir "toplevel";;
115 let ocamlc_solver =
116 let native_deps = ["ocamlc.opt"; "stdlib/stdlib.cmxa";
117 "stdlib/std_exit.cmx"; "stdlib/std_exit"-.-C.o] in
118 let byte_deps = ["ocamlc"; "stdlib/stdlib.cma"; "stdlib/std_exit.cmo"] in
119 fun () ->
120 if List.for_all Pathname.exists native_deps then
121 S[A"./ocamlc.opt"; A"-nostdlib"]
122 else if List.for_all Pathname.exists byte_deps then
123 S[ocamlrun; A"./ocamlc"; A"-nostdlib"]
124 else boot_ocamlc;;
126 Command.setup_virtual_command_solver "OCAMLC" ocamlc_solver;;
127 Command.setup_virtual_command_solver "OCAMLCWIN" (convert_for_windows_shell ocamlc_solver);;
129 let ocamlopt_solver () =
130 S[if Pathname.exists "ocamlopt.opt" && Pathname.exists ("stdlib/stdlib.cmxa")
131 then A"./ocamlopt.opt"
132 else S[ocamlrun; A"./ocamlopt"];
133 A"-nostdlib"];;
135 Command.setup_virtual_command_solver "OCAMLOPT" ocamlopt_solver;;
136 Command.setup_virtual_command_solver "OCAMLOPTWIN" (convert_for_windows_shell ocamlopt_solver);;
138 let ocamlc = V"OCAMLC";;
139 let ocamlopt = V"OCAMLOPT";;
141 let ar = A"ar";;
143 dispatch begin function
144 | Before_hygiene ->
145 if partial then
146 let patt = String.concat ","
147 ["asmcomp"; "bytecomp"; "debugger"; "driver";
148 "lex"; "ocamldoc"; "otherlibs"; "parsing"; "stdlib"; "tools";
149 "toplevel"; "typing"; "utils"]
150 in Ocamlbuild_pack.Configuration.parse_string
151 (sprintf "<{%s}/**>: not_hygienic, -traverse" patt)
153 | After_options ->
154 begin
155 Options.ocamlrun := ocamlrun;
156 Options.ocamllex := S[ocamlrun; P"boot/ocamllex"];
157 Options.ocamlyacc := if windows then P"./boot/ocamlyacc.exe" else P"boot/ocamlyacc";
158 Options.ocamlmklib := S[ocamlrun; P"tools/ocamlmklib.byte"; A"-ocamlc"; Quote (V"OCAMLCWIN");
159 A"-ocamlopt"; Quote (V"OCAMLOPTWIN")(* ; A"-v" *)];
160 Options.ocamldep := S[ocamlrun; P"boot/ocamldep"];
162 Options.ext_obj := C.o;
163 Options.ext_lib := C.a;
164 Options.ext_dll := String.after C.ext_dll 1;
166 Options.nostdlib := true;
167 Options.make_links := false;
168 if !Options.just_plugin then
169 Options.ocamlc := boot_ocamlc
170 else begin
171 Options.ocamlc := ocamlc;
172 Options.plugin := false;
173 Options.ocamlopt := ocamlopt;
174 end;
176 | After_rules ->
177 let module M = struct
181 let hot_camlp4boot = "camlp4"/"boot"/"camlp4boot.byte";;
182 let cold_camlp4boot = "camlp4boot" (* The installed version *);;
184 flag ["ocaml"; "ocamlyacc"] (A"-v");;
186 flag ["ocaml"; "compile"; "warn_Ale"] (S[A"-w";A"Ale"; A"-warn-error";A"Ale"]);;
187 flag ["ocaml"; "compile"; "warn_Alezv"] (S[A"-w";A"Alezv"; A"-warn-error";A"Alezv"]);;
189 non_dependency "otherlibs/threads/pervasives.ml" "Unix";;
190 non_dependency "otherlibs/threads/pervasives.ml" "String";;
192 let add_extensions extensions modules =
193 List.fold_right begin fun x ->
194 List.fold_right begin fun ext acc ->
195 x-.-ext :: acc
196 end extensions
197 end modules [];;
199 flag ["ocaml"; "pp"; "camlp4boot"] (convert_command_for_windows_shell (S[ocamlrun; P hot_camlp4boot]));;
200 flag ["ocaml"; "pp"; "camlp4boot"; "native"] (S[A"-D"; A"OPT"]);;
201 flag ["ocaml"; "pp"; "camlp4boot"; "pp:dep"] (S[A"-D"; A"OPT"]);;
202 flag ["ocaml"; "pp"; "camlp4boot"; "pp:doc"] (S[A"-printer"; A"o"]);;
203 let exn_tracer = Pathname.pwd/"camlp4"/"boot"/"Camlp4ExceptionTracer.cmo" in
204 if Pathname.exists exn_tracer then
205 flag ["ocaml"; "pp"; "camlp4boot"; "exntracer"] (P exn_tracer);
207 use_lib "camlp4/mkcamlp4" "camlp4/camlp4lib";;
208 use_lib "toplevel/topstart" "toplevel/toplevellib";;
209 use_lib "otherlibs/dynlink/extract_crc" "otherlibs/dynlink/dynlink";;
211 hide_package_contents "otherlibs/dynlink/dynlinkaux";;
213 flag ["ocaml"; "link"; "file:driver/main.native"; "native"] begin
214 S[A"-ccopt"; A C.bytecclinkopts; A"-cclib"; A C.bytecclibs]
215 end;;
217 dep ["ocaml"; "link"; "file:driver/main.native"; "native"]
218 ["asmrun/meta"-.-C.o; "asmrun/dynlink"-.-C.o];;
220 dep ["ocaml"; "compile"; "native"] ["stdlib/libasmrun"-.-C.a];;
222 flag ["ocaml"; "link"] (S[A"-I"; P "stdlib"]);;
223 flag ["ocaml"; "compile"; "include_unix"] (S[A"-I"; P unix_dir]);;
224 flag ["ocaml"; "compile"; "include_str"] (S[A"-I"; P str_dir]);;
225 flag ["ocaml"; "compile"; "include_dynlink"] (S[A"-I"; P dynlink_dir]);;
226 flag ["ocaml"; "compile"; "include_toplevel"] (S[A"-I"; P toplevel_dir]);;
227 flag ["ocaml"; "link"; "use_unix"] (S[A"-I"; P unix_dir]);;
228 flag ["ocaml"; "link"; "use_dynlink"] (S[A"-I"; P dynlink_dir]);;
229 flag ["ocaml"; "link"; "use_str"] (S[A"-I"; P str_dir]);;
230 flag ["ocaml"; "link"; "use_toplevel"] (S[A"-I"; P toplevel_dir]);;
232 let setup_arch arch =
233 let annotated_arch = annotate arch in
234 let (_include_dirs_table, _for_pack_table) = mk_tables annotated_arch in
235 (* Format.eprintf "%a@." (Ocaml_arch.print_table (List.print pp_print_string)) include_dirs_table;; *)
236 iter_info begin fun i ->
237 Pathname.define_context i.current_path i.include_dirs
238 end annotated_arch;;
240 let camlp4_arch =
241 dir "" [
242 dir "stdlib" [];
243 dir "camlp4" [
244 dir "build" [];
245 dir_pack "Camlp4" [
246 dir_pack "Struct" [
247 dir_pack "Grammar" [];
249 dir_pack "Printers" [];
251 dir_pack "Camlp4Top" [];
255 setup_arch camlp4_arch;;
257 Pathname.define_context "" ["stdlib"];;
258 Pathname.define_context "utils" [Pathname.current_dir_name; "stdlib"];;
259 Pathname.define_context "camlp4" ["camlp4"; "stdlib"];;
260 Pathname.define_context "camlp4/boot" ["camlp4"; "stdlib"];;
261 Pathname.define_context "camlp4/Camlp4Parsers" ["camlp4"; "stdlib"];;
262 Pathname.define_context "camlp4/Camlp4Printers" ["camlp4"; "stdlib"];;
263 Pathname.define_context "camlp4/Camlp4Filters" ["camlp4"; "stdlib"];;
264 Pathname.define_context "camlp4/Camlp4Top" ["camlp4"; "stdlib"];;
265 Pathname.define_context "parsing" ["parsing"; "utils"; "stdlib"];;
266 Pathname.define_context "typing" ["typing"; "parsing"; "utils"; "stdlib"];;
267 Pathname.define_context "ocamldoc" ["typing"; "parsing"; "utils"; "tools"; "bytecomp"; "stdlib"];;
268 Pathname.define_context "bytecomp" ["bytecomp"; "parsing"; "typing"; "utils"; "stdlib"];;
269 Pathname.define_context "tools" ["tools"; (* "toplevel"; *) "parsing"; "utils"; "driver"; "bytecomp"; "asmcomp"; "typing"; "stdlib"];;
270 Pathname.define_context "toplevel" ["toplevel"; "parsing"; "typing"; "bytecomp"; "utils"; "driver"; "stdlib"];;
271 Pathname.define_context "driver" ["driver"; "asmcomp"; "bytecomp"; "typing"; "utils"; "parsing"; "stdlib"];;
272 Pathname.define_context "debugger" ["bytecomp"; "utils"; "typing"; "parsing"; "toplevel"; "stdlib"];;
273 Pathname.define_context "otherlibs/dynlink" ["otherlibs/dynlink"; "bytecomp"; "utils"; "typing"; "parsing"; "stdlib"];;
274 Pathname.define_context "asmcomp" ["asmcomp"; "bytecomp"; "parsing"; "typing"; "utils"; "stdlib"];;
275 Pathname.define_context "ocamlbuild" ["ocamlbuild"; "stdlib"; "."];;
276 Pathname.define_context "lex" ["lex"; "stdlib"];;
278 List.iter (fun x -> let x = "otherlibs"/x in Pathname.define_context x [x; "stdlib"])
279 ["bigarray"; "dbm"; "graph"; "num"; "str"; "systhreads"; "unix"; "win32graph"; "win32unix"];;
281 (* The bootstrap standard library *)
282 copy_rule "The bootstrap standard library" "stdlib/%" "boot/%";;
284 (* About the standard library *)
285 copy_rule "stdlib asmrun" ("asmrun/%"-.-C.a) ("stdlib/%"-.-C.a);;
286 copy_rule "stdlib byterun" ("byterun/%"-.-C.a) ("stdlib/%"-.-C.a);;
288 (* The thread specific standard library *)
289 copy_rule "The thread specific standard library (mllib)" ~insert:`bottom "stdlib/%.mllib" "otherlibs/threads/%.mllib";;
290 copy_rule "The thread specific standard library (cmo)" ~insert:`bottom "stdlib/%.cmo" "otherlibs/threads/%.cmo";;
291 copy_rule "The thread specific standard library (cmi)" ~insert:`top "stdlib/%.cmi" "otherlibs/threads/%.cmi";;
292 copy_rule "The thread specific standard library (mli)" ~insert:`bottom "stdlib/%.mli" "otherlibs/threads/%.mli";;
293 copy_rule "The thread specific unix library (mli)" ~insert:`bottom "otherlibs/unix/%.mli" "otherlibs/threads/%.mli";;
294 copy_rule "The thread specific unix library (ml)" ~insert:`bottom "otherlibs/unix/%.ml" "otherlibs/threads/%.ml";;
295 copy_rule "The thread specific unix library (mllib)" ~insert:`bottom "otherlibs/unix/%.mllib" "otherlibs/threads/%.mllib";;
297 (* Temporary rule, waiting for a full usage of ocamlbuild *)
298 copy_rule "Temporary rule, waiting for a full usage of ocamlbuild" "%.mlbuild" "%.ml";;
300 if windows then
301 copy_rule "thread_win32.ml -> thread.ml"
302 "otherlibs/systhreads/thread_win32.ml" "otherlibs/systhreads/thread.ml"
303 else
304 copy_rule "thread_posix.ml -> thread.ml"
305 "otherlibs/systhreads/thread_posix.ml" "otherlibs/systhreads/thread.ml";;
307 copy_rule "graph/graphics.ml -> win32graph/graphics.ml" "otherlibs/graph/graphics.ml" "otherlibs/win32graph/graphics.ml";;
308 copy_rule "graph/graphics.mli -> win32graph/graphics.mli" "otherlibs/graph/graphics.mli" "otherlibs/win32graph/graphics.mli";;
310 rule "the ocaml toplevel"
311 ~prod:"ocaml"
312 ~deps:["stdlib/stdlib.mllib"; "toplevel/topstart.byte"; "toplevel/expunge.byte"]
313 begin fun _ _ ->
314 let modules = string_list_of_file "stdlib/stdlib.mllib" in
315 Cmd(S[ocamlrun; A"toplevel/expunge.byte"; A"toplevel/topstart.byte"; Px"ocaml";
316 A"outcometree"; A"topdirs"; A"toploop"; atomize modules])
317 end;;
319 let copy_rule' ?insert src dst = copy_rule (sprintf "%s -> %s" src dst) ?insert src dst;;
321 copy_rule' "driver/main.byte" "ocamlc";;
322 copy_rule' "driver/main.native" "ocamlc.opt";;
323 copy_rule' "driver/optmain.byte" "ocamlopt";;
324 copy_rule' "driver/optmain.native" "ocamlopt.opt";;
325 copy_rule' "lex/main.byte" "lex/ocamllex";;
326 copy_rule' "lex/main.native" "lex/ocamllex.opt";;
327 copy_rule' "debugger/main.byte" "debugger/ocamldebug";;
328 copy_rule' "ocamldoc/odoc.byte" "ocamldoc/ocamldoc";;
329 copy_rule' "ocamldoc/odoc_opt.native" "ocamldoc/ocamldoc.opt";;
330 copy_rule' "tools/ocamlmklib.byte" "tools/ocamlmklib";;
331 copy_rule' "otherlibs/dynlink/extract_crc.byte" "otherlibs/dynlink/extract_crc";;
333 copy_rule' ~insert:`bottom "%" "%.exe";;
335 ocaml_lib "stdlib/stdlib";;
337 let stdlib_mllib_contents =
338 lazy (string_list_of_file "stdlib/stdlib.mllib");;
340 let import_stdlib_contents build exts =
341 let l =
342 List.fold_right begin fun x ->
343 List.fold_right begin fun ext acc ->
344 ["stdlib"/(String.uncapitalize x)-.-ext] :: acc
345 end exts
346 end !*stdlib_mllib_contents []
348 let res = build l in
349 List.iter Outcome.ignore_good res
352 rule "byte stdlib in partial mode"
353 ~stamp:"byte_stdlib_partial_mode"
354 ~deps:["stdlib/stdlib.mllib"; "stdlib/stdlib.cma";
355 "stdlib/std_exit.cmo"; "stdlib/libcamlrun"-.-C.a;
356 "stdlib/camlheader"; "stdlib/camlheader_ur"]
357 begin fun env build ->
358 let (_ : Command.t) =
359 Ocamlbuild_pack.Ocaml_compiler.byte_library_link_mllib
360 "stdlib/stdlib.mllib" "stdlib/stdlib.cma" env build
362 import_stdlib_contents build ["cmi"];
364 end;;
366 rule "native stdlib in partial mode"
367 ~stamp:"native_stdlib_partial_mode"
368 ~deps:["stdlib/stdlib.mllib"; "stdlib/stdlib.cmxa";
369 "stdlib/stdlib"-.-C.a; "stdlib/std_exit.cmx";
370 "stdlib/std_exit"-.-C.o; "stdlib/libasmrun"-.-C.a;
371 "stdlib/camlheader"; "stdlib/camlheader_ur"]
372 begin fun env build ->
373 let (_ : Command.t) =
374 Ocamlbuild_pack.Ocaml_compiler.native_library_link_mllib
375 "stdlib/stdlib.mllib" "stdlib/stdlib.cmxa" env build
377 import_stdlib_contents build ["cmi"];
379 end;;
381 rule "C files"
382 ~prod:("%"-.-C.o)
383 ~dep:"%.c"
384 ~insert:(`before "ocaml C stubs: c -> o")
385 begin fun env _ ->
386 let c = env "%.c" in
387 mkobj (env "%") c (T(tags_of_pathname c++"c"++"compile"++ccomptype))
388 end;;
390 rule "C files for windows dynamic libraries"
391 ~prod:("%.d"-.-C.o)
392 ~dep:"%.c"
393 ~insert:(`before "C files")
394 begin fun env _ ->
395 let c = env "%.c" in
396 mkdynobj (env "%") c (T(tags_of_pathname c++"c"++"compile"++"dll"++ccomptype))
397 end;;
399 (* ../ is because .h files are not dependencies so they are not imported in build dir *)
400 flag ["c"; "compile"; "otherlibs_bigarray"] (S[A"-I"; P"../otherlibs/bigarray"]);;
401 flag [(* "ocaml" or "c"; *) "ocamlmklib"; "otherlibs_graph"] (S[Sh C.x11_link]);;
402 flag ["c"; "compile"; "otherlibs_graph"] (S[Sh C.x11_includes; A"-I../otherlibs/graph"]);;
403 flag ["c"; "compile"; "otherlibs_win32graph"] (A"-I../otherlibs/win32graph");;
404 flag ["c"; "compile"; "otherlibs_dbm"] (Sh C.dbm_includes);;
405 flag [(* "ocaml" oc "c"; *) "ocamlmklib"; "otherlibs_dbm"] (S[A"-oc"; A"otherlibs/dbm/mldbm"; Sh C.dbm_link]);;
406 flag ["ocaml"; "ocamlmklib"; "otherlibs_threads"] (S[A"-oc"; A"otherlibs/threads/vmthreads"]);;
407 flag ["c"; "compile"; "otherlibs_num"] begin
408 S[A("-DBNG_ARCH_"^C.bng_arch);
409 A("-DBNG_ASM_LEVEL="^C.bng_asm_level);
410 A"-I"; P"../otherlibs/num"]
411 end;;
412 flag ["c"; "compile"; "otherlibs_win32unix"] (A"-I../otherlibs/win32unix");;
413 flag [(* "ocaml" or "c"; *) "ocamlmklib"; "otherlibs_win32unix"] (S[A"-cclib"; Quote (syslib "wsock32")]);;
414 flag ["c"; "link"; "dll"; "otherlibs_win32unix"] (syslib "wsock32");;
415 let flags = S[syslib "kernel32"; syslib "gdi32"; syslib "user32"] in
416 flag ["c"; "ocamlmklib"; "otherlibs_win32graph"] (S[A"-cclib"; Quote flags]);
417 flag ["c"; "link"; "dll"; "otherlibs_win32graph"] flags;;
419 if windows then flag ["c"; "compile"; "otherlibs_bigarray"] (A"-DIN_OCAML_BIGARRAY");;
421 if windows then flag ["ocamlmklib"] (A"-custom");;
423 flag ["ocaml"; "pp"; "ocamldoc_sources"] begin
424 if windows then
425 S[A"grep"; A"-v"; A"DEBUG"]
426 else
427 A"../ocamldoc/remove_DEBUG"
428 end;;
430 let ocamldoc = P"./ocamldoc/ocamldoc.opt" in
431 let stdlib_mlis =
432 List.fold_right
433 (fun x acc -> "stdlib"/(String.uncapitalize x)-.-"mli" :: acc)
434 (string_list_of_file "stdlib/stdlib.mllib")
435 ["otherlibs/unix/unix.mli"; "otherlibs/str/str.mli";
436 "otherlibs/bigarray/bigarray.mli"; "otherlibs/num/num.mli"] in
437 rule "Standard library manual"
438 ~prod:"ocamldoc/stdlib_man/Pervasives.3o"
439 ~stamp:"ocamldoc/stdlib_man.stamp" (* Depend on this file if you want to depends on all files of stdlib_man/* *)
440 ~deps:stdlib_mlis
441 begin fun _ _ ->
442 Seq[Cmd(S[A"mkdir"; A"-p"; P"ocamldoc/stdlib_man"]);
443 Cmd(S[ocamldoc; A"-man"; A"-d"; P"ocamldoc/stdlib_man";
444 A"-I"; P "stdlib"; A"-I"; P"otherlibs/unix"; A"-I"; P"otherlibs/num";
445 A"-t"; A"Ocaml library"; A"-man-mini"; atomize stdlib_mlis])]
446 end;;
448 flag ["ocaml"; "compile"; "bootstrap_thread"]
449 (S[A"-I"; P systhreads_dir; A"-I"; P threads_dir]);;
451 flag ["ocaml"; "link"; "bootstrap_thread"]
452 (S[A"-I"; P systhreads_dir; A"-I"; P threads_dir]);;
454 flag ["ocaml"; "compile"; "otherlibs_labltk"] (S[A"-I"; P unix_dir]);;
456 flag ["c"; "compile"; "otherlibs_labltk"] (S[A"-Ibyterun"; Sh C.tk_defs; Sh C.sharedcccompopts]);;
458 (* Sys threads *)
460 rule "posix native systhreads"
461 ~prod:"otherlibs/systhreads/posix_n.o"
462 ~dep:"otherlibs/systhreads/posix.c"
463 ~insert:`top
464 begin fun _ _ ->
465 Cmd(S[Sh C.nativecc; A"-O"; A"-I../asmrun"; A"-I../byterun";
466 Sh C.nativecccompopts; Sh C.sharedcccompopts;
467 A"-DNATIVE_CODE"; A("-DTARGET_"^C.arch); A("-DSYS_"^C.system); A"-c";
468 A"otherlibs/systhreads/posix.c"; A"-o"; Px"otherlibs/systhreads/posix_n.o"])
469 end;;
471 rule "posix bytecode systhreads"
472 ~prod:"otherlibs/systhreads/posix_b.o"
473 ~dep:"otherlibs/systhreads/posix.c"
474 ~insert:`top
475 begin fun _ _ ->
476 Cmd(S[Sh C.bytecc; A"-O"; A"-I../byterun";
477 Sh C.bytecccompopts; Sh C.sharedcccompopts;
478 A"-c"; A"otherlibs/systhreads/posix.c"; A"-o"; Px"otherlibs/systhreads/posix_b.o"])
479 end;;
481 rule "windows native systhreads"
482 ~prod:("otherlibs/systhreads/win32_n"-.-C.o)
483 ~dep:"otherlibs/systhreads/win32.c"
484 ~insert:`top
485 begin fun _ _ ->
486 mknatobj "otherlibs/systhreads/win32_n"
487 "otherlibs/systhreads/win32.c"
488 (S[A"-I../asmrun"; A"-I../byterun"; A"-DNATIVE_CODE"])
489 end;;
491 rule "windows bytecode static systhreads"
492 ~prod:("otherlibs/systhreads/win32_b"-.-C.o)
493 ~dep:"otherlibs/systhreads/win32.c"
494 ~insert:`top
495 begin fun _ _ ->
496 mkobj "otherlibs/systhreads/win32_b" "otherlibs/systhreads/win32.c"
497 ((*A"-O"; why ? *) A"-I../byterun")
498 end;;
500 rule "windows bytecode dynamic systhreads"
501 ~prod:("otherlibs/systhreads/win32_b.d"-.-C.o)
502 ~dep:"otherlibs/systhreads/win32.c"
503 ~insert:`top
504 begin fun _ _ ->
505 mkdynobj "otherlibs/systhreads/win32_b" "otherlibs/systhreads/win32.c"
506 ((*A"-O"; why ? *) A"-I../byterun")
507 end;;
509 if windows then begin
510 rule "windows libthreadsnat.a"
511 ~prod:("otherlibs/systhreads/libthreadsnat"-.-C.a)
512 ~dep:("otherlibs/systhreads/win32_n"-.-C.o)
513 ~insert:`top
514 begin fun _ _ ->
515 mklib ("otherlibs/systhreads/libthreadsnat"-.-C.a) (P("otherlibs/systhreads/win32_n"-.-C.o)) N
517 end else begin
518 (* Dynamic linking with -lpthread is risky on many platforms, so
519 do not create a shared object for libthreadsnat. *)
520 rule "libthreadsnat.a"
521 ~prod:"otherlibs/systhreads/libthreadsnat.a"
522 ~dep:"otherlibs/systhreads/posix_n.o"
523 ~insert:`top
524 begin fun _ _ ->
525 mklib "otherlibs/systhreads/libthreadsnat.a" (A"otherlibs/systhreads/posix_n.o") N
526 end;
528 (* See remark above: force static linking of libthreadsnat.a *)
529 flag ["ocaml"; "link"; "library"; "otherlibs_systhreads"; "native"] begin
530 S[A"-cclib"; syscamllib "threadsnat"; (* A"-cclib"; syscamllib "unix"; seems to be useless and can be dangerous during bootstrap *) Sh C.pthread_link]
531 end;
532 end;;
534 if windows then
535 copy_rule "systhreads/libthreads.clib is diffrent on windows"
536 ~insert:`top
537 ("otherlibs/systhreads/libthreadswin32"-.-C.a)
538 ("otherlibs/systhreads/libthreads"-.-C.a);;
540 flag ["ocaml"; "ocamlmklib"; "otherlibs_systhreads"] (S[(* A"-cclib"; syscamllib "unix";; seems to be useless and can be dangerous during bootstrap *) Sh C.pthread_link]);;
543 flag ["c"; "compile"; "otherlibs"] begin
544 S[A"-I"; P"../byterun";
545 A"-I"; P(".."/unix_dir);
546 Sh C.bytecccompopts;
547 Sh C.sharedcccompopts]
548 end;;
550 flag ["c"; "compile"; "otherlibs"; "cc"] (A"-O");;
551 flag ["c"; "compile"; "otherlibs"; "mingw"] (A"-O");;
553 (* The numeric opcodes *)
554 rule "The numeric opcodes"
555 ~prod:"bytecomp/opcodes.ml"
556 ~dep:"byterun/instruct.h"
557 ~insert:`top
558 begin fun _ _ ->
559 Cmd(Sh "sed -n -e '/^enum/p' -e 's/,//g' -e '/^ /p' byterun/instruct.h | \
560 awk -f ../tools/make-opcodes > bytecomp/opcodes.ml")
561 end;;
563 rule "tools/opnames.ml"
564 ~prod:"tools/opnames.ml"
565 ~dep:"byterun/instruct.h"
566 begin fun _ _ ->
567 Cmd(Sh"unset LC_ALL || : ; \
568 unset LC_CTYPE || : ; \
569 unset LC_COLLATE LANG || : ; \
570 sed -e '/\\/\\*/d' \
571 -e '/^#/d' \
572 -e 's/enum \\(.*\\) {/let names_of_\\1 = [|/' \
573 -e 's/};$/ |]/' \
574 -e 's/\\([A-Z][A-Z_0-9a-z]*\\)/\"\\1\"/g' \
575 -e 's/,/;/g' \
576 byterun/instruct.h > tools/opnames.ml")
577 end;;
579 (* The version number *)
580 rule "stdlib/sys.ml"
581 ~prod:"stdlib/sys.ml"
582 ~deps:["stdlib/sys.mlp"; "VERSION"]
583 begin fun _ _ ->
584 let version = with_input_file "VERSION" input_line in
585 Seq [rm_f "stdlib/sys.ml";
586 Cmd (S[A"sed"; A"-e";
587 A(sprintf "s,%%%%VERSION%%%%,%s," version);
588 Sh"<"; P"stdlib/sys.mlp"; Sh">"; Px"stdlib/sys.ml"]);
589 chmod (A"-w") "stdlib/sys.ml"]
590 end;;
592 (* The predefined exceptions and primitives *)
594 rule "camlheader"
595 ~prods:["stdlib/camlheader"; "stdlib/camlheader_ur"]
596 ~deps:["stdlib/header.c"; "stdlib/headernt.c"]
597 begin fun _ _ ->
598 if C.sharpbangscripts then
599 Cmd(Sh("echo '#!"^C.bindir^"/ocamlrun' > stdlib/camlheader && \
600 echo '#!' | tr -d '\\012' > stdlib/camlheader_ur"))
601 else if windows then
602 Seq[mkexe "tmpheader.exe" (P"stdlib/headernt.c") (S[A"-I../byterun"; Sh C.extralibs]);
603 rm_f "camlheader.exe";
604 mv "tmpheader.exe" "stdlib/camlheader";
605 cp "stdlib/camlheader" "stdlib/camlheader_ur"]
606 else
607 let tmpheader = "tmpheader"^C.exe in
608 Cmd(S[Sh C.bytecc; Sh C.bytecccompopts; Sh C.bytecclinkopts;
609 A"-I"; A"../stdlib";
610 A("-DRUNTIME_NAME='\""^C.bindir^"/ocamlrun\"'");
611 A"stdlib/header.c"; A"-o"; Px tmpheader; Sh"&&";
612 A"strip"; P tmpheader; Sh"&&";
613 A"mv"; P tmpheader; A"stdlib/camlheader"; Sh"&&";
614 A"cp"; A"stdlib/camlheader"; A"stdlib/camlheader_ur"])
615 end;;
617 rule "ocaml C stubs on windows: dlib & d.o* -> dll"
618 ~prod:"%.dll"
619 ~deps:["%.dlib"(*; "byterun/ocamlrun"-.-C.a*)]
620 ~insert:`top
621 begin fun env build ->
622 let dlib = env "%.dlib" in
623 let dll = env "%.dll" in
624 let objs = string_list_of_file dlib in
625 let include_dirs = Pathname.include_dirs_of (Pathname.dirname dll) in
626 let resluts = build begin
627 List.map begin fun d_o ->
628 List.map (fun dir -> dir / (Pathname.update_extension C.o d_o)) include_dirs
629 end objs
630 end in
631 let objs = List.map begin function
632 | Outcome.Good d_o -> d_o
633 | Outcome.Bad exn -> raise exn
634 end resluts in
635 mkdll dll (P("tmp"-.-C.a)) (S[atomize objs; P("byterun/ocamlrun"-.-C.a)])
636 (T(tags_of_pathname dll++"dll"++"link"++"c"))
637 end;;
639 copy_rule "win32unix use some unix files" "otherlibs/unix/%" "otherlibs/win32unix/%";;
641 (* Temporary rule *)
642 rule "tools/ocamlmklib.ml"
643 ~prod:"tools/ocamlmklib.ml"
644 ~dep:"tools/ocamlmklib.mlp"
645 (fun _ _ -> cp "tools/ocamlmklib.mlp" "tools/ocamlmklib.ml");;
648 rule "bytecomp/runtimedef.ml"
649 ~prod:"bytecomp/runtimedef.ml"
650 ~deps:["byterun/primitives"; "byterun/fail.h"]
651 begin fun _ _ ->
652 Cmd(S[A"../build/mkruntimedef.sh";Sh">"; Px"bytecomp/runtimedef.ml"])
653 end;;
655 (* Choose the right machine-dependent files *)
657 let mk_arch_rule ~src ~dst =
658 let prod = "asmcomp"/dst in
659 let dep = "asmcomp"/C.arch/src in
660 rule (sprintf "arch specific files %S%%" dst) ~prod ~dep begin
661 if windows then fun env _ -> cp (env dep) (env prod)
662 else fun env _ -> ln_s (env (C.arch/src)) (env prod)
663 end;;
665 mk_arch_rule ~src:(if ccomptype = "msvc" then "proc_nt.ml" else "proc.ml") ~dst:"proc.ml";;
666 List.iter (fun x -> mk_arch_rule ~src:x ~dst:x)
667 ["arch.ml"; "reload.ml"; "scheduling.ml"; "selection.ml"];;
669 let emit_mlp = "asmcomp"/C.arch/(if ccomptype = "msvc" then "emit_nt.mlp" else "emit.mlp") in
670 rule "emit.mlp"
671 ~prod:"asmcomp/emit.ml"
672 ~deps:[emit_mlp; "tools/cvt_emit.byte"]
673 begin fun _ _ ->
674 Cmd(S[ocamlrun; P"tools/cvt_emit.byte"; Sh "<"; P emit_mlp;
675 Sh">"; Px"asmcomp/emit.ml"])
676 end;;
678 let p4 = Pathname.concat "camlp4"
679 let pa = Pathname.concat (p4 "Camlp4Parsers")
680 let pr = Pathname.concat (p4 "Camlp4Printers")
681 let fi = Pathname.concat (p4 "Camlp4Filters")
682 let top = Pathname.concat (p4 "Camlp4Top")
684 let pa_r = pa "Camlp4OCamlRevisedParser"
685 let pa_o = pa "Camlp4OCamlParser"
686 let pa_q = pa "Camlp4QuotationExpander"
687 let pa_qc = pa "Camlp4QuotationCommon"
688 let pa_rq = pa "Camlp4OCamlRevisedQuotationExpander"
689 let pa_oq = pa "Camlp4OCamlOriginalQuotationExpander"
690 let pa_rp = pa "Camlp4OCamlRevisedParserParser"
691 let pa_op = pa "Camlp4OCamlParserParser"
692 let pa_g = pa "Camlp4GrammarParser"
693 let pa_l = pa "Camlp4ListComprehension"
694 let pa_macro = pa "Camlp4MacroParser"
695 let pa_debug = pa "Camlp4DebugParser"
697 let pr_dump = pr "Camlp4OCamlAstDumper"
698 let pr_r = pr "Camlp4OCamlRevisedPrinter"
699 let pr_o = pr "Camlp4OCamlPrinter"
700 let pr_a = pr "Camlp4AutoPrinter"
701 let fi_exc = fi "Camlp4ExceptionTracer"
702 let fi_tracer = fi "Camlp4Tracer"
703 let fi_meta = fi "MetaGenerator"
704 let camlp4_bin = p4 "Camlp4Bin"
705 let top_rprint = top "Rprint"
706 let top_top = top "Top"
707 let camlp4Profiler = p4 "Camlp4Profiler"
709 let camlp4lib_cma = p4 "camlp4lib.cma"
710 let camlp4lib_cmxa = p4 "camlp4lib.cmxa"
711 let camlp4lib_lib = p4 ("camlp4lib"-.-C.a)
713 let special_modules =
714 if Sys.file_exists "./boot/Profiler.cmo" then [camlp4Profiler] else []
717 let camlp4_import_list =
718 ["utils/misc.ml";
719 "utils/terminfo.ml";
720 "parsing/linenum.ml";
721 "utils/warnings.ml";
722 "parsing/location.ml";
723 "parsing/longident.ml";
724 "parsing/asttypes.mli";
725 "parsing/parsetree.mli";
726 "typing/outcometree.mli";
727 "myocamlbuild_config.ml";
728 "utils/config.mlbuild"]
731 rule "camlp4/Camlp4_import.ml"
732 ~deps:camlp4_import_list
733 ~prod:"camlp4/Camlp4_import.ml"
734 begin fun _ _ ->
735 Echo begin
736 List.fold_right begin fun path acc ->
737 let modname = module_name_of_pathname path in
738 "module " :: modname :: " = struct\n" :: Pathname.read path :: "\nend;;\n" :: acc
739 end camlp4_import_list [],
740 "camlp4/Camlp4_import.ml"
742 end;;
744 let mk_camlp4_top_lib name modules =
745 let name = "camlp4"/name in
746 let cma = name-.-"cma" in
747 let deps = special_modules @ modules @ [top_top] in
748 let cmos = add_extensions ["cmo"] deps in
749 rule cma
750 ~deps:(camlp4lib_cma::cmos)
751 ~prods:[cma]
752 ~insert:(`before "ocaml: mllib & cmo* -> cma")
753 begin fun _ _ ->
754 Cmd(S[ocamlc; A"-a"; T(tags_of_pathname cma++"ocaml"++"link"++"byte");
755 P camlp4lib_cma; A"-linkall"; atomize cmos; A"-o"; Px cma])
756 end;;
758 let mk_camlp4_bin name ?unix:(link_unix=true) modules =
759 let name = "camlp4"/name in
760 let byte = name-.-"byte" in
761 let native = name-.-"native" in
762 let unix_cma, unix_cmxa, include_unix =
763 if link_unix
764 then A"unix.cma", A"unix.cmxa", S[A"-I"; P unix_dir]
765 else N,N,N in
766 let dep_unix_byte, dep_unix_native =
767 if link_unix && not partial
768 then [unix_dir/"unix.cma"],
769 [unix_dir/"unix.cmxa"; unix_dir/"unix"-.-C.a]
770 else [],[] in
771 let deps = special_modules @ modules @ [camlp4_bin] in
772 let cmos = add_extensions ["cmo"] deps in
773 let cmxs = add_extensions ["cmx"] deps in
774 let objs = add_extensions [C.o] deps in
775 rule byte
776 ~deps:(camlp4lib_cma::cmos @ dep_unix_byte)
777 ~prod:(add_exe byte)
778 ~insert:(`before "ocaml: cmo* -> byte")
779 begin fun _ _ ->
780 Cmd(S[ocamlc; include_unix; unix_cma; T(tags_of_pathname byte++"ocaml"++"link"++"byte");
781 P camlp4lib_cma; A"-linkall"; atomize cmos; A"-o"; Px (add_exe byte)])
782 end;
783 rule native
784 ~deps:(camlp4lib_cmxa :: camlp4lib_lib :: (cmxs @ objs @ dep_unix_native))
785 ~prod:(add_exe native)
786 ~insert:(`before "ocaml: cmx* & o* -> native")
787 begin fun _ _ ->
788 Cmd(S[ocamlopt; include_unix; unix_cmxa; T(tags_of_pathname native++"ocaml"++"link"++"native");
789 P camlp4lib_cmxa; A"-linkall"; atomize cmxs; A"-o"; Px (add_exe native)])
790 end;;
792 let mk_camlp4 name ?unix modules bin_mods top_mods =
793 mk_camlp4_bin name ?unix (modules @ bin_mods);
794 mk_camlp4_top_lib name (modules @ top_mods);;
796 copy_rule "camlp4: boot/Camlp4Ast.ml -> Camlp4/Struct/Camlp4Ast.ml"
797 ~insert:`top "camlp4/boot/Camlp4Ast.ml" "camlp4/Camlp4/Struct/Camlp4Ast.ml";;
799 rule "camlp4: Camlp4/Struct/Lexer.ml -> boot/Lexer.ml"
800 ~prod:"camlp4/boot/Lexer.ml"
801 ~dep:"camlp4/Camlp4/Struct/Lexer.ml"
802 begin fun _ _ ->
803 Cmd(S[P"camlp4o"; P"camlp4/Camlp4/Struct/Lexer.ml";
804 A"-printer"; A"r"; A"-o"; Px"camlp4/boot/Lexer.ml"])
805 end;;
807 module Camlp4deps = struct
808 let lexer = Genlex.make_lexer ["INCLUDE"; ";"; "="; ":"];;
810 let rec parse strm =
811 match Stream.peek strm with
812 | None -> []
813 | Some(Genlex.Kwd "INCLUDE") ->
814 Stream.junk strm;
815 begin match Stream.peek strm with
816 | Some(Genlex.String s) ->
817 Stream.junk strm;
818 s :: parse strm
819 | _ -> invalid_arg "Camlp4deps parse failure"
821 | Some _ ->
822 Stream.junk strm;
823 parse strm
825 let parse_file file =
826 with_input_file file begin fun ic ->
827 let strm = Stream.of_channel ic in
828 parse (lexer strm)
831 let build_deps build file =
832 let includes = parse_file file in
833 List.iter Outcome.ignore_good (build (List.map (fun i -> [i]) includes));
834 end;;
836 dep ["ocaml"; "file:camlp4/Camlp4/Sig.ml"]
837 ["camlp4/Camlp4/Camlp4Ast.partial.ml"];;
839 rule "camlp4: ml4 -> ml"
840 ~prod:"%.ml"
841 ~dep:"%.ml4"
842 begin fun env build ->
843 let ml4 = env "%.ml4" and ml = env "%.ml" in
844 Camlp4deps.build_deps build ml4;
845 Cmd(S[P cold_camlp4boot; A"-impl"; P ml4; A"-printer"; A"o";
846 A"-D"; A"OPT"; A"-o"; Px ml])
847 end;;
849 rule "camlp4: mlast -> ml"
850 ~prod:"%.ml"
851 ~deps:["%.mlast"; "camlp4/Camlp4/Camlp4Ast.partial.ml"]
852 begin fun env _ ->
853 let mlast = env "%.mlast" and ml = env "%.ml" in
854 (* Camlp4deps.build_deps build mlast; too hard to lex *)
855 Cmd(S[P cold_camlp4boot;
856 A"-printer"; A"r";
857 A"-filter"; A"map";
858 A"-filter"; A"fold";
859 A"-filter"; A"meta";
860 A"-filter"; A"trash";
861 A"-impl"; P mlast;
862 A"-o"; Px ml])
863 end;;
865 dep ["ocaml"; "compile"; "file:camlp4/Camlp4/Sig.ml"]
866 ["camlp4/Camlp4/Camlp4Ast.partial.ml"];;
868 mk_camlp4_bin "camlp4" [];;
869 mk_camlp4 "camlp4boot" ~unix:false
870 [pa_r; pa_qc; pa_q; pa_rp; pa_g; pa_macro; pa_debug; pa_l] [pr_dump] [top_rprint];;
871 mk_camlp4 "camlp4r"
872 [pa_r; pa_rp] [pr_a] [top_rprint];;
873 mk_camlp4 "camlp4rf"
874 [pa_r; pa_qc; pa_q; pa_rp; pa_g; pa_macro; pa_l] [pr_a] [top_rprint];;
875 mk_camlp4 "camlp4o"
876 [pa_r; pa_o; pa_rp; pa_op] [pr_a] [];;
877 mk_camlp4 "camlp4of"
878 [pa_r; pa_qc; pa_q; pa_o; pa_rp; pa_op; pa_g; pa_macro; pa_l] [pr_a] [];;
879 mk_camlp4 "camlp4oof"
880 [pa_r; pa_o; pa_rp; pa_op; pa_qc; pa_oq; pa_g; pa_macro; pa_l] [pr_a] [];;
881 mk_camlp4 "camlp4orf"
882 [pa_r; pa_o; pa_rp; pa_op; pa_qc; pa_rq; pa_g; pa_macro; pa_l] [pr_a] [];;
885 (* Labltk *)
887 Pathname.define_context "otherlibs/labltk/support" ["otherlibs/labltk/support"; "stdlib"];;
888 Pathname.define_context "otherlibs/labltk/compiler" ["otherlibs/labltk/compiler"; "otherlibs/labltk/support"; "stdlib"];;
889 Pathname.define_context "otherlibs/labltk/labltk" ["otherlibs/labltk/labltk"; "otherlibs/labltk/support"; "stdlib"];;
890 Pathname.define_context "otherlibs/labltk/camltk" ["otherlibs/labltk/camltk"; "otherlibs/labltk/support"; "stdlib"];;
891 Pathname.define_context "otherlibs/labltk/lib"
892 ["otherlibs/labltk/labltk"; "otherlibs/labltk/camltk"; "otherlibs/labltk/support"; "stdlib"];;
893 Pathname.define_context "otherlibs/labltk/jpf"
894 ["otherlibs/labltk/jpf"; "otherlibs/labltk/labltk"; "otherlibs/labltk/support"; "stdlib"];;
895 Pathname.define_context "otherlibs/labltk/frx"
896 ["otherlibs/labltk/frx"; "otherlibs/labltk/camltk"; "otherlibs/labltk/support"; "stdlib"];;
897 Pathname.define_context "otherlibs/labltk/tkanim"
898 ["otherlibs/labltk/tkanim"; "otherlibs/labltk/camltk"; "otherlibs/labltk/support"; "stdlib"];;
899 Pathname.define_context "otherlibs/labltk/browser"
900 ["otherlibs/labltk/browser"; "otherlibs/labltk/labltk"; "otherlibs/labltk/support"; "parsing"; "utils"; "typing"; "stdlib"];;
902 rule "otherlibs/labltk/compiler/copyright"
903 ~dep:"otherlibs/labltk/compiler/copyright"
904 ~prod:"otherlibs/labltk/compiler/copyright.ml"
905 begin fun _ _ ->
906 Echo(["let copyright = \"";
907 Pathname.read "otherlibs/labltk/compiler/copyright";
908 "\";;\nlet write ~w = w copyright;;"],
909 "otherlibs/labltk/compiler/copyright.ml")
910 end;;
912 copy_rule "labltk tkcompiler" "otherlibs/labltk/compiler/maincompile.byte" "otherlibs/labltk/compiler/tkcompiler";;
913 copy_rule "labltk pp" "otherlibs/labltk/compiler/pp.byte" "otherlibs/labltk/compiler/pp";;
914 copy_rule "labltk ocamlbrowser" "otherlibs/labltk/browser/main.byte" "otherlibs/labltk/browser/ocamlbrowser";;
916 let builtins =
917 let dir = "otherlibs/labltk/builtin" in
918 List.filter (fun f -> not (Pathname.is_directory f))
919 (List.map (fun f -> dir/f) (Array.to_list (Pathname.readdir dir)));;
921 let labltk_support =
922 ["support"; "rawwidget"; "widget"; "protocol"; "textvariable"; "timer"; "fileevent"; "camltkwrap"];;
924 let labltk_generated_modules =
925 ["place"; "wm"; "imagephoto"; "canvas"; "button"; "text"; "label"; "scrollbar";
926 "image"; "encoding"; "pixmap"; "palette"; "font"; "message"; "menu"; "entry";
927 "listbox"; "focus"; "menubutton"; "pack"; "option"; "toplevel"; "frame";
928 "dialog"; "imagebitmap"; "clipboard"; "radiobutton"; "tkwait"; "grab";
929 "selection"; "scale"; "optionmenu"; "winfo"; "grid"; "checkbutton"; "bell"; "tkvars"];;
931 let labltk_generated_files =
932 let dir = "otherlibs/labltk/labltk" in
933 List.fold_right (fun x acc -> dir/x-.-"ml" :: dir/x-.-"mli" :: acc)
934 labltk_generated_modules [] in
936 rule "labltk/_tkgen.ml"
937 ~deps:(["otherlibs/labltk/Widgets.src"; "otherlibs/labltk/compiler/tkcompiler"] @ builtins)
938 ~prods:("otherlibs/labltk/labltk/_tkgen.ml" :: "otherlibs/labltk/labltk/labltk.ml" :: labltk_generated_files)
939 begin fun env _ ->
940 Cmd(S[A"cd"; A"otherlibs/labltk"; Sh"&&"; full_ocamlrun;
941 A"compiler/tkcompiler"; A"-outdir"; Px"labltk"])
942 end;;
944 let camltk_generated_modules =
945 ["cPlace"; "cResource"; "cWm"; "cImagephoto"; "cCanvas"; "cButton"; "cText"; "cLabel";
946 "cScrollbar"; "cImage"; "cEncoding"; "cPixmap"; "cPalette"; "cFont"; "cMessage";
947 "cMenu"; "cEntry"; "cListbox"; "cFocus"; "cMenubutton"; "cPack"; "cOption"; "cToplevel";
948 "cFrame"; "cDialog"; "cImagebitmap"; "cClipboard"; "cRadiobutton"; "cTkwait"; "cGrab";
949 "cSelection"; "cScale"; "cOptionmenu"; "cWinfo"; "cGrid"; "cCheckbutton"; "cBell"; "cTkvars"];;
951 let camltk_generated_files =
952 let dir = "otherlibs/labltk/camltk" in
953 List.fold_right (fun x acc -> dir/x-.-"ml" :: dir/x-.-"mli" :: acc)
954 camltk_generated_modules [] in
956 rule "camltk/_tkgen.ml"
957 ~deps:(["otherlibs/labltk/Widgets.src"; "otherlibs/labltk/compiler/tkcompiler"] @ builtins)
958 ~prods:("otherlibs/labltk/camltk/_tkgen.ml" :: "otherlibs/labltk/camltk/camltk.ml" :: camltk_generated_files)
959 begin fun env _ ->
960 Cmd(S[A"cd"; A"otherlibs/labltk"; Sh"&&"; full_ocamlrun;
961 A"compiler/tkcompiler"; A"-camltk"; A"-outdir"; Px"camltk"])
962 end;;
964 rule "tk.ml"
965 ~prod:"otherlibs/labltk/labltk/tk.ml"
966 ~deps:(["otherlibs/labltk/labltk/_tkgen.ml";
967 "otherlibs/labltk/compiler/pp.byte"]
968 @ builtins)
969 begin fun _ _ ->
970 Seq[Cmd(Sh"\
971 (echo 'open StdLabels'; \
972 echo 'open Widget'; \
973 echo 'open Protocol'; \
974 echo 'open Support'; \
975 echo 'open Textvariable'; \
976 cat otherlibs/labltk/builtin/report.ml; \
977 cat otherlibs/labltk/builtin/builtin_*.ml; \
978 cat otherlibs/labltk/labltk/_tkgen.ml; \
979 echo ; \
980 echo ; \
981 echo 'module Tkintf = struct'; \
982 cat otherlibs/labltk/builtin/builtini_*.ml; \
983 cat otherlibs/labltk/labltk/_tkigen.ml; \
984 echo 'end (* module Tkintf *)'; \
985 echo ; \
986 echo ; \
987 echo 'open Tkintf' ;\
988 echo ; \
989 echo ; \
990 cat otherlibs/labltk/builtin/builtinf_*.ml; \
991 cat otherlibs/labltk/labltk/_tkfgen.ml; \
992 echo ; \
993 ) > otherlibs/labltk/labltk/_tk.ml");
994 Cmd(S[ocamlrun; P"otherlibs/labltk/compiler/pp.byte"; Sh"<"; P"otherlibs/labltk/labltk/_tk.ml";
995 Sh">"; Px"otherlibs/labltk/labltk/tk.ml"]);
996 rm_f "otherlibs/labltk/labltk/_tk.ml"]
997 end;;
999 rule "cTk.ml"
1000 ~prod:"otherlibs/labltk/camltk/cTk.ml"
1001 ~deps:(["otherlibs/labltk/camltk/_tkgen.ml";
1002 "otherlibs/labltk/compiler/pp.byte"]
1003 @ builtins)
1004 begin fun _ _ ->
1005 Seq[Cmd(Sh"\
1006 (echo '##define CAMLTK'; \
1007 echo 'include Camltkwrap'; \
1008 echo 'open Widget'; \
1009 echo 'open Protocol'; \
1010 echo 'open Textvariable'; \
1011 echo ; \
1012 cat otherlibs/labltk/builtin/report.ml; \
1013 echo ; \
1014 cat otherlibs/labltk/builtin/builtin_*.ml; \
1015 echo ; \
1016 cat otherlibs/labltk/camltk/_tkgen.ml; \
1017 echo ; \
1018 echo ; \
1019 echo 'module Tkintf = struct'; \
1020 cat otherlibs/labltk/builtin/builtini_*.ml; \
1021 cat otherlibs/labltk/camltk/_tkigen.ml; \
1022 echo 'end (* module Tkintf *)'; \
1023 echo ; \
1024 echo ; \
1025 echo 'open Tkintf' ;\
1026 echo ; \
1027 echo ; \
1028 cat otherlibs/labltk/builtin/builtinf_*.ml; \
1029 cat otherlibs/labltk/camltk/_tkfgen.ml; \
1030 echo ; \
1031 ) > otherlibs/labltk/camltk/_cTk.ml");
1032 Cmd(S[ocamlrun; P"otherlibs/labltk/compiler/pp.byte"; Sh"<"; P"otherlibs/labltk/camltk/_cTk.ml";
1033 Sh">"; Px"otherlibs/labltk/camltk/cTk.ml"]);
1034 rm_f "otherlibs/labltk/camltk/_cTk.ml"]
1035 end;;
1037 let labltk_lib_contents =
1038 labltk_support
1039 @ "tk"
1040 :: labltk_generated_modules
1041 @ "cTk"
1042 :: camltk_generated_modules;;
1044 let labltk_contents obj_ext =
1045 List.map (fun x -> "otherlibs/labltk/support"/x-.-obj_ext) labltk_support
1046 @ "otherlibs/labltk/labltk/tk"-.-obj_ext
1047 :: List.map (fun x -> "otherlibs/labltk/labltk"/x-.-obj_ext) labltk_generated_modules
1048 @ "otherlibs/labltk/camltk/cTk"-.-obj_ext
1049 :: List.map (fun x -> "otherlibs/labltk/camltk"/x-.-obj_ext) camltk_generated_modules;;
1051 let labltk_cma_contents = labltk_contents "cmo" in
1052 rule "labltk.cma"
1053 ~prod:"otherlibs/labltk/lib/labltk.cma"
1054 ~deps:labltk_cma_contents
1055 (Ocamlbuild_pack.Ocaml_compiler.byte_library_link_modules
1056 labltk_lib_contents "otherlibs/labltk/lib/labltk.cma");;
1058 let labltk_cmxa_contents = labltk_contents "cmx" in
1059 rule "labltk.cmxa"
1060 ~prod:"otherlibs/labltk/lib/labltk.cmxa"
1061 ~deps:labltk_cmxa_contents
1062 (Ocamlbuild_pack.Ocaml_compiler.native_library_link_modules
1063 labltk_lib_contents "otherlibs/labltk/lib/labltk.cmxa");;
1065 rule "labltktop"
1066 ~prod:(add_exe "otherlibs/labltk/lib/labltktop")
1067 ~deps:["toplevel/toplevellib.cma"; "toplevel/topstart.cmo";
1068 "otherlibs/labltk/lib/labltk.cma"; "otherlibs/labltk/support/liblabltk"-.-C.a]
1069 begin fun _ _ ->
1070 Cmd(S[!Options.ocamlc; A"-verbose"; A"-linkall"; A"-o"; Px(add_exe "otherlibs/labltk/lib/labltktop");
1071 A"-I"; P"otherlibs/labltk/support"; A"-I"; P"toplevel"; P"toplevellib.cma";
1072 A"-I"; P"otherlibs/labltk/labltk"; A"-I"; P"otherlibs/labltk/camltk";
1073 A"-I"; P"otherlibs/labltk/lib"; P"labltk.cma"; A"-I"; P unix_dir; P"unix.cma";
1074 A"-I"; P"otherlibs/str"; A"-I"; P "stdlib"; P"str.cma"; P"topstart.cmo"])
1075 end;;
1077 let labltk_installdir = C.libdir/"labltk" in
1078 rule "labltk"
1079 ~prod:"otherlibs/labltk/lib/labltk"
1080 begin fun _ _ ->
1081 Echo(["#!/bin/sh\n";
1082 Printf.sprintf "exec %s -I %s $*\n" (labltk_installdir/"labltktop") labltk_installdir],
1083 "otherlibs/labltk/lib/labltk")
1084 end;;
1086 use_lib "otherlibs/labltk/browser/main" "toplevel/toplevellib";;
1087 use_lib "otherlibs/labltk/browser/main" "otherlibs/labltk/browser/jglib";;
1088 use_lib "otherlibs/labltk/browser/main" "otherlibs/labltk/lib/labltk";;
1090 if windows then begin
1092 dep ["ocaml"; "link"; "program"; "ocamlbrowser"] ["otherlibs/labltk/browser/winmain"-.-C.o];
1093 flag ["ocaml"; "link"; "program"; "ocamlbrowser"] (S[A"-custom"; A"threads.cma"]);
1095 match ccomptype with
1096 | "cc" -> flag ["ocaml"; "link"; "program"; "ocamlbrowser"] (S[A"-ccopt"; A"-Wl,--subsystem,windows"])
1097 | "msvc" -> flag ["ocaml"; "link"; "program"; "ocamlbrowser"] (S[A"-ccopt"; A"/link /subsystem:windows"])
1098 | _ -> assert false
1100 end;;
1102 let space_sep_strings s = Ocamlbuild_pack.Lexers.space_sep_strings (Lexing.from_string s);;
1104 flag [(* "ocaml" or "c"; *) "ocamlmklib"; "otherlibs_labltk"]
1105 (if windows then begin
1106 S(List.fold_right (fun s acc -> A"-cclib" :: A s :: acc) (space_sep_strings C.tk_link) [])
1107 end else Sh C.tk_link);;
1109 flag ["ocaml"; "link"; "program"; "otherlibs_labltk"] (S[A"-I"; A"otherlibs/labltk/support"]);;
1111 flag ["c"; "compile"; "otherlibs_labltk"] (A"-Iotherlibs/labltk/support");;
1113 copy_rule "ocamlbrowser dummy module"
1114 ("otherlibs/labltk/browser"/(if windows then "dummyWin.mli" else "dummyUnix.mli"))
1115 "otherlibs/labltk/browser/dummy.mli";;
1117 end in ()
1118 | _ -> ()