diff options
author | Nicolas Pouillard <np@nicolaspouillard.fr> | 2007-02-07 10:03:23 +0000 |
---|---|---|
committer | Nicolas Pouillard <np@nicolaspouillard.fr> | 2007-02-07 10:03:23 +0000 |
commit | ee5ff1e8ac7bd379c5b9fdbba532cb3dd69e2db6 (patch) | |
tree | cc2b97dbda1eeaa6196cbb028b2756c32a4bdb21 /myocamlbuild.ml | |
parent | b100c4375327133a0af2da7590609cbf21fdbbb9 (diff) | |
download | ocaml-ee5ff1e8ac7bd379c5b9fdbba532cb3dd69e2db6.tar.gz |
Add some .itarget files. Add also _tags, myocamlbuild.ml, myocamlbuild_config.mli, utils/config.mlbuild
git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@7826 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
Diffstat (limited to 'myocamlbuild.ml')
-rw-r--r-- | myocamlbuild.ml | 975 |
1 files changed, 975 insertions, 0 deletions
diff --git a/myocamlbuild.ml b/myocamlbuild.ml new file mode 100644 index 0000000000..371e8240df --- /dev/null +++ b/myocamlbuild.ml @@ -0,0 +1,975 @@ +open Ocamlbuild_plugin +open Command +open Arch +open Format + +module C = Myocamlbuild_config + +let windows = Sys.os_type = "Win32";; +if windows then tag_any ["windows"];; +let ccomptype = C.ccomptype +let () = if ccomptype <> "cc" then eprintf "ccomptype: %s@." ccomptype;; + +let fp_cat oc f = with_input_file ~bin:true f (fun ic -> copy_chan ic oc) + +(* Improve using the command module in Myocamlbuild_config + with the variant version (`S, `A...) *) +let mkdll out implib files opts = + let s = Command.string_of_command_spec in + Cmd(Sh(C.mkdll out (s implib) (s files) (s opts))) + +let mkexe out files opts = + let s = Command.string_of_command_spec in + Cmd(Sh(C.mkexe out (s files) (s opts))) + +let mklib out files opts = + let s = Command.string_of_command_spec in + Cmd(Sh(C.mklib out (s files) (s opts))) + +let syslib x = A(C.syslib x);; +let syscamllib x = + if ccomptype = "msvc" then A(Printf.sprintf "lib%s.lib" x) + else A("-l"^x) + +let mkobj obj file opts = + let obj = obj-.-C.o in + if ccomptype = "msvc" then + Seq[Cmd(S[Sh C.bytecc; Sh C.bytecccompopts; opts; A"-c"; Px file]); + mv (Pathname.basename (Pathname.update_extension C.o file)) obj] + else + Cmd(S[Sh C.bytecc; Sh C.bytecccompopts; opts; A"-c"; P file; A"-o"; Px obj]) + +let mkdynobj obj file opts = + let d_obj = obj-.-"d"-.-C.o in + if ccomptype = "msvc" then + Seq[Cmd(S[Sh C.bytecc; opts; Sh C.dllcccompopts; A"-c"; Px file]); + mv (Pathname.basename (Pathname.update_extension C.o file)) d_obj] + else + Cmd(S[Sh C.bytecc; opts; Sh C.dllcccompopts; A"-c"; P file; A"-o"; Px d_obj]) + +let mknatobj obj file opts = + let obj = obj-.-C.o in + if ccomptype = "msvc" then + Seq[Cmd(S[Sh C.nativecc; opts; A"-c"; Px file]); + mv (Pathname.basename (Pathname.update_extension C.o file)) obj] + else + Cmd(S[Sh C.nativecc; A"-O"; opts; + Sh C.nativecccompopts; A"-c"; P file; A"-o"; Px obj]) + +let add_exe a = + if not windows || Pathname.check_extension a "exe" then a + else a-.-"exe";; + +let add_exe_if_exists a = + if not windows || Pathname.check_extension a "exe" then a + else + let exe = a-.-"exe" in + if Pathname.exists exe then exe else a;; + +let convert_command_for_windows_shell spec = + if not windows then spec else + let rec self specs acc = + match specs with + | N :: specs -> self specs acc + | S[] :: specs -> self specs acc + | S[x] :: specs -> self (x :: specs) acc + | S specs :: specs' -> self (specs @ specs') acc + | (P(a) | A(a)) :: specs -> + let dirname = Pathname.dirname a in + let basename = Pathname.basename a in + let p = + if dirname = Pathname.current_dir_name then Sh(add_exe_if_exists basename) + else Sh(add_exe_if_exists (dirname ^ "\\" ^ basename)) in + if String.contains_string basename 0 "ocamlrun" = None then + List.rev (p :: acc) @ specs + else + self specs (p :: acc) + | [] | (Px _ | T _ | V _ | Sh _ | Quote _) :: _ -> + invalid_arg "convert_command_for_windows_shell: invalid atom in head position" + in S(self [spec] []) + +let convert_for_windows_shell solver () = + convert_command_for_windows_shell (solver ()) + +let ocamlrun = A"boot/ocamlrun" +let full_ocamlrun = P((Sys.getcwd ()) / "boot/ocamlrun") + +let boot_ocamlc = S[ocamlrun; A"boot/ocamlc"; A"-I"; A"boot"; A"-nostdlib"] + +let partial = bool_of_string (getenv ~default:"false" "OCAMLBUILD_PARTIAL");; + +let if_partial_dir dir = + if partial then ".."/dir else dir;; + +let unix_dir = + match Sys.os_type with + | "Win32" -> if_partial_dir "otherlibs/win32unix" + | _ -> if_partial_dir "otherlibs/unix";; + +let threads_dir = if_partial_dir "otherlibs/threads";; +let systhreads_dir = if_partial_dir "otherlibs/systhreads";; +let dynlink_dir = if_partial_dir "otherlibs/dynlink";; +let str_dir = if_partial_dir "otherlibs/str";; +let stdlib_dir = if_partial_dir "stdlib";; +let toplevel_dir = if_partial_dir "toplevel";; + +let ocamlc_solver () = + if Pathname.exists "ocamlc.opt" && Pathname.exists (stdlib_dir/"stdlib.cmxa") then + S[A"./ocamlc.opt"; A"-nostdlib"] + else if Pathname.exists "ocamlc" && Pathname.exists (stdlib_dir/"stdlib.cma") then + S[ocamlrun; A"./ocamlc"; A"-nostdlib"] + else boot_ocamlc;; + +Command.setup_virtual_command_solver "OCAMLC" ocamlc_solver;; +Command.setup_virtual_command_solver "OCAMLCWIN" (convert_for_windows_shell ocamlc_solver);; + +let ocamlopt_solver () = + S[if Pathname.exists "ocamlopt.opt" && Pathname.exists (stdlib_dir/"stdlib.cmxa") + then A"./ocamlopt.opt" + else S[ocamlrun; A"./ocamlopt"]; + A"-nostdlib"];; + +Command.setup_virtual_command_solver "OCAMLOPT" ocamlopt_solver;; +Command.setup_virtual_command_solver "OCAMLOPTWIN" (convert_for_windows_shell ocamlopt_solver);; + +let ocamlc = V"OCAMLC";; +let ocamlopt = V"OCAMLOPT";; + +let ar = A"ar";; + +dispatch begin function +| Before_hygiene -> + if partial then + List.iter (fun x -> tag_file x ["not_hygienic"]) + ["asmcomp"; "asmrun"; "boot"; "bytecomp"; "debugger"; "driver"; + "lex"; "ocamldoc"; "otherlibs"; "parsing"; "stdlib"; "tools"; + "toplevel"; "typing"; "utils"; "win32caml"] + +| After_options -> + begin + Options.ocamlrun := ocamlrun; + Options.ocamllex := S[ocamlrun; P"boot/ocamllex"]; + Options.ocamlyacc := if windows then P"./boot/ocamlyacc.exe" else P"boot/ocamlyacc"; + Options.ocamlmklib := S[ocamlrun; P"tools/ocamlmklib.byte"; A"-ocamlc"; Quote (V"OCAMLCWIN"); + A"-ocamlopt"; Quote (V"OCAMLOPTWIN")(* ; A"-v" *)]; + Options.ocamldep := S[ocamlrun; P"boot/ocamldep"]; + + Options.ext_obj := C.o; + Options.ext_lib := C.a; + Options.ext_dll := String.after C.ext_dll 1; + + Options.nostdlib := true; + Options.make_links := false; + if !Options.just_plugin then + Options.ocamlc := boot_ocamlc + else begin + Options.ocamlc := ocamlc; + Options.plugin := false; + Options.ocamlopt := ocamlopt; + end; + end +| After_rules -> + let module M = struct + + + +let hot_camlp4boot = "camlp4"/"boot"/"camlp4boot.byte";; +let cold_camlp4boot = "camlp4boot" (* The installed version *);; + +flag ["ocaml"; "ocamlyacc"] (A"-v");; + +flag ["ocaml"; "compile"; "warn_Ale"] (S[A"-w";A"Ale"; A"-warn-error";A"Ale"]);; +flag ["ocaml"; "compile"; "warn_Alezv"] (S[A"-w";A"Alezv"; A"-warn-error";A"Alezv"]);; + +non_dependency "otherlibs/threads/pervasives.ml" "Unix";; +non_dependency "otherlibs/threads/pervasives.ml" "String";; + +let add_extensions extensions modules = + List.fold_right begin fun x -> + List.fold_right begin fun ext acc -> + x-.-ext :: acc + end extensions + end modules [];; + +flag ["ocaml"; "pp"; "camlp4boot"] (convert_command_for_windows_shell (S[ocamlrun; P hot_camlp4boot]));; +flag ["ocaml"; "pp"; "camlp4boot"; "native"] (S[A"-D"; A"OPT"]);; +flag ["ocaml"; "pp"; "camlp4boot"; "ocamldep"] (S[A"-D"; A"OPT"]);; +let exn_tracer = Pathname.pwd/"camlp4"/"boot"/"Camlp4ExceptionTracer.cmo" in +if Pathname.exists exn_tracer then + flag ["ocaml"; "pp"; "camlp4boot"; "exntracer"] (P exn_tracer); + +use_lib "camlp4/mkcamlp4" "camlp4/camlp4lib";; +use_lib "toplevel/topstart" "toplevel/toplevellib";; +use_lib "otherlibs/dynlink/extract_crc" "otherlibs/dynlink/dynlink";; + +hide_package_contents "otherlibs/dynlink/dynlinkaux";; + +flag ["ocaml"; "link"; "file:driver/main.native"; "native"] begin + S[A("asmrun/meta"-.-C.o); A("asmrun/dynlink"-.-C.o); + A"-ccopt"; A C.bytecclinkopts; A"-cclib"; A C.bytecclibs] +end;; + +flag ["ocaml"; "link"] (S[A"-I"; P stdlib_dir]);; +flag ["ocaml"; "compile"; "include_stdlib"] (S[A"-I"; P stdlib_dir]);; +flag ["ocaml"; "compile"; "include_threads_stdlib"] (S[A"-I"; P threads_dir; A"-I"; P stdlib_dir]);; +flag ["ocaml"; "compile"; "include_unix"] (S[A"-I"; P unix_dir]);; +flag ["ocaml"; "compile"; "include_str"] (S[A"-I"; P str_dir]);; +flag ["ocaml"; "compile"; "include_dynlink"] (S[A"-I"; P dynlink_dir]);; +flag ["ocaml"; "compile"; "include_toplevel"] (S[A"-I"; P toplevel_dir]);; +flag ["ocaml"; "link"; "use_unix"] (S[A"-I"; P unix_dir]);; +flag ["ocaml"; "link"; "use_dynlink"] (S[A"-I"; P dynlink_dir]);; +flag ["ocaml"; "link"; "use_str"] (S[A"-I"; P str_dir]);; +flag ["ocaml"; "link"; "use_toplevel"] (S[A"-I"; P toplevel_dir]);; + +let setup_arch arch = + let annotated_arch = annotate arch in + let (_include_dirs_table, _for_pack_table) = mk_tables annotated_arch in + (* Format.eprintf "%a@." (Ocaml_arch.print_table (List.print pp_print_string)) include_dirs_table;; *) + iter_info begin fun i -> + Pathname.define_context i.current_path i.include_dirs + end annotated_arch;; + +let camlp4_arch = + dir "" [ + dir "utils" []; + dir "parsing" []; + dir "camlp4" [ + dir "build" []; + dir_pack "Camlp4" [ + dir_pack "Struct" [ + dir_pack "Grammar" []; + ]; + dir_pack "Printers" []; + ]; + dir_pack "Camlp4Top" []; + ]; + ];; + +setup_arch camlp4_arch;; + +Pathname.define_context "utils" [Pathname.current_dir_name];; +Pathname.define_context "camlp4" ["camlp4/build"; "utils"];; +Pathname.define_context "camlp4/boot" ["camlp4/build"; "utils"; "parsing"; "camlp4"];; +Pathname.define_context "camlp4/Camlp4Parsers" ["camlp4"; "camlp4/build"];; +Pathname.define_context "camlp4/Camlp4Printers" ["camlp4"; "camlp4/build"];; +Pathname.define_context "camlp4/Camlp4Filters" ["camlp4"; "camlp4/build"];; +Pathname.define_context "camlp4/Camlp4Top" ["typing"];; +Pathname.define_context "typing" ["typing"; "parsing"; "utils"];; +Pathname.define_context "ocamldoc" ["typing"; "parsing"; "utils"; "tools"; "bytecomp"];; +Pathname.define_context "bytecomp" ["bytecomp"; "parsing"; "typing"; "utils"];; +Pathname.define_context "tools" ["tools"; (* "toplevel"; *) "parsing"; "utils"; "driver"; "bytecomp"; "asmcomp"; "typing"];; +Pathname.define_context "toplevel" ["toplevel"; "parsing"; "typing"; "bytecomp"; "utils"; "driver"];; +Pathname.define_context "driver" ["driver"; "asmcomp"; "bytecomp"; "typing"; "utils"; "parsing"];; +Pathname.define_context "debugger" ["bytecomp"; "utils"; "typing"; "parsing"; "toplevel"];; +Pathname.define_context "otherlibs/dynlink" ["otherlibs/dynlink"; "bytecomp"; "utils"; "typing"; "parsing"];; +Pathname.define_context "asmcomp" ["asmcomp"; "bytecomp"; "parsing"; "typing"; "utils"];; + +(* The bootstrap standard library *) +copy_rule "The bootstrap standard library" "stdlib/%" "boot/%";; + +(* The thread specific standard library *) +copy_rule "The thread specific standard library (mllib)" ~insert:`bottom "stdlib/%.mllib" "otherlibs/threads/%.mllib";; +copy_rule "The thread specific standard library (cmo)" ~insert:`bottom "stdlib/%.cmo" "otherlibs/threads/%.cmo";; +copy_rule "The thread specific standard library (cmi)" ~insert:`top "stdlib/%.cmi" "otherlibs/threads/%.cmi";; +copy_rule "The thread specific standard library (mli)" ~insert:`bottom "stdlib/%.mli" "otherlibs/threads/%.mli";; +copy_rule "The thread specific unix library (mli)" ~insert:`bottom "otherlibs/unix/%.mli" "otherlibs/threads/%.mli";; +copy_rule "The thread specific unix library (ml)" ~insert:`bottom "otherlibs/unix/%.ml" "otherlibs/threads/%.ml";; +copy_rule "The thread specific unix library (mllib)" ~insert:`bottom "otherlibs/unix/%.mllib" "otherlibs/threads/%.mllib";; + +(* Temporary rule, waiting for a full usage of ocamlbuild *) +copy_rule "Temporary rule, waiting for a full usage of ocamlbuild" "%.mlbuild" "%.ml";; + +if windows then + copy_rule "thread_win32.ml -> thread.ml" + "otherlibs/systhreads/thread_win32.ml" "otherlibs/systhreads/thread.ml" +else + copy_rule "thread_posix.ml -> thread.ml" + "otherlibs/systhreads/thread_posix.ml" "otherlibs/systhreads/thread.ml";; + +copy_rule "graph/graphics.ml -> win32graph/graphics.ml" "otherlibs/graph/graphics.ml" "otherlibs/win32graph/graphics.ml";; +copy_rule "graph/graphics.mli -> win32graph/graphics.mli" "otherlibs/graph/graphics.mli" "otherlibs/win32graph/graphics.mli";; + +rule "the ocaml toplevel" + ~prod:"ocaml" + ~deps:["stdlib/stdlib.mllib"; "toplevel/topstart.byte"; "toplevel/expunge.byte"] + begin fun _ _ -> + let modules = string_list_of_file "stdlib/stdlib.mllib" in + Cmd(S[ocamlrun; A"toplevel/expunge.byte"; A"toplevel/topstart.byte"; Px"ocaml"; + A"outcometree"; A"topdirs"; A"toploop"; atomize modules]) + end;; + +let copy_rule' ?insert src dst = copy_rule (sprintf "%s -> %s" src dst) ?insert src dst;; + +copy_rule' "driver/main.byte" "ocamlc";; +copy_rule' "driver/main.native" "ocamlc.opt";; +copy_rule' "driver/optmain.byte" "ocamlopt";; +copy_rule' "driver/optmain.native" "ocamlopt.opt";; +copy_rule' "lex/main.byte" "lex/ocamllex";; +copy_rule' "lex/main.native" "lex/ocamllex.opt";; +copy_rule' "debugger/main.byte" "debugger/ocamldebug";; +copy_rule' "ocamldoc/odoc.byte" "ocamldoc/ocamldoc";; +copy_rule' "ocamldoc/odoc_opt.native" "ocamldoc/ocamldoc.opt";; +copy_rule' "tools/ocamlmklib.byte" "tools/ocamlmklib";; +copy_rule' "otherlibs/dynlink/extract_crc.byte" "otherlibs/dynlink/extract_crc";; + +copy_rule' ~insert:`bottom "%" "%.exe";; + +rule "C files" + ~prod:("%"-.-C.o) + ~dep:"%.c" + ~insert:(`before "ocaml C stubs: c -> o") + begin fun env _ -> + let c = env "%.c" in + mkobj (env "%") c (T(tags_of_pathname c++"c"++"compile"++ccomptype)) + end;; + +rule "C files for windows dynamic libraries" + ~prod:("%.d"-.-C.o) + ~dep:"%.c" + ~insert:(`before "C files") + begin fun env _ -> + let c = env "%.c" in + mkdynobj (env "%") c (T(tags_of_pathname c++"c"++"compile"++"dll"++ccomptype)) + end;; + +(* ../ is because .h files are not dependencies so they are not imported in build dir *) +flag ["c"; "compile"; "otherlibs_bigarray"] (S[A"-I"; P"../otherlibs/bigarray"]);; +flag [(* "ocaml" or "c"; *) "ocamlmklib"; "otherlibs_graph"] (S[Sh C.x11_link]);; +flag ["c"; "compile"; "otherlibs_graph"] (S[Sh C.x11_includes; A"-I../otherlibs/graph"]);; +flag ["c"; "compile"; "otherlibs_win32graph"] (A"-I../otherlibs/win32graph");; +flag ["c"; "compile"; "otherlibs_dbm"] (Sh C.dbm_includes);; +flag [(* "ocaml" oc "c"; *) "ocamlmklib"; "otherlibs_dbm"] (S[A"-oc"; A"otherlibs/dbm/mldbm"; Sh C.dbm_link]);; +flag ["ocaml"; "ocamlmklib"; "otherlibs_threads"] (S[A"-oc"; A"otherlibs/threads/vmthreads"]);; +flag ["c"; "compile"; "otherlibs_num"] begin + S[A("-DBNG_ARCH_"^C.bng_arch); + A("-DBNG_ASM_LEVEL="^C.bng_asm_level); + A"-I"; P"../otherlibs/num"] +end;; +flag ["c"; "compile"; "otherlibs_win32unix"] (A"-I../otherlibs/win32unix");; +flag [(* "ocaml" or "c"; *) "ocamlmklib"; "otherlibs_win32unix"] (S[A"-cclib"; Quote (syslib "wsock32")]);; +flag ["c"; "link"; "dll"; "otherlibs_win32unix"] (syslib "wsock32");; +let flags = S[syslib "kernel32"; syslib "gdi32"; syslib "user32"] in +flag ["c"; "ocamlmklib"; "otherlibs_win32graph"] (S[A"-cclib"; Quote flags]); +flag ["c"; "link"; "dll"; "otherlibs_win32graph"] flags;; + +if windows then flag ["c"; "compile"; "otherlibs_bigarray"] (A"-DIN_OCAML_BIGARRAY");; + +if windows then flag ["ocamlmklib"] (A"-custom");; + +flag ["ocaml"; "pp"; "ocamldoc_sources"] begin + if windows then + S[A"grep"; A"-v"; A"DEBUG"] + else + A"../ocamldoc/remove_DEBUG" +end;; + +let ocamldoc = P"./ocamldoc/ocamldoc.opt" in +let stdlib_mlis = + List.fold_right + (fun x acc -> "stdlib"/(String.uncapitalize x)-.-"mli" :: acc) + (string_list_of_file "stdlib/stdlib.mllib") + ["otherlibs/unix/unix.mli"; "otherlibs/str/str.mli"; + "otherlibs/bigarray/bigarray.mli"; "otherlibs/num/num.mli"] in +rule "Standard library manual" + ~prod:"ocamldoc/stdlib_man/Pervasives.3o" + ~deps:stdlib_mlis + begin fun _ _ -> + Seq[Cmd(S[A"mkdir"; A"-p"; P"ocamldoc/stdlib_man"]); + Cmd(S[ocamldoc; A"-man"; A"-d"; P"ocamldoc/stdlib_man"; + A"-I"; P"stdlib"; A"-I"; P"otherlibs/unix"; A"-I"; P"otherlibs/num"; + A"-t"; A"Ocaml library"; A"-man-mini"; atomize stdlib_mlis])] + end;; + +flag ["ocaml"; "compile"; "bootstrap_thread"] + (S[A"-I"; P systhreads_dir; A"-I"; P threads_dir]);; + +flag ["ocaml"; "link"; "bootstrap_thread"] + (S[A"-I"; P systhreads_dir; A"-I"; P threads_dir]);; + +flag ["ocaml"; "compile"; "otherlibs_labltk"] (S[A"-I"; P unix_dir]);; + +flag ["c"; "compile"; "otherlibs_labltk"] (S[A"-Ibyterun"; Sh C.tk_defs; Sh C.sharedcccompopts]);; + +(* Sys threads *) + +rule "posix native systhreads" + ~prod:"otherlibs/systhreads/posix_n.o" + ~dep:"otherlibs/systhreads/posix.c" + ~insert:`top + begin fun _ _ -> + Cmd(S[Sh C.nativecc; A"-O"; A"-I../asmrun"; A"-I../byterun"; + Sh C.nativecccompopts; Sh C.sharedcccompopts; + A"-DNATIVE_CODE"; A("-DTARGET_"^C.arch); A("-DSYS_"^C.system); A"-c"; + A"otherlibs/systhreads/posix.c"; A"-o"; Px"otherlibs/systhreads/posix_n.o"]) + end;; + +rule "posix bytecode systhreads" + ~prod:"otherlibs/systhreads/posix_b.o" + ~dep:"otherlibs/systhreads/posix.c" + ~insert:`top + begin fun _ _ -> + Cmd(S[Sh C.bytecc; A"-O"; A"-I../byterun"; + Sh C.bytecccompopts; Sh C.sharedcccompopts; + A"-c"; A"otherlibs/systhreads/posix.c"; A"-o"; Px"otherlibs/systhreads/posix_b.o"]) + end;; + +rule "windows native systhreads" + ~prod:("otherlibs/systhreads/win32_n"-.-C.o) + ~dep:"otherlibs/systhreads/win32.c" + ~insert:`top + begin fun _ _ -> + mknatobj "otherlibs/systhreads/win32_n" + "otherlibs/systhreads/win32.c" + (S[A"-I../asmrun"; A"-I../byterun"; A"-DNATIVE_CODE"]) + end;; + +rule "windows bytecode static systhreads" + ~prod:("otherlibs/systhreads/win32_b"-.-C.o) + ~dep:"otherlibs/systhreads/win32.c" + ~insert:`top + begin fun _ _ -> + mkobj "otherlibs/systhreads/win32_b" "otherlibs/systhreads/win32.c" + ((*A"-O"; why ? *) A"-I../byterun") + end;; + +rule "windows bytecode dynamic systhreads" + ~prod:("otherlibs/systhreads/win32_b.d"-.-C.o) + ~dep:"otherlibs/systhreads/win32.c" + ~insert:`top + begin fun _ _ -> + mkdynobj "otherlibs/systhreads/win32_b" "otherlibs/systhreads/win32.c" + ((*A"-O"; why ? *) A"-I../byterun") + end;; + +if windows then begin + rule "windows libthreadsnat.a" + ~prod:("otherlibs/systhreads/libthreadsnat"-.-C.a) + ~dep:("otherlibs/systhreads/win32_n"-.-C.o) + ~insert:`top + begin fun _ _ -> + mklib ("otherlibs/systhreads/libthreadsnat"-.-C.a) (P("otherlibs/systhreads/win32_n"-.-C.o)) N + end +end else begin +(* Dynamic linking with -lpthread is risky on many platforms, so + do not create a shared object for libthreadsnat. *) +rule "libthreadsnat.a" + ~prod:"otherlibs/systhreads/libthreadsnat.a" + ~dep:"otherlibs/systhreads/posix_n.o" + ~insert:`top + begin fun _ _ -> + mklib "otherlibs/systhreads/libthreadsnat.a" (A"otherlibs/systhreads/posix_n.o") N + end; + +(* See remark above: force static linking of libthreadsnat.a *) +flag ["ocaml"; "link"; "library"; "otherlibs_systhreads"; "native"] begin + S[A"-cclib"; syscamllib "threadsnat"; (* A"-cclib"; syscamllib "unix"; seems to be useless and can be dangerous during bootstrap *) A"-cclib"; A C.pthread_link] +end; +end;; + +if windows then +copy_rule "systhreads/libthreads.clib is diffrent on windows" + ~insert:`top + ("otherlibs/systhreads/libthreadswin32"-.-C.a) + ("otherlibs/systhreads/libthreads"-.-C.a);; + +flag ["ocaml"; "ocamlmklib"; "otherlibs_systhreads"] (S[(* A"-cclib"; syscamllib "unix";; seems to be useless and can be dangerous during bootstrap *) Sh C.pthread_link]);; + + +flag ["c"; "compile"; "otherlibs"] begin + S[A"-I"; P"../byterun"; + A"-I"; P(".."/unix_dir); + Sh C.bytecccompopts; + Sh C.sharedcccompopts] +end;; + +flag ["c"; "compile"; "otherlibs"; "cc"] (A"-O");; +flag ["c"; "compile"; "otherlibs"; "mingw"] (A"-O");; + +(* The numeric opcodes *) +rule "The numeric opcodes" + ~prod:"bytecomp/opcodes.ml" + ~dep:"byterun/instruct.h" + ~insert:`top + begin fun _ _ -> + Cmd(Sh "sed -n -e '/^enum/p' -e 's/,//g' -e '/^ /p' byterun/instruct.h | \ + awk -f ../tools/make-opcodes > bytecomp/opcodes.ml") + end;; + +rule "tools/opnames.ml" + ~prod:"tools/opnames.ml" + ~dep:"byterun/instruct.h" + begin fun _ _ -> + Cmd(Sh"unset LC_ALL || : ; \ + unset LC_CTYPE || : ; \ + unset LC_COLLATE LANG || : ; \ + sed -e '/\\/\\*/d' \ + -e '/^#/d' \ + -e 's/enum \\(.*\\) {/let names_of_\\1 = [|/' \ + -e 's/};$/ |]/' \ + -e 's/\\([A-Z][A-Z_0-9a-z]*\\)/\"\\1\"/g' \ + -e 's/,/;/g' \ + byterun/instruct.h > tools/opnames.ml") + end;; + +(* The predefined exceptions and primitives *) + +rule "camlheader" + ~prods:["stdlib/camlheader"; "stdlib/camlheader_ur"] + ~deps:["stdlib/header.c"; "stdlib/headernt.c"] + begin fun _ _ -> + if C.sharpbangscripts then + Cmd(Sh("echo '#!"^C.bindir^"/ocamlrun' > stdlib/camlheader && \ + echo '#!' | tr -d '\\012' > stdlib/camlheader_ur")) + else if windows then + Seq[mkexe "tmpheader.exe" (P"stdlib/headernt.c") (S[A"-I../byterun"; Sh C.extralibs]); + rm_f "camlheader.exe"; + mv "tmpheader.exe" "stdlib/camlheader"; + cp "stdlib/camlheader" "stdlib/camlheader_ur"] + else + let tmpheader = "tmpheader"^C.exe in + Cmd(S[Sh C.bytecc; Sh C.bytecccompopts; Sh C.bytecclinkopts; + A"-I"; A"../stdlib"; + A("-DRUNTIME_NAME='\""^C.bindir^"/ocamlrun\"'"); + A"stdlib/header.c"; A"-o"; Px tmpheader; Sh"&&"; + A"strip"; P tmpheader; Sh"&&"; + A"mv"; P tmpheader; A"stdlib/camlheader"; Sh"&&"; + A"cp"; A"stdlib/camlheader"; A"stdlib/camlheader_ur"]) + end;; + +rule "ocaml C stubs on windows: dlib & d.o* -> dll" + ~prod:"%.dll" + ~deps:["%.dlib"(*; "byterun/ocamlrun"-.-C.a*)] + ~insert:`top + begin fun env build -> + let dlib = env "%.dlib" in + let dll = env "%.dll" in + let objs = string_list_of_file dlib in + let include_dirs = Pathname.include_dirs_of (Pathname.dirname dll) in + let resluts = build begin + List.map begin fun d_o -> + List.map (fun dir -> dir / (Pathname.update_extension C.o d_o)) include_dirs + end objs + end in + let objs = List.map begin function + | Outcome.Good d_o -> d_o + | Outcome.Bad exn -> raise exn + end resluts in + mkdll dll (P("tmp"-.-C.a)) (S[atomize objs; P("byterun/ocamlrun"-.-C.a)]) + (T(tags_of_pathname dll++"dll"++"link"++"c")) + end;; + +copy_rule "win32unix use some unix files" "otherlibs/unix/%" "otherlibs/win32unix/%";; + +(* Temporary rule *) +rule "tools/ocamlmklib.ml" + ~prod:"tools/ocamlmklib.ml" + ~dep:"tools/ocamlmklib.mlp" + (fun _ _ -> cp "tools/ocamlmklib.mlp" "tools/ocamlmklib.ml");; + + +rule "bytecomp/runtimedef.ml" + ~prod:"bytecomp/runtimedef.ml" + ~deps:["byterun/primitives"; "byterun/fail.h"] + begin fun _ _ -> + Cmd(Sh"(echo 'let builtin_exceptions = [|'; \ + sed -n -e 's|.*/\\* \\(\"[A-Za-z_]*\"\\) \\*/$| \\1;|p' byterun/fail.h | \ + sed -e '$s/;$//'; \ + echo '|]'; \ + echo 'let builtin_primitives = [|'; \ + sed -e 's/.*/ \"&\";/' -e '$s/;$//' byterun/primitives; \ + echo '|]') > bytecomp/runtimedef.ml") + end;; + +(* Choose the right machine-dependent files *) + +let mk_arch_rule ~src ~dst = + let prod = "asmcomp"/dst in + let dep = "asmcomp"/C.arch/src in + rule (sprintf "arch specific files %S%%" dst) ~prod ~dep begin + if windows then fun env _ -> cp (env dep) (env prod) + else fun env _ -> ln_s (env (C.arch/src)) (env prod) + end;; + +mk_arch_rule ~src:(if ccomptype = "msvc" then "proc_nt.ml" else "proc.ml") ~dst:"proc.ml";; +List.iter (fun x -> mk_arch_rule ~src:x ~dst:x) + ["arch.ml"; "reload.ml"; "scheduling.ml"; "selection.ml"];; + +let emit_mlp = "asmcomp"/C.arch/(if ccomptype = "msvc" then "emit_nt.mlp" else "emit.mlp") in +rule "emit.mlp" + ~prod:"asmcomp/emit.ml" + ~deps:[emit_mlp; "tools/cvt_emit.byte"] + begin fun _ _ -> + Cmd(S[ocamlrun; P"tools/cvt_emit.byte"; Sh "<"; P emit_mlp; + Sh">"; Px"asmcomp/emit.ml"]) + end;; + +let p4 = Pathname.concat "camlp4" +let pa = Pathname.concat (p4 "Camlp4Parsers") +let pr = Pathname.concat (p4 "Camlp4Printers") +let fi = Pathname.concat (p4 "Camlp4Filters") +let top = Pathname.concat (p4 "Camlp4Top") + +let pa_r = pa "Camlp4OCamlRevisedParser" +let pa_o = pa "Camlp4OCamlParser" +let pa_q = pa "Camlp4QuotationExpander" +let pa_qc = pa "Camlp4QuotationCommon" +let pa_rq = pa "Camlp4OCamlRevisedQuotationExpander" +let pa_oq = pa "Camlp4OCamlOriginalQuotationExpander" +let pa_rp = pa "Camlp4OCamlRevisedParserParser" +let pa_op = pa "Camlp4OCamlParserParser" +let pa_g = pa "Camlp4GrammarParser" +let pa_macro = pa "Camlp4MacroParser" +let pa_debug = pa "Camlp4DebugParser" + +let pr_dump = pr "Camlp4OCamlAstDumper" +let pr_r = pr "Camlp4OCamlRevisedPrinter" +let pr_o = pr "Camlp4OCamlPrinter" +let pr_a = pr "Camlp4AutoPrinter" +let fi_exc = fi "Camlp4ExceptionTracer" +let fi_tracer = fi "Camlp4Tracer" +let fi_meta = fi "MetaGenerator" +let camlp4_bin = p4 "Camlp4Bin" +let top_rprint = top "Rprint" +let top_top = top "Top" +let camlp4Profiler = p4 "Camlp4Profiler" + +let camlp4lib_cma = p4 "camlp4lib.cma" +let camlp4lib_cmxa = p4 "camlp4lib.cmxa" + +let special_modules = + if Sys.file_exists "./boot/Profiler.cmo" then [camlp4Profiler] else [] + +let mk_camlp4_top_lib name modules = + let name = "camlp4"/name in + let cma = name-.-"cma" in + let deps = special_modules @ modules @ [top_top] in + let cmos = add_extensions ["cmo"] deps in + rule cma + ~deps:(camlp4lib_cma::cmos) + ~prods:[cma] + ~insert:(`before "ocaml: mllib & cmo* -> cma") + begin fun _ _ -> + Cmd(S[ocamlc; A"-a"; T(tags_of_pathname cma++"ocaml"++"link"++"byte"); + P camlp4lib_cma; A"-linkall"; atomize cmos; A"-o"; Px cma]) + end;; + +let mk_camlp4_bin name ?unix:(link_unix=true) modules = + let name = "camlp4"/name in + let byte = name-.-"byte" in + let native = name-.-"native" in + let unix_cma, unix_cmxa, include_unix = + if link_unix then A"unix.cma", A"unix.cmxa", S[A"-I"; P unix_dir] else N,N,N in + let deps = special_modules @ modules @ [camlp4_bin] in + let cmos = add_extensions ["cmo"] deps in + let cmxs = add_extensions ["cmx"] deps in + rule byte + ~deps:(camlp4lib_cma::cmos) + ~prod:(add_exe byte) + ~insert:(`before "ocaml: cmo* -> byte") + begin fun _ _ -> + Cmd(S[ocamlc; include_unix; unix_cma; T(tags_of_pathname byte++"ocaml"++"link"++"byte"); + P camlp4lib_cma; A"-linkall"; atomize cmos; A"-o"; Px (add_exe byte)]) + end; + rule native + ~deps:(camlp4lib_cmxa::cmxs) + ~prod:(add_exe native) + ~insert:(`before "ocaml: cmx* & o* -> native") + begin fun _ _ -> + Cmd(S[ocamlopt; include_unix; unix_cmxa; T(tags_of_pathname native++"ocaml"++"link"++"native"); + P camlp4lib_cmxa; A"-linkall"; atomize cmxs; A"-o"; Px (add_exe native)]) + end;; + +let mk_camlp4 name ?unix modules bin_mods top_mods = + mk_camlp4_bin name ?unix (modules @ bin_mods); + mk_camlp4_top_lib name (modules @ top_mods);; + +rule "camlp4: boot/Camlp4Ast.ml -> Camlp4/Struct/Camlp4Ast.ml" + ~prod:"camlp4/Camlp4/Struct/Camlp4Ast.ml" + ~dep:"camlp4/boot/Camlp4Ast.ml" + ~insert:`top + begin fun _ _ -> + cp "camlp4/boot/Camlp4Ast.ml" "camlp4/Camlp4/Struct/Camlp4Ast.ml" + end;; + +rule "camlp4: Camlp4/Struct/Lexer.ml -> boot/Lexer.ml" + ~prod:"camlp4/boot/Lexer.ml" + ~dep:"camlp4/Camlp4/Struct/Lexer.ml" + begin fun _ _ -> + Cmd(S[P"camlp4o"; P"camlp4/Camlp4/Struct/Lexer.ml"; + A"-printer"; A"r"; A"-o"; Px"camlp4/boot/Lexer.ml"]) + end;; + +rule "camlp4: ml4 -> ml" + ~prod:"%.ml" + ~dep:"%.ml4" + begin fun env _ -> + Cmd(S[P cold_camlp4boot; A"-impl"; P(env"%.ml4"); A"-printer"; A"o"; + A"-D"; A"OPT"; A"-o"; Px(env"%.ml")]) + end;; + +rule "camlp4: mlast -> ml" + ~prod:"%.ml" + ~dep:"%.mlast" + begin fun env _ -> + Cmd(S[P cold_camlp4boot; + A"-printer"; A"r"; + A"-filter"; A"map"; + A"-filter"; A"fold"; + A"-filter"; A"meta"; + A"-filter"; A"trash"; + A"-impl"; P(env "%.mlast"); + A"-o"; Px(env "%.ml")]) + end;; + +mk_camlp4_bin "camlp4" [];; +mk_camlp4 "camlp4boot" ~unix:false + [pa_r; pa_qc; pa_q; pa_rp; pa_g; pa_macro; pa_debug] [pr_dump] [top_rprint];; +mk_camlp4 "camlp4r" + [pa_r; pa_rp] [pr_a] [top_rprint];; +mk_camlp4 "camlp4rf" + [pa_r; pa_qc; pa_q; pa_rp; pa_g; pa_macro] [pr_a] [top_rprint];; +mk_camlp4 "camlp4o" + [pa_r; pa_o; pa_rp; pa_op] [pr_a] [];; +mk_camlp4 "camlp4of" + [pa_r; pa_qc; pa_q; pa_o; pa_rp; pa_op; pa_g; pa_macro] [pr_a] [];; +mk_camlp4 "camlp4oof" + [pa_r; pa_o; pa_rp; pa_op; pa_qc; pa_oq; pa_g; pa_macro] [pr_a] [];; +mk_camlp4 "camlp4orf" + [pa_r; pa_o; pa_rp; pa_op; pa_qc; pa_rq; pa_g; pa_macro] [pr_a] [];; + + +(* Labltk *) + +Pathname.define_context "otherlibs/labltk/compiler" ["otherlibs/labltk/compiler"; "otherlibs/labltk/support"];; +Pathname.define_context "otherlibs/labltk/labltk" ["otherlibs/labltk/labltk"; "otherlibs/labltk/support"];; +Pathname.define_context "otherlibs/labltk/camltk" ["otherlibs/labltk/camltk"; "otherlibs/labltk/support"];; +Pathname.define_context "otherlibs/labltk/lib" + ["otherlibs/labltk/labltk"; "otherlibs/labltk/camltk"; "otherlibs/labltk/support"];; +Pathname.define_context "otherlibs/labltk/jpf" + ["otherlibs/labltk/jpf"; "otherlibs/labltk/labltk"; "otherlibs/labltk/support"];; +Pathname.define_context "otherlibs/labltk/frx" + ["otherlibs/labltk/frx"; "otherlibs/labltk/camltk"; "otherlibs/labltk/support"];; +Pathname.define_context "otherlibs/labltk/tkanim" + ["otherlibs/labltk/tkanim"; "otherlibs/labltk/camltk"; "otherlibs/labltk/support"];; +Pathname.define_context "otherlibs/labltk/browser" + ["otherlibs/labltk/browser"; "otherlibs/labltk/labltk"; "otherlibs/labltk/support"; "parsing"; "utils"; "typing"];; + +file_rule "otherlibs/labltk/compiler/copyright" + ~dep:"otherlibs/labltk/compiler/copyright" + ~prod:"otherlibs/labltk/compiler/copyright.ml" + ~cache:(fun _ -> "0.1") + begin fun _ oc -> + Printf.fprintf oc "let copyright = \"%a\";;\n\ + let write ~w = w copyright;;" + fp_cat "otherlibs/labltk/compiler/copyright" + end;; + +copy_rule "labltk tkcompiler" "otherlibs/labltk/compiler/maincompile.byte" "otherlibs/labltk/compiler/tkcompiler";; +copy_rule "labltk pp" "otherlibs/labltk/compiler/pp.byte" "otherlibs/labltk/compiler/pp";; +copy_rule "labltk ocamlbrowser" "otherlibs/labltk/browser/main.byte" "otherlibs/labltk/browser/ocamlbrowser";; + +let builtins = + let dir = "otherlibs/labltk/builtin" in + List.filter (fun f -> not (Pathname.is_directory f)) + (List.map (fun f -> dir/f) (Array.to_list (Pathname.readdir dir)));; + +let labltk_support = + ["support"; "rawwidget"; "widget"; "protocol"; "textvariable"; "timer"; "fileevent"; "camltkwrap"];; + +let labltk_generated_modules = + ["place"; "wm"; "imagephoto"; "canvas"; "button"; "text"; "label"; "scrollbar"; + "image"; "encoding"; "pixmap"; "palette"; "font"; "message"; "menu"; "entry"; + "listbox"; "focus"; "menubutton"; "pack"; "option"; "toplevel"; "frame"; + "dialog"; "imagebitmap"; "clipboard"; "radiobutton"; "tkwait"; "grab"; + "selection"; "scale"; "optionmenu"; "winfo"; "grid"; "checkbutton"; "bell"; "tkvars"];; + +let labltk_generated_files = + let dir = "otherlibs/labltk/labltk" in + List.fold_right (fun x acc -> dir/x-.-"ml" :: dir/x-.-"mli" :: acc) + labltk_generated_modules [] in + +rule "labltk/_tkgen.ml" + ~deps:(["otherlibs/labltk/Widgets.src"; "otherlibs/labltk/compiler/tkcompiler"] @ builtins) + ~prods:("otherlibs/labltk/labltk/_tkgen.ml" :: "otherlibs/labltk/labltk/labltk.ml" :: labltk_generated_files) + begin fun env _ -> + Cmd(S[A"cd"; A"otherlibs/labltk"; Sh"&&"; full_ocamlrun; + A"compiler/tkcompiler"; A"-outdir"; Px"labltk"]) + end;; + +let camltk_generated_modules = + ["cPlace"; "cResource"; "cWm"; "cImagephoto"; "cCanvas"; "cButton"; "cText"; "cLabel"; + "cScrollbar"; "cImage"; "cEncoding"; "cPixmap"; "cPalette"; "cFont"; "cMessage"; + "cMenu"; "cEntry"; "cListbox"; "cFocus"; "cMenubutton"; "cPack"; "cOption"; "cToplevel"; + "cFrame"; "cDialog"; "cImagebitmap"; "cClipboard"; "cRadiobutton"; "cTkwait"; "cGrab"; + "cSelection"; "cScale"; "cOptionmenu"; "cWinfo"; "cGrid"; "cCheckbutton"; "cBell"; "cTkvars"];; + +let camltk_generated_files = + let dir = "otherlibs/labltk/camltk" in + List.fold_right (fun x acc -> dir/x-.-"ml" :: dir/x-.-"mli" :: acc) + camltk_generated_modules [] in + +rule "camltk/_tkgen.ml" + ~deps:(["otherlibs/labltk/Widgets.src"; "otherlibs/labltk/compiler/tkcompiler"] @ builtins) + ~prods:("otherlibs/labltk/camltk/_tkgen.ml" :: "otherlibs/labltk/camltk/camltk.ml" :: camltk_generated_files) + begin fun env _ -> + Cmd(S[A"cd"; A"otherlibs/labltk"; Sh"&&"; full_ocamlrun; + A"compiler/tkcompiler"; A"-camltk"; A"-outdir"; Px"camltk"]) + end;; + +rule "tk.ml" + ~prod:"otherlibs/labltk/labltk/tk.ml" + ~deps:(["otherlibs/labltk/labltk/_tkgen.ml"; + "otherlibs/labltk/compiler/pp.byte"] + @ builtins) + begin fun _ _ -> + Seq[Cmd(Sh"\ + (echo 'open StdLabels'; \ + echo 'open Widget'; \ + echo 'open Protocol'; \ + echo 'open Support'; \ + echo 'open Textvariable'; \ + cat otherlibs/labltk/builtin/report.ml; \ + cat otherlibs/labltk/builtin/builtin_*.ml; \ + cat otherlibs/labltk/labltk/_tkgen.ml; \ + echo ; \ + echo ; \ + echo 'module Tkintf = struct'; \ + cat otherlibs/labltk/builtin/builtini_*.ml; \ + cat otherlibs/labltk/labltk/_tkigen.ml; \ + echo 'end (* module Tkintf *)'; \ + echo ; \ + echo ; \ + echo 'open Tkintf' ;\ + echo ; \ + echo ; \ + cat otherlibs/labltk/builtin/builtinf_*.ml; \ + cat otherlibs/labltk/labltk/_tkfgen.ml; \ + echo ; \ + ) > otherlibs/labltk/labltk/_tk.ml"); + Cmd(S[ocamlrun; P"otherlibs/labltk/compiler/pp.byte"; Sh"<"; P"otherlibs/labltk/labltk/_tk.ml"; + Sh">"; Px"otherlibs/labltk/labltk/tk.ml"]); + rm_f "otherlibs/labltk/labltk/_tk.ml"] + end;; + +rule "cTk.ml" + ~prod:"otherlibs/labltk/camltk/cTk.ml" + ~deps:(["otherlibs/labltk/camltk/_tkgen.ml"; + "otherlibs/labltk/compiler/pp.byte"] + @ builtins) + begin fun _ _ -> + Seq[Cmd(Sh"\ + (echo '##define CAMLTK'; \ + echo 'include Camltkwrap'; \ + echo 'open Widget'; \ + echo 'open Protocol'; \ + echo 'open Textvariable'; \ + echo ; \ + cat otherlibs/labltk/builtin/report.ml; \ + echo ; \ + cat otherlibs/labltk/builtin/builtin_*.ml; \ + echo ; \ + cat otherlibs/labltk/camltk/_tkgen.ml; \ + echo ; \ + echo ; \ + echo 'module Tkintf = struct'; \ + cat otherlibs/labltk/builtin/builtini_*.ml; \ + cat otherlibs/labltk/camltk/_tkigen.ml; \ + echo 'end (* module Tkintf *)'; \ + echo ; \ + echo ; \ + echo 'open Tkintf' ;\ + echo ; \ + echo ; \ + cat otherlibs/labltk/builtin/builtinf_*.ml; \ + cat otherlibs/labltk/camltk/_tkfgen.ml; \ + echo ; \ + ) > otherlibs/labltk/camltk/_cTk.ml"); + Cmd(S[ocamlrun; P"otherlibs/labltk/compiler/pp.byte"; Sh"<"; P"otherlibs/labltk/camltk/_cTk.ml"; + Sh">"; Px"otherlibs/labltk/camltk/cTk.ml"]); + rm_f "otherlibs/labltk/camltk/_cTk.ml"] + end;; + +let labltk_lib_contents = + labltk_support + @ "tk" + :: labltk_generated_modules + @ "cTk" + :: camltk_generated_modules;; + +let labltk_contents obj_ext = + List.map (fun x -> "otherlibs/labltk/support"/x-.-obj_ext) labltk_support + @ "otherlibs/labltk/labltk/tk"-.-obj_ext + :: List.map (fun x -> "otherlibs/labltk/labltk"/x-.-obj_ext) labltk_generated_modules + @ "otherlibs/labltk/camltk/cTk"-.-obj_ext + :: List.map (fun x -> "otherlibs/labltk/camltk"/x-.-obj_ext) camltk_generated_modules;; + +let labltk_cma_contents = labltk_contents "cmo" in +rule "labltk.cma" + ~prod:"otherlibs/labltk/lib/labltk.cma" + ~deps:labltk_cma_contents + (Ocamlbuild_pack.Ocaml_compiler.byte_library_link_modules + labltk_lib_contents "otherlibs/labltk/lib/labltk.cma");; + +let labltk_cmxa_contents = labltk_contents "cmx" in +rule "labltk.cmxa" + ~prod:"otherlibs/labltk/lib/labltk.cmxa" + ~deps:labltk_cmxa_contents + (Ocamlbuild_pack.Ocaml_compiler.native_library_link_modules + labltk_lib_contents "otherlibs/labltk/lib/labltk.cmxa");; + +rule "labltktop" + ~prod:(add_exe "otherlibs/labltk/lib/labltktop") + ~deps:["toplevel/toplevellib.cma"; "toplevel/topstart.cmo"; + "otherlibs/labltk/lib/labltk.cma"; "otherlibs/labltk/support/liblabltk"-.-C.a] + begin fun _ _ -> + Cmd(S[!Options.ocamlc; A"-verbose"; A"-linkall"; A"-o"; Px(add_exe "otherlibs/labltk/lib/labltktop"); + A"-I"; P"otherlibs/labltk/support"; A"-I"; P"toplevel"; P"toplevellib.cma"; + A"-I"; P"otherlibs/labltk/labltk"; A"-I"; P"otherlibs/labltk/camltk"; + A"-I"; P"otherlibs/labltk/lib"; P"labltk.cma"; A"-I"; P unix_dir; P"unix.cma"; + A"-I"; P"otherlibs/str"; A"-I"; P"stdlib"; P"str.cma"; P"topstart.cmo"]) + end;; + +let labltk_installdir = C.libdir/"labltk" in +file_rule "labltk" + ~prod:"otherlibs/labltk/lib/labltk" + ~cache:(fun _ -> labltk_installdir) + begin fun _ oc -> + Printf.fprintf oc + "#!/bin/sh\n\ + exec %s -I %s $*\n" (labltk_installdir/"labltktop") labltk_installdir + end;; + +use_lib "otherlibs/labltk/browser/main" "toplevel/toplevellib";; +use_lib "otherlibs/labltk/browser/main" "otherlibs/labltk/browser/jglib";; +use_lib "otherlibs/labltk/browser/main" "otherlibs/labltk/lib/labltk";; + +if windows then begin + + dep ["ocaml"; "link"; "program"; "ocamlbrowser"] ["otherlibs/labltk/browser/winmain"-.-C.o]; + flag ["ocaml"; "link"; "program"; "ocamlbrowser"] (S[A"-custom"; A"threads.cma"]); + + match ccomptype with + | "cc" -> flag ["ocaml"; "link"; "program"; "ocamlbrowser"] (S[A"-ccopt"; A"-Wl,--subsystem,windows"]) + | "msvc" -> flag ["ocaml"; "link"; "program"; "ocamlbrowser"] (S[A"-ccopt"; A"/link /subsystem:windows"]) + | _ -> assert false + +end;; + +let space_sep_strings s = Ocamlbuild_pack.Lexers.space_sep_strings (Lexing.from_string s);; + +flag [(* "ocaml" or "c"; *) "ocamlmklib"; "otherlibs_labltk"] + (if windows then begin + S(List.fold_right (fun s acc -> A"-cclib" :: A s :: acc) (space_sep_strings C.tk_link) []) + end else Sh C.tk_link);; + +flag ["ocaml"; "link"; "program"; "otherlibs_labltk"] (S[A"-I"; A"otherlibs/labltk/support"]);; + +flag ["c"; "compile"; "otherlibs_labltk"] (A"-Iotherlibs/labltk/support");; + +copy_rule "ocamlbrowser dummy module" + ("otherlibs/labltk/browser"/(if windows then "dummyWin.mli" else "dummyUnix.mli")) + "otherlibs/labltk/browser/dummy.mli";; + + end in () + | _ -> () +end
\ No newline at end of file |