diff options
153 files changed, 3500 insertions, 2472 deletions
@@ -447,7 +447,7 @@ asmcomp/clambda.cmi: bytecomp/lambda.cmi typing/ident.cmi \ asmcomp/debuginfo.cmi parsing/asttypes.cmi asmcomp/closure.cmi: bytecomp/lambda.cmi asmcomp/clambda.cmi asmcomp/cmm.cmi: typing/ident.cmi asmcomp/debuginfo.cmi -asmcomp/cmmgen.cmi: asmcomp/cmm.cmi asmcomp/clambda.cmi +asmcomp/cmmgen.cmi: asmcomp/compilenv.cmi asmcomp/cmm.cmi asmcomp/clambda.cmi asmcomp/codegen.cmi: asmcomp/cmm.cmi asmcomp/comballoc.cmi: asmcomp/mach.cmi asmcomp/compilenv.cmi: typing/ident.cmi asmcomp/clambda.cmi @@ -745,6 +745,10 @@ driver/pparse.cmx: utils/misc.cmx parsing/location.cmx utils/clflags.cmx \ utils/ccomp.cmx driver/pparse.cmi toplevel/genprintval.cmi: typing/types.cmi typing/path.cmi \ typing/outcometree.cmi typing/env.cmi +toplevel/opttopdirs.cmi: parsing/longident.cmi +toplevel/opttoploop.cmi: utils/warnings.cmi typing/types.cmi typing/path.cmi \ + parsing/parsetree.cmi typing/outcometree.cmi parsing/longident.cmi \ + parsing/location.cmi typing/env.cmi toplevel/topdirs.cmi: parsing/longident.cmi toplevel/toploop.cmi: utils/warnings.cmi typing/types.cmi typing/path.cmi \ parsing/parsetree.cmi typing/outcometree.cmi parsing/longident.cmi \ @@ -763,6 +767,48 @@ toplevel/genprintval.cmx: typing/types.cmx typing/printtyp.cmx \ typing/predef.cmx typing/path.cmx typing/outcometree.cmi utils/misc.cmx \ parsing/longident.cmx typing/ident.cmx typing/env.cmx typing/datarepr.cmx \ typing/ctype.cmx typing/btype.cmx toplevel/genprintval.cmi +toplevel/opttopdirs.cmo: utils/warnings.cmi typing/types.cmi \ + typing/printtyp.cmi typing/path.cmi toplevel/opttoploop.cmi \ + utils/misc.cmi parsing/longident.cmi typing/ident.cmi typing/env.cmi \ + typing/ctype.cmi utils/config.cmi utils/clflags.cmi \ + toplevel/opttopdirs.cmi +toplevel/opttopdirs.cmx: utils/warnings.cmx typing/types.cmx \ + typing/printtyp.cmx typing/path.cmx toplevel/opttoploop.cmx \ + utils/misc.cmx parsing/longident.cmx typing/ident.cmx typing/env.cmx \ + typing/ctype.cmx utils/config.cmx utils/clflags.cmx \ + toplevel/opttopdirs.cmi +toplevel/opttoploop.cmo: utils/warnings.cmi typing/unused_var.cmi \ + typing/types.cmi typing/typemod.cmi typing/typedtree.cmi \ + typing/typecore.cmi bytecomp/translmod.cmi bytecomp/simplif.cmi \ + typing/printtyp.cmi bytecomp/printlambda.cmi parsing/printast.cmi \ + typing/predef.cmi typing/path.cmi parsing/parsetree.cmi parsing/parse.cmi \ + typing/outcometree.cmi driver/opterrors.cmi driver/optcompile.cmi \ + typing/oprint.cmi utils/misc.cmi parsing/longident.cmi \ + parsing/location.cmi parsing/lexer.cmi bytecomp/lambda.cmi \ + typing/ident.cmi toplevel/genprintval.cmi typing/env.cmi utils/config.cmi \ + asmcomp/compilenv.cmi utils/clflags.cmi typing/btype.cmi \ + asmcomp/asmlink.cmi asmcomp/asmgen.cmi toplevel/opttoploop.cmi +toplevel/opttoploop.cmx: utils/warnings.cmx typing/unused_var.cmx \ + typing/types.cmx typing/typemod.cmx typing/typedtree.cmx \ + typing/typecore.cmx bytecomp/translmod.cmx bytecomp/simplif.cmx \ + typing/printtyp.cmx bytecomp/printlambda.cmx parsing/printast.cmx \ + typing/predef.cmx typing/path.cmx parsing/parsetree.cmi parsing/parse.cmx \ + typing/outcometree.cmi driver/opterrors.cmx driver/optcompile.cmx \ + typing/oprint.cmx utils/misc.cmx parsing/longident.cmx \ + parsing/location.cmx parsing/lexer.cmx bytecomp/lambda.cmx \ + typing/ident.cmx toplevel/genprintval.cmx typing/env.cmx utils/config.cmx \ + asmcomp/compilenv.cmx utils/clflags.cmx typing/btype.cmx \ + asmcomp/asmlink.cmx asmcomp/asmgen.cmx toplevel/opttoploop.cmi +toplevel/opttopmain.cmo: utils/warnings.cmi asmcomp/printmach.cmi \ + toplevel/opttoploop.cmi toplevel/opttopdirs.cmi driver/opterrors.cmi \ + utils/misc.cmi utils/config.cmi utils/clflags.cmi asmcomp/arch.cmo \ + toplevel/opttopmain.cmi +toplevel/opttopmain.cmx: utils/warnings.cmx asmcomp/printmach.cmx \ + toplevel/opttoploop.cmx toplevel/opttopdirs.cmx driver/opterrors.cmx \ + utils/misc.cmx utils/config.cmx utils/clflags.cmx asmcomp/arch.cmx \ + toplevel/opttopmain.cmi +toplevel/opttopstart.cmo: toplevel/opttopmain.cmi +toplevel/opttopstart.cmx: toplevel/opttopmain.cmx toplevel/topdirs.cmo: utils/warnings.cmi typing/types.cmi toplevel/trace.cmi \ toplevel/toploop.cmi bytecomp/symtable.cmi typing/printtyp.cmi \ typing/path.cmi bytecomp/opcodes.cmo utils/misc.cmi bytecomp/meta.cmi \ @@ -18,7 +18,7 @@ include config/Makefile include stdlib/StdlibModules CAMLC=boot/ocamlrun boot/ocamlc -nostdlib -I boot -CAMLOPT=boot/ocamlrun ./ocamlopt -nostdlib -I stdlib +CAMLOPT=boot/ocamlrun ./ocamlopt -nostdlib -I stdlib -I otherlibs/dynlink COMPFLAGS=-warn-error A $(INCLUDES) LINKFLAGS= @@ -102,6 +102,11 @@ TOPLIB=$(UTILS) $(PARSING) $(TYPING) $(COMP) $(BYTECOMP) $(TOPLEVEL) TOPOBJS=$(TOPLEVELLIB) $(TOPLEVELSTART) +NATTOPOBJS=$(OPTUTILS) $(PARSING) $(TYPING) $(COMP) $(ASMCOMP) \ + driver/pparse.cmo driver/opterrors.cmo driver/optcompile.cmo \ + toplevel/genprintval.cmo toplevel/opttoploop.cmo toplevel/opttopdirs.cmo \ + toplevel/opttopmain.cmo toplevel/opttopstart.cmo + OPTOBJS=$(OPTUTILS) $(PARSING) $(TYPING) $(COMP) $(ASMCOMP) $(OPTDRIVER) EXPUNGEOBJS=utils/misc.cmo utils/tbl.cmo \ @@ -315,6 +320,17 @@ toplevel/toplevellib.cma: $(TOPLIB) partialclean:: rm -f ocaml toplevel/toplevellib.cma +# The native toplevel + +ocamlnat: ocamlopt otherlibs/dynlink/dynlink.cmxa $(NATTOPOBJS:.cmo=.cmx) + $(CAMLOPT) $(LINKFLAGS) otherlibs/dynlink/dynlink.cmxa -o ocamlnat $(NATTOPOBJS:.cmo=.cmx) -linkall + +toplevel/opttoploop.cmx: otherlibs/dynlink/dynlink.cmxa + +otherlibs/dynlink/dynlink.cmxa: otherlibs/dynlink/natdynlink.ml + cd otherlibs/dynlink && make allopt + + # The configuration file utils/config.ml: utils/config.mlp config/Makefile diff --git a/Makefile.nt b/Makefile.nt index 5e272b4ff..ffca36d99 100644 --- a/Makefile.nt +++ b/Makefile.nt @@ -18,7 +18,7 @@ include config/Makefile include stdlib/StdlibModules CAMLC=boot/ocamlrun boot/ocamlc -I boot -CAMLOPT=boot/ocamlrun ./ocamlopt -I stdlib +CAMLOPT=boot/ocamlrun ./ocamlopt -I stdlib -I otherlibs/dynlink COMPFLAGS=$(INCLUDES) LINKFLAGS= CAMLYACC=boot/ocamlyacc @@ -98,6 +98,11 @@ TOPLIB=$(UTILS) $(PARSING) $(TYPING) $(COMP) $(BYTECOMP) $(TOPLEVEL) TOPOBJS=$(TOPLEVELLIB) $(TOPLEVELSTART) +NATTOPOBJS=$(OPTUTILS) $(PARSING) $(TYPING) $(COMP) $(ASMCOMP) \ + driver/pparse.cmo driver/opterrors.cmo driver/optcompile.cmo \ + toplevel/genprintval.cmo toplevel/opttoploop.cmo toplevel/opttopdirs.cmo \ + toplevel/opttopmain.cmo toplevel/opttopstart.cmo + OPTOBJS=$(OPTUTILS) $(PARSING) $(TYPING) $(COMP) $(ASMCOMP) $(OPTDRIVER) EXPUNGEOBJS=utils/misc.cmo utils/tbl.cmo \ @@ -148,7 +153,6 @@ LIBFILES=stdlib.cma std_exit.cmo *.cmi camlheader coldstart: cd byterun ; $(MAKEREC) all cp byterun/ocamlrun.exe boot/ocamlrun.exe - cp byterun/ocamlrun.dll boot/ocamlrun.dll cd yacc ; $(MAKEREC) all cp yacc/ocamlyacc.exe boot/ocamlyacc.exe cd stdlib ; $(MAKEREC) COMPILER=../boot/ocamlc all @@ -213,8 +217,6 @@ installbyt: mkdir -p $(BINDIR) mkdir -p $(LIBDIR) cd byterun ; $(MAKEREC) install - echo "$(STUBLIBDIR)" > $(LIBDIR)/ld.conf - echo "$(LIBDIR)" >> $(LIBDIR)/ld.conf cp ocamlc $(BINDIR)/ocamlc.exe cp ocaml $(BINDIR)/ocaml.exe cd stdlib ; $(MAKEREC) install @@ -288,6 +290,17 @@ toplevel/toplevellib.cma: $(TOPLIB) partialclean:: rm -f ocaml +# The native toplevel + +ocamlnat: ocamlopt otherlibs/dynlink/dynlink.cmxa $(NATTOPOBJS:.cmo=.cmx) + $(CAMLOPT) $(LINKFLAGS) otherlibs/dynlink/dynlink.cmxa -o ocamlnat $(NATTOPOBJS:.cmo=.cmx) -linkall + +toplevel/opttoploop.cmx: otherlibs/dynlink/dynlink.cmxa + +otherlibs/dynlink/dynlink.cmxa: otherlibs/dynlink/natdynlink.ml + cd otherlibs/dynlink && make allopt + + # The configuration file utils/config.ml: utils/config.mlp config/Makefile @@ -296,9 +309,9 @@ utils/config.ml: utils/config.mlp config/Makefile -e "s|%%BYTERUN%%|ocamlrun|" \ -e 's|%%CCOMPTYPE%%|$(CCOMPTYPE)|' \ -e "s|%%BYTECC%%|$(BYTECC) $(BYTECCCOMPOPTS)|" \ - -e "s|%%BYTELINK%%|$(BYTECC) $(BYTECCLINKOPTS)|" \ + -e "s|%%BYTELINK%%|flexlink|" \ -e "s|%%NATIVECC%%|$(NATIVECC) $(NATIVECCCOMPOPTS)|" \ - -e "s|%%NATIVELINK%%|$(NATIVECC) $(NATIVECCLINKOPTS)|" \ + -e "s|%%NATIVELINK%%|flexlink|" \ -e "s|%%PARTIALLD%%|$(PARTIALLD)|" \ -e "s|%%PACKLD%%|$(PACKLD)|" \ -e "s|%%BYTECCLIBS%%|$(BYTECCLIBS)|" \ @@ -1,4 +1,4 @@ -3.11+dev5 Private_abbrevs (2007-11-1) +3.11+dev5 Private_abbrevs+natdynlink (2007-11-1) # The version string is the first line of this file. # It must be in the format described in stdlib/sys.mli @@ -32,7 +32,7 @@ true: use_stdlib <camlp4/**/*.ml*>: camlp4boot, -warn_Alez, warn_Ale <camlp4/Camlp4_config.ml*>: -camlp4boot <camlp4/build/*> or <camlp4/boot/*> or "camlp4/Camlp4/Struct/Lexer.ml": -camlp4boot, -warn_Ale, warn_a -"camlp4/Camlp4Bin.byte" or "camlp4/mkcamlp4.byte" or "camlp4/camlp4lib.cma": use_dynlink +<camlp4/Camlp4Bin.{byte,native}> or "camlp4/mkcamlp4.byte" or "camlp4/camlp4lib.cma": use_dynlink "camlp4/Camlp4/Printers/OCaml.ml" or "camlp4/Camlp4/Printers/OCamlr.ml": warn_Alezv <camlp4/Camlp4Printers/**.ml>: include_unix "camlp4/Camlp4/Struct/DynLoader.ml": include_dynlink diff --git a/asmcomp/amd64/emit.mlp b/asmcomp/amd64/emit.mlp index 4f2d54d17..215cec326 100644 --- a/asmcomp/amd64/emit.mlp +++ b/asmcomp/amd64/emit.mlp @@ -56,6 +56,24 @@ let slot_offset loc cl = let emit_symbol s = Emitaux.emit_symbol '$' s +let emit_call s = + if !Clflags.dlcode + then `call {emit_symbol s}@PLT` + else `call {emit_symbol s}` + +let emit_jump s = + if !Clflags.dlcode + then `jmp {emit_symbol s}@PLT` + else `jmp {emit_symbol s}` + +let load_symbol_addr s = + if !Clflags.dlcode + then `movq {emit_symbol s}@GOTPCREL(%rip)` + else if !pic_code + then `leaq {emit_symbol s}(%rip)` + else `movq ${emit_symbol s}` + + (* Output a label *) let emit_label lbl = @@ -111,7 +129,8 @@ let emit_reg32 r = emit_subreg reg_low_32_name r let emit_addressing addr r n = match addr with - Ibased(s, d) -> + | Ibased _ when !Clflags.dlcode -> assert false + | Ibased(s, d) -> `{emit_symbol s}`; if d <> 0 then ` + {emit_int d}`; `(%rip)` @@ -164,7 +183,7 @@ type gc_call = let call_gc_sites = ref ([] : gc_call list) let emit_call_gc gc = - `{emit_label gc.gc_lbl}: call {emit_symbol "caml_call_gc"}\n`; + `{emit_label gc.gc_lbl}: {emit_call "caml_call_gc"}\n`; `{emit_label gc.gc_frame}: jmp {emit_label gc.gc_return_lbl}\n` (* Record calls to caml_ml_array_bound_error. @@ -191,13 +210,13 @@ let bound_error_label dbg = end let emit_call_bound_error bd = - `{emit_label bd.bd_lbl}: call {emit_symbol "caml_ml_array_bound_error"}\n`; + `{emit_label bd.bd_lbl}: {emit_call "caml_ml_array_bound_error"}\n`; `{emit_label bd.bd_frame}:\n` let emit_call_bound_errors () = List.iter emit_call_bound_error !bound_error_sites; if !bound_error_call > 0 then - `{emit_label !bound_error_call}: jmp {emit_symbol "caml_ml_array_bound_error"}\n` + `{emit_label !bound_error_call}: {emit_jump "caml_ml_array_bound_error"}\n` (* Names for instructions *) @@ -326,15 +345,12 @@ let emit_instr fallthrough i = ` movlpd {emit_label lbl}(%rip), {emit_reg i.res.(0)}\n` end | Lop(Iconst_symbol s) -> - if !pic_code then - ` leaq {emit_symbol s}(%rip), {emit_reg i.res.(0)}\n` - else - ` movq ${emit_symbol s}, {emit_reg i.res.(0)}\n` + ` {load_symbol_addr s}, {emit_reg i.res.(0)}\n` | Lop(Icall_ind) -> ` call *{emit_reg i.arg.(0)}\n`; record_frame i.live i.dbg | Lop(Icall_imm(s)) -> - ` call {emit_symbol s}\n`; + ` {emit_call s}\n`; record_frame i.live i.dbg | Lop(Itailcall_ind) -> output_epilogue(); @@ -344,15 +360,15 @@ let emit_instr fallthrough i = ` jmp {emit_label !tailrec_entry_point}\n` else begin output_epilogue(); - ` jmp {emit_symbol s}\n` + ` {emit_jump s}\n` end | Lop(Iextcall(s, alloc)) -> if alloc then begin - ` leaq {emit_symbol s}(%rip), %rax\n`; - ` call {emit_symbol "caml_c_call"}\n`; + ` {load_symbol_addr s}, %rax\n`; + ` {emit_call "caml_c_call"}\n`; record_frame i.live i.dbg end else begin - ` call {emit_symbol s}\n` + ` {emit_call s}\n` end | Lop(Istackoffset n) -> if n < 0 @@ -401,7 +417,11 @@ let emit_instr fallthrough i = if !fastcode_flag then begin let lbl_redo = new_label() in `{emit_label lbl_redo}: subq ${emit_int n}, %r15\n`; - ` cmpq {emit_symbol "caml_young_limit"}(%rip), %r15\n`; + if !Clflags.dlcode then begin + ` {load_symbol_addr "caml_young_limit"}, %rax\n`; + ` cmpq (%rax), %r15\n`; + end else + ` cmpq {emit_symbol "caml_young_limit"}(%rip), %r15\n`; let lbl_call_gc = new_label() in let lbl_frame = record_frame_label i.live Debuginfo.none in ` jb {emit_label lbl_call_gc}\n`; @@ -412,11 +432,11 @@ let emit_instr fallthrough i = gc_frame = lbl_frame } :: !call_gc_sites end else begin begin match n with - 16 -> ` call {emit_symbol "caml_alloc1"}\n` - | 24 -> ` call {emit_symbol "caml_alloc2"}\n` - | 32 -> ` call {emit_symbol "caml_alloc3"}\n` + 16 -> ` {emit_call "caml_alloc1"}\n` + | 24 -> ` {emit_call "caml_alloc2"}\n` + | 32 -> ` {emit_call "caml_alloc3"}\n` | _ -> ` movq ${emit_int n}, %rax\n`; - ` call {emit_symbol "caml_allocN"}\n` + ` {emit_call "caml_allocN"}\n` end; `{record_frame i.live Debuginfo.none} leaq 8(%r15), {emit_reg i.res.(0)}\n` end @@ -487,7 +507,7 @@ let emit_instr fallthrough i = | Lop(Ispecific(Istore_int(n, addr))) -> ` movq ${emit_nativeint n}, {emit_addressing addr i.arg 0}\n` | Lop(Ispecific(Istore_symbol(s, addr))) -> - assert (not !pic_code); + assert (not !pic_code && not !Clflags.dlcode); ` movq ${emit_symbol s}, {emit_addressing addr i.arg 0}\n` | Lop(Ispecific(Ioffset_loc(n, addr))) -> ` addq ${emit_int n}, {emit_addressing addr i.arg 0}\n` @@ -548,7 +568,7 @@ let emit_instr fallthrough i = end | Lswitch jumptbl -> let lbl = new_label() in - if !pic_code then begin + if !pic_code || !Clflags.dlcode then begin ` leaq {emit_label lbl}(%rip), %r11\n`; ` jmp *(%r11, {emit_reg i.arg.(0)}, 8)\n` end else begin @@ -573,7 +593,7 @@ let emit_instr fallthrough i = stack_offset := !stack_offset - 16 | Lraise -> if !Clflags.debug then begin - ` call {emit_symbol "caml_raise_exn"}\n`; + ` {emit_call "caml_raise_exn"}\n`; record_frame Reg.Set.empty i.dbg end else begin ` movq %r14, %rsp\n`; @@ -605,7 +625,7 @@ let emit_profile () = ` pushq %r10\n`; ` movq %rsp, %rbp\n`; ` pushq %r11\n`; - ` call {emit_symbol "mcount"}\n`; + ` {emit_call "mcount"}\n`; ` popq %r11\n`; ` popq %r10\n` | _ -> @@ -679,6 +699,14 @@ let data l = (* Beginning / end of an assembly file *) let begin_assembly() = + if !Clflags.dlcode then begin + (* from amd64.S; could emit these constants on demand *) + ` .section .rodata.cst8,\"a\",@progbits\n`; + ` .align 16\n`; + `caml_negf_mask: .quad 0x8000000000000000, 0\n`; + ` .align 16\n`; + `caml_absf_mask: .quad 0x7FFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF\n`; + end; let lbl_begin = Compilenv.make_symbol (Some "data_begin") in ` .data\n`; ` .globl {emit_symbol lbl_begin}\n`; diff --git a/asmcomp/amd64/proc.ml b/asmcomp/amd64/proc.ml index 2b0cdc6d1..32d669dbb 100644 --- a/asmcomp/amd64/proc.ml +++ b/asmcomp/amd64/proc.ml @@ -170,7 +170,7 @@ let destroyed_at_oper = function | Iop(Istore(Single, _)) -> [| rxmm15 |] | Iop(Ialloc _ | Iintop(Icomp _) | Iintop_imm((Idiv|Imod|Icomp _), _)) -> [| rax |] - | Iswitch(_, _) when !pic_code -> [| r11 |] + | Iswitch(_, _) when !pic_code || !Clflags.dlcode -> [| r11 |] | _ -> [||] let destroyed_at_raise = all_phys_regs diff --git a/asmcomp/amd64/reload.ml b/asmcomp/amd64/reload.ml index 99413edcc..6901b5594 100644 --- a/asmcomp/amd64/reload.ml +++ b/asmcomp/amd64/reload.ml @@ -93,7 +93,7 @@ method reload_operation op arg res = then (arg, res) else super#reload_operation op arg res | Iconst_symbol _ -> - if !pic_code + if !pic_code || !Clflags.dlcode then super#reload_operation op arg res else (arg, res) | _ -> (* Other operations: all args and results in registers *) diff --git a/asmcomp/amd64/selection.ml b/asmcomp/amd64/selection.ml index d33ae744c..6ee3ee160 100644 --- a/asmcomp/amd64/selection.ml +++ b/asmcomp/amd64/selection.ml @@ -32,7 +32,7 @@ type addressing_expr = let rec select_addr exp = match exp with - Cconst_symbol s -> + Cconst_symbol s when not !Clflags.dlcode -> (Asymbol s, 0) | Cop((Caddi | Cadda), [arg; Cconst_int m]) -> let (a, n) = select_addr arg in (a, n + m) @@ -144,7 +144,7 @@ method select_store addr exp = (Ispecific(Istore_int(Nativeint.of_int n, addr)), Ctuple []) | Cconst_natpointer n when self#is_immediate_natint n -> (Ispecific(Istore_int(n, addr)), Ctuple []) - | Cconst_symbol s when not !pic_code -> + | Cconst_symbol s when not (!pic_code || !Clflags.dlcode) -> (Ispecific(Istore_symbol(s, addr)), Ctuple []) | _ -> super#select_store addr exp diff --git a/asmcomp/asmgen.ml b/asmcomp/asmgen.ml index 341d71c7b..93364628c 100644 --- a/asmcomp/asmgen.ml +++ b/asmcomp/asmgen.ml @@ -83,7 +83,18 @@ let compile_phrase ppf p = | Cfunction fd -> compile_fundecl ppf fd | Cdata dl -> Emit.data dl -let compile_implementation prefixname ppf (size, lam) = + +(* For the native toplevel: generates generic functions unless + they are already available in the process *) +let compile_genfuns ppf f = + List.iter + (function + | (Cfunction {fun_name = name}) as ph when f name -> + compile_phrase ppf ph + | _ -> ()) + (Cmmgen.generic_functions true [Compilenv.current_unit_infos ()]) + +let compile_implementation ?toplevel prefixname ppf (size, lam) = let asmfile = if !keep_asm_file then prefixname ^ ext_asm @@ -95,6 +106,7 @@ let compile_implementation prefixname ppf (size, lam) = Closure.intro size lam ++ Cmmgen.compunit size ++ List.iter (compile_phrase ppf) ++ (fun () -> ()); + (match toplevel with None -> () | Some f -> compile_genfuns ppf f); Emit.end_assembly(); close_out oc with x -> diff --git a/asmcomp/asmgen.mli b/asmcomp/asmgen.mli index 0f6b831ce..fe578bd4f 100644 --- a/asmcomp/asmgen.mli +++ b/asmcomp/asmgen.mli @@ -15,6 +15,7 @@ (* From lambda to assembly code *) val compile_implementation : + ?toplevel:(string -> bool) -> string -> Format.formatter -> int * Lambda.lambda -> unit val compile_phrase : Format.formatter -> Cmm.phrase -> unit diff --git a/asmcomp/asmlink.ml b/asmcomp/asmlink.ml index 0b79aa398..eeb318d0f 100644 --- a/asmcomp/asmlink.ml +++ b/asmcomp/asmlink.ml @@ -96,6 +96,30 @@ let add_ccobjs l = lib_ccopts := l.lib_ccopts @ !lib_ccopts end +let runtime_lib () = + let libname = + if !Clflags.gprofile + then "libasmrunp" ^ ext_lib + else "libasmrun" ^ ext_lib in + try + if !Clflags.nopervasives then "" + else find_in_path !load_path libname + with Not_found -> + raise(Error(File_not_found libname)) + +let object_file_name name = + let file_name = + try + find_in_path !load_path name + with Not_found -> + fatal_error "Asmlink.object_file_name: not found" in + if Filename.check_suffix file_name ".cmx" then + Filename.chop_suffix file_name ".cmx" ^ ext_obj + else if Filename.check_suffix file_name ".cmxa" then + Filename.chop_suffix file_name ".cmxa" ^ ext_lib + else + fatal_error "Asmlink.object_file_name: bad ext" + (* First pass: determine which units are needed *) let missing_globals = (Hashtbl.create 17 : (string, string list ref) Hashtbl.t) @@ -119,7 +143,11 @@ let extract_missing_globals () = Hashtbl.iter (fun md rq -> mg := (md, !rq) :: !mg) missing_globals; !mg -let scan_file obj_name tolink = +type file = + | Unit of string * Compilenv.unit_infos * Digest.t + | Library of string * Compilenv.library_infos + +let read_file obj_name = let file_name = try find_in_path !load_path obj_name @@ -129,45 +157,46 @@ let scan_file obj_name tolink = (* This is a .cmx file. It must be linked in any case. Read the infos to see which modules it requires. *) let (info, crc) = Compilenv.read_unit_info file_name in - remove_required info.ui_name; - List.iter (add_required file_name) info.ui_imports_cmx; - (info, file_name, crc) :: tolink + Unit (file_name,info,crc) end else if Filename.check_suffix file_name ".cmxa" then begin - (* This is an archive file. Each unit contained in it will be linked - in only if needed. *) - let ic = open_in_bin file_name in - let buffer = String.create (String.length cmxa_magic_number) in - really_input ic buffer 0 (String.length cmxa_magic_number); - if buffer <> cmxa_magic_number then - raise(Error(Not_an_object_file file_name)); - let infos = (input_value ic : library_infos) in - close_in ic; - add_ccobjs infos; - List.fold_right - (fun (info, crc) reqd -> - if info.ui_force_link - || !Clflags.link_everything - || is_required info.ui_name - then begin - remove_required info.ui_name; - List.iter (add_required (Printf.sprintf "%s(%s)" - file_name info.ui_name)) - info.ui_imports_cmx; - (info, file_name, crc) :: reqd - end else - reqd) - infos.lib_units tolink + let infos = + try Compilenv.read_library_info file_name + with Compilenv.Error(Not_a_unit_info _) -> + raise(Error(Not_an_object_file file_name)) + in + Library (file_name,infos) end else raise(Error(Not_an_object_file file_name)) -(* Second pass: generate the startup file and link it with everything else *) +let scan_file obj_name tolink = match read_file obj_name with + | Unit (file_name,info,crc) -> + (* This is a .cmx file. It must be linked in any case. + Read the infos to see which modules it requires. *) + let (info, crc) = Compilenv.read_unit_info file_name in + remove_required info.ui_name; + List.iter (add_required file_name) info.ui_imports_cmx; + (info, file_name, crc) :: tolink + | Library (file_name,infos) -> + (* This is an archive file. Each unit contained in it will be linked + in only if needed. *) + add_ccobjs infos; + List.fold_right + (fun (info, crc) reqd -> + if info.ui_force_link + || !Clflags.link_everything + || is_required info.ui_name + then begin + remove_required info.ui_name; + List.iter (add_required (Printf.sprintf "%s(%s)" + file_name info.ui_name)) + info.ui_imports_cmx; + (info, file_name, crc) :: reqd + end else + reqd) + infos.lib_units tolink -module IntSet = Set.Make( - struct - type t = int - let compare = compare - end) +(* Second pass: generate the startup file and link it with everything else *) let make_startup_file ppf filename units_list = let compile_phrase p = Asmgen.compile_phrase ppf p in @@ -179,64 +208,134 @@ let make_startup_file ppf filename units_list = let name_list = List.flatten (List.map (fun (info,_,_) -> info.ui_defines) units_list) in compile_phrase (Cmmgen.entry_point name_list); - let apply_functions = ref (IntSet.add 2 (IntSet.add 3 IntSet.empty)) in - (* The callback functions always reference caml_apply[23] *) - let send_functions = ref IntSet.empty in - let curry_functions = ref IntSet.empty in - List.iter - (fun (info,_,_) -> - List.iter - (fun n -> apply_functions := IntSet.add n !apply_functions) - info.ui_apply_fun; - List.iter - (fun n -> send_functions := IntSet.add n !send_functions) - info.ui_send_fun; - List.iter - (fun n -> curry_functions := IntSet.add n !curry_functions) - info.ui_curry_fun) - units_list; - IntSet.iter - (fun n -> compile_phrase (Cmmgen.apply_function n)) - !apply_functions; - IntSet.iter - (fun n -> compile_phrase (Cmmgen.send_function n)) - !send_functions; - IntSet.iter - (fun n -> List.iter (compile_phrase) (Cmmgen.curry_function n)) - !curry_functions; + let units = List.map (fun (info,_,_) -> info) units_list in + List.iter compile_phrase (Cmmgen.generic_functions false units); Array.iter (fun name -> compile_phrase (Cmmgen.predef_exception name)) Runtimedef.builtin_exceptions; compile_phrase (Cmmgen.global_table name_list); compile_phrase (Cmmgen.globals_map - (List.map - (fun (unit,_,_) -> - try (unit.ui_name, List.assoc unit.ui_name unit.ui_imports_cmi) - with Not_found -> assert false) - units_list)); + (List.map + (fun (unit,_,crc) -> + try (unit.ui_name, List.assoc unit.ui_name unit.ui_imports_cmi, + crc, + unit.ui_defines) + with Not_found -> assert false) + units_list)); compile_phrase(Cmmgen.data_segment_table ("_startup" :: name_list)); compile_phrase(Cmmgen.code_segment_table ("_startup" :: name_list)); compile_phrase (Cmmgen.frame_table("_startup" :: "_system" :: name_list)); + Emit.end_assembly(); close_out oc +let make_shared_startup_file ppf units filename = + let compile_phrase p = Asmgen.compile_phrase ppf p in + let oc = open_out filename in + Emitaux.output_channel := oc; + Location.input_name := "caml_startup"; + Compilenv.reset "_shared_startup"; + Emit.begin_assembly(); + List.iter compile_phrase + (Cmmgen.generic_functions true (List.map fst units)); + compile_phrase (Cmmgen.plugin_header units); + compile_phrase + (Cmmgen.global_table + (List.map (fun (ui,_) -> ui.Compilenv.ui_symbol) units)); + (* this is to force a reference to all units, otherwise the linker + might drop some of them (in case of libraries) *) + + Emit.end_assembly(); + close_out oc + + +let call_linker_shared file_list output_name = + let files = Ccomp.quote_files file_list in + let cmd = match Config.system with + | "mingw" | "win32" | "cygwin" -> + Printf.sprintf + "flexlink -merge-manifest -chain %s -o %s %s %s %s %s %s" + (match Config.system with + | "mingw" -> "mingw" + | "win32" -> "msvc" + | "cygwin" -> "cygwin" + | _ -> assert false) + (Filename.quote output_name) + (String.concat " " + (List.map (fun s -> if s = "" then "" else + "-I " ^ (Filename.quote s)) !load_path)) + files + (if !Clflags.verbose then "-v" else "") + (Ccomp.make_link_options !Clflags.ccopts) + (if !Clflags.verbose then "" else ">NUL") + | _ -> + Printf.sprintf + "gcc %s %s %s %s -o %s %s" + (match Config.system with + | "macosx" | "rhapsody" -> "-bundle -flat_namespace -undefined suppress -all_load" + | _ -> "-shared") + (Clflags.std_include_flag "-I") + (Ccomp.quote_files + (List.map (fun dir -> if dir = "" then "" else "-L" ^ dir) + !load_path)) + (String.concat " " (List.rev !Clflags.ccopts)) + (Filename.quote output_name) + files + in + if Ccomp.command cmd <> 0 then raise(Error Linking_error) + +let link_shared ppf objfiles output_name = + let units_tolink = List.fold_right scan_file objfiles [] in + List.iter + (fun (info, file_name, crc) -> check_consistency file_name info crc) + units_tolink; + Clflags.ccobjs := !Clflags.ccobjs @ !lib_ccobjs; + let objfiles = List.rev (List.map object_file_name objfiles) @ + !Clflags.ccobjs in + + let startup = + if !Clflags.keep_startup_file + then output_name ^ ".startup" ^ ext_asm + else Filename.temp_file "camlstartup" ext_asm in + make_shared_startup_file ppf + (List.map (fun (ui,_,crc) -> (ui,crc)) units_tolink) startup; + let startup_obj = output_name ^ ".startup" ^ ext_obj in + if Proc.assemble_file startup startup_obj <> 0 + then raise(Error(Assembler_error startup)); + if not !Clflags.keep_startup_file then remove_file startup; + call_linker_shared (startup_obj :: objfiles) output_name; + remove_file startup_obj + let call_linker file_list startup_file output_name = - let libname = - if !Clflags.gprofile - then "libasmrunp" ^ ext_lib - else "libasmrun" ^ ext_lib in - let runtime_lib = - try - if !Clflags.nopervasives then "" - else find_in_path !load_path libname - with Not_found -> - raise(Error(File_not_found libname)) in let c_lib = if !Clflags.nopervasives then "" else Config.native_c_libraries in - match Config.ccomp_type with - | "cc" -> + match Config.system, Config.ccomp_type with + | (("win32"|"mingw"|"cygwin"), _) when not !Clflags.output_c_object -> + let cmd = + Printf.sprintf + "flexlink -chain %s -merge-manifest -exe -o %s %s %s %s %s %s %s %s %s" + (match Config.system with + | "win32" -> "msvc" + | "mingw" -> "mingw" + | "cygwin" -> "cygwin" + | _ -> assert false) + (Filename.quote output_name) + (String.concat " " + (List.map (fun s -> if s = "" then "" else + "-I " ^ (Filename.quote s)) !load_path)) + (Filename.quote startup_file) + (Ccomp.quote_files (List.rev file_list)) + (Ccomp.quote_files (List.rev !Clflags.ccobjs)) + (Filename.quote (runtime_lib ())) + c_lib + (if !Clflags.verbose then " -v" else "") + (Ccomp.make_link_options !Clflags.ccopts) + in + let res = Ccomp.command cmd in + if res <> 0 then raise(Error Linking_error) + | _,"cc" -> let cmd = if not !Clflags.output_c_object then Printf.sprintf "%s %s -o %s %s %s %s %s %s %s %s %s" @@ -251,7 +350,7 @@ let call_linker file_list startup_file output_name = (List.map (fun dir -> if dir = "" then "" else "-L" ^ dir) !load_path)) (Ccomp.quote_files (List.rev !Clflags.ccobjs)) - (Filename.quote runtime_lib) + (Filename.quote (runtime_lib ())) c_lib else Printf.sprintf "%s -o %s %s %s" @@ -260,46 +359,16 @@ let call_linker file_list startup_file output_name = (Filename.quote startup_file) (Ccomp.quote_files (List.rev file_list)) in if Ccomp.command cmd <> 0 then raise(Error Linking_error) - | "msvc" -> - if not !Clflags.output_c_object then begin - let cmd = - Printf.sprintf "%s /Fe%s %s %s %s %s %s %s %s" - !Clflags.c_linker - (Filename.quote output_name) - (Clflags.std_include_flag "-I") - (Filename.quote startup_file) - (Ccomp.quote_files (List.rev file_list)) - (Ccomp.quote_files - (List.rev_map Ccomp.expand_libname !Clflags.ccobjs)) - (Filename.quote runtime_lib) - c_lib - (Ccomp.make_link_options !Clflags.ccopts) in - if Ccomp.command cmd <> 0 then raise(Error Linking_error); - if Ccomp.merge_manifest output_name <> 0 then raise(Error Linking_error) - end else begin - let cmd = - Printf.sprintf "%s /out:%s %s %s" - Config.native_partial_linker - (Filename.quote output_name) - (Filename.quote startup_file) - (Ccomp.quote_files (List.rev file_list)) - in if Ccomp.command cmd <> 0 then raise(Error Linking_error) - end + | (("win32"|"mingw"|"cygwin"), _) when !Clflags.output_c_object -> + let cmd = + Printf.sprintf "%s /out:%s %s %s" + Config.native_partial_linker + (Filename.quote output_name) + (Filename.quote startup_file) + (Ccomp.quote_files (List.rev file_list)) + in if Ccomp.command cmd <> 0 then raise(Error Linking_error) | _ -> assert false -let object_file_name name = - let file_name = - try - find_in_path !load_path name - with Not_found -> - fatal_error "Asmlink.object_file_name: not found" in - if Filename.check_suffix file_name ".cmx" then - Filename.chop_suffix file_name ".cmx" ^ ext_obj - else if Filename.check_suffix file_name ".cmxa" then - Filename.chop_suffix file_name ".cmxa" ^ ext_lib - else - fatal_error "Asmlink.object_file_name: bad ext" - (* Main entry point *) let link ppf objfiles output_name = @@ -322,7 +391,9 @@ let link ppf objfiles output_name = units_tolink; Clflags.ccobjs := !Clflags.ccobjs @ !lib_ccobjs; Clflags.ccopts := !lib_ccopts @ !Clflags.ccopts; (* put user's opts first *) - let startup = Filename.temp_file "camlstartup" ext_asm in + let startup = + if !Clflags.keep_startup_file then output_name ^ ".startup" ^ ext_asm + else Filename.temp_file "camlstartup" ext_asm in make_startup_file ppf startup units_tolink; let startup_obj = Filename.temp_file "camlstartup" ext_obj in if Proc.assemble_file startup startup_obj <> 0 then diff --git a/asmcomp/asmlink.mli b/asmcomp/asmlink.mli index 28c5287da..2070c815d 100644 --- a/asmcomp/asmlink.mli +++ b/asmcomp/asmlink.mli @@ -12,12 +12,16 @@ (* $Id$ *) -(* Link a set of .cmx/.o files and produce an executable *) +(* Link a set of .cmx/.o files and produce an executable or a plugin *) open Format val link: formatter -> string list -> string -> unit +val link_shared: formatter -> string list -> string -> unit + +val call_linker_shared: string list -> string -> unit + val check_consistency: string -> Compilenv.unit_infos -> Digest.t -> unit val extract_crc_interfaces: unit -> (string * Digest.t) list val extract_crc_implementations: unit -> (string * Digest.t) list diff --git a/asmcomp/asmpackager.ml b/asmcomp/asmpackager.ml index 4469e77e6..aabb876e4 100644 --- a/asmcomp/asmpackager.ml +++ b/asmcomp/asmpackager.ml @@ -80,10 +80,14 @@ let check_units members = (* Make the .o file for the package *) let make_package_object ppf members targetobj targetname coercion = - (* Put the full name of the module in the temporary file name - to avoid collisions with MSVC's link /lib in case of successive packs *) let objtemp = - Filename.temp_file (Compilenv.make_symbol (Some "")) Config.ext_obj in + if !Clflags.keep_asm_file + then chop_extension_if_any targetobj ^ ".pack" ^ Config.ext_obj + else + (* Put the full name of the module in the temporary file name + to avoid collisions with MSVC's link /lib in case of successive + packs *) + Filename.temp_file (Compilenv.make_symbol (Some "")) Config.ext_obj in let components = List.map (fun m -> @@ -146,7 +150,7 @@ let build_package_cmx members cmxfile = ui_send_fun = union(List.map (fun info -> info.ui_send_fun) units); ui_force_link = - List.exists (fun info -> info.ui_force_link) units + List.exists (fun info -> info.ui_force_link) units; } in Compilenv.write_unit_info pkg_infos cmxfile diff --git a/asmcomp/cmmgen.ml b/asmcomp/cmmgen.ml index 9f5e4f29b..a51f0a28a 100644 --- a/asmcomp/cmmgen.ml +++ b/asmcomp/cmmgen.ml @@ -1927,6 +1927,36 @@ let curry_function arity = then intermediate_curry_functions arity 0 else [tuplify_function (-arity)] + +module IntSet = Set.Make( + struct + type t = int + let compare = compare + end) + +let default_apply = IntSet.add 2 (IntSet.add 3 IntSet.empty) + (* These apply funs are always present in the main program. + TODO: add more, and do the same for send and curry funs + (maybe up to 10-15?). *) + +let generic_functions shared units = + let (apply,send,curry) = + List.fold_left + (fun (apply,send,curry) ui -> + List.fold_right IntSet.add ui.Compilenv.ui_apply_fun apply, + List.fold_right IntSet.add ui.Compilenv.ui_send_fun send, + List.fold_right IntSet.add ui.Compilenv.ui_curry_fun curry) + (IntSet.empty,IntSet.empty,IntSet.empty) + units + in + let apply = + if shared then IntSet.diff apply default_apply + else IntSet.union apply default_apply + in + let accu = IntSet.fold (fun n accu -> apply_function n :: accu) apply [] in + let accu = IntSet.fold (fun n accu -> send_function n :: accu) send accu in + IntSet.fold (fun n accu -> curry_function n @ accu) curry accu + (* Generate the entry point *) let entry_point namelist = @@ -1961,10 +1991,12 @@ let global_table namelist = List.map mksym namelist @ [cint_zero]) -let globals_map namelist = - Cdata(Cglobal_symbol "caml_globals_map" :: - emit_constant "caml_globals_map" - (Const_base (Const_string (Marshal.to_string namelist []))) []) +let global_data name v = + Cdata(Cglobal_symbol name :: + emit_constant name + (Const_base (Const_string (Marshal.to_string v []))) []) + +let globals_map v = global_data "caml_globals_map" v (* Generate the master table of frame descriptors *) @@ -2006,3 +2038,33 @@ let predef_exception name = Cint(block_header 0 1); Cdefine_symbol bucketname; Csymbol_address symname ]) + +(* Header for a plugin *) + +let mapflat f l = List.flatten (List.map f l) + +type dynunit = { + name: string; + crc: Digest.t; + imports_cmi: (string * Digest.t) list; + imports_cmx: (string * Digest.t) list; + defines: string list; +} + +type dynheader = { + magic: string; + units: dynunit list; +} + +let dyn_magic_number = "Caml2007D001" + +let plugin_header units = + let mk (ui,crc) = + { name = ui.Compilenv.ui_name; + crc = crc; + imports_cmi = ui.Compilenv.ui_imports_cmi; + imports_cmx = ui.Compilenv.ui_imports_cmx; + defines = ui.Compilenv.ui_defines + } in + global_data "caml_plugin_header" + { magic = dyn_magic_number; units = List.map mk units } diff --git a/asmcomp/cmmgen.mli b/asmcomp/cmmgen.mli index fa4dba277..f73d6fcb3 100644 --- a/asmcomp/cmmgen.mli +++ b/asmcomp/cmmgen.mli @@ -19,10 +19,13 @@ val compunit: int -> Clambda.ulambda -> Cmm.phrase list val apply_function: int -> Cmm.phrase val send_function: int -> Cmm.phrase val curry_function: int -> Cmm.phrase list +val generic_functions: bool -> Compilenv.unit_infos list -> Cmm.phrase list val entry_point: string list -> Cmm.phrase val global_table: string list -> Cmm.phrase -val globals_map: (string * string) list -> Cmm.phrase +val globals_map: (string * Digest.t * Digest.t * string list) list -> + Cmm.phrase val frame_table: string list -> Cmm.phrase val data_segment_table: string list -> Cmm.phrase val code_segment_table: string list -> Cmm.phrase val predef_exception: string -> Cmm.phrase +val plugin_header: (Compilenv.unit_infos * Digest.t) list -> Cmm.phrase diff --git a/asmcomp/compilenv.ml b/asmcomp/compilenv.ml index 9f4288821..e0f999c20 100644 --- a/asmcomp/compilenv.ml +++ b/asmcomp/compilenv.ml @@ -126,6 +126,17 @@ let read_unit_info filename = close_in ic; raise(Error(Corrupted_unit_info(filename))) +let read_library_info filename = + let ic = open_in_bin filename in + let buffer = String.create (String.length cmxa_magic_number) in + really_input ic buffer 0 (String.length cmxa_magic_number); + if buffer <> cmxa_magic_number then + raise(Error(Not_a_unit_info filename)); + let infos = (input_value ic : library_infos) in + close_in ic; + infos + + (* Read and cache info on global identifiers *) let cmx_not_found_crc = @@ -160,10 +171,18 @@ let cache_unit_info ui = (* Return the approximation of a global identifier *) +let toplevel_approx = Hashtbl.create 16 + +let record_global_approx_toplevel id = + Hashtbl.add toplevel_approx current_unit.ui_name current_unit.ui_approx + let global_approx id = - match get_global_info id with - | None -> Value_unknown - | Some ui -> ui.ui_approx + if Ident.is_predef_exn id then Value_unknown + else try Hashtbl.find toplevel_approx (Ident.name id) + with Not_found -> + match get_global_info id with + | None -> Value_unknown + | Some ui -> ui.ui_approx (* Return the symbol used to refer to a global identifier *) diff --git a/asmcomp/compilenv.mli b/asmcomp/compilenv.mli index 3b547872a..762123b01 100644 --- a/asmcomp/compilenv.mli +++ b/asmcomp/compilenv.mli @@ -70,6 +70,9 @@ val global_approx: Ident.t -> Clambda.value_approximation (* Return the approximation for the given global identifier *) val set_global_approx: Clambda.value_approximation -> unit (* Record the approximation of the unit being compiled *) +val record_global_approx_toplevel: unit -> unit + (* Record the current approximation for the current toplevel phrase *) + val need_curry_fun: int -> unit val need_apply_fun: int -> unit @@ -77,6 +80,7 @@ val need_send_fun: int -> unit (* Record the need of a currying (resp. application, message sending) function with the given arity *) + val read_unit_info: string -> unit_infos * Digest.t (* Read infos and CRC from a [.cmx] file. *) val write_unit_info: unit_infos -> string -> unit @@ -92,6 +96,8 @@ val cmx_not_found_crc: Digest.t (* Special digest used in the [ui_imports_cmx] list to signal that no [.cmx] file was found and used for the imported unit *) +val read_library_info: string -> library_infos + type error = Not_a_unit_info of string | Corrupted_unit_info of string @@ -100,3 +106,5 @@ type error = exception Error of error val report_error: Format.formatter -> error -> unit + + diff --git a/asmcomp/i386/proc_nt.ml b/asmcomp/i386/proc_nt.ml index 2c460f78b..fa9d60590 100644 --- a/asmcomp/i386/proc_nt.ml +++ b/asmcomp/i386/proc_nt.ml @@ -171,4 +171,5 @@ let contains_calls = ref false let assemble_file infile outfile = Ccomp.command (Config.asm ^ - Filename.quote outfile ^ " " ^ Filename.quote infile ^ ">NUL") + Filename.quote outfile ^ " " ^ Filename.quote infile ^ + (if !Clflags.verbose then "" else ">NUL")) diff --git a/asmcomp/power/emit.mlp b/asmcomp/power/emit.mlp index 81a1894e5..f36d44129 100644 --- a/asmcomp/power/emit.mlp +++ b/asmcomp/power/emit.mlp @@ -81,15 +81,17 @@ let data_space = | "rhapsody" -> " .data\n" | _ -> assert false -let code_space = +let code_space () = match Config.system with | "elf" | "bsd" -> " .section \".text\"\n" - | "rhapsody" -> " .text\n" + | "rhapsody" when !Clflags.dlcode -> " .section __TEXT,__selfmod,regular,self_modifying_code\n" + | "rhapsody" -> " .text\n" | _ -> assert false -let rodata_space = +let rodata_space () = match Config.system with | "elf" | "bsd" -> " .section \".rodata\"\n" + | "rhapsody" when !Clflags.dlcode -> " .data\n" | "rhapsody" -> " .const\n" | _ -> assert false @@ -251,6 +253,37 @@ let emit_external s = ` .indirect_symbol {emit_symbol s}\n`; ` {emit_string datag} 0\n` + +let external_stubs = ref StringSet.empty +let external_non_lazy = ref StringSet.empty + +let emit_stub s = + let lbl = new_label() in + ` .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32\n`; + ` .align 5\n`; + `L{emit_symbol s}$stub:\n`; + ` .indirect_symbol {emit_symbol s}\n`; + ` mflr r0\n`; + ` bcl 20,31,{emit_label lbl}\n`; + `{emit_label lbl}:\n`; + ` mflr r11\n`; + ` addis r11,r11,ha16(L{emit_symbol s}$lazy_ptr-{emit_label lbl})\n`; + ` mtlr r0\n`; + ` lwzu r12,lo16(L{emit_symbol s}$lazy_ptr-{emit_label lbl})(r11)\n`; + ` mtctr r12\n`; + ` bctr\n`; + ` .lazy_symbol_pointer\n`; + `L{emit_symbol s}$lazy_ptr:\n`; + ` .indirect_symbol {emit_symbol s}\n`; + ` .long dyld_stub_binding_helper\n` + +let emit_non_lazy s = + ` .non_lazy_symbol_pointer\n`; + `L{emit_symbol s}$non_lazy_ptr:\n`; + ` .indirect_symbol {emit_symbol s}\n`; + ` {emit_string datag} 0\n` + + (* Names for conditional branches after comparisons *) let branch_for_comparison = function @@ -478,14 +511,28 @@ let rec emit_instr i dslot = ` addis {emit_gpr 11}, 0, {emit_upper emit_label lbl}\n`; ` lfd {emit_reg i.res.(0)}, {emit_lower emit_label lbl}({emit_gpr 11})\n` | Lop(Iconst_symbol s) -> - ` addis {emit_reg i.res.(0)}, 0, {emit_upper emit_symbol s}\n`; - ` addi {emit_reg i.res.(0)}, {emit_reg i.res.(0)}, {emit_lower emit_symbol s}\n` + if !Clflags.dlcode then begin + let lbl = new_label () in + external_non_lazy := StringSet.add s !external_non_lazy; + ` bcl 20,31,{emit_label lbl}\n`; + `{emit_label lbl}:\n`; + ` mflr {emit_reg i.res.(0)}\n`; + ` addis {emit_reg i.res.(0)}, {emit_reg i.res.(0)}, ha16(L{emit_symbol s}$non_lazy_ptr-{emit_label lbl})\n`; + ` addi {emit_reg i.res.(0)}, {emit_reg i.res.(0)}, lo16(L{emit_symbol s}$non_lazy_ptr-{emit_label lbl})\n` + end else begin + ` addis {emit_reg i.res.(0)}, 0, {emit_upper emit_symbol s}\n`; + ` addi {emit_reg i.res.(0)}, {emit_reg i.res.(0)}, {emit_lower emit_symbol s}\n` + end | Lop(Icall_ind) -> ` mtctr {emit_reg i.arg.(0)}\n`; ` bctrl\n`; record_frame i.live i.dbg | Lop(Icall_imm s) -> - ` bl {emit_symbol s}\n`; + if !Clflags.dlcode then begin + external_stubs := StringSet.add s !external_stubs; + ` bl L{emit_symbol s}$stub\n`; + end else + ` bl {emit_symbol s}\n`; record_frame i.live i.dbg | Lop(Itailcall_ind) -> let n = frame_size() in @@ -524,7 +571,12 @@ let rec emit_instr i dslot = ` addis {emit_gpr 11}, 0, {emit_upper emit_symbol s}\n`; ` addi {emit_gpr 11}, {emit_gpr 11}, {emit_lower emit_symbol s}\n` end; - ` bl {emit_symbol "caml_c_call"}\n`; + if !Clflags.dlcode then begin + (* WRONG: stub will destroy r11 *) + external_stubs := StringSet.add "caml_c_call" !external_stubs; + ` bl L{emit_symbol "caml_c_call"}$stub\n`; + end else + ` bl {emit_symbol "caml_c_call"}\n`; record_frame i.live i.dbg end else begin if pic_externals then begin @@ -748,12 +800,12 @@ let rec emit_instr i dslot = ` add {emit_gpr 0}, {emit_gpr 11}, {emit_gpr 0}\n`; ` mtctr {emit_gpr 0}\n`; ` bctr\n`; - emit_string rodata_space; + emit_string (rodata_space ()); `{emit_label lbl}:`; for i = 0 to Array.length jumptbl - 1 do ` .long {emit_label jumptbl.(i)} - {emit_label lbl}\n` done; - emit_string code_space + emit_string (code_space ()) | Lsetuptrap lbl -> ` bl {emit_label lbl}\n` | Lpushtrap -> @@ -841,7 +893,7 @@ let fundecl fundecl = ` .type {emit_symbol fundecl.fun_name}, @function\n` | _ -> () end; - emit_string code_space; + emit_string (code_space ()); ` .align 2\n`; `{emit_symbol fundecl.fun_name}:\n`; let n = frame_size() in @@ -859,11 +911,16 @@ let fundecl fundecl = (* Emit the glue code to call the GC *) if !call_gc_label > 0 then begin `{emit_label !call_gc_label}:\n`; - ` b {emit_symbol "caml_call_gc"}\n` +(* if !Clflags.dlcode then begin + (* WRONG: stub will destroy r11 *) + external_stubs := StringSet.add "caml_call_gc" !external_stubs; + ` b L{emit_symbol "caml_call_gc"}$stub\n`; + end else *) + ` b {emit_symbol "caml_call_gc"}\n` end; (* Emit the numeric literals *) if !float_literals <> [] || !int_literals <> [] then begin - emit_string rodata_space; + emit_string (rodata_space ()); ` .align 3\n`; List.iter (fun (f, lbl) -> @@ -921,13 +978,15 @@ let data l = let begin_assembly() = defined_functions := StringSet.empty; external_functions := StringSet.empty; + external_stubs := StringSet.empty; + external_non_lazy := StringSet.empty; (* Emit the beginning of the segments *) let lbl_begin = Compilenv.make_symbol (Some "data_begin") in emit_string data_space; declare_global_data lbl_begin; `{emit_symbol lbl_begin}:\n`; let lbl_begin = Compilenv.make_symbol (Some "code_begin") in - emit_string code_space; + emit_string (code_space ()); declare_global_data lbl_begin; `{emit_symbol lbl_begin}:\n` @@ -935,8 +994,10 @@ let end_assembly() = if pic_externals then (* Emit the pointers to external functions *) StringSet.iter emit_external !external_functions; + StringSet.iter emit_stub !external_stubs; + StringSet.iter emit_non_lazy !external_non_lazy; (* Emit the end of the segments *) - emit_string code_space; + emit_string (code_space ()); let lbl_end = Compilenv.make_symbol (Some "code_end") in declare_global_data lbl_end; `{emit_symbol lbl_end}:\n`; @@ -947,7 +1008,7 @@ let end_assembly() = `{emit_symbol lbl_end}:\n`; ` {emit_string datag} 0\n`; (* Emit the frame descriptors *) - emit_string rodata_space; + emit_string (rodata_space ()); let lbl = Compilenv.make_symbol (Some "frametable") in declare_global_data lbl; `{emit_symbol lbl}:\n`; diff --git a/asmcomp/power/selection.ml b/asmcomp/power/selection.ml index f3880b0da..1b2b3b533 100644 --- a/asmcomp/power/selection.ml +++ b/asmcomp/power/selection.ml @@ -28,7 +28,7 @@ type addressing_expr = | Aadd of expression * expression let rec select_addr = function - Cconst_symbol s -> + Cconst_symbol s when not !Clflags.dlcode -> (Asymbol s, 0) | Cop((Caddi | Cadda), [arg; Cconst_int m]) -> let (a, n) = select_addr arg in (a, n + m) diff --git a/asmrun/Makefile b/asmrun/Makefile index 7c3e84063..ba5f4c036 100644 --- a/asmrun/Makefile +++ b/asmrun/Makefile @@ -17,7 +17,7 @@ include ../config/Makefile CC=$(NATIVECC) FLAGS=-I../byterun -DCAML_NAME_SPACE -DNATIVE_CODE \ - -DTARGET_$(ARCH) -DSYS_$(SYSTEM) + -DTARGET_$(ARCH) -DSYS_$(SYSTEM) $(FLEXLINK) CFLAGS=$(FLAGS) -O $(NATIVECCCOMPOPTS) DFLAGS=$(FLAGS) -g -DDEBUG $(NATIVECCCOMPOPTS) PFLAGS=$(FLAGS) -pg -O -DPROFILING $(NATIVECCPROFOPTS) @@ -26,7 +26,7 @@ COBJS=startup.o main.o fail.o roots.o globroots.o signals.o signals_asm.o \ misc.o freelist.o major_gc.o minor_gc.o memory.o alloc.o compare.o ints.o \ floats.o str.o array.o io.o extern.o intern.o hash.o sys.o parsing.o \ gc_ctrl.o terminfo.o md5.o obj.o lexing.o printexc.o callback.o weak.o \ - compact.o finalise.o custom.o unix.o backtrace.o + compact.o finalise.o custom.o unix.o backtrace.o natdynlink.o ASMOBJS=$(ARCH).o diff --git a/asmrun/Makefile.nt b/asmrun/Makefile.nt index 8737a5861..bdc9e90fa 100644 --- a/asmrun/Makefile.nt +++ b/asmrun/Makefile.nt @@ -24,7 +24,7 @@ COBJS=startup.$(O) main.$(O) fail.$(O) roots.$(O) signals.$(O) signals_asm.$(O) intern.$(O) hash.$(O) sys.$(O) parsing.$(O) gc_ctrl.$(O) terminfo.$(O) \ md5.$(O) obj.$(O) lexing.$(O) win32.$(O) printexc.$(O) callback.$(O) \ weak.$(O) compact.$(O) finalise.$(O) custom.$(O) globroots.$(O) \ - backtrace.$(O) + backtrace.$(O) natdynlink.$(O) LINKEDFILES=misc.c freelist.c major_gc.c minor_gc.c memory.c alloc.c array.c \ compare.c ints.c floats.c str.c io.c extern.c intern.c hash.c sys.c \ @@ -62,7 +62,7 @@ $(LINKEDFILES): %.c: ../byterun/%.c # Need special compilation rule so as not to do -I../byterun win32.$(O): ../byterun/win32.c - $(CC) -c $(NATIVECCCOMPOPTS) -DNATIVE_CODE ../byterun/win32.c + $(CC) -c $(NATIVECCCOMPOPTS) -DNATIVE_CODE -I../../flexdll/ ../byterun/win32.c .SUFFIXES: .c .$(O) diff --git a/asmrun/natdynlink.c b/asmrun/natdynlink.c new file mode 100644 index 000000000..05da896b9 --- /dev/null +++ b/asmrun/natdynlink.c @@ -0,0 +1,169 @@ +#include "misc.h" +#include "mlvalues.h" +#include "memory.h" +#include "stack.h" +#include "callback.h" +#include "alloc.h" +#include "natdynlink.h" +#include "osdeps.h" +#include "fail.h" + +#include <stdio.h> +#include <string.h> + +static void *getsym(void *handle, char *module, char *name, int opt){ + char *fullname = malloc(strlen(module) + strlen(name) + 5); + void *sym; + sprintf(fullname, "caml%s%s", module, name); + sym = caml_dlsym (handle, fullname); + /* printf("%s => %lx\n", fullname, (uintnat) sym); */ + free(fullname); + if (NULL == sym && !opt) { + printf("natdynlink: cannot find symbol %s\n", fullname); + exit(2); + } + return sym; +} + + +/* Data segments are used by the Is_atom predicate (mlvalues.h) + to detect static Caml blocks. + + Code segments are used in signals_asm.c + + TODO: use dichotomic search +*/ + +typedef struct segment { + void *begin; + void *end; + struct segment *next; +} segment; + +segment *caml_dyn_data_segments = NULL; +segment *caml_dyn_code_segments = NULL; + +static segment *segment_cons(void *begin, void *end, segment *tl) { + segment *lnk = caml_stat_alloc(sizeof(segment)); + lnk->begin = begin; + lnk->end = end; + lnk->next = tl; + return lnk; +} + +int caml_is_in_data(void *p) { + segment *lnk; + for (lnk = caml_dyn_data_segments; NULL != lnk; lnk = lnk->next) + if (p >= lnk->begin && p <= lnk->end) return 1; + return 0; +} +int caml_is_in_code(void *p) { + segment *lnk; + for (lnk = caml_dyn_code_segments; NULL != lnk; lnk = lnk->next) + if (p >= lnk->begin && p <= lnk->end) return 1; + return 0; +} + +extern char caml_globals_map[]; + +CAMLprim value caml_natdynlink_getmap(value unit) +{ + return (value)caml_globals_map; +} + +CAMLprim value caml_natdynlink_globals_inited(value unit) +{ + return Val_int(caml_globals_inited); +} + +CAMLprim value caml_natdynlink_open(value filename) +{ + CAMLparam1 (filename); + CAMLlocal1 (res); + void *sym; + void *handle; + + /* TODO: dlclose in case of error... */ + + handle = caml_dlopen(String_val(filename), 1); + + if (NULL == handle) + CAMLreturn(caml_copy_string(caml_dlerror())); + + sym = caml_dlsym(handle, "caml_plugin_header"); + if (NULL == sym) + CAMLreturn(caml_copy_string("not an OCaml plugin")); + + res = caml_alloc_tuple(2); + Field(res, 0) = (value) handle; + Field(res, 1) = (value) (sym); + CAMLreturn(res); +} + +CAMLprim value caml_natdynlink_run(void *handle, value symbol) { + CAMLparam1 (symbol); + CAMLlocal1 (result); + void *sym,*sym2; + +#define optsym(n) getsym(handle,unit,n,1) + char *unit; + void (*entrypoint)(void); + + unit = String_val(symbol); + + sym = optsym("__frametable"); + if (NULL != sym) caml_register_frametable(sym); + + sym = optsym(""); + if (NULL != sym) caml_register_dyn_global(sym); + + sym = optsym("__data_begin"); + sym2 = optsym("__data_end"); + if (NULL != sym && NULL != sym2) + caml_dyn_data_segments = segment_cons(sym,sym2,caml_dyn_data_segments); + + sym = optsym("__code_begin"); + sym2 = optsym("__code_end"); + if (NULL != sym && NULL != sym2) + caml_dyn_code_segments = segment_cons(sym,sym2,caml_dyn_code_segments); + + entrypoint = optsym("__entry"); + if (NULL != entrypoint) result = caml_callback((value)(&entrypoint), 0); + else result = Val_unit; + +#undef optsym + + CAMLreturn (result); +} + +CAMLprim value caml_natdynlink_run_toplevel(value filename, value symbol) +{ + CAMLparam2 (filename, symbol); + CAMLlocal2 (res, v); + void *handle; + + /* TODO: dlclose in case of error... */ + + handle = caml_dlopen(String_val(filename), 1); + + if (NULL == handle) { + res = caml_alloc(1,1); + v = caml_copy_string(caml_dlerror()); + Store_field(res, 0, v); + } else { + res = caml_alloc(1,0); + v = caml_natdynlink_run(handle, symbol); + Store_field(res, 0, v); + } + CAMLreturn(res); +} + +CAMLprim value caml_natdynlink_loadsym(value symbol) +{ + CAMLparam1 (symbol); + CAMLlocal1 (sym); + + sym = (value) caml_globalsym(String_val(symbol)); + if (!sym) caml_failwith(String_val(symbol)); + CAMLreturn(sym); +} diff --git a/asmrun/natdynlink.h b/asmrun/natdynlink.h new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/asmrun/natdynlink.h diff --git a/asmrun/roots.c b/asmrun/roots.c index f5ff1591e..4a4ade47e 100644 --- a/asmrun/roots.c +++ b/asmrun/roots.c @@ -24,6 +24,8 @@ #include "mlvalues.h" #include "stack.h" #include "roots.h" +#include <string.h> +#include <stdio.h> /* Roots registered from C functions */ @@ -36,6 +38,37 @@ void (*caml_scan_roots_hook) (scanning_action) = NULL; frame_descr ** caml_frame_descriptors = NULL; int caml_frame_descriptors_mask; +/* Linked-list */ + +typedef struct link { + void *data; + struct link *next; +} link; + +static link *cons(void *data, link *tl) { + link *lnk = caml_stat_alloc(sizeof(link)); + lnk->data = data; + lnk->next = tl; + return lnk; +} + +#define iter_list(list,lnk) \ + for (lnk = list; lnk != NULL; lnk = lnk->next) + +/* Linked-list of frametables */ + +static link *frametables = NULL; + +void caml_register_frametable(intnat *table) { + frametables = cons(table,frametables); + + if (NULL != caml_frame_descriptors) { + caml_stat_free(caml_frame_descriptors); + caml_frame_descriptors = NULL; + /* force caml_init_frame_descriptors to be called */ + } +} + void caml_init_frame_descriptors(void) { intnat num_descr, tblsize, i, j, len; @@ -43,11 +76,21 @@ void caml_init_frame_descriptors(void) frame_descr * d; uintnat nextd; uintnat h; + link *lnk; + static int inited = 0; + + if (!inited) { + for (i = 0; caml_frametable[i] != 0; i++) + caml_register_frametable(caml_frametable[i]); + inited = 1; + } + /* Count the frame descriptors */ num_descr = 0; - for (i = 0; caml_frametable[i] != 0; i++) - num_descr += *(caml_frametable[i]); + iter_list(frametables,lnk) { + num_descr += *((intnat*) lnk->data); + } /* The size of the hashtable is a power of 2 greater or equal to 2 times the number of descriptors */ @@ -61,21 +104,21 @@ void caml_init_frame_descriptors(void) caml_frame_descriptors_mask = tblsize - 1; /* Fill the hash table */ - for (i = 0; caml_frametable[i] != 0; i++) { - tbl = caml_frametable[i]; + iter_list(frametables,lnk) { + tbl = (intnat*) lnk->data; len = *tbl; d = (frame_descr *)(tbl + 1); for (j = 0; j < len; j++) { h = Hash_retaddr(d->retaddr); while (caml_frame_descriptors[h] != NULL) { - h = (h+1) & caml_frame_descriptors_mask; + h = (h+1) & caml_frame_descriptors_mask; } caml_frame_descriptors[h] = d; nextd = - ((uintnat)d + - sizeof(char *) + sizeof(short) + sizeof(short) + - sizeof(short) * d->num_live + sizeof(frame_descr *) - 1) - & -sizeof(frame_descr *); + ((uintnat)d + + sizeof(char *) + sizeof(short) + sizeof(short) + + sizeof(short) * d->num_live + sizeof(frame_descr *) - 1) + & -sizeof(frame_descr *); if (d->frame_size & 1) nextd += 8; d = (frame_descr *) nextd; } @@ -89,6 +132,11 @@ uintnat caml_last_return_address = 1; /* not in Caml code initially */ value * caml_gc_regs; intnat caml_globals_inited = 0; static intnat caml_globals_scanned = 0; +static link * caml_dyn_globals = NULL; + +void caml_register_dyn_global(void *v) { + caml_dyn_globals = cons((void*) v,caml_dyn_globals); +} /* Call [caml_oldify_one] on (at least) all the roots that point to the minor heap. */ @@ -105,6 +153,7 @@ void caml_oldify_local_roots (void) value * root; struct global_root * gr; struct caml__roots_block *lr; + link *lnk; /* The global roots */ for (i = caml_globals_scanned; @@ -117,6 +166,14 @@ void caml_oldify_local_roots (void) } caml_globals_scanned = caml_globals_inited; + /* Dynamic global roots */ + iter_list(caml_dyn_globals, lnk) { + glob = (value) lnk->data; + for (j = 0; j < Wosize_val(glob); j++){ + Oldify (&Field (glob, j)); + } + } + /* The stack and local roots */ if (caml_frame_descriptors == NULL) caml_init_frame_descriptors(); sp = caml_bottom_of_stack; @@ -198,6 +255,7 @@ void caml_do_roots (scanning_action f) int i, j; value glob; struct global_root * gr; + link *lnk; /* The global roots */ for (i = 0; caml_globals[i] != 0; i++) { @@ -205,6 +263,15 @@ void caml_do_roots (scanning_action f) for (j = 0; j < Wosize_val(glob); j++) f (Field (glob, j), &Field (glob, j)); } + + /* Dynamic global roots */ + iter_list(caml_dyn_globals, lnk) { + glob = (value) lnk->data; + for (j = 0; j < Wosize_val(glob); j++){ + f (Field (glob, j), &Field (glob, j)); + } + } + /* The stack and local roots */ if (caml_frame_descriptors == NULL) caml_init_frame_descriptors(); caml_do_local_roots(f, caml_bottom_of_stack, caml_last_return_address, diff --git a/asmrun/signals_asm.c b/asmrun/signals_asm.c index f33354051..187b6f0c5 100644 --- a/asmrun/signals_asm.c +++ b/asmrun/signals_asm.c @@ -46,10 +46,12 @@ extern void caml_win32_overflow_detection(); #endif extern char * caml_code_area_start, * caml_code_area_end; +CAMLextern int caml_is_in_code(void *); #define In_code_area(pc) \ - ((char *)(pc) >= caml_code_area_start && \ - (char *)(pc) <= caml_code_area_end) + ( ((char *)(pc) >= caml_code_area_start && \ + (char *)(pc) <= caml_code_area_end) \ + || caml_is_in_code((void *)(pc)) ) /* This routine is the common entry point for garbage collection and signal handling. It can trigger a callback to Caml code. diff --git a/asmrun/stack.h b/asmrun/stack.h index 913ec4f55..578e9cf87 100644 --- a/asmrun/stack.h +++ b/asmrun/stack.h @@ -114,6 +114,8 @@ extern int caml_frame_descriptors_mask; (((uintnat)(addr) >> 3) & caml_frame_descriptors_mask) extern void caml_init_frame_descriptors(void); +extern void caml_register_frametable(intnat *); +extern void caml_register_dyn_global(void *); /* Declaration of variables used in the asm code */ extern char * caml_bottom_of_stack; @@ -124,5 +126,4 @@ extern value caml_globals[]; extern intnat caml_globals_inited; extern intnat * caml_frametable[]; - #endif /* CAML_STACK_H */ diff --git a/asmrun/startup.c b/asmrun/startup.c index 765d2a8bf..54610e6c6 100644 --- a/asmrun/startup.c +++ b/asmrun/startup.c @@ -28,12 +28,13 @@ #include "osdeps.h" #include "printexc.h" #include "sys.h" +#include "natdynlink.h" #ifdef HAS_UI #include "ui.h" #endif extern int caml_parser_trace; -header_t caml_atom_table[256]; +CAMLexport header_t caml_atom_table[256]; char * caml_static_data_start, * caml_static_data_end; char * caml_code_area_start, * caml_code_area_end; diff --git a/boot/ocamlc b/boot/ocamlc Binary files differindex 6285c507d..279e28398 100755 --- a/boot/ocamlc +++ b/boot/ocamlc diff --git a/boot/ocamldep b/boot/ocamldep Binary files differindex bed3b40ce..9e2203e9f 100755 --- a/boot/ocamldep +++ b/boot/ocamldep diff --git a/boot/ocamllex b/boot/ocamllex Binary files differindex 4020c0313..441d7c79d 100755 --- a/boot/ocamllex +++ b/boot/ocamllex diff --git a/build/mkconfig.sh b/build/mkconfig.sh index 591bebc65..1cd66f37e 100755 --- a/build/mkconfig.sh +++ b/build/mkconfig.sh @@ -5,6 +5,7 @@ cd `dirname $0`/.. sed -e 's/^\(.*\$([0-9]).*\)$/# \1/' \ -e 's/\$(\([^)]*\))/${\1}/g' \ + -e 's/^FLEX.*$//g' \ -e 's/^\([^#=]*\)=\([^"]*\)$/if [ "x$\1" = "x" ]; then \1="\2"; fi/' \ config/Makefile > config/config.sh diff --git a/build/mkmyocamlbuild_config.sh b/build/mkmyocamlbuild_config.sh index 158e13d5e..1a7a19441 100755 --- a/build/mkmyocamlbuild_config.sh +++ b/build/mkmyocamlbuild_config.sh @@ -4,6 +4,7 @@ cd `dirname $0`/.. sed \ + -e 's/^FLEX.*$//g' \ -e 's/^#ml \(.*\)/\1/' \ -e 's/^\(#.*\)$/(* \1 *)/' \ -e 's/^\(.*\$([0-9]).*\)$/(* \1 *)/' \ diff --git a/bytecomp/bytelink.ml b/bytecomp/bytelink.ml index b9aa3dd23..826173c0f 100644 --- a/bytecomp/bytelink.ml +++ b/bytecomp/bytelink.ml @@ -45,13 +45,15 @@ let lib_ccopts = ref [] let lib_dllibs = ref [] let add_ccobjs l = - if not !Clflags.no_auto_link - && String.length !Clflags.use_runtime = 0 + if not !Clflags.no_auto_link then begin + if + String.length !Clflags.use_runtime = 0 && String.length !Clflags.use_prims = 0 - then begin - if l.lib_custom then Clflags.custom_runtime := true; - lib_ccobjs := l.lib_ccobjs @ !lib_ccobjs; - lib_ccopts := l.lib_ccopts @ !lib_ccopts; + then begin + if l.lib_custom then Clflags.custom_runtime := true; + lib_ccobjs := l.lib_ccobjs @ !lib_ccobjs; + lib_ccopts := l.lib_ccopts @ !lib_ccopts; + end; lib_dllibs := l.lib_dllibs @ !lib_dllibs end @@ -429,10 +431,27 @@ void caml_startup(char ** argv) (* Build a custom runtime *) let build_custom_runtime prim_name exec_name = - match Config.ccomp_type with - "cc" -> + match Config.system, Config.ccomp_type with + | ("win32"|"mingw"|"cygwin"),_ -> + (* TODO: load path? *) Ccomp.command (Printf.sprintf + "flexlink -chain %s -merge-manifest -exe -o %s %s %s %s %s %s %s" + (match Config.system with + | "win32" -> "msvc" + | "mingw" -> "mingw" + | "cygwin" -> "cygwin" + | _ -> assert false) + (Filename.quote exec_name) + (Clflags.std_include_flag "-I ") + prim_name + (Ccomp.quote_files (List.rev !Clflags.ccobjs)) + (Filename.quote "-lcamlrun") + Config.bytecomp_c_libraries + (Ccomp.make_link_options !Clflags.ccopts)) + | _,"cc" -> + Ccomp.command + (Printf.sprintf "%s -o %s %s %s %s %s %s -lcamlrun %s" !Clflags.c_linker (Filename.quote exec_name) @@ -444,27 +463,6 @@ let build_custom_runtime prim_name exec_name = !load_path)) (Ccomp.quote_files (List.rev !Clflags.ccobjs)) Config.bytecomp_c_libraries) - | "msvc" -> - let retcode = - Ccomp.command - (Printf.sprintf - "%s /Fe%s %s %s %s %s %s %s" - !Clflags.c_linker - (Filename.quote exec_name) - (Clflags.std_include_flag "-I") - prim_name - (Ccomp.quote_files - (List.rev_map Ccomp.expand_libname !Clflags.ccobjs)) - (Filename.quote (Ccomp.expand_libname "-lcamlrun")) - Config.bytecomp_c_libraries - (Ccomp.make_link_options !Clflags.ccopts)) in - (* C compiler doesn't clean up after itself. Note that the .obj - file is created in the current working directory. *) - remove_file - (Filename.chop_suffix (Filename.basename prim_name) ".c" ^ ".obj"); - if retcode <> 0 - then retcode - else Ccomp.merge_manifest exec_name | _ -> assert false let append_bytecode_and_cleanup bytecode_name exec_name prim_name = diff --git a/bytecomp/translmod.ml b/bytecomp/translmod.ml index 00d08e475..9125d8e7e 100644 --- a/bytecomp/translmod.ml +++ b/bytecomp/translmod.ml @@ -361,9 +361,21 @@ let transl_implementation module_name (str, cc) = "map" is a table from defined idents to (pos in global block, coercion). "prim" is a list of (pos in global block, primitive declaration). *) +let transl_store_subst = ref Ident.empty + (** In the native toplevel, this reference is threaded through successive + calls of transl_store_structure *) + +let nat_toplevel_name id = + try match Ident.find_same id !transl_store_subst with + | Lprim(Pfield pos, [Lprim(Pgetglobal glob, [])]) -> (glob,pos) + | _ -> raise Not_found + with Not_found -> + fatal_error("Translmod.nat_toplevel_name: " ^ Ident.unique_name id) + let transl_store_structure glob map prims str = let rec transl_store subst = function [] -> + transl_store_subst := subst; lambda_unit | Tstr_eval expr :: rem -> Lsequence(subst_lambda subst (transl_exp expr), @@ -468,7 +480,7 @@ let transl_store_structure glob map prims str = [Lprim(Pgetglobal glob, []); transl_primitive prim]), cont) - in List.fold_right store_primitive prims (transl_store Ident.empty str) + in List.fold_right store_primitive prims (transl_store !transl_store_subst str) (* Build the list of value identifiers defined by a toplevel structure (excluding primitive declarations). *) @@ -530,15 +542,29 @@ let build_ident_map restr idlist = (* Compile an implementation using transl_store_structure (for the native-code compiler). *) -let transl_store_implementation module_name (str, restr) = +let transl_store_gen module_name (str, restr) topl = reset_labels (); primitive_declarations := []; let module_id = Ident.create_persistent module_name in let (map, prims, size) = build_ident_map restr (defined_idents str) in - transl_store_label_init module_id size - (transl_store_structure module_id map prims) str + let f = function + | [ Tstr_eval expr ] when topl -> + assert (size = 0); + subst_lambda !transl_store_subst (transl_exp expr) + | str -> transl_store_structure module_id map prims str in + transl_store_label_init module_id size f str (*size, transl_label_init (transl_store_structure module_id map prims str)*) +let transl_store_phrases module_name str = + transl_store_gen module_name (str,Tcoerce_none) true + +let transl_store_implementation module_name (str, restr) = + let s = !transl_store_subst in + transl_store_subst := Ident.empty; + let r = transl_store_gen module_name (str, restr) false in + transl_store_subst := s; + r + (* Compile a toplevel phrase *) let toploop_ident = Ident.create_persistent "Toploop" diff --git a/bytecomp/translmod.mli b/bytecomp/translmod.mli index 7a2aa5a0f..b7cf6d5dd 100644 --- a/bytecomp/translmod.mli +++ b/bytecomp/translmod.mli @@ -19,6 +19,7 @@ open Typedtree open Lambda val transl_implementation: string -> structure * module_coercion -> lambda +val transl_store_phrases: string -> structure -> int * lambda val transl_store_implementation: string -> structure * module_coercion -> int * lambda val transl_toplevel_definition: structure -> lambda @@ -28,6 +29,7 @@ val transl_store_package: Ident.t option list -> Ident.t -> module_coercion -> int * lambda val toplevel_name: Ident.t -> string +val nat_toplevel_name: Ident.t -> Ident.t * int val primitive_declarations: string list ref diff --git a/byterun/Makefile b/byterun/Makefile index f5ee4feed..0381aef10 100644 --- a/byterun/Makefile +++ b/byterun/Makefile @@ -13,97 +13,30 @@ # $Id$ -include ../config/Makefile +include Makefile.common -CC=$(BYTECC) -CFLAGS=-DCAML_NAME_SPACE -O $(BYTECCCOMPOPTS) +CFLAGS=-DCAML_NAME_SPACE -O $(BYTECCCOMPOPTS) $(FLEXLINK) DFLAGS=-DCAML_NAME_SPACE -g -DDEBUG $(BYTECCCOMPOPTS) -OBJS=interp.o misc.o stacks.o fix_code.o startup.o main.o \ - freelist.o major_gc.o minor_gc.o memory.o alloc.o roots.o globroots.o \ - fail.o signals.o signals_byt.o printexc.o backtrace.o \ - compare.o ints.o floats.o str.o array.o io.o extern.o intern.o \ - hash.o sys.o meta.o parsing.o gc_ctrl.o terminfo.o md5.o obj.o \ - lexing.o callback.o debugger.o weak.o compact.o finalise.o custom.o \ - dynlink.o unix.o - +OBJS=$(COMMONOBJS) unix.o main.o DOBJS=$(OBJS:.o=.d.o) instrtrace.d.o -PRIMS=alloc.c array.c compare.c extern.c floats.c gc_ctrl.c hash.c \ - intern.c interp.c ints.c io.c lexing.c md5.c meta.c obj.c parsing.c \ - signals.c str.c sys.c terminfo.c callback.c weak.c finalise.c stacks.c \ - dynlink.c - -PUBLIC_INCLUDES=alloc.h callback.h config.h custom.h fail.h intext.h \ - memory.h misc.h mlvalues.h printexc.h signals.h compatibility.h - -all: ocamlrun$(EXE) ld.conf - ocamlrun$(EXE): libcamlrun.a prims.o - $(BYTECC) $(BYTECCCOMPOPTS) $(BYTECCLINKOPTS) -o ocamlrun$(EXE) \ - prims.o libcamlrun.a $(BYTECCLIBS) + $(call MKEXE,ocamlrun$(EXE),main.o prims.o libcamlrun.a $(BYTECCLIBS), \ + $(BYTECCCOMPOPTS) $(BYTECCLINKOPTS)) ocamlrund$(EXE): libcamlrund.a prims.o $(BYTECC) -g $(BYTECCCOMPOPTS) $(BYTECCLINKOPTS) -o ocamlrund$(EXE) \ prims.o libcamlrund.a $(BYTECCLIBS) -install: - cp ocamlrun$(EXE) $(BINDIR)/ocamlrun$(EXE) - cp libcamlrun.a $(LIBDIR)/libcamlrun.a - cd $(LIBDIR); $(RANLIB) libcamlrun.a - if test -d $(LIBDIR)/caml; then : ; else mkdir $(LIBDIR)/caml; fi - for i in $(PUBLIC_INCLUDES); do \ - sed -f ../tools/cleanup-header $$i > $(LIBDIR)/caml/$$i; \ - done - cp ld.conf $(LIBDIR)/ld.conf - -ld.conf: ../config/Makefile - echo "$(STUBLIBDIR)" >ld.conf - echo "$(LIBDIR)" >>ld.conf +libcamlrun.$(A): $(OBJS) + $(call MKLIB,libcamlrun.$(A),$(OBJS)) -libcamlrun.a: $(OBJS) - ar rc libcamlrun.a $(OBJS) - $(RANLIB) libcamlrun.a libcamlrund.a: $(DOBJS) ar rc libcamlrund.a $(DOBJS) $(RANLIB) libcamlrund.a -clean: - rm -f ocamlrun$(EXE) ocamlrund$(EXE) *.o lib*.a - rm -f primitives prims.c opnames.h jumptbl.h ld.conf - rm -f version.h - -primitives : $(PRIMS) - sed -n -e "s/CAMLprim value \([a-z0-9_][a-z0-9_]*\).*/\1/p" \ - $(PRIMS) > primitives - -prims.c : primitives - (echo '#include "mlvalues.h"'; \ - echo '#include "prims.h"'; \ - sed -e 's/.*/extern value &();/' primitives; \ - echo 'c_primitive caml_builtin_cprim[] = {'; \ - sed -e 's/.*/ &,/' primitives; \ - echo ' 0 };'; \ - echo 'char * caml_names_of_builtin_cprim[] = {'; \ - sed -e 's/.*/ "&",/' primitives; \ - echo ' 0 };') > prims.c - -opnames.h : instruct.h - sed -e '/\/\*/d' \ - -e '/^#/d' \ - -e 's/enum /char * names_of_/' \ - -e 's/{$$/[] = {/' \ - -e 's/\([[:upper:]][[:upper:]_0-9]*\)/"\1"/g' instruct.h > opnames.h - -# jumptbl.h is required only if you have GCC 2.0 or later -jumptbl.h : instruct.h - sed -n -e '/^ /s/ \([A-Z]\)/ \&\&lbl_\1/gp' \ - -e '/^}/q' instruct.h > jumptbl.h - -version.h : ../VERSION - echo "#define OCAML_VERSION \"`head -1 ../VERSION`\"" >version.h - .SUFFIXES: .d.o .c.d.o: diff --git a/byterun/Makefile.common b/byterun/Makefile.common new file mode 100755 index 000000000..67d0fc162 --- /dev/null +++ b/byterun/Makefile.common @@ -0,0 +1,90 @@ +######################################################################### +# # +# Objective Caml # +# # +# Xavier Leroy, projet Cristal, INRIA Rocquencourt # +# # +# Copyright 1999 Institut National de Recherche en Informatique et # +# en Automatique. All rights reserved. This file is distributed # +# under the terms of the GNU Library General Public License, with # +# the special exception on linking described in file ../LICENSE. # +# # +######################################################################### + +# $Id$ + +include ../config/Makefile + +CC=$(BYTECC) + +COMMONOBJS=\ + interp.o misc.o stacks.o fix_code.o startup.o \ + freelist.o major_gc.o minor_gc.o memory.o alloc.o roots.o globroots.o \ + fail.o signals.o signals_byt.o printexc.o backtrace.o \ + compare.o ints.o floats.o str.o array.o io.o extern.o intern.o \ + hash.o sys.o meta.o parsing.o gc_ctrl.o terminfo.o md5.o obj.o \ + lexing.o callback.o debugger.o weak.o compact.o finalise.o custom.o \ + dynlink.o + +PRIMS=\ + alloc.c array.c compare.c extern.c floats.c gc_ctrl.c hash.c \ + intern.c interp.c ints.c io.c lexing.c md5.c meta.c obj.c parsing.c \ + signals.c str.c sys.c terminfo.c callback.c weak.c finalise.c stacks.c \ + dynlink.c + +PUBLIC_INCLUDES=\ + alloc.h callback.h config.h custom.h fail.h intext.h \ + memory.h misc.h mlvalues.h printexc.h signals.h compatibility.h + + +all: ocamlrun$(EXE) ld.conf libcamlrun.$(A) + +ld.conf: ../config/Makefile + echo "$(STUBLIBDIR)" >ld.conf + echo "$(LIBDIR)" >>ld.conf + +install: + cp ocamlrun$(EXE) $(BINDIR)/ocamlrun$(EXE) + cp libcamlrun.$(A) $(LIBDIR)/libcamlrun.$(A) + cd $(LIBDIR); $(RANLIB) libcamlrun.$(A) + if test -d $(LIBDIR)/caml; then : ; else mkdir $(LIBDIR)/caml; fi + for i in $(PUBLIC_INCLUDES); do \ + sed -f ../tools/cleanup-header $$i > $(LIBDIR)/caml/$$i; \ + done + cp ld.conf $(LIBDIR)/ld.conf + + +primitives : $(PRIMS) + sed -n -e "s/CAMLprim value \([a-z0-9_][a-z0-9_]*\).*/\1/p" \ + $(PRIMS) > primitives + +prims.c : primitives + (echo '#include "mlvalues.h"'; \ + echo '#include "prims.h"'; \ + sed -e 's/.*/extern value &();/' primitives; \ + echo 'c_primitive caml_builtin_cprim[] = {'; \ + sed -e 's/.*/ &,/' primitives; \ + echo ' 0 };'; \ + echo 'char * caml_names_of_builtin_cprim[] = {'; \ + sed -e 's/.*/ "&",/' primitives; \ + echo ' 0 };') > prims.c + +opnames.h : instruct.h + sed -e '/\/\*/d' \ + -e '/^#/d' \ + -e 's/enum /char * names_of_/' \ + -e 's/{$$/[] = {/' \ + -e 's/\([[:upper:]][[:upper:]_0-9]*\)/"\1"/g' instruct.h > opnames.h + +# jumptbl.h is required only if you have GCC 2.0 or later +jumptbl.h : instruct.h + sed -n -e '/^ /s/ \([A-Z]\)/ \&\&lbl_\1/gp' \ + -e '/^}/q' instruct.h > jumptbl.h + +version.h : ../VERSION + echo "#define OCAML_VERSION \"`head -1 ../VERSION`\"" >version.h + +clean: + rm -f ocamlrun$(EXE) ocamlrund$(EXE) *.$(O) *.$(A) + rm -f primitives prims.c opnames.h jumptbl.h ld.conf + rm -f version.h diff --git a/byterun/Makefile.nt b/byterun/Makefile.nt index aa31b44d8..ce1f69316 100644 --- a/byterun/Makefile.nt +++ b/byterun/Makefile.nt @@ -13,105 +13,42 @@ # $Id$ -include ../config/Makefile +include Makefile.common -CC=$(BYTECC) -CFLAGS=-DIN_OCAMLRUN -DOCAML_STDLIB_DIR='"$(LIBDIR)"' +CFLAGS=-DOCAML_STDLIB_DIR='"$(LIBDIR)"' $(FLEXLINK) -COMMONOBJS=interp.o misc.o stacks.o fix_code.o startup.o \ - fail.o signals.o signals_byt.o freelist.o major_gc.o minor_gc.o \ - memory.o alloc.o roots.o compare.o ints.o floats.o \ - str.o array.o io.o extern.o intern.o hash.o sys.o \ - meta.o parsing.o gc_ctrl.o terminfo.o md5.o obj.o lexing.o \ - win32.o printexc.o callback.o debugger.o weak.o compact.o \ - finalise.o custom.o backtrace.o globroots.o dynlink.o +DBGO=d.$(O) +OBJS=$(COMMONOBJS:.o=.$(O)) win32.$(O) +DOBJS=$(COMMONOBJS:.o=.$(DBGO)) win32.$(DBGO) prims.$(DBGO) instrtrace.$(DBGO) -DOBJS=$(COMMONOBJS:.o=.$(DO)) prims.$(DO) -SOBJS=$(COMMONOBJS:.o=.$(SO)) main.$(SO) -DBGOBJS=$(COMMONOBJS:.o=.$(DBGO)) prims.$(DBGO) main.$(DBGO) instrtrace.$(DBGO) +ocamlrun$(EXE): libcamlrun.$(A) prims.$(O) main.$(O) + $(call MKEXE,ocamlrun$(EXE),main.$(O) prims.$(O) libcamlrun.$(A)) +ocamlrund$(EXE): libcamlrund.$(A) prims.$(O) main.$(O) + $(call MKEXE,ocamlrun$(EXE),$(BYTECCDBGCOMPOPTS) main.$(O) prims.$(O) libcamlrund.$(A)) -PRIMS=alloc.c array.c compare.c extern.c floats.c gc_ctrl.c hash.c \ - intern.c interp.c ints.c io.c lexing.c md5.c meta.c obj.c parsing.c \ - signals.c str.c sys.c terminfo.c callback.c weak.c finalise.c stacks.c \ - dynlink.c +libcamlrun.$(A): $(OBJS) + $(call MKLIB,libcamlrun.$(A),$(OBJS)) -PUBLIC_INCLUDES=alloc.h callback.h config.h custom.h fail.h intext.h \ - memory.h misc.h mlvalues.h printexc.h signals.h compatibility.h +libcamlrund.$(A): $(DOBJS) + $(call MKLIB,libcamlrund.$(A),$(DOBJS)) -all: ocamlrun.exe libcamlrun.$(A) +.SUFFIXES: .$(O) .$(DBGO) -ocamlrun.exe: ocamlrun.dll main.$(DO) - $(call MKEXE,ocamlrun.exe,main.$(DO) ocamlrun.$(A)) - -ocamlrun.dll: $(DOBJS) - $(call MKDLL,ocamlrun.dll,ocamlrun.$(A),$(DOBJS) $(BYTECCLIBS)) - -libcamlrun.$(A): $(SOBJS) - $(call MKLIB,libcamlrun.$(A),$(SOBJS)) - -ocamlrund.exe: opnames.h $(DBGOBJS) - $(call MKEXE,ocamlrund.exe,$(BYTECCDBGCOMPOPTS) $(DBGOBJS)) - -install: - cp ocamlrun.exe $(BINDIR)/ocamlrun.exe - cp ocamlrun.dll $(BINDIR)/ocamlrun.dll - cp ocamlrun.$(A) $(LIBDIR)/ocamlrun.$(A) - cp libcamlrun.$(A) $(LIBDIR)/libcamlrun.$(A) - test -d $(LIBDIR)/caml || mkdir -p $(LIBDIR)/caml - for i in $(PUBLIC_INCLUDES); do sed -f ../tools/cleanup-header $$i > $(LIBDIR)/caml/$$i; done - -clean: - rm -f *.exe *.dll *.$(O) *.$(A) - rm -f primitives prims.c opnames.h jumptbl.h - -primitives : $(PRIMS) - sed -n -e "s/CAMLprim value \([a-z0-9_][a-z0-9_]*\).*/\1/p" \ - $(PRIMS) > primitives - -prims.c : primitives - (echo '#include "mlvalues.h"'; \ - echo '#include "prims.h"'; \ - sed -e 's/.*/extern value &();/' primitives; \ - echo 'c_primitive caml_builtin_cprim[] = {'; \ - sed -e 's/.*/ &,/' primitives; \ - echo ' 0 };'; \ - echo 'char * caml_names_of_builtin_cprim[] = {'; \ - sed -e 's/.*/ "&",/' primitives; \ - echo ' 0 };') > prims.c - -opnames.h : instruct.h - sed -e '/\/\*/d' \ - -e '/^#/d' \ - -e 's/enum /char * names_of_/' \ - -e 's/{$$/[] = {/' \ - -e 's/\([[:upper:]][[:upper:]_0-9]*\)/"\1"/g' instruct.h > opnames.h - -# jumptbl.h is required only if you have GCC 2.0 or later -jumptbl.h : instruct.h - sed -n -e "/^ /s/ \([A-Z]\)/ \&\&lbl_\1/gp" \ - -e "/^}/q" instruct.h > jumptbl.h - -version.h : ../VERSION - echo "#define OCAML_VERSION \"`head -1 ../VERSION`\"" >version.h - -main.$(DO): main.c - $(CC) $(DLLCCCOMPOPTS) -c main.c - mv main.$(O) main.$(DO) - -.SUFFIXES: .$(DO) .$(SO) .$(DBGO) - -.c.$(DO): - $(CC) $(CFLAGS) $(DLLCCCOMPOPTS) -c $< - mv $*.$(O) $*.$(DO) -.c.$(SO): +.c.$(O): $(CC) $(CFLAGS) $(BYTECCCOMPOPTS) -c $< - mv $*.$(O) $*.$(SO) + .c.$(DBGO): $(CC) $(CFLAGS) $(BYTECCDBGCOMPOPTS) -c $< mv $*.$(O) $*.$(DBGO) .depend.nt: .depend - sed -e '/\.d\.o/q' -e 's/^\(.*\)\.o:/\1.$$(DO) \1.$$(SO) \1.$$(DBGO):/' .depend > .depend.nt + rm -f .depend.win32 + echo "win32.o: win32.c fail.h compatibility.h misc.h config.h \\" >> .depend.win32 + echo " ../config/m.h ../config/s.h mlvalues.h memory.h gc.h \\" >> .depend.win32 + echo " major_gc.h freelist.h minor_gc.h osdeps.h signals.h" >> .depend.win32 + cat .depend >> .depend.win32 + sed -e '/\.d\.o/q' -e 's/^\(.*\)\.o:/\1.$$(O) \1.$$(DBGO):/' .depend.win32 > .depend.nt + rm -f .depend.win32 include .depend.nt diff --git a/byterun/array.c b/byterun/array.c index 468fe444a..a9902b7c6 100644 --- a/byterun/array.c +++ b/byterun/array.c @@ -139,7 +139,7 @@ CAMLprim value caml_make_vect(value len, value init) res = Atom(0); } else if (Is_block(init) - && (Is_atom(init) || Is_young(init) || Is_in_heap(init)) + && (Is_young(init) || Is_in_heap(init) || Is_atom(init)) && Tag_val(init) == Double_tag) { d = Double_val(init); wsize = size * Double_wosize; @@ -181,7 +181,7 @@ CAMLprim value caml_make_array(value init) } else { v = Field(init, 0); if (Is_long(v) - || (!Is_atom(v) && !Is_young(v) && !Is_in_heap(v)) + || (!Is_young(v) && !Is_in_heap(v) && !Is_atom(v)) || Tag_val(v) != Double_tag) { CAMLreturn (init); } else { diff --git a/byterun/compare.c b/byterun/compare.c index 4cd6df29e..f6a18b1d4 100644 --- a/byterun/compare.c +++ b/byterun/compare.c @@ -104,7 +104,7 @@ static intnat compare_val(value v1, value v2, int total) if (Is_long(v2)) return Long_val(v1) - Long_val(v2); /* Subtraction above cannot overflow and cannot result in UNORDERED */ - if ((Is_atom(v2) || Is_young(v2) || Is_in_heap(v2)) && + if ((Is_young(v2) || Is_in_heap(v2) || Is_atom(v2)) && Tag_val(v2) == Forward_tag) { v2 = Forward_val(v2); continue; @@ -112,7 +112,7 @@ static intnat compare_val(value v1, value v2, int total) return LESS; /* v1 long < v2 block */ } if (Is_long(v2)) { - if ((Is_atom(v1) || Is_young(v1) || Is_in_heap(v1)) && + if ((Is_young(v1) || Is_in_heap(v1) || Is_atom(v1)) && Tag_val(v1) == Forward_tag) { v1 = Forward_val(v1); continue; @@ -122,8 +122,8 @@ static intnat compare_val(value v1, value v2, int total) /* If one of the objects is outside the heap (but is not an atom), use address comparison. Since both addresses are 2-aligned, shift lsb off to avoid overflow in subtraction. */ - if ((!Is_atom(v1) && !Is_young(v1) && !Is_in_heap(v1)) || - (!Is_atom(v2) && !Is_young(v2) && !Is_in_heap(v2))) { + if ((!Is_young(v1) && !Is_in_heap(v1) && !Is_atom(v1)) || + (!Is_young(v2) && !Is_in_heap(v2) && !Is_atom(v2))) { if (v1 == v2) goto next_item; return (v1 >> 1) - (v2 >> 1); /* Subtraction above cannot result in UNORDERED */ diff --git a/byterun/hash.c b/byterun/hash.c index 2b8a23575..feb4619d1 100644 --- a/byterun/hash.c +++ b/byterun/hash.c @@ -62,7 +62,7 @@ static void hash_aux(value obj) We can inspect the block contents. */ Assert (Is_block (obj)); - if (Is_atom(obj) || Is_young(obj) || Is_in_heap(obj)) { + if (Is_young(obj) || Is_in_heap(obj) || Is_atom(obj)) { tag = Tag_val(obj); switch (tag) { case String_tag: diff --git a/byterun/misc.h b/byterun/misc.h index a1b2b9260..afc0aef95 100644 --- a/byterun/misc.h +++ b/byterun/misc.h @@ -49,19 +49,9 @@ typedef char * addr; /* Export control (to mark primitives and to handle Windows DLL) */ -#if defined(_WIN32) && defined(CAML_DLL) -# define CAMLexport __declspec(dllexport) -# define CAMLprim __declspec(dllexport) -# if defined(IN_OCAMLRUN) -# define CAMLextern __declspec(dllexport) extern -# else -# define CAMLextern __declspec(dllimport) extern -# endif -#else -# define CAMLexport -# define CAMLprim -# define CAMLextern extern -#endif +#define CAMLexport +#define CAMLprim +#define CAMLextern extern /* Assertions */ diff --git a/byterun/mlvalues.h b/byterun/mlvalues.h index 113590b0e..4d8a690ba 100644 --- a/byterun/mlvalues.h +++ b/byterun/mlvalues.h @@ -278,10 +278,12 @@ CAMLextern header_t caml_atom_table[]; #define Is_atom(v) ((v) >= Atom(0) && (v) <= Atom(255)) #else CAMLextern char * caml_static_data_start, * caml_static_data_end; +CAMLextern int caml_is_in_data(void *); #define Is_atom(v) \ - ((((char *)(v) >= caml_static_data_start \ - && (char *)(v) < caml_static_data_end) \ - || ((v) >= Atom(0) && (v) <= Atom(255)))) + ( ( (char *)(v) >= caml_static_data_start \ + &&(char *)(v) < caml_static_data_end ) \ + || ((v) >= Atom(0) && (v) <= Atom(255)) \ + || (caml_is_in_data((void *)v)) ) #endif /* Booleans are integers 0 or 1 */ diff --git a/byterun/osdeps.h b/byterun/osdeps.h index 2dababedf..0c0c71238 100644 --- a/byterun/osdeps.h +++ b/byterun/osdeps.h @@ -51,6 +51,8 @@ extern void caml_dlclose(void * handle); Return [NULL] if not found, or symbol value if found. */ extern void * caml_dlsym(void * handle, char * name); +extern void * caml_globalsym(char * name); + /* Return an error message describing the most recent dynlink failure. */ extern char * caml_dlerror(void); diff --git a/byterun/unix.c b/byterun/unix.c index 3b8bb22e6..7343a0957 100644 --- a/byterun/unix.c +++ b/byterun/unix.c @@ -25,6 +25,8 @@ #ifdef SUPPORT_DYNAMIC_LINKING #ifdef HAS_NSLINKMODULE #include <mach-o/dyld.h> +#elif defined(__CYGWIN32__) +#include "flexdll.h" #else #include <dlfcn.h> #endif @@ -263,6 +265,11 @@ void * caml_dlsym(void * handle, char * name) else return NULL; } +void * caml_globalsym(char * name) +{ + return NULL; +} + char * caml_dlerror(void) { NSLinkEditErrors c; @@ -273,6 +280,36 @@ char * caml_dlerror(void) return (char *) errorString; } +#elif defined(__CYGWIN32__) +/* Use flexdll */ + +void * caml_dlopen(char * libname, int for_execution) +{ + int flags = FLEXDLL_RTLD_GLOBAL; + if (!for_execution) flags |= FLEXDLL_RTLD_NOEXEC; + return flexdll_dlopen(libname, flags); +} + +void caml_dlclose(void * handle) +{ + flexdll_dlclose(handle); +} + +void * caml_dlsym(void * handle, char * name) +{ + return flexdll_dlsym(handle, name); +} + +void * caml_globalsym(char * name) +{ + return flexdll_dlsym(flexdll_dlopen(NULL,0), name); +} + +char * caml_dlerror(void) +{ + return flexdll_dlerror(); +} + #else /* Use normal dlopen */ @@ -304,6 +341,11 @@ void * caml_dlsym(void * handle, char * name) return dlsym(handle, name); } +void * caml_globalsym(char * name) +{ + return caml_dlsym(dlopen(NULL,RTLD_GLOBAL), name); +} + char * caml_dlerror(void) { return dlerror(); @@ -326,6 +368,11 @@ void * caml_dlsym(void * handle, char * name) return NULL; } +void * caml_globalsym(char * name) +{ + return NULL; +} + char * caml_dlerror(void) { return "dynamic loading not supported on this platform"; diff --git a/byterun/win32.c b/byterun/win32.c index c2ffed677..f61e1d69e 100644 --- a/byterun/win32.c +++ b/byterun/win32.c @@ -31,6 +31,9 @@ #include "misc.h" #include "osdeps.h" #include "signals.h" +#include "sys.h" + +#include "flexdll.h" #ifndef S_ISREG #define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG) @@ -123,40 +126,35 @@ char * caml_search_dll_in_path(struct ext_table * path, char * name) void * caml_dlopen(char * libname, int for_execution) { - HMODULE m; - m = LoadLibraryEx(libname, NULL, - for_execution ? 0 : DONT_RESOLVE_DLL_REFERENCES); - /* Under Win 95/98/ME, LoadLibraryEx can fail in cases where LoadLibrary - would succeed. Just try again with LoadLibrary for good measure. */ - if (m == NULL) m = LoadLibrary(libname); - return (void *) m; + void *handle; + int flags = FLEXDLL_RTLD_GLOBAL; + if (!for_execution) flags |= FLEXDLL_RTLD_NOEXEC; + handle = flexdll_dlopen(libname, flags); + if ((handle != NULL) && ((caml_verb_gc & 0x100) != 0)) { + flexdll_dump_exports(handle); + fflush(stdout); + } + return handle; } void caml_dlclose(void * handle) { - FreeLibrary((HMODULE) handle); + flexdll_dlclose(handle); } void * caml_dlsym(void * handle, char * name) { - return (void *) GetProcAddress((HMODULE) handle, name); + return flexdll_dlsym(handle, name); +} + +void * caml_globalsym(char * name) +{ + return flexdll_dlsym(flexdll_dlopen(NULL,0), name); } char * caml_dlerror(void) { - static char dlerror_buffer[256]; - DWORD msglen = - FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, /* message source */ - GetLastError(), /* error number */ - 0, /* default language */ - dlerror_buffer, /* destination */ - sizeof(dlerror_buffer), /* size of destination */ - NULL); /* no inserts */ - if (msglen == 0) - return "unknown error"; - else - return dlerror_buffer; + return flexdll_dlerror(); } /* Proper emulation of signal(), including ctrl-C and ctrl-break */ @@ -486,10 +484,12 @@ static void caml_reset_stack (void *faulting_address) } extern char * caml_code_area_start, * caml_code_area_end; +CAMLextern int caml_is_in_code(void *); #define In_code_area(pc) \ - ((char *)(pc) >= caml_code_area_start && \ - (char *)(pc) <= caml_code_area_end) + ( ((char *)(pc) >= caml_code_area_start && \ + (char *)(pc) <= caml_code_area_end) \ + || caml_is_in_code((void *)(pc)) ) static LONG CALLBACK caml_UnhandledExceptionFilter (EXCEPTION_POINTERS* exn_info) diff --git a/camlp4/Camlp4/Sig.ml b/camlp4/Camlp4/Sig.ml index afa425ed2..5f1500a5a 100644 --- a/camlp4/Camlp4/Sig.ml +++ b/camlp4/Camlp4/Sig.ml @@ -876,6 +876,9 @@ module type DynLoader = sig (** [find_in_path f] Returns the full path of the file [f] if [f] is in the current load path, raises [Not_found] otherwise. *) value find_in_path : t -> string -> string; + + (** [is_native] [True] if we are in native code, [False] for bytecode. *) + value is_native : bool; end; module Grammar = struct diff --git a/camlp4/Camlp4/Struct/DynLoader.ml b/camlp4/Camlp4/Struct/DynLoader.ml index 715a0d764..5fbd4fbb4 100644 --- a/camlp4/Camlp4/Struct/DynLoader.ml +++ b/camlp4/Camlp4/Struct/DynLoader.ml @@ -61,9 +61,7 @@ value find_in_path x name = value load = let _initialized = ref False in fun _path file -> - IFDEF OPT THEN - raise (Error file "native-code program cannot do a dynamic load") - ELSE do { + do { if not _initialized.val then try do { Dynlink.init (); @@ -80,5 +78,7 @@ value load = in try Dynlink.loadfile fname with [ Dynlink.Error e -> raise (Error fname (Dynlink.error_message e)) ] - } - END; + }; + + +value is_native = Dynlink.is_native; diff --git a/camlp4/Camlp4Bin.ml b/camlp4/Camlp4Bin.ml index 9464e65c4..48d39f4ca 100644 --- a/camlp4/Camlp4Bin.ml +++ b/camlp4/Camlp4Bin.ml @@ -48,6 +48,10 @@ value loaded_modules = ref SSet.empty; value add_to_loaded_modules name = loaded_modules.val := SSet.add name loaded_modules.val; +value (objext,libext) = + if DynLoader.is_native then (".cmxs",".cmxs") + else (".cmo",".cma"); + value rewrite_and_load n x = let dyn_loader = dyn_loader.val () in let find_in_path = DynLoader.find_in_path dyn_loader in @@ -59,7 +63,7 @@ value rewrite_and_load n x = if SSet.mem n loaded_modules.val || List.mem n Register.loaded_modules.val then () else begin add_to_loaded_modules n; - DynLoader.load dyn_loader (n ^ ".cmo"); + DynLoader.load dyn_loader (n ^ objext); end end in do { @@ -97,7 +101,7 @@ value rewrite_and_load n x = | ("Printers"|"", "a" | "auto" | "camlp4autoprinter.cmo") -> load ["Camlp4AutoPrinter"] | _ -> - let y = "Camlp4"^n^"/"^x^".cmo" in + let y = "Camlp4"^n^"/"^x^objext in real_load (try find_in_path y with [ Not_found -> x ]) ]; rcall_callback.val (); }; @@ -172,7 +176,9 @@ Usage: camlp4 [load-options] [--] [other-options] Options: <file>.ml Parse this implementation file <file>.mli Parse this interface file -<file>.(cmo|cma) Load this module inside the Camlp4 core@."; +<file>.%s Load this module inside the Camlp4 core@." +(if DynLoader.is_native then "cmx " else "(cmo|cma)") +; Options.print_usage_list ini_sl; (* loop (ini_sl @ ext_sl) where rec loop = fun @@ -276,8 +282,8 @@ value anon_fun name = input_file (if Filename.check_suffix name ".mli" then Intf name else if Filename.check_suffix name ".ml" then Impl name - else if Filename.check_suffix name ".cmo" then ModuleImpl name - else if Filename.check_suffix name ".cma" then ModuleImpl name + else if Filename.check_suffix name objext then ModuleImpl name + else if Filename.check_suffix name libext then ModuleImpl name else raise (Arg.Bad ("don't know what to do with " ^ name))); value main argv = diff --git a/config/Makefile.mingw b/config/Makefile.mingw index 2fdfde300..00acc8b62 100644 --- a/config/Makefile.mingw +++ b/config/Makefile.mingw @@ -70,6 +70,7 @@ DEBUGGER= CC_PROFILE= SYSTHREAD_SUPPORT=true EXTRALIBS= +CMXS=cmxs ########## Configuration for the bytecode compiler @@ -92,13 +93,17 @@ NATIVECCLIBS= ### How to invoke the C preprocessor CPP=$(BYTECC) -E +### Path to the FlexDLL includes +FLEXDIR=$(shell flexlink -where) +FLEXLINK=-I"$(FLEXDIR)" + ### How to build an EXE -MKEXE=$(BYTECC) -o $(1) $(2) -#ml let mkexe out files opts = Printf.sprintf "%s -o %s %s %s" bytecc out opts files;; +MKEXE=flexlink -merge-manifest -chain mingw -exe -o $(1) $(2) -- $(3) +#ml let mkexe out files opts = Printf.sprintf "flexlink -merge-manifest -chain mingw -exe -o %s %s -- %s" out files opts;; ### How to build a DLL -MKDLL=$(BYTECC) -shared -o $(1) -Wl,--out-implib,$(2) $(3) -#ml let mkdll out implib files opts = Printf.sprintf "%s -shared -o %s -Wl,--out-implib,%s %s %s" bytecc out implib files opts;; +MKDLL=flexlink -merge-manifest -chain mingw -o $(1) $(3) -- $(4) +#ml let mkdll out implib files opts = Printf.sprintf "flexlink -merge-manifest -chain mingw -o %s %s -- %s" out files opts;; ### How to build a static library MKLIB=rm -f $(1); ar rcs $(1) $(2) @@ -138,7 +143,7 @@ PACKLD=$(PARTIALLD) -o #there must be a space after this '-o' ############# Configuration for the contributed libraries -OTHERLIBRARIES=win32unix systhreads str num win32graph dynlink bigarray labltk +OTHERLIBRARIES=win32unix str num win32graph dynlink bigarray systhreads labltk ### Name of the target architecture for the "num" library BNG_ARCH=ia32 @@ -149,7 +154,8 @@ BNG_ASM_LEVEL=1 # There must be no spaces or special characters in $(TK_ROOT) TK_ROOT=c:/tcl TK_DEFS=-I$(TK_ROOT)/include -TK_LINK=$(TK_ROOT)/lib/tk84.lib $(TK_ROOT)/lib/tcl84.lib +TK_LINK=$(TK_ROOT)/bin/tk83.dll $(TK_ROOT)/bin/tcl83.dll +#TK_LINK=$(TK_ROOT)/lib/tk84.lib $(TK_ROOT)/lib/tcl84.lib ############# Aliases for common commands diff --git a/config/Makefile.msvc b/config/Makefile.msvc index 38be21962..4404732a0 100644 --- a/config/Makefile.msvc +++ b/config/Makefile.msvc @@ -69,6 +69,7 @@ DEBUGGER= CC_PROFILE= SYSTHREAD_SUPPORT=true EXTRALIBS= +CMXS=cmxs ########## Configuration for the bytecode compiler @@ -76,13 +77,13 @@ EXTRALIBS= BYTECC=cl /nologo -D_CRT_SECURE_NO_DEPRECATE ### Additional compile-time options for $(BYTECC). (For static linking.) -BYTECCCOMPOPTS=/Ox /MT +BYTECCCOMPOPTS=/Ox /MD ### Additional link-time options for $(BYTECC). (For static linking.) -BYTECCLINKOPTS=/MT +BYTECCLINKOPTS=/MD ### Additional compile-time options for $(BYTECC). (For building a DLL.) -DLLCCCOMPOPTS=/Ox /MD -DCAML_DLL +DLLCCCOMPOPTS=/Ox /MD ### Libraries needed BYTECCLIBS=advapi32.lib @@ -91,21 +92,17 @@ NATIVECCLIBS=advapi32.lib ### How to invoke the C preprocessor CPP=cl /nologo /EP -### How to merge a .manifest (if any) in a .exe -MERGEMANIFESTEXE=test ! -f $(1).manifest || mt -nologo -outputresource:$(1) -manifest $(1).manifest && rm -f $(1).manifest -#ml let mergemanifestexe out = Printf.sprintf "test ! -f %s.manifest || mt -nologo -outputresource:%s -manifest %s.manifest && rm -f %s.manifest" out out out out;; +### Path to the FlexDLL includes +FLEXDIR=$(shell flexlink -where) +FLEXLINK=-I"$(FLEXDIR)" ### How to build an EXE -MKEXE=$(BYTECC) /Fe$(1) $(2) && ($(MERGEMANIFESTEXE)) -#ml let mkexe out files opts = Printf.sprintf "%s /Fe%s %s %s && (%s)" bytecc out opts files (mergemanifestexe out);; - -### How to merge a .manifest (if any) in a .dll -MERGEMANIFESTDLL=test ! -f $(1).manifest || mt -nologo -outputresource:"$(1);\#2" -manifest $(1).manifest && rm -f $(1).manifest -#ml let mergemanifestdll out = Printf.sprintf "test ! -f %s.manifest || mt -nologo -outputresource:\"%s;\\#2\" -manifest %s.manifest && rm -f %s.manifest" out out out out;; +MKEXE=flexlink -merge-manifest -exe -o $(1) $(2) -- $(3) +#ml let mkexe out files opts = Printf.sprintf "flexlink -merge-manifest -exe -o %s %s -- %s" out files opts;; ### How to build a DLL -MKDLL=link /nologo /dll /out:$(1) /implib:$(2) $(3) && ($(MERGEMANIFESTDLL)) -#ml let mkdll out implib files opts = Printf.sprintf "link /nologo /dll /out:%s /implib:%s %s %s && (%s)" out implib opts files (mergemanifestdll out);; +MKDLL=flexlink -merge-manifest -o $(1) $(3) -- $(4) +#ml let mkdll out implib files opts = Printf.sprintf "flexlink -merge-manifest -o %s %s -- %s" out files opts;; ### How to build a static library MKLIB=link /lib /nologo /out:$(1) $(2) @@ -117,7 +114,7 @@ SYSLIB=$(1).lib #ml let syslib x = x ^ ".lib";; ### The ranlib command -RANLIB= +RANLIB=echo RANLIBCMD= ############# Configuration for the native-code compiler @@ -135,10 +132,10 @@ SYSTEM=win32 NATIVECC=cl /nologo -D_CRT_SECURE_NO_DEPRECATE ### Additional compile-time options for $(NATIVECC). -NATIVECCCOMPOPTS=/Ox /MT +NATIVECCCOMPOPTS=/Ox /MD ### Additional link-time options for $(NATIVECC) -NATIVECCLINKOPTS=/MT +NATIVECCLINKOPTS=/MD ### Build partially-linked object file PARTIALLD=link /lib /nologo @@ -160,7 +157,8 @@ TK_DEFS=-I$(TK_ROOT)/include # produced by OCaml, and is therefore required for binary distribution # of these libraries. However, $(TK_ROOT) must be added to the LIB # environment variable, as described in README.win32. -TK_LINK=tk84.lib tcl84.lib +#TK_LINK=tk84.lib tcl84.lib +TK_LINK=tk83.lib tcl83.lib # An alternative definition that avoids mucking with the LIB variable, # but hard-wires the Tcl/Tk location in the binaries # TK_LINK=$(TK_ROOT)/tk83.lib $(TK_ROOT)/tcl83.lib @@ -239,8 +239,11 @@ esac # Configure the bytecode compiler bytecc="$cc" +mkexe="\$(BYTECC) -o \$(1) \$(2) \$(3)" +mkexe_ml="Printf.sprintf \"%s -o %s %s %s\" bytecc out opts files" bytecccompopts="" bytecclinkopts="" +dllccompopts="" ostype="Unix" exe="" @@ -297,6 +300,9 @@ case "$bytecc,$host" in bytecccompopts="-D_XOPEN_SOURCE=500";; gcc*,*-*-cygwin*) bytecccompopts="-fno-defer-pop $gcc_warnings -U_WIN32" + dllccompopts="-D_WIN32 -DCAML_DLL" + mkexe="flexlink -exe -chain cygwin -o \$(1) \$(2) -- \$(3)" + mkexe_ml="Printf.sprintf \"flexlink -exe -chain cygwin -o %s %s -- %s\" out files opts" exe=".exe" ostype="Cygwin";; gcc*,x86_64-*-linux*) @@ -491,15 +497,24 @@ sharedcccompopts='' mksharedlib='' byteccrpath='' mksharedlibrpath='' +natdynlinkopts="" +flexlink='' +cmxs="cmxa" if test $withsharedlibs = "yes"; then + cmxs="cmxs" case "$host" in + *-*-cygwin*) + flexlink="-I`flexlink -where`" + mksharedlib="flexlink -chain cygwin -o" + shared_libraries_supported=true;; *-*-linux-gnu|*-*-linux|*-*-freebsd[3-9]*|*-*-openbsd*|*-*-netbsd*|*-*-gnu*) sharedcccompopts="-fPIC" mksharedlib="$bytecc -shared -o" bytecclinkopts="$bytecclinkopts -Wl,-E" byteccrpath="-Wl,-rpath," mksharedlibrpath="-Wl,-rpath," + natdynlinkopts="-Wl,-E" shared_libraries_supported=true;; alpha*-*-osf*) case "$bytecc" in @@ -1450,12 +1465,13 @@ echo "EXE=$exe" >> Makefile echo "SUPPORTS_SHARED_LIBRARIES=$shared_libraries_supported" >> Makefile echo "SHAREDCCCOMPOPTS=$sharedcccompopts" >> Makefile echo "MKSHAREDLIBRPATH=$mksharedlibrpath" >> Makefile +echo "NATDYNLINKOPTS=$natdynlinkopts" >> Makefile cat >> Makefile <<EOF SYSLIB=-l\$(1) #ml let syslib x = "-l"^x;; -MKEXE=\$(BYTECC) -o \$(1) \$(2) -#ml let mkexe out files opts = Printf.sprintf "%s -o %s %s %s" bytecc out opts files;; +MKEXE=$mkexe +#ml let mkexe out files opts = $mkexe_ml;; ### How to build a DLL MKDLL=$mksharedlib \$(1) \$(3) @@ -1484,7 +1500,8 @@ echo "DEBUGGER=$debugger" >> Makefile echo "CC_PROFILE=$cc_profile" >> Makefile echo "SYSTHREAD_SUPPORT=$systhread_support" >> Makefile echo "PARTIALLD=$partialld" >> Makefile -echo "DLLCCCOMPOPTS=" >> Makefile +echo "DLLCCCOMPOPTS=$dllccompopts" >> Makefile +echo "FLEXLINK=$flexlink" >> Makefile echo "O=o" >> Makefile echo "A=a" >> Makefile echo "EXT_OBJ=.o" >> Makefile @@ -1494,6 +1511,7 @@ echo "EXT_DLL=.so" >> Makefile echo "EXTRALIBS=" >> Makefile echo "CCOMPTYPE=cc" >> Makefile echo "TOOLCHAIN=cc" >> Makefile +echo "CMXS=$cmxs" >> Makefile rm -f tst hasgot.c rm -f ../m.h ../s.h ../Makefile diff --git a/driver/optmain.ml b/driver/optmain.ml index ac28b7618..554d0ef26 100644 --- a/driver/optmain.ml +++ b/driver/optmain.ml @@ -32,11 +32,8 @@ let process_implementation_file ppf name = let process_file ppf name = if Filename.check_suffix name ".ml" - || Filename.check_suffix name ".mlt" then begin - let opref = output_prefix name in - Optcompile.implementation ppf name opref; - objfiles := (opref ^ ".cmx") :: !objfiles - end + || Filename.check_suffix name ".mlt" then + process_implementation_file ppf name else if Filename.check_suffix name !Config.interface_suffix then begin let opref = output_prefix name in Optcompile.interface ppf name opref; @@ -111,6 +108,8 @@ let main () = " Optimize code size rather than speed"; "-config", Arg.Unit show_config, " print configuration values and exit"; + "-dlcode", Arg.Set dlcode, + " Compile into code that can be dynlinked"; "-dtypes", Arg.Set annotations, " (deprecated) same as -annot"; "-for-pack", Arg.String (fun s -> for_package := Some s), @@ -156,6 +155,8 @@ let main () = " Check principality of type inference"; "-rectypes", Arg.Set recursive_types, " Allow arbitrary recursive types"; + "-shared", Arg.Unit (fun () -> shared := true; dlcode := true), + " Produce a dynlinkable plugin"; "-S", Arg.Set keep_asm_file, " Keep intermediate assembly file"; "-thread", Arg.Set use_threads, " Generate code that supports the system threads library"; @@ -212,15 +213,27 @@ let main () = "-", Arg.String (process_file ppf), "<file> Treat <file> as a file name (even if it starts with `-')" ]) (process_file ppf) usage; + if + List.length (List.filter (fun x -> !x) + [make_archive;make_package;shared;compile_only]) > 1 + then begin + prerr_endline "Please specify at most one of -pack, -a, -shared, -c"; + exit 2 + end; if !make_archive then begin Optcompile.init_path(); - Asmlibrarian.create_archive (List.rev !objfiles) - (extract_output !output_name) + let target = extract_output !output_name in + Asmlibrarian.create_archive (List.rev !objfiles) target; end else if !make_package then begin Optcompile.init_path(); - Asmpackager.package_files ppf (List.rev !objfiles) - (extract_output !output_name) + let target = extract_output !output_name in + Asmpackager.package_files ppf (List.rev !objfiles) target; + end + else if !shared then begin + Optcompile.init_path(); + let target = extract_output !output_name in + Asmlink.link_shared ppf (List.rev !objfiles) target; end else if not !compile_only && !objfiles <> [] then begin Optcompile.init_path(); diff --git a/myocamlbuild.ml b/myocamlbuild.ml index 0e522f0e2..c56404343 100644 --- a/myocamlbuild.ml +++ b/myocamlbuild.ml @@ -731,6 +731,9 @@ let mk_camlp4_bin name ?unix:(link_unix=true) modules = 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 dynlink_cmxa,include_dynlink = + A"dynlink.cmxa", S[A"-I"; P dynlink_dir] + in let deps = special_modules @ modules @ [camlp4_bin] in let cmos = add_extensions ["cmo"] deps in let cmxs = add_extensions ["cmx"] deps in @@ -747,7 +750,7 @@ let mk_camlp4_bin name ?unix:(link_unix=true) modules = ~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"); + Cmd(S[ocamlopt; include_dynlink; dynlink_cmxa; 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;; diff --git a/ocamldoc/Makefile b/ocamldoc/Makefile index b6b47156f..4e9256b24 100644 --- a/ocamldoc/Makefile +++ b/ocamldoc/Makefile @@ -69,7 +69,7 @@ INCLUDES_NODEP= -I $(OCAMLSRCDIR)/stdlib \ INCLUDES=$(INCLUDES_DEP) $(INCLUDES_NODEP) COMPFLAGS=$(INCLUDES) -warn-error A -LINKFLAGS=$(INCLUDES) +LINKFLAGS=$(INCLUDES) -nostdlib CMOFILES= odoc_config.cmo \ odoc_global.cmo\ @@ -261,7 +261,7 @@ install: dummy if test -d $(INSTALL_BINDIR); then : ; else $(MKDIR) $(INSTALL_BINDIR); fi if test -d $(INSTALL_LIBDIR); then : ; else $(MKDIR) $(INSTALL_LIBDIR); fi if test -d $(INSTALL_CUSTOMDIR); then : ; else $(MKDIR) $(INSTALL_CUSTOMDIR); fi - $(CP) $(OCAMLDOC)$(EXE) $(INSTALL_BINDIR)/$(OCAMLDOC)$(EXE) + $(CP) $(OCAMLDOC) $(INSTALL_BINDIR)/$(OCAMLDOC)$(EXE) $(CP) ocamldoc.hva *.cmi $(OCAMLDOC_LIBCMA) $(INSTALL_LIBDIR) $(CP) $(INSTALL_MLIS) $(INSTALL_CMIS) $(INSTALL_LIBDIR) if test -d $(INSTALL_MANODIR); then : ; else $(MKDIR) $(INSTALL_MANODIR); fi diff --git a/ocamldoc/Makefile.nt b/ocamldoc/Makefile.nt index c11f1bd0f..33ccc4f3a 100644 --- a/ocamldoc/Makefile.nt +++ b/ocamldoc/Makefile.nt @@ -63,7 +63,7 @@ INCLUDES_NODEP= -I $(OCAMLSRCDIR)/stdlib \ INCLUDES=$(INCLUDES_DEP) $(INCLUDES_NODEP) COMPFLAGS=$(INCLUDES) -LINKFLAGS=$(INCLUDES) +LINKFLAGS=$(INCLUDES) -nostdlib CMOFILES= odoc_config.cmo \ odoc_global.cmo\ diff --git a/otherlibs/Makefile b/otherlibs/Makefile new file mode 100644 index 000000000..e959213b1 --- /dev/null +++ b/otherlibs/Makefile @@ -0,0 +1,24 @@ +######################################################################### +# # +# Objective Caml # +# # +# Xavier Leroy, projet Cristal, INRIA Rocquencourt # +# # +# Copyright 1999 Institut National de Recherche en Informatique et # +# en Automatique. All rights reserved. This file is distributed # +# under the terms of the GNU Library General Public License, with # +# the special exception on linking described in file ../../LICENSE. # +# # +######################################################################### + +# $Id$ + +# Common Makefile for otherlibs on the Unix ports + +CAMLC?=$(ROOTDIR)/ocamlcomp.sh +CAMLOPT?=$(ROOTDIR)/ocamlcompopt.sh +CFLAGS?=-I$(ROOTDIR)/byterun -O $(BYTECCCOMPOPTS) $(SHAREDCCCOMPOPTS) $(EXTRACFLAGS) + +include ../Makefile.shared +# Note .. is the current directory (this makefile is included from +# a subdirectory) diff --git a/otherlibs/Makefile.nt b/otherlibs/Makefile.nt new file mode 100644 index 000000000..ef79cf1fc --- /dev/null +++ b/otherlibs/Makefile.nt @@ -0,0 +1,24 @@ +######################################################################### +# # +# Objective Caml # +# # +# Xavier Leroy, projet Cristal, INRIA Rocquencourt # +# # +# Copyright 1999 Institut National de Recherche en Informatique et # +# en Automatique. All rights reserved. This file is distributed # +# under the terms of the GNU Library General Public License, with # +# the special exception on linking described in file ../../LICENSE. # +# # +######################################################################### + +# $Id$ + +# Common Makefile for otherlibs on the Win32/MinGW ports + +CAMLC=$(CAMLRUN) $(ROOTDIR)/ocamlc -nostdlib -I $(ROOTDIR)/stdlib -w s +CAMLOPT=$(CAMLRUN) $(ROOTDIR)/ocamlopt -nostdlib -I $(ROOTDIR)/stdlib -w s +CFLAGS=-I$(ROOTDIR)/byterun $(EXTRACFLAGS) + +include ../Makefile +# Note .. is the current directory (this makefile is included from +# a subdirectory)
\ No newline at end of file diff --git a/otherlibs/Makefile.shared b/otherlibs/Makefile.shared new file mode 100644 index 000000000..0f890453f --- /dev/null +++ b/otherlibs/Makefile.shared @@ -0,0 +1,90 @@ +######################################################################### +# # +# Objective Caml # +# # +# Xavier Leroy, projet Cristal, INRIA Rocquencourt # +# # +# Copyright 1999 Institut National de Recherche en Informatique et # +# en Automatique. All rights reserved. This file is distributed # +# under the terms of the GNU Library General Public License, with # +# the special exception on linking described in file ../../LICENSE. # +# # +######################################################################### + +# $Id$ + +# Common Makefile for otherlibs + +ROOTDIR=../.. +include $(ROOTDIR)/config/Makefile + +# Compilation options +CC=$(BYTECC) +CAMLRUN=$(ROOTDIR)/boot/ocamlrun +COMPFLAGS=-warn-error A -g $(EXTRACAMLFLAGS) +MKLIB=$(CAMLRUN) $(ROOTDIR)/tools/ocamlmklib + +# Variables to be defined by individual libraries: +#LIBNAME= +#CLIBNAME= +#CMIFILES= +#CAMLOBJS= +#COBJS= +#EXTRACFLAGS= +#EXTRACAMLFLAGS= +#LINKOPTS= +#LDOPTS= +#HEADERS= + +CMIFILES ?= $(CAMLOBJS:.cmo=.cmi) +CAMLOBJS_NAT ?= $(CAMLOBJS:.cmo=.cmx) +CLIBNAME ?= $(LIBNAME) + +all: lib$(CLIBNAME).$(A) $(LIBNAME).cma $(CMIFILES) + +allopt: lib$(CLIBNAME).$(A) $(LIBNAME).cmxa $(LIBNAME).$(CMXS) $(CMIFILES) + +$(LIBNAME).cma: $(CAMLOBJS) + $(MKLIB) -o $(LIBNAME) -oc $(CLIBNAME) -ocamlc '$(CAMLC)' -linkall $(CAMLOBJS) $(LINKOPTS) + +$(LIBNAME).cmxa: $(CAMLOBJS_NAT) + $(MKLIB) -o $(LIBNAME) -oc $(CLIBNAME) -ocamlopt '$(CAMLOPT)' -linkall $(CAMLOBJS_NAT) $(LINKOPTS) + +$(LIBNAME).cmxs: $(LIBNAME).cmxa lib$(CLIBNAME).$(A) + $(CAMLOPT) -shared -o $(LIBNAME).cmxs -I . $(LIBNAME).cmxa + +lib$(CLIBNAME).$(A): $(COBJS) + $(MKLIB) -oc $(CLIBNAME) $(COBJS) $(LDOPTS) + +install:: + if test -f dll$(CLIBNAME)$(EXT_DLL); then \ + cp dll$(CLIBNAME)$(EXT_DLL) $(STUBLIBDIR)/; fi + cp lib$(CLIBNAME).$(A) $(LIBDIR)/ + cd $(LIBDIR); $(RANLIB) lib$(CLIBNAME).$(A) + cp $(LIBNAME).cma $(CMIFILES) $(CMIFILES:.cmi=.mli) $(LIBDIR)/ + if test -n "$(HEADERS)"; then cp $(HEADERS) $(LIBDIR)/caml/; fi + +installopt: + cp $(CAMLOBJS_NAT) $(LIBNAME).cmxa $(LIBNAME).$(A) $(LIBDIR)/ + cd $(LIBDIR); $(RANLIB) $(LIBNAME).a + if test -f $(LIBNAME).cmxs; then cp $(LIBNAME).cmxs $(LIBDIR)/; fi + +partialclean: + rm -f *.cm* + +clean:: partialclean + rm -f *.dll *.so *.a *.lib *.o *.obj + +.SUFFIXES: .ml .mli .cmi .cmo .cmx .$(O) + +.mli.cmi: + $(CAMLC) -c $(COMPFLAGS) $< + +.ml.cmo: + $(CAMLC) -c $(COMPFLAGS) $< + +.ml.cmx: + $(CAMLOPT) -dlcode -c $(COMPFLAGS) $< + +.c.$(O): + $(BYTECC) $(BYTECCCOMPOPTS) $(CFLAGS) -c $< diff --git a/otherlibs/bigarray/Makefile b/otherlibs/bigarray/Makefile index 7e07815e5..d3a4cc521 100644 --- a/otherlibs/bigarray/Makefile +++ b/otherlibs/bigarray/Makefile @@ -13,62 +13,17 @@ # $Id$ -include ../../config/Makefile +LIBNAME=bigarray +EXTRACFLAGS=-I../unix -DIN_OCAML_BIGARRAY +EXTRACAMLFLAGS=-I ../unix +COBJS=bigarray_stubs.$(O) mmap_unix.$(O) +CAMLOBJS=bigarray.cmo +HEADERS=bigarray.h -CC=$(BYTECC) -CFLAGS=-I../../byterun -O $(BYTECCCOMPOPTS) $(SHAREDCCCOMPOPTS) -CAMLC=../../ocamlcomp.sh -I ../unix -CAMLOPT=../../ocamlcompopt.sh -I ../unix -MKLIB=../../boot/ocamlrun ../../tools/ocamlmklib -COMPFLAGS=-warn-error A -g - -C_OBJS=bigarray_stubs.o mmap_unix.o - -CAML_OBJS=bigarray.cmo - -all: libbigarray.a bigarray.cma - -allopt: libbigarray.a bigarray.cmxa - -libbigarray.a: $(C_OBJS) - $(MKLIB) -o bigarray $(C_OBJS) - -bigarray.cma: $(CAML_OBJS) - $(MKLIB) -ocamlc '$(CAMLC)' -linkall -o bigarray $(CAML_OBJS) - -bigarray.cmxa: $(CAML_OBJS:.cmo=.cmx) - $(MKLIB) -ocamlopt '$(CAMLOPT)' -linkall -o bigarray \ - $(CAML_OBJS:.cmo=.cmx) - -install: - if test -f dllbigarray.so; then cp dllbigarray.so $(STUBLIBDIR)/dllbigarray.so; fi - cp bigarray.cmi bigarray.mli libbigarray.a bigarray.cma $(LIBDIR) - cd $(LIBDIR); $(RANLIB) libbigarray.a - cp bigarray.h $(LIBDIR)/caml/bigarray.h - -installopt: - cp bigarray.a $(CAML_OBJS:.cmo=.cmx) bigarray.cmxa $(LIBDIR) - cd $(LIBDIR); $(RANLIB) bigarray.a - -partialclean: - rm -f *.cm* - -clean: partialclean - rm -f *.o *.so *.a - -.SUFFIXES: .ml .mli .cmo .cmi .cmx - -.mli.cmi: - $(CAMLC) -c $(COMPFLAGS) $< - -.ml.cmo: - $(CAMLC) -c $(COMPFLAGS) $< - -.ml.cmx: - $(CAMLOPT) -c $(COMPFLAGS) $< +include ../Makefile depend: - gcc -MM -I../../byterun -I../unix *.c > .depend + gcc -MM $(CFLAGS) *.c > .depend ../../boot/ocamlrun ../../tools/ocamldep *.mli *.ml >> .depend include .depend diff --git a/otherlibs/bigarray/Makefile.nt b/otherlibs/bigarray/Makefile.nt index b90f049ac..119eaea55 100644 --- a/otherlibs/bigarray/Makefile.nt +++ b/otherlibs/bigarray/Makefile.nt @@ -13,70 +13,14 @@ # $Id$ -include ../../config/Makefile - -CC=$(BYTECC) -CFLAGS=-I../../byterun -I../win32unix -DIN_OCAML_BIGARRAY -CAMLC=../../boot/ocamlrun ../../ocamlc -I ../../stdlib -I ../win32unix -CAMLOPT=../../boot/ocamlrun ../../ocamlopt -I ../../stdlib -I ../win32unix -COMPFLAGS=-warn-error A -g - -C_OBJS=bigarray_stubs.obj mmap_win32.obj - -CAML_OBJS=bigarray.cmo - -all: dllbigarray.dll libbigarray.$(A) bigarray.cma - -allopt: libbigarray.$(A) bigarray.cmxa - -dllbigarray.dll: $(C_OBJS:.obj=.$(DO)) - $(call MKDLL,dllbigarray.dll,dllbigarray.$(A),\ - $(C_OBJS:.obj=.$(DO)) ../../byterun/ocamlrun.$(A)) - -libbigarray.$(A): $(C_OBJS:.obj=.$(SO)) - $(call MKLIB,libbigarray.$(A),$(C_OBJS:.obj=.$(SO))) - -bigarray.cma: $(CAML_OBJS) - $(CAMLC) -a -linkall -o bigarray.cma $(CAML_OBJS) \ - -dllib -lbigarray -cclib -lbigarray - -bigarray.cmxa: $(CAML_OBJS:.cmo=.cmx) - $(CAMLOPT) -a -linkall -o bigarray.cmxa \ - $(CAML_OBJS:.cmo=.cmx) -cclib -lbigarray - -install: - cp dllbigarray.dll $(STUBLIBDIR) - cp libbigarray.$(A) dllbigarray.$(A) $(LIBDIR) - cp bigarray.cmi bigarray.mli bigarray.cma $(LIBDIR) - cp bigarray.h $(LIBDIR)/caml/bigarray.h - -installopt: - cp bigarray.$(A) $(CAML_OBJS:.cmo=.cmx) bigarray.cmxa $(LIBDIR) - -partialclean: - rm -f *.cm* - -clean: partialclean - rm -f *.dll *.$(A) *.$(O) - -.SUFFIXES: .ml .mli .cmo .cmi .cmx .$(DO) .$(SO) - -.mli.cmi: - $(CAMLC) -c $(COMPFLAGS) $< - -.ml.cmo: - $(CAMLC) -c $(COMPFLAGS) $< - -.ml.cmx: - $(CAMLOPT) -c $(COMPFLAGS) $< - -.c.$(DO): - $(BYTECC) $(DLLCCCOMPOPTS) $(CFLAGS) -c $< - mv $*.$(O) $*.$(DO) - -.c.$(SO): - $(BYTECC) $(BYTECCCOMPOPTS) $(CFLAGS) -c $< - mv $*.$(O) $*.$(SO) +LIBNAME=bigarray +EXTRACFLAGS=-I../win32unix -DIN_OCAML_BIGARRAY +EXTRACAMLFLAGS=-I ../win32unix +COBJS=bigarray_stubs.$(O) mmap_win32.$(O) +CAMLOBJS=bigarray.cmo +HEADERS=bigarray.h + +include ../Makefile.nt depend: gcc -MM $(CFLAGS) *.c > .depend diff --git a/otherlibs/bigarray/bigarray.ml b/otherlibs/bigarray/bigarray.ml index 91eab314e..c4da3d5c9 100644 --- a/otherlibs/bigarray/bigarray.ml +++ b/otherlibs/bigarray/bigarray.ml @@ -238,3 +238,10 @@ let _ = let _ = Array2.get in let _ = Array3.get in () + +external get1: unit -> unit = "caml_ba_get_1" +external get2: unit -> unit = "caml_ba_get_2" +external get3: unit -> unit = "caml_ba_get_3" +external set1: unit -> unit = "caml_ba_set_1" +external set2: unit -> unit = "caml_ba_set_2" +external set3: unit -> unit = "caml_ba_set_3" diff --git a/otherlibs/dbm/Makefile b/otherlibs/dbm/Makefile index 394586416..bb65b6b1c 100644 --- a/otherlibs/dbm/Makefile +++ b/otherlibs/dbm/Makefile @@ -15,57 +15,15 @@ # Makefile for the ndbm library -include ../../config/Makefile - -# Compilation optiosn -CC=$(BYTECC) -g -CAMLC=../../ocamlcomp.sh -CAMLOPT=../../ocamlcompopt.sh -MKLIB=../../boot/ocamlrun ../../tools/ocamlmklib -COMPFLAGS=-warn-error A - -CFLAGS=$(DBM_INCLUDES) -I../../byterun -O $(BYTECCCOMPOPTS) $(SHAREDCCCOMPOPTS) +LIBNAME=dbm +CLIBNAME=mldbm +CAMLOBJS=dbm.cmo COBJS=cldbm.o +EXTRACFLAGS=$(DBM_INCLUDES) +LINKOPTS=$(DBM_LINK) -all: libmldbm.a dbm.cmi dbm.cma - -allopt: libmldbm.a dbm.cmi dbm.cmxa - -libmldbm.a: $(COBJS) - $(MKLIB) -oc mldbm $(COBJS) $(DBM_LINK) - -dbm.cma: dbm.cmo - $(MKLIB) -ocamlc '$(CAMLC)' -o dbm -oc mldbm dbm.cmo $(DBM_LINK) - -dbm.cmxa: dbm.cmx - $(MKLIB) -ocamlopt '$(CAMLOPT)' -o dbm -oc mldbm dbm.cmx $(DBM_LINK) - -partialclean: - rm -f *.cm* - -clean: partialclean - rm -f *.a *.o *.so - -install: - if test -f dllmldbm.so; then cp dllmldbm.so $(STUBLIBDIR)/dllmldbm.so; fi - cp libmldbm.a $(LIBDIR)/libmldbm.a - cd $(LIBDIR); $(RANLIB) libmldbm.a - cp dbm.cma dbm.cmi dbm.mli $(LIBDIR) - -installopt: - cp dbm.cmx dbm.cmxa dbm.a $(LIBDIR) - cd $(LIBDIR); $(RANLIB) dbm.a - -.SUFFIXES: .ml .mli .cmo .cmi .cmx - -.mli.cmi: - $(CAMLC) -c $(COMPFLAGS) $< - -.ml.cmo: - $(CAMLC) -c $(COMPFLAGS) $< +include ../Makefile -.ml.cmx: - $(CAMLOPT) -c $(COMPFLAGS) $< depend: ../../boot/ocamlrun ../../tools/ocamldep *.mli *.ml > .depend diff --git a/otherlibs/dynlink/Makefile b/otherlibs/dynlink/Makefile index 576d49283..9092458f1 100644 --- a/otherlibs/dynlink/Makefile +++ b/otherlibs/dynlink/Makefile @@ -18,6 +18,7 @@ include ../../config/Makefile CAMLC=../../boot/ocamlrun ../../ocamlc +CAMLOPT=../../ocamlcompopt.sh INCLUDES=-I ../../utils -I ../../typing -I ../../bytecomp COMPFLAGS=-warn-error A -I ../../stdlib $(INCLUDES) @@ -39,30 +40,44 @@ COMPILEROBJS=\ ../../bytecomp/dll.cmo ../../bytecomp/meta.cmo \ ../../bytecomp/symtable.cmo +NATOBJS=dynlink.cmx + all: dynlink.cma extract_crc -allopt: +allopt: dynlink.cmxa dynlink.cma: $(OBJS) $(CAMLC) $(COMPFLAGS) -a -o dynlink.cma $(OBJS) +dynlink.cmxa: $(NATOBJS) + $(CAMLOPT) $(COMPFLAGS) -ccopt "$(NATDYNLINKOPTS)" -a -o dynlink.cmxa $(NATOBJS) + dynlinkaux.cmo dynlinkaux.cmi: $(COMPILEROBJS) $(CAMLC) $(COMPFLAGS) -pack -o dynlinkaux.cmo $(COMPILEROBJS) +dynlink.cmx: dynlink.cmi natdynlink.ml + cp natdynlink.ml dynlink.mlopt + $(CAMLOPT) -c $(COMPFLAGS) -impl dynlink.mlopt + rm -f dynlink.mlopt + extract_crc: dynlink.cma extract_crc.cmo $(CAMLC) $(COMPFLAGS) -o extract_crc dynlink.cma extract_crc.cmo install: - cp dynlink.cmi dynlink.cma dynlink.mli extract_crc $(LIBDIR) + cp dynlink.cmi dynlink.cma dynlink.mli $(LIBDIR) + cp extract_crc $(LIBDIR)/extract_crc$(EXE) installopt: + cp $(NATOBJS) dynlink.cmxa dynlink.$(A) $(LIBDIR) + cd $(LIBDIR); $(RANLIB) dynlink.$(A) partialclean: - rm -f extract_crc *.cm[ioa] + rm -f extract_crc *.cm[ioax] *.cmxa clean: partialclean + rm -f *.$(A) *.$(O) *.so *.dll dynlink.mlopt -.SUFFIXES: .ml .mli .cmo .cmi +.SUFFIXES: .ml .mli .cmo .cmi .cmx .mli.cmi: $(CAMLC) -c $(COMPFLAGS) $< @@ -70,6 +85,9 @@ clean: partialclean .ml.cmo: $(CAMLC) -c $(COMPFLAGS) $< +.ml.cmx: + $(CAMLOPT) -c $(COMPFLAGS) $< + depend: dynlink.cmo: dynlinkaux.cmi dynlink.cmi diff --git a/otherlibs/dynlink/Makefile.nt b/otherlibs/dynlink/Makefile.nt index 3ce4fd0b5..3d8b84b77 100644 --- a/otherlibs/dynlink/Makefile.nt +++ b/otherlibs/dynlink/Makefile.nt @@ -15,63 +15,4 @@ # Makefile for the dynamic link library -include ../../config/Makefile - -CAMLC=../../boot/ocamlrun ../../ocamlc -INCLUDES=-I ../../utils -I ../../typing -I ../../bytecomp -COMPFLAGS=-warn-error A -I ../../stdlib $(INCLUDES) - -OBJS=dynlinkaux.cmo dynlink.cmo - -COMPILEROBJS=\ - ../../utils/misc.cmo ../../utils/config.cmo ../../utils/clflags.cmo \ - ../../utils/tbl.cmo ../../utils/consistbl.cmo \ - ../../utils/terminfo.cmo ../../utils/warnings.cmo \ - ../../parsing/asttypes.cmi ../../parsing/linenum.cmo \ - ../../parsing/location.cmo ../../parsing/longident.cmo \ - ../../typing/ident.cmo ../../typing/path.cmo \ - ../../typing/primitive.cmo ../../typing/types.cmo \ - ../../typing/btype.cmo ../../typing/subst.cmo ../../typing/predef.cmo \ - ../../typing/datarepr.cmo ../../typing/env.cmo \ - ../../bytecomp/lambda.cmo ../../bytecomp/instruct.cmo \ - ../../bytecomp/cmo_format.cmi ../../bytecomp/opcodes.cmo \ - ../../bytecomp/runtimedef.cmo ../../bytecomp/bytesections.cmo \ - ../../bytecomp/dll.cmo ../../bytecomp/meta.cmo \ - ../../bytecomp/symtable.cmo - -all: dynlink.cma extract_crc - -allopt: - -dynlink.cma: $(OBJS) - $(CAMLC) $(COMPFLAGS) -a -o dynlink.cma $(OBJS) - -dynlinkaux.cmo dynlinkaux.cmi: $(COMPILEROBJS) - $(CAMLC) $(COMPFLAGS) -pack -o dynlinkaux.cmo $(COMPILEROBJS) - -extract_crc: dynlink.cma extract_crc.cmo - $(CAMLC) $(COMPFLAGS) -o extract_crc dynlink.cma extract_crc.cmo - -install: - cp dynlink.cmi dynlink.cma dynlink.mli $(LIBDIR) - cp extract_crc $(LIBDIR)/extract_crc.exe - -installopt: - -partialclean: - rm -f extract_crc *.cm[ioa] - -clean: partialclean - -.SUFFIXES: .ml .mli .cmo .cmi - -.mli.cmi: - $(CAMLC) -c $(COMPFLAGS) $< - -.ml.cmo: - $(CAMLC) -c $(COMPFLAGS) $< - -depend: - -dynlink.cmo: dynlinkaux.cmi dynlink.cmi -extract_crc.cmo: dynlink.cmi +include Makefile diff --git a/otherlibs/dynlink/dynlink.ml b/otherlibs/dynlink/dynlink.ml index 6fb154bd7..423d31884 100644 --- a/otherlibs/dynlink/dynlink.ml +++ b/otherlibs/dynlink/dynlink.ml @@ -248,3 +248,5 @@ let error_message = function "cannot find file " ^ name ^ " in search path" | Cannot_open_dll reason -> "error loading shared library: " ^ reason + +let is_native = false diff --git a/otherlibs/dynlink/dynlink.mli b/otherlibs/dynlink/dynlink.mli index ac5c1a211..445492cd4 100644 --- a/otherlibs/dynlink/dynlink.mli +++ b/otherlibs/dynlink/dynlink.mli @@ -13,7 +13,11 @@ (* $Id$ *) -(** Dynamic loading of bytecode object files. *) +(** Dynamic loading of object files. *) + +val is_native: bool +(** [true] if the program is native, + [false] if the program is bytecode. *) (** {6 Initialization} *) @@ -21,11 +25,14 @@ val init : unit -> unit (** Initialize the [Dynlink] library. Must be called before any other function in this module. *) -(** {6 Dynamic loading of compiled bytecode files} *) +(** {6 Dynamic loading of compiled files} *) val loadfile : string -> unit -(** Load the given bytecode object file ([.cmo] file) or - bytecode library file ([.cma] file), and link it with the running program. +(** In bytecode: load the given bytecode object file ([.cmo] file) or + bytecode library file ([.cma] file), and link it with the running + program. In native code: load the given OCaml plugin file (usually + [.cmxs]), and link it with the running + program. All toplevel expressions in the loaded compilation units are evaluated. No facilities are provided to access value names defined by the unit. Therefore, the unit @@ -77,7 +84,8 @@ val allow_unsafe_modules : bool -> unit since the default initialization of allowed units, along with the [allow_only] and [prohibit] function, provides a better, safer mechanism to control access to program units. The three functions - below are provided for backward compatibility only. *) + below are provided for backward compatibility only and are not + available in native code. *) val add_interfaces : string list -> string list -> unit (** [add_interfaces units path] grants dynamically-linked object diff --git a/otherlibs/dynlink/natdynlink.ml b/otherlibs/dynlink/natdynlink.ml new file mode 100644 index 000000000..f2028a482 --- /dev/null +++ b/otherlibs/dynlink/natdynlink.ml @@ -0,0 +1,286 @@ +(***********************************************************************) +(* *) +(* Objective Caml *) +(* *) +(* Xavier Leroy, projet Gallium, INRIA Rocquencourt *) +(* *) +(* Copyright 1996 Institut National de Recherche en Informatique et *) +(* en Automatique. All rights reserved. This file is distributed *) +(* under the terms of the GNU Library General Public License, with *) +(* the special exception on linking described in file ../../LICENSE. *) +(* *) +(***********************************************************************) + +(* $Id$ *) + +(* Dynamic loading of .cmx files *) + +type handle + +external ndl_open: string -> handle * string = "caml_natdynlink_open" +external ndl_run: handle -> string -> unit = "caml_natdynlink_run" +external ndl_getmap : unit -> string = "caml_natdynlink_getmap" +external ndl_globals_inited : unit -> int = "caml_natdynlink_globals_inited" + +(** {6 Error reporting} *) + +type linking_error = + Undefined_global of string + | Unavailable_primitive of string + | Uninitialized_global of string + +type error = + Not_a_bytecode_file of string + | Inconsistent_import of string + | Unavailable_unit of string + | Unsafe_file + | Linking_error of string * linking_error + | Corrupted_interface of string + | File_not_found of string + | Cannot_open_dll of string + +exception Error of error + +(* Copied from other places to avoid dependencies *) + +type dynunit = { + name: string; + crc: Digest.t; + imports_cmi: (string * Digest.t) list; + imports_cmx: (string * Digest.t) list; + defines: string list; +} + +type dynheader = { + magic: string; + units: dynunit list; +} + +let dyn_magic_number = "Caml2007D001" + +let dll_filename fname = + if Filename.is_implicit fname then Filename.concat (Sys.getcwd ()) fname + else fname + +let read_file filename = + let dll = dll_filename filename in + if not (Sys.file_exists dll) then raise (Error (File_not_found dll)); + + let (handle,data) as res = ndl_open dll in + if Obj.tag (Obj.repr res) = Obj.string_tag + then raise (Error (Cannot_open_dll (Obj.magic res))); + + let header : dynheader = Marshal.from_string data 0 in + if header.magic <> dyn_magic_number + then raise(Error(Not_a_bytecode_file dll)); + (dll, handle, header.units) + +let cmx_not_found_crc = + "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + + +(* Management of interface and implementation CRCs *) + +module StrMap = Map.Make(String) + +type implem_state = + | Loaded + | Check_inited of int + +type state = { + ifaces: (string*string) StrMap.t; + implems: (string*string*implem_state) StrMap.t; +(* loaded_symbols: string StrMap.t; *) +} + +let allow_extension = ref true + +let add_check_ifaces allow_ext filename ui ifaces = + List.fold_left + (fun ifaces (name, crc) -> + if name = ui.name + then StrMap.add name (crc,filename) ifaces + else + try + let (old_crc,old_src) = StrMap.find name ifaces in + if old_crc <> crc + then raise(Error(Inconsistent_import(name))) + else ifaces + with Not_found -> + if allow_ext then StrMap.add name (crc,filename) ifaces + else raise (Error(Unavailable_unit name)) + ) ifaces ui.imports_cmi + +let check_implems filename ui implems = + List.iter + (fun (name, crc) -> + match name with + |"Out_of_memory" + |"Sys_error" + |"Failure" + |"Invalid_argument" + |"End_of_file" + |"Division_by_zero" + |"Not_found" + |"Match_failure" + |"Stack_overflow" + |"Sys_blocked_io" + |"Assert_failure" + |"Undefined_recursive_module" -> () + | _ -> + try + let (old_crc,old_src,state) = StrMap.find name implems in + if crc <> cmx_not_found_crc && old_crc <> crc + then raise(Error(Inconsistent_import(name))) + else match state with + | Check_inited i -> + if ndl_globals_inited() < i + then raise(Error(Unavailable_unit name)) + | Loaded -> () + with Not_found -> + raise (Error(Unavailable_unit name)) + ) ui.imports_cmx + +(* Prevent redefinition of a unit symbol *) + +(* TODO: make loaded_symbols a global variable, otherwise could + break safety with load_private (or not?) *) +(* +let check_symbols filename ui symbols = + List.fold_left + (fun syms name -> + try + let old_src = StrMap.find name symbols in + raise (Error(Reloading_symbol(name,old_src,filename))) + with Not_found -> + StrMap.add name filename syms + ) + symbols + ui.defines +*) + +let empty_state = { + ifaces = StrMap.empty; + implems = StrMap.empty; +(* loaded_symbols = StrMap.empty; *) +} + +let global_state = ref empty_state + +let loadunits priv filename handle units state = +(* let new_symbols = + List.fold_left (fun accu ui -> check_symbols filename ui accu) + state.loaded_symbols units in *) + let new_ifaces = + List.fold_left + (fun accu ui -> add_check_ifaces !allow_extension filename ui accu) + state.ifaces units in + let new_implems = + List.fold_left + (fun accu ui -> + check_implems filename ui accu; + StrMap.add ui.name (ui.crc,filename,Loaded) accu) + state.implems units in + + let defines = List.flatten (List.map (fun ui -> ui.defines) units) in + + ndl_run handle "_shared_startup"; + List.iter (ndl_run handle) defines; + { implems = new_implems; ifaces = new_ifaces; + (*loaded_symbols = new_symbols*) } + +let load priv filename state = + let (filename,handle,units) = read_file filename in + loadunits priv filename handle units state + +let loadfile filename = global_state := load false filename !global_state +let loadfile_private filename = ignore (load true filename !global_state) + +let add_builtin_map st = + let map : (string*Digest.t*Digest.t*string list) list = + Marshal.from_string (ndl_getmap ()) 0 in + let exe = Sys.executable_name in + let rank = ref 0 in + List.fold_left + (fun st (name,crc_intf,crc_impl,syms) -> + rank := !rank + List.length syms; { + ifaces = StrMap.add name (crc_intf,exe) st.ifaces; + implems =StrMap.add name (crc_impl,exe,Check_inited !rank) st.implems; +(* + loaded_symbols = + List.fold_left (fun l s -> StrMap.add s exe l) + st.loaded_symbols syms +*) + } + ) + st + map + + +(* is it ok to restrict only the accessible interfaces? *) +let allow_only names = + let old = !global_state.ifaces in + let ifaces = + List.fold_left + (fun ifaces name -> + try StrMap.add name (StrMap.find name old) ifaces + with Not_found -> ifaces) + StrMap.empty names in + global_state := { !global_state with ifaces = ifaces }; + allow_extension := false + +let prohibit names = + let ifaces = List.fold_right StrMap.remove names !global_state.ifaces in + global_state := { !global_state with ifaces = ifaces }; + allow_extension := false + +let default_available_units () = + global_state := add_builtin_map empty_state; + allow_extension := true + +let init () = + default_available_units () + +let digest_interface _ _ = + failwith "Dynlink.digest_interface: not implemented in native code" +let add_interfaces _ _ = + failwith "Dynlink.add_interfaces: not implemented in native code" +let add_available_units _ = + failwith "Dynlink.add_available_units: not implemented in native code" +let clear_available_units _ = + failwith "Dynlink.clear_available_units: not implemented in native code" +let allow_unsafe_modules _ = + () +(* failwith "Dynlink.allow_unsafe_modules: not implemented in native code" *) + + +(* Error report *) + +(* Error report *) + +let error_message = function + Not_a_bytecode_file name -> + name ^ " is not an object file" + | Inconsistent_import name -> + "interface or implementation mismatch on " ^ name + | Unavailable_unit name -> + "no implementation available for " ^ name + | Unsafe_file -> + "this object file uses unsafe features" + | Linking_error (name, Undefined_global s) -> + "error while linking " ^ name ^ ".\n" ^ + "Reference to undefined global `" ^ s ^ "'" + | Linking_error (name, Unavailable_primitive s) -> + "error while linking " ^ name ^ ".\n" ^ + "The external function `" ^ s ^ "' is not available" + | Linking_error (name, Uninitialized_global s) -> + "error while linking " ^ name ^ ".\n" ^ + "The module `" ^ s ^ "' is not yet initialized" + | Corrupted_interface name -> + "corrupted interface file " ^ name + | File_not_found name -> + "cannot find file " ^ name ^ " in search path" + | Cannot_open_dll reason -> + "error loading shared library: " ^ reason + +let is_native = true diff --git a/otherlibs/graph/Makefile b/otherlibs/graph/Makefile index d9f5c1abb..382dd9e1a 100644 --- a/otherlibs/graph/Makefile +++ b/otherlibs/graph/Makefile @@ -15,59 +15,17 @@ # Makefile for the portable graphics library -include ../../config/Makefile - -CC=$(BYTECC) -CFLAGS=-I../../byterun $(X11_INCLUDES) -O $(BYTECCCOMPOPTS) $(SHAREDCCCOMPOPTS) -CAMLC=../../ocamlcomp.sh -CAMLOPT=../../ocamlcompopt.sh -MKLIB=../../boot/ocamlrun ../../tools/ocamlmklib -COMPFLAGS=-warn-error A -g - -OBJS=open.o draw.o fill.o color.o text.o \ +LIBNAME=graphics +COBJS=open.o draw.o fill.o color.o text.o \ image.o make_img.o dump_img.o point_col.o sound.o events.o \ subwindow.o - CAMLOBJS=graphics.cmo graphicsX11.cmo +LINKOPTS=-cclib "\"$(X11_LINK)\"" +LDOPTS=-ldopt "$(X11_LINK)" -all: libgraphics.a graphics.cmi graphics.cma - -allopt: libgraphics.a graphics.cmi graphics.cmxa - -libgraphics.a: $(OBJS) - $(MKLIB) -o graphics $(OBJS) $(X11_LINK) - -graphics.cma: $(CAMLOBJS) - $(MKLIB) -ocamlc '$(CAMLC)' -o graphics $(CAMLOBJS) $(X11_LINK) - -graphics.cmxa: $(CAMLOBJS:.cmo=.cmx) - $(MKLIB) -ocamlopt '$(CAMLOPT)' -o graphics $(CAMLOBJS:.cmo=.cmx) $(X11_LINK) - -partialclean: - rm -f *.cm* - -clean: partialclean - rm -f *.a *.so *.o - -install: - if test -f dllgraphics.so; then cp dllgraphics.so $(STUBLIBDIR)/dllgraphics.so; fi - cp libgraphics.a $(LIBDIR)/libgraphics.a - cd $(LIBDIR); $(RANLIB) libgraphics.a - cp graphics.cm[ia] graphicsX11.cmi graphics.mli graphicsX11.mli $(LIBDIR) - -installopt: - cp graphics.cmx graphics.cmxa graphics.a $(LIBDIR) - cd $(LIBDIR); $(RANLIB) graphics.a - -.SUFFIXES: .ml .mli .cmo .cmi .cmx - -.mli.cmi: - $(CAMLC) -c $(COMPFLAGS) $< -.ml.cmo: - $(CAMLC) -c $(COMPFLAGS) $< -.ml.cmx: - $(CAMLOPT) -c $(COMPFLAGS) $< +include ../Makefile +#CFLAGS=-I../../byterun $(X11_INCLUDES) -O $(BYTECCCOMPOPTS) $(SHAREDCCCOMPOPTS) depend: gcc -MM $(CFLAGS) *.c | sed -e 's, /usr[^ ]*\.h,,g' > .depend ../../boot/ocamlrun ../../tools/ocamldep *.mli *.ml >> .depend diff --git a/otherlibs/labltk/Makefile b/otherlibs/labltk/Makefile index 83ecabe74..b7fc54937 100644 --- a/otherlibs/labltk/Makefile +++ b/otherlibs/labltk/Makefile @@ -32,15 +32,7 @@ allopt: byte: all opt: allopt -.PHONY: labltk camltk examples_labltk examples_camltk - -labltk: Widgets.src - compiler/tkcompiler -outdir labltk - cd labltk; $(MAKE) - -camltk: Widgets.src - compiler/tkcompiler -camltk -outdir camltk - cd camltk; $(MAKE) +.PHONY: examples_labltk examples_camltk examples: examples_labltk examples_camltk diff --git a/otherlibs/labltk/Makefile.nt b/otherlibs/labltk/Makefile.nt index bcbfc3d3c..45d539192 100644 --- a/otherlibs/labltk/Makefile.nt +++ b/otherlibs/labltk/Makefile.nt @@ -2,6 +2,8 @@ include ../../config/Makefile + + SUBDIRS=compiler support lib labltk camltk jpf frx tkanim examples_labltk examples_camltk browser all: @@ -28,13 +30,15 @@ allopt: cd frx ; $(MAKEREC) opt cd tkanim ; $(MAKEREC) opt -example: examples_labltk/all examples_camltk/all +.PHONY: examples_labltk examples_camltk + +examples: examples_labltk examples_camltk -examples_labltk/all: - cd examples_labltk ; $(MAKEREC) all +examples_labltk: + cd examples_labltk; $(MAKE) all -examples_camltk/all: - cd examples_camltk ; $(MAKEREC) all +examples_camltk: + cd examples_camltk; $(MAKE) all install: cd labltk ; $(MAKEREC) install diff --git a/otherlibs/labltk/browser/Makefile b/otherlibs/labltk/browser/Makefile index b611622a2..5eb7eefbf 100644 --- a/otherlibs/labltk/browser/Makefile +++ b/otherlibs/labltk/browser/Makefile @@ -1,65 +1,6 @@ -include ../support/Makefile.common - -LABLTKLIB=-I ../labltk -I ../lib -I ../support -#OTHERSLIB=-I $(OTHERS)/win32unix -I $(OTHERS)/systhreads -I $(OTHERS)/str OTHERSLIB=-I $(OTHERS)/unix -I $(OTHERS)/str -OCAMLTOPLIB=-I $(TOPDIR)/parsing -I $(TOPDIR)/utils -I $(TOPDIR)/typing -INCLUDES=$(OTHERSLIB) $(LABLTKLIB) $(OCAMLTOPLIB) - -OBJ = list2.cmo useunix.cmo setpath.cmo lexical.cmo \ - fileselect.cmo searchid.cmo searchpos.cmo shell.cmo \ - help.cmo \ - viewer.cmo typecheck.cmo editor.cmo main.cmo - -JG = jg_tk.cmo jg_config.cmo jg_bind.cmo jg_completion.cmo \ - jg_box.cmo \ - jg_button.cmo jg_toplevel.cmo jg_text.cmo jg_message.cmo \ - jg_menu.cmo jg_entry.cmo jg_multibox.cmo jg_memo.cmo - -# Default rules - -.SUFFIXES: .ml .mli .cmo .cmi .cmx - -.ml.cmo: - $(CAMLCOMP) $(INCLUDES) $< - -.mli.cmi: - $(CAMLCOMP) $(INCLUDES) $< - -all: ocamlbrowser$(EXE) - -ocamlbrowser$(EXE): $(TOPDIR)/toplevel/toplevellib.cma jglib.cma $(OBJ) \ - ../support/lib$(LIBNAME).a - $(CAMLC) -o ocamlbrowser$(EXE) $(INCLUDES) \ - $(TOPDIR)/toplevel/toplevellib.cma \ - unix.cma str.cma $(LIBNAME).cma jglib.cma $(OBJ) - -ocamlbrowser.cma: jglib.cma $(OBJ) - $(CAMLC) -a -o $@ -linkall jglib.cma $(OBJ) - -jglib.cma: $(JG) - $(CAMLCOMP) -a -o jglib.cma $(JG) - -help.ml: - echo 'let text = "\\' > $@ - sed -e 's/^ /\\032/' -e 's/$$/\\n\\/' help.txt >> $@ - echo '";;' >> $@ - -install: - if test -f ocamlbrowser$(EXE); then : ; \ - cp ocamlbrowser$(EXE) $(BINDIR); fi - -clean: - rm -f *.cm? ocamlbrowser$(EXE) dummy.mli *~ *.orig - -depend: - $(CAMLDEP) *.ml *.mli > .depend dummy.mli: - rm -f $@ - ln -s dummyUnix.mli $@ -shell.cmo: dummy.cmi -setpath.cmo fileselect.cmo lexical.cmi searchid.cmi typecheck.cmi: $(TOPDIR)/toplevel/toplevellib.cma -mytypes.cmi searchpos.cmi searchpos.cmo typecheck.cmo: $(TOPDIR)/typing/stypes.cmi + cp dummyUnix.mli dummy.mli -include .depend +include Makefile.shared diff --git a/otherlibs/labltk/browser/Makefile.nt b/otherlibs/labltk/browser/Makefile.nt index 6de29fcfb..ec619f76f 100644 --- a/otherlibs/labltk/browser/Makefile.nt +++ b/otherlibs/labltk/browser/Makefile.nt @@ -1,9 +1,5 @@ -include ../support/Makefile.common.nt - -LABLTKLIB=-I ../labltk -I ../lib -I ../support OTHERSLIB=-I $(OTHERS)/win32unix -I $(OTHERS)/str -I $(OTHERS)/systhreads -OCAMLTOPLIB=-I $(TOPDIR)/parsing -I $(TOPDIR)/utils -I $(TOPDIR)/typing -INCLUDES=$(OTHERSLIB) $(LABLTKLIB) $(OCAMLTOPLIB) + CCFLAGS=-I../../../byterun $(TK_DEFS) ifeq ($(CCOMPTYPE),cc) @@ -12,59 +8,10 @@ else WINDOWS_APP=-ccopt "/link /subsystem:windows" endif -OBJS = list2.cmo useunix.cmo setpath.cmo lexical.cmo \ - fileselect.cmo searchid.cmo searchpos.cmo shell.cmo \ - help.cmo \ - viewer.cmo typecheck.cmo editor.cmo main.cmo - -JG = jg_tk.cmo jg_config.cmo jg_bind.cmo jg_completion.cmo \ - jg_box.cmo \ - jg_button.cmo jg_toplevel.cmo jg_text.cmo jg_message.cmo \ - jg_menu.cmo jg_entry.cmo jg_multibox.cmo jg_memo.cmo - -# Default rules - -.SUFFIXES: .ml .mli .cmo .cmi .cmx .c .$(O) - -.ml.cmo: - $(CAMLCOMP) $(INCLUDES) $< - -.mli.cmi: - $(CAMLCOMP) $(INCLUDES) $< - -.c.$(O): - $(BYTECC) $(BYTECCCOMPOPTS) $(CCFLAGS) -c $< - -all: ocamlbrowser.exe - -ocamlbrowser.exe: $(TOPDIR)/toplevel/toplevellib.cma \ - ../support/lib$(LIBNAME).$(A) -ocamlbrowser.exe: jglib.cma $(OBJS) winmain.$(O) - $(CAMLC) -o ocamlbrowser.exe -custom $(INCLUDES) \ - $(TOPDIR)/toplevel/toplevellib.cma \ - unix.cma threads.cma str.cma $(LIBNAME).cma jglib.cma $(OBJS) \ - winmain.$(O) $(WINDOWS_APP) - -jglib.cma: $(JG) - $(CAMLCOMP) -a -o jglib.cma $(JG) - -help.ml: - echo 'let text = "\\' > $@ - sed -e 's/^ /\\032/' -e 's/$$/\\n\\/' help.txt >> $@ - echo '";;' >> $@ - -install: - if test -f ocamlbrowser.exe; then cp ocamlbrowser.exe $(BINDIR); fi - -clean: - rm -f *.cm? ocamlbrowser.exe dummy.mli *~ *.orig *.$(O) - -depend: - $(CAMLDEP) *.ml *.mli > .depend +OCAMLBR=threads.cma winmain.$(O) $(WINDOWS_APP) dummy.mli: cp dummyWin.mli dummy.mli -shell.cmo: dummy.cmi -setpath.cmo fileselect.cmo lexical.cmi searchid.cmi typecheck.cmi: $(TOPDIR)/toplevel/toplevellib.cma -include .depend +include Makefile.shared + diff --git a/otherlibs/labltk/browser/Makefile.shared b/otherlibs/labltk/browser/Makefile.shared new file mode 100644 index 000000000..fe1d7ed5d --- /dev/null +++ b/otherlibs/labltk/browser/Makefile.shared @@ -0,0 +1,63 @@ +include ../support/Makefile.common + +LABLTKLIB=-I ../labltk -I ../lib -I ../support +OCAMLTOPLIB=-I $(TOPDIR)/parsing -I $(TOPDIR)/utils -I $(TOPDIR)/typing +INCLUDES=$(OTHERSLIB) $(LABLTKLIB) $(OCAMLTOPLIB) + +OBJ = list2.cmo useunix.cmo setpath.cmo lexical.cmo \ + fileselect.cmo searchid.cmo searchpos.cmo shell.cmo \ + help.cmo \ + viewer.cmo typecheck.cmo editor.cmo main.cmo + +JG = jg_tk.cmo jg_config.cmo jg_bind.cmo jg_completion.cmo \ + jg_box.cmo \ + jg_button.cmo jg_toplevel.cmo jg_text.cmo jg_message.cmo \ + jg_menu.cmo jg_entry.cmo jg_multibox.cmo jg_memo.cmo + +# Default rules + +.SUFFIXES: .ml .mli .cmo .cmi .cmx .c .$(O) + +.ml.cmo: + $(CAMLCOMP) $(INCLUDES) $< + +.mli.cmi: + $(CAMLCOMP) $(INCLUDES) $< + +.c.$(O): + $(BYTECC) $(BYTECCCOMPOPTS) $(CCFLAGS) -c $< + +all: ocamlbrowser$(EXE) + +ocamlbrowser$(EXE): $(TOPDIR)/toplevel/toplevellib.cma jglib.cma $(OBJ) \ + ../support/lib$(LIBNAME).$(A) + $(CAMLC) -o ocamlbrowser$(EXE) $(INCLUDES) \ + $(TOPDIR)/toplevel/toplevellib.cma \ + unix.cma str.cma $(OCAMLBR) $(LIBNAME).cma jglib.cma $(OBJ) + +ocamlbrowser.cma: jglib.cma $(OBJ) + $(CAMLC) -a -o $@ -linkall jglib.cma $(OBJ) + +jglib.cma: $(JG) + $(CAMLCOMP) -a -o jglib.cma $(JG) + +help.ml: + echo 'let text = "\\' > $@ + sed -e 's/^ /\\032/' -e 's/$$/\\n\\/' help.txt >> $@ + echo '";;' >> $@ + +install: + if test -f ocamlbrowser$(EXE); then : ; \ + cp ocamlbrowser$(EXE) $(BINDIR); fi + +clean: + rm -f *.cm? ocamlbrowser$(EXE) dummy.mli *~ *.orig *.$(O) + +depend: + $(CAMLDEP) *.ml *.mli > .depend + +shell.cmo: dummy.cmi +setpath.cmo fileselect.cmo lexical.cmi searchid.cmi typecheck.cmi: $(TOPDIR)/toplevel/toplevellib.cma +mytypes.cmi searchpos.cmi searchpos.cmo typecheck.cmo: $(TOPDIR)/typing/stypes.cmi + +include .depend diff --git a/otherlibs/labltk/browser/winmain.c b/otherlibs/labltk/browser/winmain.c index 4e82d1e2b..b647fb79b 100644 --- a/otherlibs/labltk/browser/winmain.c +++ b/otherlibs/labltk/browser/winmain.c @@ -3,10 +3,10 @@ #include <callback.h> #include <sys.h> -extern int __argc; -extern char **__argv; -extern void caml_expand_command_line(int * argcp, char *** argvp); -extern void caml_main (char **); +CAMLextern int __argc; +CAMLextern char **__argv; +CAMLextern void caml_expand_command_line(int * argcp, char *** argvp); +/* extern void caml_main (char **); */ int WINAPI WinMain(HINSTANCE h, HINSTANCE HPrevInstance, LPSTR lpCmdLine, int nCmdShow) diff --git a/otherlibs/labltk/camltk/Makefile b/otherlibs/labltk/camltk/Makefile index afa6f3af2..c3b4e3db1 100644 --- a/otherlibs/labltk/camltk/Makefile +++ b/otherlibs/labltk/camltk/Makefile @@ -1,8 +1,6 @@ include ../support/Makefile.common -COMPFLAGS= -I ../support - -TOPDEPS = $(TOPDIR)/toplevel/toplevellib.cma $(TOPDIR)/toplevel/topmain.cmo +COMPFLAGS= -I ../support -I $(OTHERS)/win32unix -I $(OTHERS)/unix all: camltkobjs diff --git a/otherlibs/labltk/camltk/Makefile.gen b/otherlibs/labltk/camltk/Makefile.gen index 6b5478840..cbdb29808 100644 --- a/otherlibs/labltk/camltk/Makefile.gen +++ b/otherlibs/labltk/camltk/Makefile.gen @@ -2,10 +2,10 @@ include ../support/Makefile.common all: cTk.ml camltk.ml .depend -_tkgen.ml: ../Widgets.src ../compiler/tkcompiler - cd ..; $(CAMLRUNGEN) compiler/tkcompiler -camltk -outdir camltk +_tkgen.ml: ../Widgets.src ../compiler/tkcompiler$(EXE) + cd ..; $(CAMLRUNGEN) compiler/tkcompiler$(EXE) -camltk -outdir camltk -cTk.ml camltk.ml .depend: _tkgen.ml ../builtin/report.ml ../compiler/pp #../builtin/builtin_*.ml +cTk.ml camltk.ml .depend: _tkgen.ml ../builtin/report.ml ../compiler/pp$(EXE) #../builtin/builtin_*.ml (echo '##define CAMLTK'; \ echo 'include Camltkwrap'; \ echo 'open Widget'; \ @@ -34,13 +34,16 @@ cTk.ml camltk.ml .depend: _tkgen.ml ../builtin/report.ml ../compiler/pp #../buil ) > _cTk.ml $(CAMLRUN) ../compiler/pp < _cTk.ml > cTk.ml rm -f _cTk.ml - $(CAMLDEP) -I ../support [a-z]*.mli [a-z]*.ml > .depend + $(CAMLDEP) -slash -I ../support [a-z]*.mli [a-z]*.ml > .depend -../compiler/pp: - cd ../compiler; $(MAKE) pp +../compiler/pp$(EXE): + cd ../compiler; $(MAKE) pp($EXE) + +../compiler/tkcompiler$(EXE): + cd ../compiler; $(MAKE) tkcompiler($EXE) # All .{ml,mli} files are generated in this directory clean: - rm -f *.cm* *.ml *.mli *.o *.a .depend + rm -f *.cm* *.ml *.mli *.$(O) *.$(A) .depend # rm -f modules diff --git a/otherlibs/labltk/camltk/Makefile.gen.nt b/otherlibs/labltk/camltk/Makefile.gen.nt index 4fdba7713..046b87823 100644 --- a/otherlibs/labltk/camltk/Makefile.gen.nt +++ b/otherlibs/labltk/camltk/Makefile.gen.nt @@ -1,46 +1 @@ -include ../support/Makefile.common.nt - -all: cTk.ml camltk.ml .depend - -_tkgen.ml: ../Widgets.src ../compiler/tkcompiler.exe - cd .. ; $(CAMLRUNGEN) compiler/tkcompiler.exe -camltk -outdir camltk - -# dependencies are broken: wouldn't work with gmake 3.77 - -cTk.ml camltk.ml .depend: _tkgen.ml ../builtin/report.ml ../compiler/pp.exe #../builtin/builtin_*.ml - (echo '##define CAMLTK'; \ - echo 'include Camltkwrap'; \ - echo 'open Widget'; \ - echo 'open Protocol'; \ - echo 'open Textvariable'; \ - echo ; \ - cat ../builtin/report.ml; \ - echo ; \ - cat ../builtin/builtin_*.ml; \ - echo ; \ - cat _tkgen.ml; \ - echo ; \ - echo ; \ - echo 'module Tkintf = struct'; \ - cat ../builtin/builtini_*.ml; \ - cat _tkigen.ml; \ - echo 'end (* module Tkintf *)'; \ - echo ; \ - echo ; \ - echo 'open Tkintf' ;\ - echo ; \ - echo ; \ - cat ../builtin/builtinf_*.ml; \ - cat _tkfgen.ml; \ - echo ; \ - ) > _cTk.ml - $(CAMLRUN) ../compiler/pp < _cTk.ml > cTk.ml - rm -f _cTk.ml - $(CAMLDEP) -slash -I ../support [a-z]*.mli [a-z]*.ml > .depend - -../compiler/pp.exe: - cd ../compiler; $(MAKEREC) pp.exe - -clean: - rm -f *.cm* *.ml *.mli *.$(O) *.$(A) -# rm -f modules .depend +include Makefile.gen diff --git a/otherlibs/labltk/camltk/Makefile.nt b/otherlibs/labltk/camltk/Makefile.nt index 6c81dbc49..2b0b5ab53 100644 --- a/otherlibs/labltk/camltk/Makefile.nt +++ b/otherlibs/labltk/camltk/Makefile.nt @@ -1,43 +1 @@ -include ../support/Makefile.common.nt - -COMPFLAGS= -I ../support - -all: camltkobjs - -opt: camltkobjsx - -# All .{ml,mli} files are generated in this directory -clean : - rm -f *.cm* *.ml *.mli *.$(A) *.$(O) - $(MAKE) -f Makefile.gen.nt clean - -include ./modules - -CAMLTKOBJS = $(WIDGETOBJS) cTk.cmo camltk.cmo -CAMLTKOBJSX = $(CAMLTKOBJS:.cmo=.cmx) - -camltkobjs: $(CAMLTKOBJS) - -camltkobjsx: $(CAMLTKOBJSX) - -install: $(CAMLTKOBJS) - mkdir -p $(INSTALLDIR) - cp *.cmi [a-z]*.mli $(INSTALLDIR) - -installopt: $(CAMLTKOBJSX) - mkdir -p $(INSTALLDIR) - cp $(CAMLTKOBJSX) $(INSTALLDIR) - -.SUFFIXES : -.SUFFIXES : .mli .ml .cmi .cmx .cmo .mlp - -.mli.cmi: - $(CAMLCOMP) $(COMPFLAGS) $< - -.ml.cmo: - $(CAMLCOMP) $(COMPFLAGS) $< - -.ml.cmx: - $(CAMLOPT) -c $(COMPFLAGS) $< - -include .depend +include Makefile diff --git a/otherlibs/labltk/compiler/Makefile.nt b/otherlibs/labltk/compiler/Makefile.nt index 3c936ba4c..2b0b5ab53 100644 --- a/otherlibs/labltk/compiler/Makefile.nt +++ b/otherlibs/labltk/compiler/Makefile.nt @@ -1,63 +1 @@ -include ../support/Makefile.common.nt - -OBJS= ../support/support.cmo flags.cmo copyright.cmo \ - tsort.cmo tables.cmo printer.cmo lexer.cmo \ - pplex.cmo ppyac.cmo ppexec.cmo ppparse.cmo \ - parser.cmo compile.cmo intf.cmo maincompile.cmo - -PPOBJS= pplex.cmo ppyac.cmo ppexec.cmo ppparse.cmo pp.cmo - -all: tkcompiler.exe pp.exe - -tkcompiler.exe : $(OBJS) - $(CAMLC) $(LINKFLAGS) -o tkcompiler.exe $(OBJS) - -pp.exe : $(PPOBJS) - $(CAMLC) $(LINKFLAGS) -o pp.exe $(PPOBJS) - -lexer.ml: lexer.mll - $(CAMLLEX) lexer.mll - -parser.ml parser.mli: parser.mly - $(CAMLYACC) -v parser.mly - -pplex.ml: pplex.mll - $(CAMLLEX) pplex.mll - -pplex.mli: ppyac.cmi - -ppyac.ml ppyac.mli: ppyac.mly - $(CAMLYACC) -v ppyac.mly - -copyright.ml: copyright - (echo "let copyright=\"\\"; \ - cat copyright; \ - echo "\""; \ - echo "let write ~w = w copyright;;") > copyright.ml - -clean : - rm -f *.cm* parser.ml parser.mli lexer.ml copyright.ml - rm -f pplex.ml ppyac.ml ppyac.mli ppyac.output - rm -f tkcompiler.exe pp.exe parser.output - -scratch : - rm -f *.cm* parser.ml parser.mli lexer.ml tkcompiler.exe - rm -f *.cm* pplex.ml ppyac.ml ppyac.mli pp.exe - -install: - cp tkcompiler.exe $(INSTALLDIR) - cp pp.exe $(INSTALLDIR) - -.SUFFIXES : -.SUFFIXES : .mli .ml .cmi .cmo .mlp - -.mli.cmi: - $(CAMLCOMP) $(COMPFLAGS) -I ../support $< - -.ml.cmo: - $(CAMLCOMP) $(COMPFLAGS) -I ../support $< - -depend: parser.ml parser.mli lexer.ml pplex.ml ppyac.ml ppyac.mli - $(CAMLDEP) *.mli *.ml > .depend - -include .depend +include Makefile diff --git a/otherlibs/labltk/frx/Makefile b/otherlibs/labltk/frx/Makefile index 226ba129f..4793727a6 100644 --- a/otherlibs/labltk/frx/Makefile +++ b/otherlibs/labltk/frx/Makefile @@ -1,6 +1,6 @@ include ../support/Makefile.common -COMPFLAGS=-I ../camltk -I ../support -I $(OTHERS)/unix +COMPFLAGS=-I ../camltk -I ../support OBJS= frx_misc.cmo frx_widget.cmo frx_font.cmo frx_entry.cmo frx_text.cmo \ frx_listbox.cmo frx_req.cmo frx_fillbox.cmo frx_focus.cmo \ @@ -23,10 +23,10 @@ install: frxlib.cma cp *.cmi *.mli frxlib.cma $(INSTALLDIR) installopt: frxlib.cmxa - cp frxlib.cmxa frxlib.a $(INSTALLDIR) + cp frxlib.cmxa frxlib.$(A) $(INSTALLDIR) clean: - rm -f *.cm* *.o *.a + rm -f *.cm* *.$(O) *.$(A) $(OBJS) $(OBJS:.cmo=.cmi): ../lib/$(LIBNAME).cma diff --git a/otherlibs/labltk/frx/Makefile.nt b/otherlibs/labltk/frx/Makefile.nt index 2f37a4cb9..2b0b5ab53 100644 --- a/otherlibs/labltk/frx/Makefile.nt +++ b/otherlibs/labltk/frx/Makefile.nt @@ -1,53 +1 @@ -include ../support/Makefile.common.nt - -COMPFLAGS=-I ../camltk -I ../support - -OBJS= frx_misc.cmo frx_widget.cmo frx_font.cmo frx_entry.cmo frx_text.cmo \ - frx_listbox.cmo frx_req.cmo frx_fillbox.cmo frx_focus.cmo \ - frx_dialog.cmo frx_mem.cmo frx_rpc.cmo frx_synth.cmo frx_selection.cmo \ - frx_after.cmo frx_fit.cmo frx_ctext.cmo frx_color.cmo - -OBJSX = $(OBJS:.cmo=.cmx) - -all: libfrx.cma - -opt: libfrx.cmxa - -libfrx.cma: $(OBJS) - $(CAMLLIBR) -o libfrx.cma $(OBJS) - -libfrx.cmxa: $(OBJSX) - $(CAMLOPTLIBR) -o libfrx.cmxa $(OBJSX) - - -install: libfrx.cma - cp *.cmi *.mli libfrx.cma $(INSTALLDIR) - -installopt: libfrx.cmxa - cp libfrx.cmxa libfrx.$(A) $(INSTALLDIR) - - -clean: - rm -f *.cm* *.$(O) *.$(A) *~ *test - -$(OBJS) $(OBJS:.cmo=.cmi): ../lib/$(LIBNAME).cma - -$(OBJSX): ../lib/$(LIBNAME).cmxa - -.SUFFIXES : -.SUFFIXES : .mli .ml .cmi .cmo .cmx - -.mli.cmi: - $(CAMLCOMP) $(COMPFLAGS) $< - -.ml.cmo: - $(CAMLCOMP) $(COMPFLAGS) $< - -.ml.cmx: - $(CAMLOPT) -c $(COMPFLAGS) $< - - -depend: - $(CAMLDEP) *.mli *.ml > .depend - -include .depend +include Makefile diff --git a/otherlibs/labltk/jpf/Makefile b/otherlibs/labltk/jpf/Makefile index 1c499356d..62a86b9a1 100644 --- a/otherlibs/labltk/jpf/Makefile +++ b/otherlibs/labltk/jpf/Makefile @@ -1,6 +1,6 @@ include ../support/Makefile.common -COMPFLAGS=-I ../labltk -I ../support -I $(OTHERS)/unix -I $(OTHERS)/str +COMPFLAGS=-I ../labltk -I ../support -I $(OTHERS)/win32unix -I $(OTHERS)/unix -I $(OTHERS)/str OBJS= fileselect.cmo balloon.cmo shell.cmo jpf_font.cmo @@ -24,10 +24,10 @@ install: jpflib.cma cp $(OBJS:.cmo=.cmi) $(OBJS:.cmo=.mli) jpflib.cma $(INSTALLDIR) installopt: jpflib.cmxa - cp jpflib.cmxa jpflib.a $(OBJS:.cmo=.cmx) $(INSTALLDIR) + cp jpflib.cmxa jpflib.$(A) $(OBJS:.cmo=.cmx) $(INSTALLDIR) clean: - rm -f *.cm* *.o *.a *~ *test + rm -f *.cm* *.$(O) *.$(A) *~ *test $(OBJS) $(OBJS:.cmo=.cmi): ../lib/$(LIBNAME).cma diff --git a/otherlibs/labltk/jpf/Makefile.nt b/otherlibs/labltk/jpf/Makefile.nt index 7501a01d4..2b0b5ab53 100644 --- a/otherlibs/labltk/jpf/Makefile.nt +++ b/otherlibs/labltk/jpf/Makefile.nt @@ -1,75 +1 @@ -include ../support/Makefile.common.nt - -COMPFLAGS=-I ../labltk -I ../support -I $(OTHERS)/win32unix -I $(OTHERS)/str - -OBJS= fileselect.cmo balloon.cmo - -OBJSX = $(OBJS:.cmo=.cmx) - -all: libjpf.cma - -opt: libjpf.cmxa - -test: balloontest - -testopt: balloontest.opt - -libjpf.cma: $(OBJS) - $(CAMLLIBR) -o libjpf.cma $(OBJS) - -libjpf.cmxa: $(OBJSX) - $(CAMLOPTLIBR) -o libjpf.cmxa $(OBJSX) - -install: libjpf.cma - cp $(OBJS:.cmo=.cmi) $(OBJS:.cmo=.mli) libjpf.cma $(INSTALLDIR) - -installopt: libjpf.cmxa - cp libjpf.cmxa libjpf.$(A) $(INSTALLDIR) - -clean: - rm -f *.cm* *.$(O) *.$(A) *~ *test - -$(OBJS) $(OBJS:.cmo=.cmi): ../lib/$(LIBNAME).cma - -$(OBJSX): ../lib/$(LIBNAME).cmxa - -### Tests - -balloontest: balloontest.cmo - $(CAMLC) -o balloontest -I ../support -I ../labltk -I ../lib \ - -custom $(LIBNAME).cma libjpf.cma balloontest.cmo $(TKLINKOPT) - -balloontest.opt: balloontest.cmx - $(CAMLOPT) -o balloontest.opt -I ../support -I ../labltk -I ../lib \ - $(LIBNAME).cmxa libjpf.cmxa balloontest.cmx $(TKLINKOPT) - -balloontest.cmo : balloon.cmo libjpf.cma - -balloontest.cmx : balloon.cmx libjpf.cmxa - -.SUFFIXES : -.SUFFIXES : .mli .ml .cmi .cmx .cmo - -.mli.cmi: - $(CAMLCOMP) $(COMPFLAGS) $< - -.ml.cmo: - $(CAMLCOMP) $(COMPFLAGS) $< - -.ml.cmx: - $(CAMLOPT) -c $(COMPFLAGS) $< - -depend: - mv Makefile Makefile.bak - (sed -n -e '1,/^### DO NOT DELETE THIS LINE/p' Makefile.bak; \ - $(CAMLDEP) *.mli *.ml) > Makefile - - -### EVERYTHING THAT GOES BEYOND THIS COMMENT IS GENERATED -### DO NOT DELETE THIS LINE -balloon.cmo: balloon.cmi -balloon.cmx: balloon.cmi -balloontest.cmo: balloon.cmi -balloontest.cmx: balloon.cmx -fileselect.cmo: fileselect.cmi -fileselect.cmx: fileselect.cmi +include Makefile diff --git a/otherlibs/labltk/labltk/Makefile b/otherlibs/labltk/labltk/Makefile index 53276dd16..b294355de 100644 --- a/otherlibs/labltk/labltk/Makefile +++ b/otherlibs/labltk/labltk/Makefile @@ -1,6 +1,6 @@ include ../support/Makefile.common -COMPFLAGS= -I ../support +COMPFLAGS= -I ../support -I $(OTHERS)/win32unix -I $(OTHERS)/unix all: labltkobjs diff --git a/otherlibs/labltk/labltk/Makefile.gen b/otherlibs/labltk/labltk/Makefile.gen index 6853d0cb2..57edae663 100644 --- a/otherlibs/labltk/labltk/Makefile.gen +++ b/otherlibs/labltk/labltk/Makefile.gen @@ -2,12 +2,12 @@ include ../support/Makefile.common all: tk.ml labltk.ml .depend -_tkgen.ml: ../Widgets.src ../compiler/tkcompiler - cd ..; $(CAMLRUNGEN) compiler/tkcompiler -outdir labltk +_tkgen.ml: ../Widgets.src ../compiler/tkcompiler$(EXE) + cd ..; $(CAMLRUNGEN) compiler/tkcompiler$(EXE) -outdir labltk # dependencies are broken: wouldn't work with gmake 3.77 -tk.ml labltk.ml .depend: _tkgen.ml ../builtin/report.ml ../compiler/pp #../builtin/builtin_*.ml +tk.ml labltk.ml .depend: _tkgen.ml ../builtin/report.ml ../compiler/pp$(EXE) #../builtin/builtin_*.ml (echo 'open StdLabels'; \ echo 'open Widget'; \ echo 'open Protocol'; \ @@ -33,13 +33,16 @@ tk.ml labltk.ml .depend: _tkgen.ml ../builtin/report.ml ../compiler/pp #../built ) > _tk.ml $(CAMLRUN) ../compiler/pp < _tk.ml > tk.ml rm -f _tk.ml - $(CAMLDEP) -I ../support [a-z]*.mli [a-z]*.ml > .depend + $(CAMLDEP) -slash -I ../support [a-z]*.mli [a-z]*.ml > .depend -../compiler/pp: - cd ../compiler; $(MAKE) pp +../compiler/pp$(EXE): + cd ../compiler; $(MAKE) pp$(EXE) + +../compiler/tkcompiler$(EXE): + cd ../compiler; $(MAKE) tkcompiler$(EXE) # All .{ml,mli} files are generated in this directory clean: - rm -f *.cm* *.ml *.mli *.o *.a .depend + rm -f *.cm* *.ml *.mli *.$(O) *.$(A) .depend # rm -f modules diff --git a/otherlibs/labltk/labltk/Makefile.gen.nt b/otherlibs/labltk/labltk/Makefile.gen.nt index 8c6522404..046b87823 100644 --- a/otherlibs/labltk/labltk/Makefile.gen.nt +++ b/otherlibs/labltk/labltk/Makefile.gen.nt @@ -1,40 +1 @@ -include ../support/Makefile.common.nt - -all: tk.ml labltk.ml .depend - -_tkgen.ml: ../Widgets.src ../compiler/tkcompiler.exe - cd .. ; $(CAMLRUNGEN) compiler/tkcompiler.exe -outdir labltk - -# dependencies are broken: wouldn't work with gmake 3.77 - -tk.ml labltk.ml .depend: _tkgen.ml ../builtin/report.ml ../compiler/pp.exe #../builtin/builtin_*.ml - (echo 'open StdLabels'; \ - echo 'open Widget'; \ - echo 'open Protocol'; \ - echo 'open Support'; \ - echo 'open Textvariable'; \ - cat ../builtin/report.ml; \ - cat ../builtin/builtin_*.ml; \ - cat _tkgen.ml; \ - echo ; \ - echo ; \ - echo 'module Tkintf = struct'; \ - cat ../builtin/builtini_*.ml; \ - cat _tkigen.ml; \ - echo 'end (* module Tkintf *)'; \ - echo ; \ - echo ; \ - echo 'open Tkintf' ;\ - echo ; \ - echo ; \ - cat ../builtin/builtinf_*.ml; \ - cat _tkfgen.ml; \ - echo ; \ - ) > _tk.ml - $(CAMLRUN) ../compiler/pp < _tk.ml > tk.ml - rm -f _tk.ml - $(CAMLDEP) -slash -I ../support [a-z]*.mli [a-z]*.ml > .depend - -clean: - rm -f *.cm* *.ml *.mli *.$(O) *.$(A) -# rm -f modules .depend +include Makefile.gen diff --git a/otherlibs/labltk/labltk/Makefile.nt b/otherlibs/labltk/labltk/Makefile.nt index a8f4f694d..2b0b5ab53 100644 --- a/otherlibs/labltk/labltk/Makefile.nt +++ b/otherlibs/labltk/labltk/Makefile.nt @@ -1,43 +1 @@ -include ../support/Makefile.common.nt - -COMPFLAGS= -I ../support - -all: labltkobjs - -opt: labltkobjsx - -# All .{ml,mli} files are generated in this directory -clean : - rm -f *.cm* *.ml *.mli *.$(A) *.$(O) - $(MAKE) -f Makefile.gen.nt clean - -include ./modules - -LABLTKOBJS = $(WIDGETOBJS) tk.cmo labltk.cmo -LABLTKOBJSX = $(LABLTKOBJS:.cmo=.cmx) - -labltkobjs: $(LABLTKOBJS) - -labltkobjsx: $(LABLTKOBJSX) - -install: $(LABLTKOBJS) - mkdir -p $(INSTALLDIR) - cp *.cmi [a-z]*.mli $(INSTALLDIR) - -installopt: $(LABLTKOBJSX) - mkdir -p $(INSTALLDIR) - cp $(LABLTKOBJSX) $(INSTALLDIR) - -.SUFFIXES : -.SUFFIXES : .mli .ml .cmi .cmx .cmo - -.mli.cmi: - $(CAMLCOMP) $(COMPFLAGS) $< - -.ml.cmo: - $(CAMLCOMP) $(COMPFLAGS) $< - -.ml.cmx: - $(CAMLOPT) -c $(COMPFLAGS) $< - -include .depend +include Makefile diff --git a/otherlibs/labltk/lib/Makefile b/otherlibs/labltk/lib/Makefile index 225c3d1c4..e2fe5f16e 100644 --- a/otherlibs/labltk/lib/Makefile +++ b/otherlibs/labltk/lib/Makefile @@ -5,12 +5,12 @@ all: $(LIBNAME).cma $(LIBNAME)top$(EXE) $(LIBNAME) opt: $(LIBNAME).cmxa clean: - rm -f $(LIBNAME)top$(EXE) $(LIBNAME) *.cm* *.a + rm -f $(LIBNAME)top$(EXE) $(LIBNAME) *.cm* *.$(A) superclean: - if test -f tk.cmo; then \ echo We have changes... Now lib directory has no .cmo files; \ - rm -f *.cm* *.o; \ + rm -f *.cm* *.$(O); \ fi include ../labltk/modules @@ -32,9 +32,9 @@ $(LIBNAME).cma: $(SUPPORT) ../Widgets.src $(MAKE) superclean cd ../labltk; $(MAKE) cd ../camltk; $(MAKE) - $(MKLIB) -ocamlc '$(CAMLC)' -o $(LIBNAME) -oc $(LIBNAME) \ + $(MKLIB) -ocamlc '$(CAMLC)' -o $(LIBNAME) \ -I ../labltk -I ../camltk $(TKOBJS) \ - $(TK_LINK) + -ccopt "\"$(TK_LINK)\"" $(LIBNAME).cmxa: $(SUPPORT:.cmo=.cmx) ../Widgets.src $(MAKE) superclean @@ -42,13 +42,13 @@ $(LIBNAME).cmxa: $(SUPPORT:.cmo=.cmx) ../Widgets.src cd ../camltk; $(MAKE) opt $(MKLIB) -ocamlopt '$(CAMLOPT)' -o $(LIBNAME) -oc $(LIBNAME) \ -I ../labltk -I ../camltk $(TKOBJS:.cmo=.cmx) \ - $(TK_LINK) + -ccopt "\"$(TK_LINK)\"" -$(LIBNAME)top$(EXE) : $(TOPDEPS) $(LIBNAME).cma ../support/lib$(LIBNAME).a +$(LIBNAME)top$(EXE) : $(TOPDEPS) $(LIBNAME).cma ../support/lib$(LIBNAME).$(A) $(CAMLC) -verbose -linkall -o $(LIBNAME)top$(EXE) -I ../support \ -I $(TOPDIR)/toplevel toplevellib.cma \ + -I $(OTHERS)/unix -I $(OTHERS)/win32unix unix.cma \ -I ../labltk -I ../camltk $(LIBNAME).cma \ - -I $(OTHERS)/unix unix.cma \ -I $(OTHERS)/str str.cma \ topstart.cmo @@ -68,7 +68,7 @@ install: installopt: @if test -d $(INSTALLDIR); then : ; else mkdir $(INSTALLDIR); fi - cp $(LIBNAME).cmxa $(LIBNAME).a $(INSTALLDIR) - cd $(INSTALLDIR); $(RANLIB) $(LIBNAME).a + cp $(LIBNAME).cmxa $(LIBNAME).$(A) $(INSTALLDIR) + cd $(INSTALLDIR); $(RANLIB) $(LIBNAME).$(A) chmod 644 $(INSTALLDIR)/$(LIBNAME).cmxa - chmod 644 $(INSTALLDIR)/$(LIBNAME).a + chmod 644 $(INSTALLDIR)/$(LIBNAME).$(A) diff --git a/otherlibs/labltk/lib/Makefile.nt b/otherlibs/labltk/lib/Makefile.nt index 4ce22aca5..67bf904ed 100644 --- a/otherlibs/labltk/lib/Makefile.nt +++ b/otherlibs/labltk/lib/Makefile.nt @@ -1,60 +1 @@ -include ../support/Makefile.common.nt - -all: $(LIBNAME).cma - -opt: $(LIBNAME).cmxa - -clean: - rm -f $(LIBNAME).cma $(LIBNAME).cmxa *.$(A) - -include ../labltk/modules -LABLTKOBJS=tk.cmo $(WIDGETOBJS) - -include ../camltk/modules -CAMLTKOBJS=cTk.cmo $(CWIDGETOBJS) labltk.cmo camltk.cmo - -SUPPORT=../support/support.cmo ../support/rawwidget.cmo \ - ../support/widget.cmo ../support/protocol.cmo \ - ../support/textvariable.cmo ../support/timer.cmo \ - ../support/fileevent.cmo ../support/camltkwrap.cmo - -TKOBJS=$(SUPPORT) $(LABLTKOBJS) $(CAMLTKOBJS) - -TOPDEPS = $(TOPDIR)/toplevel/toplevellib.cma $(TOPDIR)/toplevel/topmain.cmo - -UNIXLIB = $(call SYSLIB,wsock32) - -$(LIBNAME).cma: $(SUPPORT) - cd ../labltk ; $(MAKEREC) - cd ../camltk ; $(MAKEREC) - $(CAMLLIBR) -o $(LIBNAME).cma -I ../labltk -I ../camltk $(TKOBJS) \ - -dllib -l$(LIBNAME) -cclib -l$(LIBNAME) \ - -cclib "$(TK_LINK)" -cclib $(UNIXLIB) - -$(LIBNAME).cmxa: $(SUPPORT:.cmo=.cmx) - cd ../labltk; $(MAKEREC) opt - cd ../camltk; $(MAKEREC) opt - $(CAMLOPTLIBR) -o $(LIBNAME).cmxa -I ../labltk -I ../camltk \ - $(TKOBJS:.cmo=.cmx) -cclib -l$(LIBNAME) \ - -cclib "$(TK_LINK)" -cclib $(UNIXLIB) - -# $(LIBNAME)top$(EXE) : $(TOPDEPS) $(LIBNAME).cma ../support/lib$(LIBNAME).a -# $(CAMLC) -linkall -o $(LIBNAME)top$(EXE) -I ../support \ -# -I $(TOPDIR)/toplevel toplevellib.cma \ -# -I ../labltk -I ../camltk $(LIBNAME).cma \ -# -I $(OTHERS)/unix unix.cma \ -# -I $(OTHERS)/str str.cma \ -# topmain.cmo -# -# $(LIBNAME): Makefile $(TOPDIR)/config/Makefile -# @echo Generate $@ -# @echo "#!/bin/sh" > $@ -# @echo 'exec $(INSTALLDIR)/$(LIBNAME)top$(EXE) -I $(INSTALLDIR) $$*' >> $@ - -install: all - mkdir -p $(INSTALLDIR) - cp $(LIBNAME).cma $(INSTALLDIR) - -installopt: opt - mkdir -p $(INSTALLDIR) - cp $(LIBNAME).cmxa $(LIBNAME).$(A) $(INSTALLDIR) +include Makefile
\ No newline at end of file diff --git a/otherlibs/labltk/support/Makefile b/otherlibs/labltk/support/Makefile index 3e315bfc3..837fbc341 100644 --- a/otherlibs/labltk/support/Makefile +++ b/otherlibs/labltk/support/Makefile @@ -2,48 +2,49 @@ include Makefile.common all: support.cmo rawwidget.cmo widget.cmo protocol.cmo \ textvariable.cmo timer.cmo fileevent.cmo camltkwrap.cmo \ - tkthread.cmo lib$(LIBNAME).a + tkthread.cmo lib$(LIBNAME).$(A) opt: support.cmx rawwidget.cmx widget.cmx protocol.cmx \ textvariable.cmx timer.cmx fileevent.cmx camltkwrap.cmx \ - tkthread.cmx lib$(LIBNAME).a + tkthread.cmx lib$(LIBNAME).$(A) -COBJS=cltkCaml.o cltkUtf.o cltkEval.o cltkEvent.o cltkFile.o cltkMain.o \ - cltkMisc.o cltkTimer.o cltkVar.o cltkWait.o cltkImg.o +COBJS=cltkCaml.$(O) cltkUtf.$(O) cltkEval.$(O) cltkEvent.$(O) \ + cltkFile.$(O) cltkMain.$(O) cltkMisc.$(O) cltkTimer.$(O) \ + cltkVar.$(O) cltkWait.$(O) cltkImg.$(O) CCFLAGS=-I../../../byterun $(TK_DEFS) $(SHAREDCCCOMPOPTS) -COMPFLAGS=-I $(OTHERS)/unix +COMPFLAGS=-I $(OTHERS)/win32unix -I $(OTHERS)/unix THFLAGS=-I $(OTHERS)/systhreads -I $(OTHERS)/threads -lib$(LIBNAME).a : $(COBJS) - $(MKLIB) -o $(LIBNAME) $(COBJS) $(TK_LINK) +lib$(LIBNAME).$(A) : $(COBJS) + $(MKLIB) -o $(LIBNAME) $(COBJS) -ldopt "$(TK_LINK)" PUBMLI=fileevent.mli protocol.mli textvariable.mli timer.mli \ rawwidget.mli widget.mli PUB= $(PUBMLI) $(PUBMLI:.mli=.cmi) tkthread.mli tkthread.cmi tkthread.cmo -install: lib$(LIBNAME).a $(PUB) +install: lib$(LIBNAME).$(A) $(PUB) if test -d $(INSTALLDIR); then : ; else mkdir $(INSTALLDIR); fi - cp $(PUB) lib$(LIBNAME).a $(INSTALLDIR) - cd $(INSTALLDIR); $(RANLIB) lib$(LIBNAME).a - cd $(INSTALLDIR); chmod 644 $(PUB) lib$(LIBNAME).a - if test -f dll$(LIBNAME).so; then \ - cp dll$(LIBNAME).so $(STUBLIBDIR)/dll$(LIBNAME).so; fi + cp $(PUB) lib$(LIBNAME).$(A) $(INSTALLDIR) + cd $(INSTALLDIR); $(RANLIB) lib$(LIBNAME).$(A) + cd $(INSTALLDIR); chmod 644 $(PUB) lib$(LIBNAME).$(A) + if test -f dll$(LIBNAME)$(EXT_DLL); then \ + cp dll$(LIBNAME)$(EXT_DLL) $(STUBLIBDIR)/; fi installopt: opt @if test -d $(INSTALLDIR); then : ; else mkdir $(INSTALLDIR); fi cp $(PUBMLI:.mli=.cmx) $(INSTALLDIR) - if test -f tkthread.cmx; then \ - cp tkthread.cmx tkthread.o $(INSTALLDIR); \ - chmod 644 $(INSTALLDIR)/tkthread.cmx $(INSTALLDIR)/tkthread.o; \ + if test -f tkthread.$(O); then \ + cp tkthread.cmx tkthread.$(O) $(INSTALLDIR); \ + chmod 644 $(INSTALLDIR)/tkthread.cmx $(INSTALLDIR)/tkthread.$(O); \ fi clean : - rm -f *.cm* *.o *.a *.so + rm -f *.cm* *.o *.a *.so *.obj *.lib *.dll *.exp .SUFFIXES : -.SUFFIXES : .mli .ml .cmi .cmo .cmx .mlp .c .o +.SUFFIXES : .mli .ml .cmi .cmo .cmx .mlp .c .$(O) .mli.cmi: $(CAMLCOMP) $(COMPFLAGS) $< @@ -54,7 +55,7 @@ clean : .ml.cmx: $(CAMLOPT) -c $(COMPFLAGS) $< -.c.o: +.c.$(O): $(BYTECC) $(BYTECCCOMPOPTS) $(CCFLAGS) -c $< tkthread.cmi: tkthread.mli diff --git a/otherlibs/labltk/support/Makefile.common b/otherlibs/labltk/support/Makefile.common index b8aa786f7..215804826 100644 --- a/otherlibs/labltk/support/Makefile.common +++ b/otherlibs/labltk/support/Makefile.common @@ -2,7 +2,7 @@ ## Where you compiled Objective Caml TOPDIR=../../.. ## Path to the otherlibs subdirectory -OTHERS=../.. +OTHERS=$(TOPDIR)/otherlibs LIBNAME=labltk @@ -13,8 +13,8 @@ INSTALLDIR=$(LIBDIR)/$(LIBNAME) ## Tools from the Objective Caml distribution CAMLRUN=$(TOPDIR)/boot/ocamlrun -CAMLC=$(TOPDIR)/ocamlcomp.sh -CAMLOPT=$(TOPDIR)/ocamlcompopt.sh +CAMLC=$(CAMLRUN) $(TOPDIR)/ocamlc -nostdlib -I $(TOPDIR)/stdlib +CAMLOPT=$(CAMLRUN) $(TOPDIR)/ocamlopt -nostdlib -I $(TOPDIR)/stdlib CAMLCOMP=$(CAMLC) -c -warn-error A CAMLYACC=$(TOPDIR)/boot/ocamlyacc -v CAMLLEX=$(CAMLRUN) $(TOPDIR)/boot/ocamllex diff --git a/otherlibs/labltk/support/Makefile.common.nt b/otherlibs/labltk/support/Makefile.common.nt deleted file mode 100644 index 3f37dda00..000000000 --- a/otherlibs/labltk/support/Makefile.common.nt +++ /dev/null @@ -1,30 +0,0 @@ -## Paths are relative to subdirectories -## Where you compiled Objective Caml -TOPDIR=../../.. -## Where to find OCaml binaries -EXEDIR=$(TOPDIR) -## Path to the otherlibs subdirectory -OTHERS=../.. - -LIBNAME=labltk - -include $(TOPDIR)/config/Makefile - -INSTALLDIR=$(LIBDIR)/$(LIBNAME) -TKLINKOPT=$(STATIC) - -## Tools from the Objective Caml distribution - -CAMLRUN=$(EXEDIR)/boot/ocamlrun -CAMLC=$(CAMLRUN) $(TOPDIR)/ocamlc -I $(TOPDIR)/stdlib -CAMLCOMP=$(CAMLC) -c -CAMLYACC=$(EXEDIR)/boot/ocamlyacc -v -CAMLLEX=$(CAMLRUN) $(TOPDIR)/boot/ocamllex -CAMLLIBR=$(CAMLC) -a -CAMLDEP=$(CAMLRUN) $(TOPDIR)/tools/ocamldep -COMPFLAGS= -LINKFLAGS= - -CAMLOPT=$(CAMLRUN) $(TOPDIR)/ocamlopt -I $(TOPDIR)/stdlib -CAMLOPTLIBR=$(CAMLOPT) -a -CAMLRUNGEN=../../boot/ocamlrun diff --git a/otherlibs/labltk/support/Makefile.nt b/otherlibs/labltk/support/Makefile.nt index 64188e3c2..67bf904ed 100644 --- a/otherlibs/labltk/support/Makefile.nt +++ b/otherlibs/labltk/support/Makefile.nt @@ -1,80 +1 @@ -include Makefile.common.nt - -all: support.cmo rawwidget.cmo widget.cmo protocol.cmo \ - textvariable.cmo timer.cmo fileevent.cmo camltkwrap.cmo \ - tkthread.cmo dll$(LIBNAME).dll lib$(LIBNAME).$(A) - -opt: support.cmx rawwidget.cmx widget.cmx protocol.cmx \ - textvariable.cmx timer.cmx fileevent.cmx camltkwrap.cmx \ - tkthread.cmx lib$(LIBNAME).$(A) - -COBJS=cltkCaml.o cltkUtf.o cltkEval.o cltkEvent.o cltkFile.o \ - cltkMain.o cltkMisc.o cltkTimer.o cltkVar.o cltkWait.o cltkImg.o -DCOBJS=$(COBJS:.o=.$(DO)) -SCOBJS=$(COBJS:.o=.$(SO)) - -CCFLAGS=-I../../../byterun -I../../win32unix $(TK_DEFS) -DIN_CAMLTKSUPPORT - -COMPFLAGS=-I $(OTHERS)/win32unix -THFLAGS=-I $(OTHERS)/systhreads -I $(OTHERS)/threads - -dll$(LIBNAME).dll : $(DCOBJS) - $(call MKDLL,dll$(LIBNAME).dll,dll$(LIBNAME).$(A),\ - $(DCOBJS) ../../../byterun/ocamlrun.$(A) \ - $(TK_LINK) $(call SYSLIB,wsock32)) - -lib$(LIBNAME).$(A) : $(SCOBJS) - $(call MKLIB,lib$(LIBNAME).$(A), $(SCOBJS)) - -PUBMLI=fileevent.mli protocol.mli textvariable.mli timer.mli \ - rawwidget.mli widget.mli tkthread.mli -PUB= $(PUBMLI) $(PUBMLI:.mli=.cmi) tkthread.cmo - -install: - mkdir -p $(INSTALLDIR) - cp $(PUB) $(INSTALLDIR) - cp dll$(LIBNAME).dll $(STUBLIBDIR)/dll$(LIBNAME).dll - cp dll$(LIBNAME).$(A) lib$(LIBNAME).$(A) $(INSTALLDIR) - -installopt: - @mkdir -p $(INSTALLDIR) - cp $(PUBMLI:.mli=.cmx) $(INSTALLDIR) - cp tkthread.$(O) $(INSTALLDIR) - -clean : - rm -f *.cm* *.$(O) *.dll *.$(A) *.exp - -.SUFFIXES : -.SUFFIXES : .mli .ml .cmi .cmo .cmx .mlp .c .$(DO) .$(SO) - -.mli.cmi: - $(CAMLCOMP) $(COMPFLAGS) $< - -.ml.cmo: - $(CAMLCOMP) $(COMPFLAGS) $< - -.ml.cmx: - $(CAMLOPT) -c $(COMPFLAGS) $< - -.c.$(DO): - $(BYTECC) $(DLLCCCOMPOPTS) $(CCFLAGS) -c $< - mv $*.$(O) $*.$(DO) - -.c.$(SO): - $(BYTECC) $(BYTECCCOMPOPTS) $(CCFLAGS) -c $< - mv $*.$(O) $*.$(SO) - -tkthread.cmi: tkthread.mli - $(CAMLCOMP) $(COMPFLAGS) $(THFLAGS) $< -tkthread.cmo: tkthread.ml - $(CAMLCOMP) $(COMPFLAGS) $(THFLAGS) $< -tkthread.cmx: tkthread.ml - if test -f $(OTHERS)/systhreads/threads.cmxa; then \ - $(CAMLOPT) -c $(COMPFLAGS) $(THFLAGS) $< ; \ - fi -depend: - $(CAMLDEP) *.mli *.ml > .depend - -$(DCOBJS) $(SCOBJS): camltk.h - -include .depend +include Makefile
\ No newline at end of file diff --git a/otherlibs/labltk/tkanim/Makefile b/otherlibs/labltk/tkanim/Makefile index be7e8a7b2..6a5a60779 100644 --- a/otherlibs/labltk/tkanim/Makefile +++ b/otherlibs/labltk/tkanim/Makefile @@ -1,32 +1,33 @@ +# tkAnimGIF.c used the function Tk_ImageObjCmd, which is not available +# in a plain Tk installation. Should we disable this subdirectory ? + include ../support/Makefile.common -COMPFLAGS=-I ../../../byterun -I ../support -I ../camltk -I ../../unix +COMPFLAGS=-I ../support -I ../camltk -I ../../unix -I ../../win32unix CCFLAGS=-I../../../byterun -I../support $(TK_DEFS) $(SHAREDCCCOMPOPTS) -all: tkanim.cma libtkanim.a -opt: tkanim.cmxa libtkanim.a -example: gifanimtest +all: tkanim.cma libtkanim.$(A) +opt: tkanim.cmxa libtkanim.$(A) +example: gifanimtest$(EXE) OBJS=tkanim.cmo -COBJS= cltkaniminit.o tkAnimGIF.o +COBJS= cltkaniminit.$(O) tkAnimGIF.$(O) tkanim.cma: $(OBJS) - $(MKLIB) -ocamlc '$(CAMLC)' -o tkanim -oc tkanim \ - $(OBJS) $(TK_LINK) + $(MKLIB) -ocamlc '$(CAMLC)' -o tkanim $(OBJS) tkanim.cmxa: $(OBJS:.cmo=.cmx) - $(MKLIB) -ocamlopt '$(CAMLOPT)' -o tkanim -oc tkanim \ - $(OBJS:.cmo=.cmx) $(TK_LINK) + $(MKLIB) -ocamlopt '$(CAMLOPT)' -o tkanim $(OBJS:.cmo=.cmx) -libtkanim.a: $(COBJS) - $(MKLIB) -o tkanim $(COBJS) $(TK_LINK) +libtkanim.$(A): $(COBJS) + $(MKLIB) -o tkanim $(COBJS) -gifanimtest-static: all gifanimtest.cmo - $(CAMLC) -custom -o $@ -I ../lib -I ../support -I ../../unix -dllpath ../support -dllpath . unix.cma -ccopt -L. $(LIBNAME).cma tkanim.cma gifanimtest.cmo +gifanimtest-static$(EXE): all gifanimtest.cmo + $(CAMLC) -custom -o $@ -I ../lib -I ../support -I ../../win32unix -I ../../unix -dllpath ../support -dllpath . unix.cma -ccopt -L. $(LIBNAME).cma tkanim.cma gifanimtest.cmo # dynamic loading -gifanimtest: all gifanimtest.cmo - $(CAMLC) -o $@ -I ../lib -I ../support -I ../../unix -dllpath ../support -dllpath . unix.cma $(LIBNAME).cma tkanim.cma gifanimtest.cmo +gifanimtest$(EXE): all gifanimtest.cmo + $(CAMLC) -o $@ -I ../lib -I ../support -I ../../win32unix -I ../../unix -dllpath ../support -dllpath . unix.cma $(LIBNAME).cma tkanim.cma gifanimtest.cmo #animwish: $(TKANIM_LIB) tkAppInit.o # $(CC) -o $@ tkAppInit.o $(TK_LINK) $(X11_LINK) \ @@ -37,10 +38,10 @@ $(OBJS) $(OBJS:.cmo=.cmi): ../lib/$(LIBNAME).cma $(OBJS:.cmo=.cmx): ../lib/$(LIBNAME).cmxa clean: - rm -f *.cm* *.o *.a dlltkanim.so gifanimtest gifanimtest-static + rm -f *.cm* *.$(O) *.$(A) dlltkanim$(EXT_DLL) gifanimtest$(EXE) gifanimtest-static$(EXE) .SUFFIXES : -.SUFFIXES : .mli .ml .cmi .cmo .mlp .cmx .c .o +.SUFFIXES : .mli .ml .cmi .cmo .mlp .cmx .c .$(O) .mli.cmi: $(CAMLCOMP) $(COMPFLAGS) $< @@ -51,18 +52,18 @@ clean: .ml.cmx: $(CAMLOPT) -c $(COMPFLAGS) $< -.c.o: +.c.$(O): $(BYTECC) $(BYTECCCOMPOPTS) $(CCFLAGS) -c $< install: tkanim.cma - cp tkanim.cma *.cmi *.mli libtkanim.a $(INSTALLDIR) - if [ -f dlltkanim.so ]; then \ - cp dlltkanim.so $(STUBLIBDIR)/dlltkanim.so; \ + cp tkanim.cma *.cmi *.mli libtkanim.$(A) $(INSTALLDIR) + if [ -f dlltkanim$(EXT_DLL) ]; then \ + cp dlltkanim$(EXT_DLL) $(STUBLIBDIR)/; \ fi installopt: tkanim.cmxa - cp tkanim.cmxa tkanim.a $(INSTALLDIR) + cp tkanim.cmxa tkanim.$(A) $(INSTALLDIR) depend: tkanim.ml $(CAMLDEP) *.mli *.ml > .depend diff --git a/otherlibs/labltk/tkanim/Makefile.nt b/otherlibs/labltk/tkanim/Makefile.nt index 9c6da7ee2..2b0b5ab53 100644 --- a/otherlibs/labltk/tkanim/Makefile.nt +++ b/otherlibs/labltk/tkanim/Makefile.nt @@ -1,78 +1 @@ -include ../support/Makefile.common.nt - -CCFLAGS=-I../support -I../../../byterun $(TK_DEFS) - -COMPFLAGS=-I $(OTHERS)/win32unix -I ../support -I ../camltk - -all: tkanim.cma dlltkanim.dll libtkanim.$(A) -opt: tkanim.cmxa libtkanim.$(A) -example: gifanimtest.exe - -OBJS=tkanim.cmo -COBJS= cltkaniminit.obj tkAnimGIF.obj -DCOBJS=$(COBJS:.obj=.$(DO)) -SCOBJS=$(COBJS:.obj=.$(SO)) - -tkanim.cma: $(OBJS) - $(CAMLLIBR) -o tkanim.cma $(OBJS) \ - -dllib -ltkanim -cclib -ltkanim -cclib "$(TK_LINK)" - -tkanim.cmxa: $(OBJS:.cmo=.cmx) - $(CAMLOPTLIBR) -o tkanim.cmxa $(OBJS:.cmo=.cmx) \ - -cclib -ltkanim -cclib "$(TK_LINK)" - -libtkanim.$(A): $(SCOBJS) - $(call MKLIB,libtkanim.$(A), $(SCOBJS)) - -dlltkanim.dll: $(DCOBJS) - $(call MKDLL,dlltkanim.dll,tmp.$(A), \ - $(DCOBJS) ../support/dll$(LIBNAME).$(A) \ - ../../../byterun/ocamlrun.$(A) \ - $(TK_LINK) $(call SYSLIB,wsock32)) - rm tmp.* - -gifanimtest.exe: all gifanimtest.cmo - $(CAMLC) -custom -o $@ -I ../lib -I ../camltk -I ../support unix.cma $(LIBNAME).cma tkanim.cma gifanimtest.cmo - -# animwish: $(TKANIM_LIB) tkAppInit.o -# $(CC) -o $@ tkAppInit.o $(TK_LINK) $(X11_LINK) \ -# -L. -ltkanim $(LIBS) - -clean: - rm -f *.cm* *.$(O) *.$(A) *.dll gifanimtest.exe - -$(OBJS) $(OBJS:.cmo=.cmi): ../lib/$(LIBNAME).cma - -$(OBJS:.cmo=.cmx): ../lib/$(LIBNAME).cmxa - -.SUFFIXES : -.SUFFIXES : .mli .ml .cmi .cmo .mlp .cmx .c .$(DO) .$(SO) - -.mli.cmi: - $(CAMLCOMP) $(COMPFLAGS) $< - -.ml.cmo: - $(CAMLCOMP) $(COMPFLAGS) $< - -.ml.cmx: - $(CAMLOPT) -c $(COMPFLAGS) $< - -.c.$(DO): - $(BYTECC) $(DLLCCCOMPOPTS) $(CCFLAGS) -c $< - mv $*.$(O) $*.$(DO) - -.c.$(SO): - $(BYTECC) $(BYTECCCOMPOPTS) $(CCFLAGS) -c $< - mv $*.$(O) $*.$(SO) - -install: tkanim.cma - cp dlltkanim.dll $(STUBLIBDIR)/dlltkanim.dll - cp tkanim.cma *.cmi *.mli libtkanim.$(A) $(INSTALLDIR) - -installopt: tkanim.cmxa - cp tkanim.cmxa tkanim.$(A) $(INSTALLDIR) - -depend: tkanim.ml - $(CAMLDEP) *.mli *.ml > .depend - -include .depend +include Makefile diff --git a/otherlibs/num/Makefile b/otherlibs/num/Makefile index 59af1a6d9..238e98a6b 100644 --- a/otherlibs/num/Makefile +++ b/otherlibs/num/Makefile @@ -15,68 +15,20 @@ # Makefile for the "num" (exact rational arithmetic) library -include ../../config/Makefile - -# Compilation options -CC=$(BYTECC) -CFLAGS=-O -I../../byterun $(BYTECCCOMPOPTS) $(SHAREDCCCOMPOPTS) \ - -DBNG_ARCH_$(BNG_ARCH) -DBNG_ASM_LEVEL=$(BNG_ASM_LEVEL) -CAMLC=../../ocamlcomp.sh -CAMLOPT=../../ocamlcompopt.sh -MKLIB=../../boot/ocamlrun ../../tools/ocamlmklib -COMPFLAGS=-warn-error A -g +LIBNAME=nums +EXTRACFLAGS=-DBNG_ARCH_$(BNG_ARCH) -DBNG_ASM_LEVEL=$(BNG_ASM_LEVEL) CAMLOBJS=int_misc.cmo nat.cmo big_int.cmo arith_flags.cmo \ ratio.cmo num.cmo arith_status.cmo - CMIFILES=big_int.cmi nat.cmi num.cmi ratio.cmi arith_status.cmi +COBJS=bng.$(O) nat_stubs.$(O) -COBJS=bng.o nat_stubs.o - -all: libnums.a nums.cma $(CMIFILES) - -allopt: libnums.a nums.cmxa $(CMIFILES) - -nums.cma: $(CAMLOBJS) - $(MKLIB) -ocamlc '$(CAMLC)' -o nums $(CAMLOBJS) - -nums.cmxa: $(CAMLOBJS:.cmo=.cmx) - $(MKLIB) -ocamlopt '$(CAMLOPT)' -o nums $(CAMLOBJS:.cmo=.cmx) - -libnums.a: $(COBJS) - $(MKLIB) -o nums $(COBJS) - -$(CAMLOBJS:.cmo=.cmx): ../../ocamlopt - -install: - if test -f dllnums.so; then cp dllnums.so $(STUBLIBDIR)/dllnums.so; fi - cp libnums.a $(LIBDIR)/libnums.a - cd $(LIBDIR); $(RANLIB) libnums.a - cp nums.cma $(CMIFILES) $(CMIFILES:.cmi=.mli) $(LIBDIR) - -installopt: - cp $(CAMLOBJS:.cmo=.cmx) nums.cmxa nums.a $(LIBDIR) - cd $(LIBDIR); $(RANLIB) nums.a - -partialclean: - rm -f *.cm* - -clean: partialclean - rm -f *.a *.o *.so - cd test; $(MAKE) clean - -.SUFFIXES: .ml .mli .cmi .cmo .cmx - -.mli.cmi: - $(CAMLC) -c $(COMPFLAGS) $< - -.ml.cmo: - $(CAMLC) -c $(COMPFLAGS) $< +include ../Makefile -.ml.cmx: - $(CAMLOPT) -c $(COMPFLAGS) $< +clean:: + cd test ; $(MAKE) clean -bng.o: bng.h bng_digit.c \ +bng.$(O): bng.h bng_digit.c \ bng_alpha.c bng_amd64.c bng_ia32.c bng_mips.c bng_ppc.c bng_sparc.c depend: diff --git a/otherlibs/num/Makefile.nt b/otherlibs/num/Makefile.nt index 3599bd221..b986460cc 100644 --- a/otherlibs/num/Makefile.nt +++ b/otherlibs/num/Makefile.nt @@ -15,83 +15,22 @@ # Makefile for the "num" (exact rational arithmetic) library -include ../../config/Makefile - -# Compilation options -CC=$(BYTECC) -CFLAGS=-I../../byterun \ - -DBNG_ARCH_$(BNG_ARCH) -DBNG_ASM_LEVEL=$(BNG_ASM_LEVEL) -CAMLC=../../boot/ocamlrun ../../ocamlc -I ../../boot -w s -CAMLOPT=../../boot/ocamlrun ../../ocamlopt -I ../../stdlib -w s -COMPFLAGS=-warn-error A -g - +LIBNAME=nums +EXTRACFLAGS=-DBNG_ARCH_$(BNG_ARCH) -DBNG_ASM_LEVEL=$(BNG_ASM_LEVEL) CAMLOBJS=int_misc.cmo nat.cmo big_int.cmo arith_flags.cmo \ ratio.cmo num.cmo arith_status.cmo - CMIFILES=big_int.cmi nat.cmi num.cmi ratio.cmi arith_status.cmi +COBJS=bng.$(O) nat_stubs.$(O) -DCOBJS=bng.$(DO) nat_stubs.$(DO) -SCOBJS=bng.$(SO) nat_stubs.$(SO) - -all: dllnums.dll libnums.$(A) nums.cma $(CMIFILES) - -allopt: libnums.$(A) nums.cmxa $(CMIFILES) - -nums.cma: $(CAMLOBJS) - $(CAMLC) -a -o nums.cma $(CAMLOBJS) -dllib -lnums -cclib -lnums - -nums.cmxa: $(CAMLOBJS:.cmo=.cmx) - $(CAMLOPT) -a -o nums.cmxa $(CAMLOBJS:.cmo=.cmx) -cclib -lnums - -dllnums.dll: $(DCOBJS) - $(call MKDLL,dllnums.dll,tmp.$(A),\ - $(DCOBJS) ../../byterun/ocamlrun.$(A)) - rm tmp.* - -libnums.$(A): $(SCOBJS) - $(call MKLIB,libnums.$(A),$(SCOBJS)) - -$(CAMLOBJS:.cmo=.cmx): ../../ocamlopt +include ../Makefile.nt -install: - cp dllnums.dll $(STUBLIBDIR)/dllnums.dll - cp libnums.$(A) $(LIBDIR)/libnums.$(A) - cp nums.cma $(CMIFILES) $(LIBDIR) - -installopt: - cp $(CAMLOBJS:.cmo=.cmx) nums.cmxa nums.$(A) $(LIBDIR) - -partialclean: - rm -f *.cm* - -clean: partialclean - rm -f *.dll *.$(A) *.$(O) +clean:: cd test ; $(MAKEREC) clean -.SUFFIXES: .ml .mli .cmi .cmo .cmx .$(DO) .$(SO) - -.mli.cmi: - $(CAMLC) -c $(COMPFLAGS) $< - -.ml.cmo: - $(CAMLC) -c $(COMPFLAGS) $< - -.ml.cmx: - $(CAMLOPT) -c $(COMPFLAGS) $< - -.c.$(DO): - $(BYTECC) $(DLLCCCOMPOPTS) $(CFLAGS) -c $< - mv $*.$(O) $*.$(DO) - -.c.$(SO): - $(BYTECC) $(BYTECCCOMPOPTS) $(CFLAGS) -c $< - mv $*.$(O) $*.$(SO) - -bng.$(DO) bng.$(SO): bng.h bng_digit.c \ +bng.$(O): bng.h bng_digit.c \ bng_alpha.c bng_amd64.c bng_ia32.c bng_mips.c bng_ppc.c bng_sparc.c depend: - sed -e 's/\.o/.$(DO)/g' .depend > .depend.nt - sed -e 's/\.o/.$(SO)/g' .depend >> .depend.nt + sed -e 's/\.o/.$(O)/g' .depend > .depend.nt include .depend.nt diff --git a/otherlibs/str/Makefile b/otherlibs/str/Makefile index 4caefdb17..049640c4d 100644 --- a/otherlibs/str/Makefile +++ b/otherlibs/str/Makefile @@ -15,58 +15,17 @@ # Makefile for the str library -include ../../config/Makefile -# Compilation options -CC=$(BYTECC) -CFLAGS=-O -I../../byterun $(BYTECCCOMPOPTS) $(SHAREDCCCOMPOPTS) -CAMLC=../../ocamlcomp.sh -CAMLOPT=../../ocamlcompopt.sh -COMPFLAGS=-warn-error A -g -COBJS=strstubs.o -MKLIB=../../boot/ocamlrun ../../tools/ocamlmklib +LIBNAME=str +COBJS=strstubs.$(O) +CAMLOBJS=str.cmo -all: libstr.a str.cmi str.cma +include ../Makefile -allopt: libstr.a str.cmi str.cmxa - -libstr.a: $(COBJS) - $(MKLIB) -o str $(COBJS) - -str.cma: str.cmo - $(MKLIB) -ocamlc '$(CAMLC)' -o str str.cmo - -str.cmxa: str.cmx - $(MKLIB) -ocamlopt '$(CAMLOPT)' -o str str.cmx - -str.cmx: ../../ocamlopt - -partialclean: - rm -f *.cm* - -clean: partialclean - rm -f *.a *.so *.o - -install: - if test -f dllstr.so; then cp dllstr.so $(STUBLIBDIR)/dllstr.so; fi - cp libstr.a $(LIBDIR)/libstr.a - cd $(LIBDIR); $(RANLIB) libstr.a - cp str.cma str.cmi str.mli $(LIBDIR) - -installopt: - cp str.cmx str.cmxa str.a $(LIBDIR) - cd $(LIBDIR); $(RANLIB) str.a - -.SUFFIXES: .ml .mli .cmo .cmi .cmx - -.mli.cmi: - $(CAMLC) -c $(COMPFLAGS) $< - -.ml.cmo: - $(CAMLC) -c $(COMPFLAGS) $< +depend: -.ml.cmx: - $(CAMLOPT) -c $(COMPFLAGS) $< +str.cmo: str.cmi +str.cmx: str.cmi depend: gcc -MM $(CFLAGS) *.c > .depend diff --git a/otherlibs/str/Makefile.nt b/otherlibs/str/Makefile.nt index 5442bbc18..eb026188c 100644 --- a/otherlibs/str/Makefile.nt +++ b/otherlibs/str/Makefile.nt @@ -15,68 +15,11 @@ # Makefile for the str library -include ../../config/Makefile +LIBNAME=str +COBJS=strstubs.$(O) +CAMLOBJS=str.cmo -# Compilation options -CC=$(BYTECC) -CFLAGS=-I../../byterun -CAMLC=../../boot/ocamlrun ../../ocamlc -I ../../boot -CAMLOPT=../../boot/ocamlrun ../../ocamlopt -I ../../stdlib -COMPFLAGS=-warn-error A -g -DCOBJS=strstubs.$(DO) -SCOBJS=strstubs.$(SO) - -all: dllstr.dll libstr.$(A) str.cmi str.cma - -allopt: libstr.$(A) str.cmi str.cmxa - -dllstr.dll: $(DCOBJS) - $(call MKDLL,dllstr.dll,tmp.$(A),$(DCOBJS) ../../byterun/ocamlrun.$(A)) - rm tmp.* - -libstr.$(A): $(SCOBJS) - $(call MKLIB,libstr.$(A),$(SCOBJS)) - -str.cma: str.cmo - $(CAMLC) -a -o str.cma str.cmo -dllib -lstr -cclib -lstr - -str.cmxa: str.cmx - $(CAMLOPT) -a -o str.cmxa str.cmx -cclib -lstr - -str.cmx: ../../ocamlopt - -partialclean: - rm -f *.cm* - -clean: partialclean - rm -f *.$(A) *.dll *.$(O) *.$(SO) - -install: - cp dllstr.dll $(STUBLIBDIR)/dllstr.dll - cp libstr.$(A) $(LIBDIR)/libstr.$(A) - cp str.cma str.cmi $(LIBDIR) - -installopt: - cp str.cmx str.cmxa str.$(A) $(LIBDIR) - -.SUFFIXES: .ml .mli .cmo .cmi .cmx .$(DO) .$(SO) - -.mli.cmi: - $(CAMLC) -c $(COMPFLAGS) $< - -.ml.cmo: - $(CAMLC) -c $(COMPFLAGS) $< - -.ml.cmx: - $(CAMLOPT) -c $(COMPFLAGS) $< - -.c.$(DO): - $(BYTECC) $(DLLCCCOMPOPTS) $(CFLAGS) -c $< - mv $*.$(O) $*.$(DO) - -.c.$(SO): - $(BYTECC) $(BYTECCCOMPOPTS) $(CFLAGS) -c $< - mv $*.$(O) $*.$(SO) +include ../Makefile.nt depend: diff --git a/otherlibs/systhreads/Makefile b/otherlibs/systhreads/Makefile index 83c40a669..1a247513c 100644 --- a/otherlibs/systhreads/Makefile +++ b/otherlibs/systhreads/Makefile @@ -29,7 +29,7 @@ GENFILES=thread.ml all: libthreads.a threads.cma -allopt: libthreadsnat.a threads.cmxa +allopt: libthreadsnat.a threads.cmxa threads.$(CMXS) libthreads.a: $(BYTECODE_C_OBJS) $(MKLIB) -o threads $(BYTECODE_C_OBJS) @@ -55,7 +55,17 @@ threads.cma: $(THREAD_OBJS) # See remark above: force static linking of libthreadsnat.a threads.cmxa: $(THREAD_OBJS:.cmo=.cmx) $(CAMLOPT) -a -o threads.cmxa $(THREAD_OBJS:.cmo=.cmx) \ - -cclib -lthreadsnat -cclib -lunix $(PTHREAD_LINK) + -cclib -lthreadsnat $(PTHREAD_LINK) + +# Note: I removed "-cclib -lunix" from the line above. +# Indeed, if we link threads.cmxa, then we must also link unix.cmxa, +# which itself will pass -lunix to the C linker. It seems more +# modular to me this way. -- Alain + + +# Build threads.cmxs, even if unsafe +threads.cmxs: threads.cmxa + $(CAMLOPT) -shared -dlcode -o threads.cmxs -I . threads.cmxa -linkall $(THREAD_OBJS:.cmo=.cmx): ../../ocamlopt @@ -83,6 +93,7 @@ installopt: cd $(LIBDIR); $(RANLIB) libthreadsnat.a cp $(THREAD_OBJS:.cmo=.cmx) threads.cmxa threads.a $(LIBDIR)/threads cd $(LIBDIR)/threads; $(RANLIB) threads.a + if test -f unix.cmxs; then cp unix.cmxs $(LIBDIR)/; fi .SUFFIXES: .ml .mli .cmo .cmi .cmx @@ -93,7 +104,7 @@ installopt: $(CAMLC) -c $(COMPFLAGS) $< .ml.cmx: - $(CAMLOPT) -c $(COMPFLAGS) $< + $(CAMLOPT) -dlcode -c $(COMPFLAGS) $< depend: $(GENFILES) -gcc -MM -I../../byterun *.c > .depend diff --git a/otherlibs/systhreads/Makefile.nt b/otherlibs/systhreads/Makefile.nt index be5ce4add..a5380134b 100644 --- a/otherlibs/systhreads/Makefile.nt +++ b/otherlibs/systhreads/Makefile.nt @@ -19,46 +19,50 @@ include ../../config/Makefile CAMLC=../../boot/ocamlrun ../../ocamlc -I ../../stdlib -I ../win32unix CAMLOPT=../../boot/ocamlrun ../../ocamlopt -I ../../stdlib -I ../win32unix COMPFLAGS=-warn-error A -g +MKLIB=../../boot/ocamlrun ../../tools/ocamlmklib +CFLAGS=-I../../byterun $(EXTRACFLAGS) -THREAD_OBJS=thread.cmo mutex.cmo condition.cmo event.cmo threadUnix.cmo +CAMLOBJS=thread.cmo mutex.cmo condition.cmo event.cmo threadUnix.cmo +CMIFILES=$(CAMLOBJS:.cmo=.cmi) +COBJS=win32_b.$(O) +COBJS_NAT=win32_n.$(O) GENFILES=thread.ml -all: dllthreads.dll libthreads.$(A) threads.cma +LIBNAME=threads -allopt: libthreadsnat.$(A) threads.cmxa +all: lib$(LIBNAME).$(A) $(LIBNAME).cma $(CMIFILES) -dllthreads.dll: win32_b.$(DO) - $(call MKDLL,dllthreads.dll,tmp.$(A),win32_b.$(DO) ../../byterun/ocamlrun.$(A)) - rm tmp.* +allopt: lib$(LIBNAME).$(A) $(LIBNAME).cmxa $(LIBNAME).cmxs $(CMIFILES) -libthreads.$(A): win32_b.$(SO) - $(call MKLIB,libthreads.$(A),win32_b.$(SO)) +$(LIBNAME).cma: $(CAMLOBJS) + $(MKLIB) -o $(LIBNAME) -ocamlc "..\\..\\boot\\ocamlrun ..\\..\\ocamlc" -linkall $(CAMLOBJS) $(LINKOPTS) -win32_b.$(DO): win32.c - $(BYTECC) -I../../byterun $(DLLCCCOMPOPTS) -c win32.c - mv win32.$(O) win32_b.$(DO) +lib$(LIBNAME).$(A): $(COBJS) + $(MKLIB) -o $(LIBNAME) $(COBJS) $(LDOPTS) -win32_b.$(SO): win32.c - $(BYTECC) -I../../byterun $(BYTECCCOMPOPTS) -c win32.c - mv win32.$(O) win32_b.$(SO) +win32_b.$(O): win32.c + $(BYTECC) $(BYTECCCOMPOPTS) $(CFLAGS) -c win32.c + mv win32.$(O) win32_b.$(O) -libthreadsnat.$(A): win32_n.$(O) - $(call MKLIB,libthreadsnat.$(A),win32_n.$(O)) + + +$(LIBNAME).cmxa: $(CAMLOBJS:.cmo=.cmx) + $(MKLIB) -o $(LIBNAME)nat -ocamlopt "..\\..\\boot\\ocamlrun ..\\..\\ocamlopt" -linkall $(CAMLOBJS:.cmo=.cmx) $(LINKOPTS) + mv $(LIBNAME)nat.cmxa $(LIBNAME).cmxa + mv $(LIBNAME)nat.$(A) $(LIBNAME).$(A) + +$(LIBNAME).cmxs: $(LIBNAME).cmxa lib$(LIBNAME)nat.$(A) + $(CAMLOPT) -shared -o $(LIBNAME).cmxs -I . $(LIBNAME).cmxa -linkall + +lib$(LIBNAME)nat.$(A): $(COBJS_NAT) + $(MKLIB) -o $(LIBNAME)nat $(COBJS_NAT) $(LDOPTS) win32_n.$(O): win32.c $(NATIVECC) -DNATIVE_CODE -O -I../../asmrun -I../../byterun $(NATIVECCCOMPOPTS) -c win32.c mv win32.$(O) win32_n.$(O) -threads.cma: $(THREAD_OBJS) - $(CAMLC) -a -o threads.cma $(THREAD_OBJS) \ - -dllib -lthreads -cclib -lthreads - -threads.cmxa: $(THREAD_OBJS:.cmo=.cmx) - $(CAMLOPT) -a -o threads.cmxa $(THREAD_OBJS:.cmo=.cmx) \ - -cclib -lthreadsnat - -$(THREAD_OBJS:.cmo=.cmx): ../../ocamlopt +$(CAMLOBJS:.cmo=.cmx): ../../ocamlopt thread.ml: thread_win32.ml cp thread_win32.ml thread.ml @@ -74,12 +78,13 @@ install: cp dllthreads.dll $(STUBLIBDIR)/dllthreads.dll cp libthreads.$(A) $(LIBDIR)/libthreads.$(A) mkdir -p $(LIBDIR)/threads - cp $(THREAD_OBJS:.cmo=.cmi) threads.cma $(LIBDIR)/threads + cp $(CMIFILES) threads.cma $(LIBDIR)/threads rm -f $(LIBDIR)/threads/stdlib.cma installopt: cp libthreadsnat.$(A) $(LIBDIR)/libthreadsnat.$(A) cp $(THREAD_OBJS:.cmo=.cmx) threads.cmxa threads.$(A) $(LIBDIR)/threads + cp threads.cmxs $(LIBDIR)/threads .SUFFIXES: .ml .mli .cmo .cmi .cmx diff --git a/otherlibs/unix/Makefile b/otherlibs/unix/Makefile index 97f7d2ada..bdb4b85cb 100644 --- a/otherlibs/unix/Makefile +++ b/otherlibs/unix/Makefile @@ -15,17 +15,11 @@ # Makefile for the Unix interface library -include ../../config/Makefile +LIBNAME=unix -# Compilation options -CC=$(BYTECC) -CFLAGS=-I../../byterun -O $(BYTECCCOMPOPTS) $(SHAREDCCCOMPOPTS) -CAMLC=../../ocamlcomp.sh -CAMLOPT=../../ocamlcompopt.sh -MKLIB=../../boot/ocamlrun ../../tools/ocamlmklib -COMPFLAGS=-warn-error A -g +EXTRACAMLFLAGS=-nolabels -OBJS=accept.o access.o addrofstr.o alarm.o bind.o chdir.o chmod.o \ +COBJS=accept.o access.o addrofstr.o alarm.o bind.o chdir.o chmod.o \ chown.o chroot.o close.o closedir.o connect.o cst2constr.o cstringv.o \ dup.o dup2.o envir.o errmsg.o execv.o execve.o execvp.o exit.o \ fchmod.o fchown.o fcntl.o fork.o ftruncate.o \ @@ -42,50 +36,11 @@ OBJS=accept.o access.o addrofstr.o alarm.o bind.o chdir.o chmod.o \ time.o times.o truncate.o umask.o unixsupport.o unlink.o \ utimes.o wait.o write.o -MLOBJS=unix.cmo unixLabels.cmo +CAMLOBJS=unix.cmo unixLabels.cmo -all: libunix.a unix.cma +HEADERS=unixsupport.h -allopt: libunix.a unix.cmxa - -libunix.a: $(OBJS) - $(MKLIB) -o unix $(OBJS) - -unix.cma: $(MLOBJS) - $(MKLIB) -o unix -ocamlc '$(CAMLC)' -linkall $(MLOBJS) - -unix.cmxa: $(MLOBJS:.cmo=.cmx) - $(MKLIB) -o unix -ocamlopt '$(CAMLOPT)' -linkall $(MLOBJS:.cmo=.cmx) - -unix.cmx: ../../ocamlopt - -partialclean: - rm -f *.cm* - -clean: partialclean - rm -f *.a *.o *.so - -install: - if test -f dllunix.so; then cp dllunix.so $(STUBLIBDIR)/dllunix.so; fi - cp libunix.a $(LIBDIR)/libunix.a - cd $(LIBDIR); $(RANLIB) libunix.a - cp unix.cma $(MLOBJS:.cmo=.cmi) $(MLOBJS:.cmo=.mli) $(LIBDIR) - cp unixsupport.h $(LIBDIR)/caml - -installopt: - cp $(MLOBJS:.cmo=.cmx) unix.cmxa unix.a $(LIBDIR) - cd $(LIBDIR); $(RANLIB) unix.a - -.SUFFIXES: .ml .mli .cmo .cmi .cmx - -.mli.cmi: - $(CAMLC) -c $(COMPFLAGS) $< - -.ml.cmo: - $(CAMLC) -c $(COMPFLAGS) -nolabels $< - -.ml.cmx: - $(CAMLOPT) -c $(COMPFLAGS) -nolabels $< +include ../Makefile depend: gcc -MM $(CFLAGS) *.c > .depend diff --git a/otherlibs/win32graph/Makefile.nt b/otherlibs/win32graph/Makefile.nt index 4c2f9b92a..12e3d2392 100644 --- a/otherlibs/win32graph/Makefile.nt +++ b/otherlibs/win32graph/Makefile.nt @@ -13,82 +13,23 @@ # $Id$ -include ../../config/Makefile - -# Compilation options -CC=$(BYTECC) -CFLAGS=-I../../byterun -CAMLC=../../boot/ocamlrun ../../ocamlc -I ../../stdlib -CAMLOPT=../../boot/ocamlrun ../../ocamlopt -I ../../stdlib -COMPFLAGS=-warn-error A -g - +LIBNAME=graphics COBJS=open.$(O) draw.$(O) events.$(O) dib.$(O) CAMLOBJS=graphics.cmo WIN32LIBS=$(call SYSLIB,kernel32) $(call SYSLIB,gdi32) $(call SYSLIB,user32) +LINKOPTS=-cclib "\"$(WIN32LIBS)\"" +LDOPTS=-ldopt "$(WIN32LIBS)" -all: dllgraphics.dll libgraphics.$(A) graphics.cma - -allopt: libgraphics.$(A) graphics.cmxa - -dllgraphics.dll: $(COBJS:.$(O)=.$(DO)) - $(call MKDLL,dllgraphics.dll,tmp.$(A),\ - $(COBJS:.$(O)=.$(DO)) ../../byterun/ocamlrun.$(A) $(WIN32LIBS)) - rm tmp.* - -libgraphics.$(A): $(COBJS:.$(O)=.$(SO)) - $(call MKLIB,libgraphics.$(A),$(COBJS:.$(O)=.$(SO))) - -graphics.cma: $(CAMLOBJS) - $(CAMLC) -a -o graphics.cma $(CAMLOBJS) \ - -dllib -lgraphics -cclib -lgraphics -cclib "$(WIN32LIBS)" - -graphics.cmxa: $(CAMLOBJS:.cmo=.cmx) - $(CAMLOPT) -a -o graphics.cmxa $(CAMLOBJS:.cmo=.cmx) \ - -cclib -lgraphics -cclib "$(WIN32LIBS)" - -partialclean: - rm -f *.cm* - -clean: partialclean - rm -f *.$(A) *.dll *.exp *.$(O) - rm -f graphics.ml graphics.mli - rm -f io.h - -install: - cp dllgraphics.dll $(STUBLIBDIR)/dllgraphics.dll - cp libgraphics.$(A) $(LIBDIR)/libgraphics.$(A) - cp graphics.cmi graphics.cma $(LIBDIR) - -installopt: - cp graphics.cmxa graphics.cmx graphics.$(A) $(LIBDIR) +include ../Makefile.nt graphics.ml: ../graph/graphics.ml cp ../graph/graphics.ml graphics.ml graphics.mli: ../graph/graphics.mli cp ../graph/graphics.mli graphics.mli -.SUFFIXES: .ml .mli .cmo .cmi .cmx .$(DO) .$(SO) - -.mli.cmi: - $(CAMLC) -c $(COMPFLAGS) $< - -.ml.cmo: - $(CAMLC) -c $(COMPFLAGS) $< - -.ml.cmx: - $(CAMLOPT) -c $(COMPFLAGS) $< - -.c.$(DO): - $(BYTECC) $(DLLCCCOMPOPTS) $(CFLAGS) -c $< - mv $*.$(O) $*.$(DO) - -.c.$(SO): - $(BYTECC) $(BYTECCCOMPOPTS) $(CFLAGS) -c $< - mv $*.$(O) $*.$(SO) - depend: graphics.cmo: graphics.cmi graphics.cmx: graphics.cmi -draw.$(SO) draw.$(DO): libgraph.h -open.$(SO) open.$(DO): libgraph.h +draw.$(O): libgraph.h +open.$(O): libgraph.h diff --git a/otherlibs/win32graph/open.c b/otherlibs/win32graph/open.c index 6086626ba..d2b63b002 100644 --- a/otherlibs/win32graph/open.c +++ b/otherlibs/win32graph/open.c @@ -17,6 +17,7 @@ #include "mlvalues.h" #include "fail.h" #include "libgraph.h" +#include "callback.h" #include <windows.h> static value gr_reset(void); @@ -343,7 +344,6 @@ CAMLprim value caml_gr_sigio_handler(void) /* Processing of graphic errors */ -value * caml_named_value (char * name); static value * graphic_failure_exn = NULL; void gr_fail(char *fmt, char *arg) { diff --git a/otherlibs/win32unix/Makefile.nt b/otherlibs/win32unix/Makefile.nt index 6c473329f..3ff9b7952 100644 --- a/otherlibs/win32unix/Makefile.nt +++ b/otherlibs/win32unix/Makefile.nt @@ -13,15 +13,6 @@ # $Id$ -include ../../config/Makefile - -# Compilation options -CC=$(BYTECC) -CFLAGS=-I../../byterun -I../unix -CAMLC=../../boot/ocamlrun ../../ocamlc -I ../../stdlib -CAMLOPT=../../boot/ocamlrun ../../ocamlopt -I ../../stdlib -COMPFLAGS=-warn-error A -g - # Files in this directory WIN_FILES = accept.c bind.c channels.c close.c \ close_on.c connect.c createprocess.c dup.c dup2.c errmsg.c \ @@ -39,83 +30,31 @@ UNIX_FILES = access.c addrofstr.c chdir.c chmod.c cst2constr.c \ getserv.c gmtime.c putenv.c rmdir.c \ socketaddr.c strofaddr.c time.c unlink.c utimes.c -ALL_FILES=$(WIN_FILES) $(UNIX_FILES) - -DOBJS=$(ALL_FILES:.c=.$(DO)) -SOBJS=$(ALL_FILES:.c=.$(SO)) - -LIBS=$(call SYSLIB,wsock32) - -CAML_OBJS=unix.cmo unixLabels.cmo -CAMLOPT_OBJS=$(CAML_OBJS:.cmo=.cmx) - UNIX_CAML_FILES = unix.mli unixLabels.mli unixLabels.ml -all: dllunix.dll libunix.$(A) unix.cma - -allopt: libunix.$(A) unix.cmxa - -dllunix.dll: $(DOBJS) - $(call MKDLL,dllunix.dll,tmp.$(A),$(DOBJS) ../../byterun/ocamlrun.$(A) $(LIBS)) - rm tmp.* - -libunix.$(A): $(SOBJS) - $(call MKLIB,libunix.$(A),$(SOBJS)) - -$(DOBJS) $(SOBJS): unixsupport.h +ALL_FILES=$(WIN_FILES) $(UNIX_FILES) +WSOCKLIB=$(call SYSLIB,wsock32) -unix.cma: $(CAML_OBJS) - $(CAMLC) -a -linkall -o unix.cma $(CAML_OBJS) \ - -dllib -lunix -cclib -lunix -cclib $(LIBS) +LIBNAME=unix +COBJS=$(ALL_FILES:.c=.$(O)) +CAMLOBJS=unix.cmo unixLabels.cmo +LINKOPTS=-cclib $(WSOCKLIB) +LDOPTS=-ldopt $(WSOCKLIB) +EXTRACAMLFLAGS=-nolabels +EXTRACFLAGS=-I../unix +HEADERS=unixsupport.h -unix.cmxa: $(CAMLOPT_OBJS) - $(CAMLOPT) -a -linkall -o unix.cmxa $(CAMLOPT_OBJS) \ - -cclib -lunix -cclib $(LIBS) -partialclean: - rm -f *.cm* +include ../Makefile.nt -clean: partialclean - rm -f *.$(A) *.dll *.$(O) +clean:: rm -f $(UNIX_FILES) $(UNIX_CAML_FILES) -install: - cp dllunix.dll $(STUBLIBDIR)/dllunix.dll - cp libunix.$(A) $(LIBDIR)/libunix.$(A) - cp $(CAML_OBJS:.cmo=.cmi) unix.cma $(CAML_OBJS:.cmo=.mli) $(LIBDIR) - cp unixsupport.h $(LIBDIR)/caml - -installopt: - cp unix.cmxa $(CAML_OBJS:.cmo=.cmx) unix.$(A) $(LIBDIR) - -unixLabels.cmo: unixLabels.ml - $(CAMLC) -c $(COMPFLAGS) -nolabels unixLabels.ml - -unixLabels.cmx: unixLabels.ml - $(CAMLOPT) -c $(COMPFLAGS) -nolabels unixLabels.ml - $(UNIX_FILES) $(UNIX_CAML_FILES): %: ../unix/% cp ../unix/$* $* -.SUFFIXES: .ml .mli .cmo .cmi .cmx .$(DO) .$(SO) - -.mli.cmi: - $(CAMLC) -c $(COMPFLAGS) $< - -.ml.cmo: - $(CAMLC) -c $(COMPFLAGS) $< - -.ml.cmx: - $(CAMLOPT) -c $(COMPFLAGS) $< - -.c.$(DO): - $(BYTECC) $(DLLCCCOMPOPTS) $(CFLAGS) -c $< - mv $*.$(O) $*.$(DO) - -.c.$(SO): - $(BYTECC) $(BYTECCCOMPOPTS) $(CFLAGS) -c $< - mv $*.$(O) $*.$(SO) - depend: +$(COBJS): unixsupport.h + include .depend diff --git a/otherlibs/win32unix/winwait.c b/otherlibs/win32unix/winwait.c index 30b3c0f57..ad510c4b4 100644 --- a/otherlibs/win32unix/winwait.c +++ b/otherlibs/win32unix/winwait.c @@ -19,6 +19,7 @@ #include <memory.h> #include "unixsupport.h" #include <sys/types.h> +#include <signals.h> static value alloc_process_status(HANDLE pid, int status) { diff --git a/stdlib/Makefile.nt b/stdlib/Makefile.nt index 4551c8915..1182ecc25 100644 --- a/stdlib/Makefile.nt +++ b/stdlib/Makefile.nt @@ -55,11 +55,15 @@ stdlib.cmxa: $(OBJS:.cmo=.cmx) $(CAMLOPT) -a -o stdlib.cmxa $(OBJS:.cmo=.cmx) camlheader camlheader_ur: headernt.c ../config/Makefile - $(call MKEXE,tmpheader.exe,-I../byterun $(BYTECCCOMPOPTS) $(BYTECCLINKOPTS) headernt.c $(EXTRALIBS)) + $(BYTECC) $(BYTECCCOMPOPTS) -c -I../byterun headernt.c + $(call MKEXE,tmpheader.exe,headernt.$(O) $(EXTRALIBS), $(BYTECCLINKOPTS)) rm -f camlheader.exe mv tmpheader.exe camlheader cp camlheader camlheader_ur +# TODO: do not call flexlink to build tmpheader.exe (we don't need +# the export table) + sys.ml: sys.mlp ../VERSION sed -e "s|%%VERSION%%|`head -1 ../VERSION`|" sys.mlp >sys.ml diff --git a/test/dynlink/Makefile b/test/dynlink/Makefile new file mode 100644 index 000000000..a4c396c1e --- /dev/null +++ b/test/dynlink/Makefile @@ -0,0 +1,54 @@ +include ../../config/Makefile + +OCAMLRUN=$(BINDIR)/ocamlrun.exe +OCAMLC=$(OCAMLRUN) $(BINDIR)/ocamlc +OCAMLMKLIB=$(OCAMLRUN) $(BINDIR)/ocamlmklib + +all: demo + +stub1.$(O): stub1.c + $(OCAMLC) -c stub1.c + +libplug1.$(A): stub1.$(O) + $(OCAMLMKLIB) -o plug1 stub1.$(O) + +plug1.cmo: plug1.ml + $(OCAMLC) -c plug1.ml + +plug1.cma: plug1.cmo libplug1.$(A) + $(OCAMLMKLIB) -o plug1 plug1.cmo + +stub2.$(O): stub2.c + $(OCAMLC) -c stub2.c + +libplug2.$(A): stub2.$(O) + $(OCAMLMKLIB) -o plug2 stub2.$(O) + +plug2.cmo: plug2.ml + $(OCAMLC) -c plug2.ml + +plug2.cma: plug2.cmo libplug2.$(A) + $(OCAMLMKLIB) -o plug2 plug2.cmo + +main.cmo: main.ml + $(OCAMLC) -c main.ml + +main.exe: main.cmo + $(OCAMLC) -o main.exe dynlink.cma main.cmo + +static.exe: plug1.cma plug2.cma + $(OCAMLC) -o static.exe -linkall plug1.cma plug2.cma -use-runtime $(OCAMLRUN) + +custom.exe: plug2.cma plug1.cma + $(OCAMLC) -o custom.exe -custom -linkall plug2.cma plug1.cma + +demo: main.exe plug1.cma plug2.cma static.exe custom.exe + @echo "********** Dynamic" + -$(OCAMLRUN) ./main.exe plug1.cma plug2.cma + @echo "********** Static" + -$(OCAMLRUN) ./static.exe + @echo "********** Custom" + -./custom.exe + +clean: + rm -f *.lib *.obj *.o *.a *.dll *.manifest *.exe *.cmo *.cmi *~ *.exp *.cma *.so
\ No newline at end of file diff --git a/test/dynlink/main.ml b/test/dynlink/main.ml new file mode 100644 index 000000000..bd980f102 --- /dev/null +++ b/test/dynlink/main.ml @@ -0,0 +1,17 @@ + Dynlink.init (); + Dynlink.allow_unsafe_modules true; + for i = 1 to Array.length Sys.argv - 1 do + let name = Sys.argv.(i) in + Printf.printf "Loading %s\n" name; flush stdout; + try + if name.[0] = '-' + then Dynlink.loadfile_private + (String.sub name 1 (String.length name - 1)) + else Dynlink.loadfile name + with + | Dynlink.Error err -> + Printf.printf "Dynlink error: %s\n" + (Dynlink.error_message err) + | exn -> + Printf.printf "Error: %s\n" (Printexc.to_string exn) + done diff --git a/test/dynlink/plug1.ml b/test/dynlink/plug1.ml new file mode 100644 index 000000000..324604517 --- /dev/null +++ b/test/dynlink/plug1.ml @@ -0,0 +1,4 @@ +external stub1: unit -> string = "stub1" + + +let () = print_endline (stub1 ()) diff --git a/test/dynlink/plug2.ml b/test/dynlink/plug2.ml new file mode 100644 index 000000000..05f4fdaed --- /dev/null +++ b/test/dynlink/plug2.ml @@ -0,0 +1,4 @@ +external stub2: unit -> unit = "stub2" + + +let () = stub2 () diff --git a/test/dynlink/stub1.c b/test/dynlink/stub1.c new file mode 100644 index 000000000..18ddf3f13 --- /dev/null +++ b/test/dynlink/stub1.c @@ -0,0 +1,11 @@ +#include "caml/mlvalues.h" +#include "caml/memory.h" +#include "caml/alloc.h" +#include <stdio.h> + +value stub1() { + CAMLlocal1(x); + printf("This is stub1!\n"); + x = caml_copy_string("ABCDEF"); + return x; +} diff --git a/test/dynlink/stub2.c b/test/dynlink/stub2.c new file mode 100644 index 000000000..a11867354 --- /dev/null +++ b/test/dynlink/stub2.c @@ -0,0 +1,13 @@ +#include "caml/mlvalues.h" +#include "caml/memory.h" +#include "caml/alloc.h" +#include <stdio.h> + +extern value stub1(); + +value stub2() { + printf("This is stub2, calling stub1:\n"); + stub1(); + printf("Ok!\n"); + return Val_unit; +} diff --git a/test/natdynlink/Makefile b/test/natdynlink/Makefile new file mode 100644 index 000000000..492a17a19 --- /dev/null +++ b/test/natdynlink/Makefile @@ -0,0 +1,83 @@ +include ../../config/Makefile + +CAMLOPT=../../boot/ocamlrun ../../ocamlopt -thread -dlcode +SUBCAMLOPT=../../../boot/ocamlrun ../../../ocamlopt -dlcode +COMPFLAGS= +#SHARED=-shared -closed -S -dstartup +#SHARED=-shared + +PLUGINS=plugin.so plugin2.so sub/plugin.so sub/plugin3.so plugin4.so mypack.so packed1.so packed1_client.so pack_client.so plugin_ref.so plugin_high_arity.so plugin_ext.so plugin_simple.so bug.so plugin_thread.so plugin4_unix.so + +all: $(PLUGINS) main mylib.so + +clean: + rm -f *.so *.o *.cm* main main_ext *.exe *.s *.asm *.obj + rm -f *.a *.lib + rm -f sub/*.so sub/*.o sub/*.cm* sub/*.s sub/*.asm sub/*.obj + +main: api.cmx main.cmx + $(CAMLOPT) -o main -linkall dynlink.cmxa api.cmx main.cmx + +main_ext: api.cmx main.cmx factorial.$(O) + $(CAMLOPT) -o main_ext dynlink.cmxa api.cmx main.cmx factorial.$(O) + +sub/plugin3.cmx: sub/api.cmi sub/api.cmx sub/plugin3.ml + (cd sub; mv api.cmx api.cmx.bak; $(SUBCAMLOPT) -c $(COMPFLAGS) plugin3.ml; mv api.cmx.bak api.cmx) + +plugin2.cmx: api.cmx plugin.cmi plugin.cmx + (mv plugin.cmx plugin.cmx.bak; $(CAMLOPT) -c $(COMPFLAGS) plugin2.ml; mv plugin.cmx.bak plugin.cmx) + +sub/api.so: sub/api.cmi sub/api.ml + (cd sub; $(SUBCAMLOPT) -c $(COMPFLAGS) $(SHARED) api.ml) + +sub/api.cmi: sub/api.mli + (cd sub; $(SUBCAMLOPT) -c $(COMPFLAGS) api.mli) + +sub/api.cmx: sub/api.cmi sub/api.ml + (cd sub; $(SUBCAMLOPT) -c $(COMPFLAGS) api.ml) + +plugin.cmx: api.cmx plugin.cmi +sub/plugin.cmx: api.cmx +plugin4.cmx: api.cmx +main.cmx: api.cmx +plugin_ext.cmx: api.cmx plugin_ext.ml + $(CAMLOPT) -c $(COMPFLAGS) plugin_ext.ml + +plugin_ext.so: factorial.$(O) plugin_ext.cmx + $(CAMLOPT) $(COMPFLAGS) -shared -o plugin_ext.so factorial.$(O) plugin_ext.cmx + +plugin4_unix.so: plugin4.cmx + $(CAMLOPT) -shared -o plugin4_unix.so unix.cmxa plugin4.cmx + +packed1_client.cmx: packed1.cmx + +pack_client.cmx: mypack.cmx + +packed1.cmx: api.cmx packed1.ml + $(CAMLOPT) -c $(COMPFLAGS) -for-pack Mypack packed1.ml + +mypack.cmx: packed1.cmx + $(CAMLOPT) $(COMPFLAGS) -S -pack -o mypack.cmx packed1.cmx + +mylib.cmxa: plugin.cmx plugin2.cmx + $(CAMLOPT) $(COMPFLAGS) -a -o mylib.cmxa plugin.cmx plugin2.cmx + +.SUFFIXES: .ml .mli .cmo .cmi .cmx .so .cmxa + +.mli.cmi: + $(CAMLOPT) -c $(COMPFLAGS) $< + +.ml.cmx: + $(CAMLOPT) -c $(COMPFLAGS) $< + +.cmx.so: + $(CAMLOPT) -o $@ -shared $(COMPFLAGS) $< + +.cmxa.so: + $(CAMLOPT) -o $@ -shared -linkall $(COMPFLAGS) $< + +factorial.$(O): factorial.c + $(CAMLOPT) -c -ccopt "$(SHAREDCCCOMPOPTS)" factorial.c + +demo: all + ./main ../../otherlibs/win32unix/unix.cmxs ../../otherlibs/systhreads/threads.cmxs plugin_thread.so diff --git a/test/natdynlink/api.ml b/test/natdynlink/api.ml new file mode 100644 index 000000000..843a1c78f --- /dev/null +++ b/test/natdynlink/api.ml @@ -0,0 +1,18 @@ +let mods = ref [] + +let reg_mod name = + if List.mem name !mods then + Printf.printf "Reloading module %s\n" name + else ( + mods := name :: !mods; + Printf.printf "Registering module %s\n" name + ) + + +let cbs = ref [] + +let add_cb f = cbs := f :: !cbs +let runall () = List.iter (fun f -> f ()) !cbs + +let () = + at_exit runall diff --git a/test/natdynlink/bug.ml b/test/natdynlink/bug.ml new file mode 100644 index 000000000..02828378d --- /dev/null +++ b/test/natdynlink/bug.ml @@ -0,0 +1,2 @@ +let () = try raise (Invalid_argument "X") with Invalid_argument s -> + raise (Invalid_argument (s ^ s)) diff --git a/test/natdynlink/factorial.c b/test/natdynlink/factorial.c new file mode 100644 index 000000000..c662333ee --- /dev/null +++ b/test/natdynlink/factorial.c @@ -0,0 +1,18 @@ +#include "caml/mlvalues.h" +#include "caml/memory.h" +#include "caml/alloc.h" +#include <stdio.h> + +value factorial(value n){ + CAMLparam1(n); + CAMLlocal1(s); + + static char buf[256]; + int x = 1; + int i; + int m = Int_val(n); + for (i = 1; i <= m; i++) x *= i; + sprintf(buf,"%i",x); + s = copy_string(buf); + CAMLreturn (s); +} diff --git a/test/natdynlink/main.ml b/test/natdynlink/main.ml new file mode 100644 index 000000000..b21253fb2 --- /dev/null +++ b/test/natdynlink/main.ml @@ -0,0 +1,20 @@ +let () = + Dynlink.init (); + Dynlink.allow_unsafe_modules true; + for i = 1 to Array.length Sys.argv - 1 do + let name = Sys.argv.(i) in + Printf.printf "Loading %s\n" name; flush stdout; + try + if name.[0] = '-' + then Dynlink.loadfile_private + (String.sub name 1 (String.length name - 1)) + else Dynlink.loadfile name + with + | Dynlink.Error err -> + Printf.printf "Dynlink error: %s\n" + (Dynlink.error_message err) + | exn -> + Printf.printf "Error: %s\n" (Printexc.to_string exn) + done + + diff --git a/test/natdynlink/pack_client.ml b/test/natdynlink/pack_client.ml new file mode 100644 index 000000000..90229885e --- /dev/null +++ b/test/natdynlink/pack_client.ml @@ -0,0 +1,2 @@ +let () = + print_endline Mypack.Packed1.mykey diff --git a/test/natdynlink/packed1.ml b/test/natdynlink/packed1.ml new file mode 100644 index 000000000..8f00e39da --- /dev/null +++ b/test/natdynlink/packed1.ml @@ -0,0 +1,6 @@ +let () = + Api.reg_mod "Packed1" + +let bla = Sys.argv.(0) ^ "XXX" +let mykey = Sys.argv.(0) + diff --git a/test/natdynlink/packed1_client.ml b/test/natdynlink/packed1_client.ml new file mode 100644 index 000000000..c62534fda --- /dev/null +++ b/test/natdynlink/packed1_client.ml @@ -0,0 +1,3 @@ +let () = + Api.reg_mod "Packed1_client"; + print_endline Packed1.mykey diff --git a/test/natdynlink/plugin.ml b/test/natdynlink/plugin.ml new file mode 100644 index 000000000..501f1bfd3 --- /dev/null +++ b/test/natdynlink/plugin.ml @@ -0,0 +1,10 @@ +let rec f x = ignore ([x]); f x + +let rec fact n = if n = 0 then 1 else n * fact (n - 1) + +let facts = [ fact 1; fact 2; fact 3; fact (Random.int 4) ] + +let () = + Api.reg_mod "Plugin"; + print_endline "COUCOU"; + () diff --git a/test/natdynlink/plugin.mli b/test/natdynlink/plugin.mli new file mode 100644 index 000000000..3e659d97b --- /dev/null +++ b/test/natdynlink/plugin.mli @@ -0,0 +1 @@ +val facts: int list diff --git a/test/natdynlink/plugin2.ml b/test/natdynlink/plugin2.ml new file mode 100644 index 000000000..daecace84 --- /dev/null +++ b/test/natdynlink/plugin2.ml @@ -0,0 +1,8 @@ +(*external ex: int -> int = "caml_ex"*) + +let () = + Api.reg_mod "Plugin2"; +(* let i = ex 3 in*) + List.iter (fun i -> Printf.printf "%i\n" i) Plugin.facts; + Printf.printf "XXX\n"; + raise Exit diff --git a/test/natdynlink/plugin4.ml b/test/natdynlink/plugin4.ml new file mode 100644 index 000000000..ccf4642fb --- /dev/null +++ b/test/natdynlink/plugin4.ml @@ -0,0 +1,5 @@ +let () = + Printf.printf "time = %f\n" (Unix.time ()); + Api.reg_mod "Plugin" + + diff --git a/test/natdynlink/plugin_ext.ml b/test/natdynlink/plugin_ext.ml new file mode 100644 index 000000000..9906769fe --- /dev/null +++ b/test/natdynlink/plugin_ext.ml @@ -0,0 +1,5 @@ +external fact: int -> string = "factorial" + +let () = + Api.reg_mod "plugin_ext"; + Printf.printf "fact 10 = %s\n" (fact 10) diff --git a/test/natdynlink/plugin_high_arity.ml b/test/natdynlink/plugin_high_arity.ml new file mode 100644 index 000000000..8c58aa15f --- /dev/null +++ b/test/natdynlink/plugin_high_arity.ml @@ -0,0 +1,6 @@ +let f x x x x x x x x x x x x x = () + +let g x = f x x x x x x x x + +let () = + Api.reg_mod "HA" diff --git a/test/natdynlink/plugin_ref.ml b/test/natdynlink/plugin_ref.ml new file mode 100644 index 000000000..06001241c --- /dev/null +++ b/test/natdynlink/plugin_ref.ml @@ -0,0 +1,11 @@ +let x = ref 0 + +let () = + Api.reg_mod "Plugin_ref"; + + Api.add_cb + (fun () -> + Printf.printf "current value for ref = %i\n" !x; + incr x + ) + diff --git a/test/natdynlink/plugin_simple.ml b/test/natdynlink/plugin_simple.ml new file mode 100644 index 000000000..dd7d0226d --- /dev/null +++ b/test/natdynlink/plugin_simple.ml @@ -0,0 +1,3 @@ +let facts = [ (Random.int 4) ] + +let () = print_endline "COUCOU"; print_char '\n' diff --git a/test/natdynlink/plugin_thread.ml b/test/natdynlink/plugin_thread.ml new file mode 100644 index 000000000..5635054b4 --- /dev/null +++ b/test/natdynlink/plugin_thread.ml @@ -0,0 +1,21 @@ +let () = + Api.reg_mod "Plugin_thread"; + let _t = + Thread.create + (fun () -> + for i = 1 to 5 do + print_endline "Thread 1"; flush stdout; + Thread.delay 1.; + done + ) () + in + for i = 1 to 10 do + print_endline "Thread 2"; flush stdout; + Thread.delay 0.50; + done + + + + + + diff --git a/test/natdynlink/sub/api.ml b/test/natdynlink/sub/api.ml new file mode 100644 index 000000000..4a60586fc --- /dev/null +++ b/test/natdynlink/sub/api.ml @@ -0,0 +1,3 @@ +let f i = + Printf.printf "Sub/api: f called with %i\n" i; + i + 1 diff --git a/test/natdynlink/sub/api.mli b/test/natdynlink/sub/api.mli new file mode 100644 index 000000000..da5e52f2e --- /dev/null +++ b/test/natdynlink/sub/api.mli @@ -0,0 +1 @@ +val f : int -> int diff --git a/test/natdynlink/sub/plugin.ml b/test/natdynlink/sub/plugin.ml new file mode 100644 index 000000000..2a41493c0 --- /dev/null +++ b/test/natdynlink/sub/plugin.ml @@ -0,0 +1,7 @@ +let rec fact n = if n = 0 then 1 else n * fact (n - 1) + +let facts = [ fact 1; fact 2; fact 3; fact 4; fact 5 ] + +let () = + Api.reg_mod "Plugin'" + diff --git a/test/natdynlink/sub/plugin3.ml b/test/natdynlink/sub/plugin3.ml new file mode 100644 index 000000000..7b0b099fe --- /dev/null +++ b/test/natdynlink/sub/plugin3.ml @@ -0,0 +1,3 @@ +let () = + ignore (Api.f 10) + diff --git a/tools/Makefile b/tools/Makefile index efef1d572..500000d23 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -12,67 +12,7 @@ # $Id$ -include ../config/Makefile - -CAMLRUN=../boot/ocamlrun -CAMLC=$(CAMLRUN) ../boot/ocamlc -nostdlib -I ../boot -CAMLOPT=$(CAMLRUN) ../ocamlopt -nostdlib -I ../stdlib -CAMLLEX=$(CAMLRUN) ../boot/ocamllex -INCLUDES=-I ../utils -I ../parsing -I ../typing -I ../bytecomp -I ../asmcomp \ - -I ../driver -COMPFLAGS= -warn-error A $(INCLUDES) -LINKFLAGS=$(INCLUDES) - -all: ocamldep ocamlprof ocamlcp ocamlmktop ocamlmklib scrapelabels addlabels \ - dumpobj - -opt.opt: ocamldep.opt - -# The dependency generator - -CAMLDEP_OBJ=depend.cmo ocamldep.cmo -CAMLDEP_IMPORTS=misc.cmo config.cmo clflags.cmo terminfo.cmo \ - linenum.cmo warnings.cmo location.cmo longident.cmo \ - syntaxerr.cmo parser.cmo lexer.cmo parse.cmo - -ocamldep: depend.cmi $(CAMLDEP_OBJ) - $(CAMLC) $(LINKFLAGS) -o ocamldep $(CAMLDEP_IMPORTS) $(CAMLDEP_OBJ) - -ocamldep.opt: depend.cmi $(CAMLDEP_OBJ:.cmo=.cmx) - $(CAMLOPT) $(LINKFLAGS) -o ocamldep.opt $(CAMLDEP_IMPORTS:.cmo=.cmx) \ - $(CAMLDEP_OBJ:.cmo=.cmx) - -# ocamldep is precious: sometimes we are stuck in the middle of a -# bootstrap and we need to remake the dependencies -clean:: - if test -f ocamldep; then mv -f ocamldep ocamldep.bak; else :; fi - rm -f ocamldep.opt - -install:: - cp ocamldep $(BINDIR)/ocamldep$(EXE) - if test -f ocamldep.opt; \ - then cp ocamldep.opt $(BINDIR)/ocamldep.opt$(EXE); else :; fi - -# The profiler - -CSLPROF=ocamlprof.cmo -CSLPROF_IMPORTS=misc.cmo config.cmo clflags.cmo terminfo.cmo \ - linenum.cmo warnings.cmo location.cmo longident.cmo \ - syntaxerr.cmo parser.cmo lexer.cmo parse.cmo - -ocamlprof: $(CSLPROF) profiling.cmo - $(CAMLC) $(LINKFLAGS) -o ocamlprof $(CSLPROF_IMPORTS) $(CSLPROF) - -ocamlcp: ocamlcp.cmo - $(CAMLC) $(LINKFLAGS) -o ocamlcp main_args.cmo ocamlcp.cmo - -install:: - cp ocamlprof $(BINDIR)/ocamlprof$(EXE) - cp ocamlcp $(BINDIR)/ocamlcp$(EXE) - cp profiling.cmi profiling.cmo $(LIBDIR) - -clean:: - rm -f ocamlprof ocamlcp +include Makefile.shared # To make custom toplevels @@ -80,186 +20,3 @@ ocamlmktop: ocamlmktop.tpl ../config/Makefile sed -e 's|%%BINDIR%%|$(BINDIR)|' ocamlmktop.tpl > ocamlmktop chmod +x ocamlmktop -install:: - cp ocamlmktop $(BINDIR)/ocamlmktop - -clean:: - rm -f ocamlmktop - -# To help building mixed-mode libraries (Caml + C) - -ocamlmklib: myocamlbuild_config.cmo ocamlmklib.cmo - $(CAMLC) $(LINKFLAGS) -o ocamlmklib myocamlbuild_config.cmo ocamlmklib.cmo - -ocamlmklib.cmo: myocamlbuild_config.cmi -myocamlbuild_config.ml: ../config/Makefile - ../build/mkmyocamlbuild_config.sh - cp ../myocamlbuild_config.ml . - -install:: - cp ocamlmklib $(BINDIR)/ocamlmklib - -clean:: - rm -f ocamlmklib - -ocamlmklib.ml: ocamlmklib.mlp ../config/Makefile - echo '(* THIS FILE IS GENERATED FROM ocamlmklib.mlp *)' >ocamlmklib.ml - sed -e "s|%%BINDIR%%|$(BINDIR)|" \ - -e "s|%%SUPPORTS_SHARED_LIBRARIES%%|$(SUPPORTS_SHARED_LIBRARIES)|" \ - -e "s|%%MKSHAREDLIB%%|$(MKSHAREDLIB)|" \ - -e "s|%%BYTECCRPATH%%|$(BYTECCRPATH)|" \ - -e "s|%%NATIVECCRPATH%%|$(NATIVECCRPATH)|" \ - -e "s|%%MKSHAREDLIBRPATH%%|$(MKSHAREDLIBRPATH)|" \ - -e "s|%%RANLIB%%|$(RANLIB)|" \ - ocamlmklib.mlp >> ocamlmklib.ml - -beforedepend:: ocamlmklib.ml - -clean:: - rm -f ocamlmklib.ml - -# Converter olabl/ocaml 2.99 to ocaml 3 - -OCAML299TO3= lexer299.cmo ocaml299to3.cmo -LIBRARY3= misc.cmo warnings.cmo linenum.cmo location.cmo - -ocaml299to3: $(OCAML299TO3) - $(CAMLC) $(LINKFLAGS) -o ocaml299to3 $(LIBRARY3) $(OCAML299TO3) - -lexer299.ml: lexer299.mll - $(CAMLLEX) lexer299.mll - -#install:: -# cp ocaml299to3 $(BINDIR)/ocaml299to3$(EXE) - -clean:: - rm -f ocaml299to3 lexer299.ml - -# Label remover for interface files (upgrade 3.02 to 3.03) - -SCRAPELABELS= lexer301.cmo scrapelabels.cmo - -scrapelabels: $(SCRAPELABELS) - $(CAMLC) $(LINKFLAGS) -o scrapelabels $(LIBRARY3) $(SCRAPELABELS) - -lexer301.ml: lexer301.mll - $(CAMLLEX) lexer301.mll - -install:: - cp scrapelabels $(LIBDIR) - -clean:: - rm -f scrapelabels lexer301.ml - -# Insert labels following an interface file (upgrade 3.02 to 3.03) - -ADDLABELS_IMPORTS=misc.cmo config.cmo clflags.cmo terminfo.cmo \ - linenum.cmo warnings.cmo location.cmo longident.cmo \ - syntaxerr.cmo parser.cmo lexer.cmo parse.cmo - -addlabels: addlabels.ml - $(CAMLC) $(LINKFLAGS) -w sl -o addlabels \ - $(ADDLABELS_IMPORTS) addlabels.ml - -install:: - cp addlabels $(LIBDIR) - -clean:: - rm -f addlabels - -# The preprocessor for asm generators - -CVT_EMIT=cvt_emit.cmo - -cvt_emit: $(CVT_EMIT) - $(CAMLC) $(LINKFLAGS) -o cvt_emit $(CVT_EMIT) - -# cvt_emit is precious: sometimes we are stuck in the middle of a -# bootstrap and we need to remake the dependencies -clean:: - if test -f cvt_emit; then mv -f cvt_emit cvt_emit.bak; else :; fi - -cvt_emit.ml: cvt_emit.mll - $(CAMLLEX) cvt_emit.mll - -clean:: - rm -f cvt_emit.ml - -beforedepend:: cvt_emit.ml - -# The bytecode disassembler - -DUMPOBJ=opnames.cmo dumpobj.cmo - -dumpobj: $(DUMPOBJ) - $(CAMLC) $(LINKFLAGS) -o dumpobj \ - misc.cmo tbl.cmo config.cmo ident.cmo \ - opcodes.cmo bytesections.cmo $(DUMPOBJ) - -clean:: - rm -f dumpobj - -opnames.ml: ../byterun/instruct.h - 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 > opnames.ml - -clean:: - rm -f opnames.ml - -beforedepend:: opnames.ml - -# Dump .cmx files - -dumpapprox: dumpapprox.cmo - $(CAMLC) $(LINKFLAGS) -o dumpapprox config.cmo dumpapprox.cmo - -clean:: - rm -f dumpapprox - -# Print imported interfaces for .cmo files - -objinfo: objinfo.cmo - $(CAMLC) $(LINKFLAGS) -o objinfo config.cmo objinfo.cmo - -clean:: - rm -f objinfo - -# Scan object files for required primitives - -PRIMREQ=primreq.cmo - -primreq: $(PRIMREQ) - $(CAMLC) $(LINKFLAGS) -o primreq config.cmo $(PRIMREQ) - -clean:: - rm -f primreq - -# Common stuff - -.SUFFIXES: -.SUFFIXES: .ml .cmo .mli .cmi .cmx - -.ml.cmo: - $(CAMLC) -c $(COMPFLAGS) $< - -.mli.cmi: - $(CAMLC) -c $(COMPFLAGS) $< - -.ml.cmx: - $(CAMLOPT) $(COMPFLAGS) -c $< - -clean:: - rm -f *.cmo *.cmi - -depend: beforedepend - $(CAMLRUN) ./ocamldep $(INCLUDES) *.mli *.ml > .depend - -include .depend diff --git a/tools/Makefile.nt b/tools/Makefile.nt index b23b572c8..7bfa7922a 100644 --- a/tools/Makefile.nt +++ b/tools/Makefile.nt @@ -12,62 +12,7 @@ # $Id$ -include ../config/Makefile - -CAMLRUN=../boot/ocamlrun -CAMLC=$(CAMLRUN) ../boot/ocamlc -I ../boot -CAMLOPT=$(CAMLRUN) ../ocamlopt -CAMLLEX=$(CAMLRUN) ../boot/ocamllex -INCLUDES=-I ../utils -I ../parsing -I ../typing -I ../bytecomp -I ../asmcomp \ - -I ../driver -COMPFLAGS=$(INCLUDES) -LINKFLAGS=$(INCLUDES) - -all: ocamldep ocamlprof ocamlcp.exe ocamlmktop.exe primreq - -opt.opt: depend.cmx - -# The dependency generator - -CAMLDEP=depend.cmo ocamldep.cmo -CAMLDEP_IMPORTS=misc.cmo config.cmo clflags.cmo terminfo.cmo \ - linenum.cmo warnings.cmo location.cmo longident.cmo \ - syntaxerr.cmo parser.cmo lexer.cmo parse.cmo - -ocamldep: depend.cmi $(CAMLDEP) - $(CAMLC) $(LINKFLAGS) -o ocamldep $(CAMLDEP_IMPORTS) $(CAMLDEP) - -depend.cmx: depend.ml - $(CAMLOPT) $(INCLUDES) -I ../stdlib depend.ml - -clean:: - rm -f ocamldep - -install:: - cp ocamldep $(BINDIR)/ocamldep.exe - -beforedepend:: ocamldep.ml - -# The profiler - -CSLPROF=ocamlprof.cmo -CSLPROF_IMPORTS=misc.cmo config.cmo clflags.cmo terminfo.cmo \ - linenum.cmo warnings.cmo location.cmo longident.cmo \ - syntaxerr.cmo parser.cmo lexer.cmo parse.cmo - -ocamlprof: $(CSLPROF) profiling.cmo - $(CAMLC) $(LINKFLAGS) -o ocamlprof $(CSLPROF_IMPORTS) $(CSLPROF) - -ocamlcp.exe: ocamlcp.cmo - $(CAMLC) $(LINKFLAGS) -o ocamlcp.exe main_args.cmo ocamlcp.cmo - -install:: - cp ocamlprof $(BINDIR)/ocamlprof.exe - cp ocamlcp.exe $(BINDIR)/ocamlcp.exe - cp profiling.cmi profiling.cmo $(LIBDIR) - -clean:: - rm -f ocamlprof ocamlcp.exe +include Makefile.shared # To make custom toplevels @@ -75,98 +20,4 @@ OCAMLMKTOP=ocamlmktop.cmo OCAMLMKTOP_IMPORTS=misc.cmo config.cmo clflags.cmo ccomp.cmo ocamlmktop.exe: $(OCAMLMKTOP) - $(CAMLC) $(LINKFLAGS) -o ocamlmktop.exe $(OCAMLMKTOP_IMPORTS) $(OCAMLMKTOP) - -install:: - cp ocamlmktop.exe $(BINDIR)/ocamlmktop.exe - -clean:: - rm -f ocamlmktop.exe - -# The preprocessor for asm generators - -CVT_EMIT=cvt_emit.cmo - -cvt_emit: $(CVT_EMIT) - $(CAMLC) $(LINKFLAGS) -o cvt_emit $(CVT_EMIT) - -clean:: - rm -f cvt_emit - -cvt_emit.ml: cvt_emit.mll - $(CAMLLEX) cvt_emit.mll - -clean:: - rm -f cvt_emit.ml - -beforedepend:: cvt_emit.ml - -# The bytecode disassembler - -DUMPOBJ=opnames.cmo dumpobj.cmo - -dumpobj: $(DUMPOBJ) - $(CAMLC) $(LINKFLAGS) -o dumpobj \ - misc.cmo tbl.cmo config.cmo ident.cmo \ - opcodes.cmo bytesections.cmo $(DUMPOBJ) - -clean:: - rm -f dumpobj - -opnames.ml: ../byterun/instruct.h - sed -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 > opnames.ml - -clean:: - rm -f opnames.ml - -beforedepend:: opnames.ml - -# Dump .cmx files - -dumpapprox: dumpapprox.cmo - $(CAMLC) $(LINKFLAGS) -o dumpapprox config.cmo dumpapprox.cmo - -clean:: - rm -f dumpapprox - -# Print imported interfaces for .cmo files - -objinfo: objinfo.cmo - $(CAMLC) $(LINKFLAGS) -o objinfo config.cmo objinfo.cmo - -clean:: - rm -f objinfo - -# Scan object files for required primitives - -PRIMREQ=primreq.cmo - -primreq: $(PRIMREQ) - $(CAMLC) $(LINKFLAGS) -o primreq config.cmo $(PRIMREQ) - -clean:: - rm -f primreq - -# Common stuff - -.SUFFIXES: -.SUFFIXES: .ml .cmo .mli .cmi - -.ml.cmo: - $(CAMLC) -c $(COMPFLAGS) $< - -.mli.cmi: - $(CAMLC) -c $(COMPFLAGS) $< - -clean:: - rm -f *.cmo *.cmi - -depend: beforedepend - $(CAMLRUN) ./ocamldep $(INCLUDES) *.mli *.ml > .depend - -include .depend + $(CAMLC) $(LINKFLAGS) -o ocamlmktop $(OCAMLMKTOP_IMPORTS) $(OCAMLMKTOP) diff --git a/tools/Makefile.shared b/tools/Makefile.shared new file mode 100644 index 000000000..5f15e7b60 --- /dev/null +++ b/tools/Makefile.shared @@ -0,0 +1,274 @@ +######################################################################### +# # +# Objective Caml # +# # +# Xavier Leroy, projet Cristal, INRIA Rocquencourt # +# # +# Copyright 1999 Institut National de Recherche en Informatique et # +# en Automatique. All rights reserved. This file is distributed # +# under the terms of the Q Public License version 1.0. # +# # +######################################################################### + +# $Id$ + +include ../config/Makefile + +CAMLRUN=../boot/ocamlrun +CAMLC=$(CAMLRUN) ../boot/ocamlc -nostdlib -I ../boot +CAMLOPT=$(CAMLRUN) ../ocamlopt -nostdlib -I ../stdlib +CAMLLEX=$(CAMLRUN) ../boot/ocamllex +INCLUDES=-I ../utils -I ../parsing -I ../typing -I ../bytecomp -I ../asmcomp \ + -I ../driver +COMPFLAGS= -warn-error A $(INCLUDES) +LINKFLAGS=$(INCLUDES) + +all: ocamldep ocamlprof ocamlcp ocamlmktop ocamlmklib scrapelabels addlabels \ + dumpobj + +opt.opt: ocamldep.opt + +# The dependency generator + +CAMLDEP_OBJ=depend.cmo ocamldep.cmo +CAMLDEP_IMPORTS=misc.cmo config.cmo clflags.cmo terminfo.cmo \ + linenum.cmo warnings.cmo location.cmo longident.cmo \ + syntaxerr.cmo parser.cmo lexer.cmo parse.cmo + +ocamldep: depend.cmi $(CAMLDEP_OBJ) + $(CAMLC) $(LINKFLAGS) -o ocamldep $(CAMLDEP_IMPORTS) $(CAMLDEP_OBJ) + +ocamldep.opt: depend.cmi $(CAMLDEP_OBJ:.cmo=.cmx) + $(CAMLOPT) $(LINKFLAGS) -o ocamldep.opt $(CAMLDEP_IMPORTS:.cmo=.cmx) \ + $(CAMLDEP_OBJ:.cmo=.cmx) + +# ocamldep is precious: sometimes we are stuck in the middle of a +# bootstrap and we need to remake the dependencies +clean:: + if test -f ocamldep; then mv -f ocamldep ocamldep.bak; else :; fi + rm -f ocamldep.opt + +install:: + cp ocamldep $(BINDIR)/ocamldep$(EXE) + if test -f ocamldep.opt; \ + then cp ocamldep.opt $(BINDIR)/ocamldep.opt$(EXE); else :; fi + +# The profiler + +CSLPROF=ocamlprof.cmo +CSLPROF_IMPORTS=misc.cmo config.cmo clflags.cmo terminfo.cmo \ + linenum.cmo warnings.cmo location.cmo longident.cmo \ + syntaxerr.cmo parser.cmo lexer.cmo parse.cmo + +ocamlprof: $(CSLPROF) profiling.cmo + $(CAMLC) $(LINKFLAGS) -o ocamlprof $(CSLPROF_IMPORTS) $(CSLPROF) + +ocamlcp: ocamlcp.cmo + $(CAMLC) $(LINKFLAGS) -o ocamlcp main_args.cmo ocamlcp.cmo + +install:: + cp ocamlprof $(BINDIR)/ocamlprof$(EXE) + cp ocamlcp $(BINDIR)/ocamlcp$(EXE) + cp profiling.cmi profiling.cmo $(LIBDIR) + +clean:: + rm -f ocamlprof ocamlcp + +# To make custom toplevels + +ocamlmktop: ocamlmktop.tpl ../config/Makefile + sed -e 's|%%BINDIR%%|$(BINDIR)|' ocamlmktop.tpl > ocamlmktop + chmod +x ocamlmktop + +install:: + cp ocamlmktop $(BINDIR)/ocamlmktop + +clean:: + rm -f ocamlmktop + +# To help building mixed-mode libraries (Caml + C) + +ocamlmklib: myocamlbuild_config.cmo ocamlmklib.cmo + $(CAMLC) $(LINKFLAGS) -o ocamlmklib myocamlbuild_config.cmo ocamlmklib.cmo + +ocamlmklib.cmo: myocamlbuild_config.cmi +myocamlbuild_config.ml: ../config/Makefile + ../build/mkmyocamlbuild_config.sh + cp ../myocamlbuild_config.ml . + +install:: + cp ocamlmklib $(BINDIR)/ocamlmklib$(EXE) + +clean:: + rm -f ocamlmklib + +ocamlmklib.ml: ocamlmklib.mlp ../config/Makefile + echo '(* THIS FILE IS GENERATED FROM ocamlmklib.mlp *)' >ocamlmklib.ml + sed -e "s|%%BINDIR%%|$(BINDIR)|" \ + -e "s|%%SUPPORTS_SHARED_LIBRARIES%%|$(SUPPORTS_SHARED_LIBRARIES)|" \ + -e "s|%%MKSHAREDLIB%%|$(MKSHAREDLIB)|" \ + -e "s|%%BYTECCRPATH%%|$(BYTECCRPATH)|" \ + -e "s|%%NATIVECCRPATH%%|$(NATIVECCRPATH)|" \ + -e "s|%%MKSHAREDLIBRPATH%%|$(MKSHAREDLIBRPATH)|" \ + -e "s|%%RANLIB%%|$(RANLIB)|" \ + ocamlmklib.mlp >> ocamlmklib.ml + +beforedepend:: ocamlmklib.ml + +clean:: + rm -f ocamlmklib.ml + +# To make custom toplevels (see Makefile/Makefile.nt) + +install:: + cp ocamlmktop $(BINDIR)/ocamlmktop$(EXE) + +clean:: + rm -f ocamlmktop + + +# Converter olabl/ocaml 2.99 to ocaml 3 + +OCAML299TO3= lexer299.cmo ocaml299to3.cmo +LIBRARY3= misc.cmo warnings.cmo linenum.cmo location.cmo + +ocaml299to3: $(OCAML299TO3) + $(CAMLC) $(LINKFLAGS) -o ocaml299to3 $(LIBRARY3) $(OCAML299TO3) + +lexer299.ml: lexer299.mll + $(CAMLLEX) lexer299.mll + +#install:: +# cp ocaml299to3 $(BINDIR)/ocaml299to3$(EXE) + +clean:: + rm -f ocaml299to3 lexer299.ml + +# Label remover for interface files (upgrade 3.02 to 3.03) + +SCRAPELABELS= lexer301.cmo scrapelabels.cmo + +scrapelabels: $(SCRAPELABELS) + $(CAMLC) $(LINKFLAGS) -o scrapelabels $(LIBRARY3) $(SCRAPELABELS) + +lexer301.ml: lexer301.mll + $(CAMLLEX) lexer301.mll + +install:: + cp scrapelabels $(LIBDIR) + +clean:: + rm -f scrapelabels lexer301.ml + +# Insert labels following an interface file (upgrade 3.02 to 3.03) + +ADDLABELS_IMPORTS=misc.cmo config.cmo clflags.cmo terminfo.cmo \ + linenum.cmo warnings.cmo location.cmo longident.cmo \ + syntaxerr.cmo parser.cmo lexer.cmo parse.cmo + +addlabels: addlabels.ml + $(CAMLC) $(LINKFLAGS) -w sl -o addlabels \ + $(ADDLABELS_IMPORTS) addlabels.ml + +install:: + cp addlabels $(LIBDIR) + +clean:: + rm -f addlabels + +# The preprocessor for asm generators + +CVT_EMIT=cvt_emit.cmo + +cvt_emit: $(CVT_EMIT) + $(CAMLC) $(LINKFLAGS) -o cvt_emit $(CVT_EMIT) + +# cvt_emit is precious: sometimes we are stuck in the middle of a +# bootstrap and we need to remake the dependencies +clean:: + if test -f cvt_emit; then mv -f cvt_emit cvt_emit.bak; else :; fi + +cvt_emit.ml: cvt_emit.mll + $(CAMLLEX) cvt_emit.mll + +clean:: + rm -f cvt_emit.ml + +beforedepend:: cvt_emit.ml + +# The bytecode disassembler + +DUMPOBJ=opnames.cmo dumpobj.cmo + +dumpobj: $(DUMPOBJ) + $(CAMLC) $(LINKFLAGS) -o dumpobj \ + misc.cmo tbl.cmo config.cmo ident.cmo \ + opcodes.cmo bytesections.cmo $(DUMPOBJ) + +clean:: + rm -f dumpobj + +opnames.ml: ../byterun/instruct.h + 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 > opnames.ml + +clean:: + rm -f opnames.ml + +beforedepend:: opnames.ml + +# Dump .cmx files + +dumpapprox: dumpapprox.cmo + $(CAMLC) $(LINKFLAGS) -o dumpapprox config.cmo dumpapprox.cmo + +clean:: + rm -f dumpapprox + +# Print imported interfaces for .cmo files + +objinfo: objinfo.cmo + $(CAMLC) $(LINKFLAGS) -o objinfo config.cmo objinfo.cmo + +clean:: + rm -f objinfo + +# Scan object files for required primitives + +PRIMREQ=primreq.cmo + +primreq: $(PRIMREQ) + $(CAMLC) $(LINKFLAGS) -o primreq config.cmo $(PRIMREQ) + +clean:: + rm -f primreq + +# Common stuff + +.SUFFIXES: +.SUFFIXES: .ml .cmo .mli .cmi .cmx + +.ml.cmo: + $(CAMLC) -c $(COMPFLAGS) $< + +.mli.cmi: + $(CAMLC) -c $(COMPFLAGS) $< + +.ml.cmx: + $(CAMLOPT) $(COMPFLAGS) -c $< + +clean:: + rm -f *.cmo *.cmi + +depend: beforedepend + $(CAMLRUN) ./ocamldep $(INCLUDES) *.mli *.ml > .depend + +include .depend diff --git a/tools/ocamlmklib.mlp b/tools/ocamlmklib.mlp index 46eeb6e7c..fcf2396c6 100644 --- a/tools/ocamlmklib.mlp +++ b/tools/ocamlmklib.mlp @@ -17,7 +17,7 @@ open Myocamlbuild_config let bytecode_objs = ref [] (* .cmo,.cma,.ml,.mli files to pass to ocamlc *) and native_objs = ref [] (* .cmx,.cmxa,.ml,.mli files to pass to ocamlopt *) -and c_objs = ref [] (* .o, .a, .obj, .lib files to pass to mksharedlib and ar *) +and c_objs = ref [] (* .o, .a, .obj, .lib, .dll files to pass to mksharedlib and ar *) and caml_libs = ref [] (* -cclib to pass to ocamlc, ocamlopt *) and caml_opts = ref [] (* -ccopt to pass to ocamlc, ocamlopt *) and dynlink = ref supports_shared_libraries @@ -30,7 +30,6 @@ and ocamlopt = ref (Filename.concat bindir "ocamlopt") and output = ref "a" (* Output name for Caml part of library *) and output_c = ref "" (* Output name for C part of library *) and rpath = ref [] (* rpath options *) -and implib = ref "" (* windows implib flag *) and verbose = ref false let starts_with s pref = @@ -63,7 +62,7 @@ let parse_arguments argv = else if ends_with s ".ml" || ends_with s ".mli" then (bytecode_objs := s :: !bytecode_objs; native_objs := s :: !native_objs) - else if List.exists (ends_with s) [".o"; ".a"; ".obj"; ".lib"] then + else if List.exists (ends_with s) [".o"; ".a"; ".obj"; ".lib"; ".dll"] then c_objs := s :: !c_objs else if s = "-cclib" then caml_libs := next_arg () :: "-cclib" :: !caml_libs @@ -71,8 +70,6 @@ let parse_arguments argv = caml_opts := next_arg () :: "-ccopt" :: !caml_opts else if s = "-custom" then dynlink := false - else if s = "-implib" then - implib := next_arg () else if s = "-I" then caml_opts := next_arg () :: "-I" :: !caml_opts else if s = "-failsafe" then @@ -128,10 +125,12 @@ let parse_arguments argv = (fun r -> r := List.rev !r) [ bytecode_objs; native_objs; c_objs; caml_libs; caml_opts; c_libs; c_objs; c_opts; ld_opts; rpath ]; + (* On retourne deux fois c_objs ?? -- AF *) + if !output_c = "" then output_c := !output let usage = "\ -Usage: ocamlmklib [options] <.cmo|.cma|.cmx|.cmxa|.ml|.mli|.o|.a|.obj|.lib files> +Usage: ocamlmklib [options] <.cmo|.cma|.cmx|.cmxa|.ml|.mli|.o|.a|.obj|.lib|.dll files> Options are: -cclib <lib> C library passed to ocamlc -a or ocamlopt -a only -ccopt <opt> C option passed to ocamlc -a or ocamlopt -a only @@ -194,12 +193,21 @@ let prepostfix pre name post = Filename.concat dir (pre ^ base ^ post) ;; +let transl_path s = + match Sys.os_type with + | "Win32" -> + let rec aux i = + if i = String.length s || s.[i] = ' ' then s + else (if s.[i] = '/' then s.[i] <- '\\'; aux (i + 1)) + in aux 0 + | _ -> s + let build_libs () = if !c_objs <> [] then begin if !dynlink then begin let retcode = command (mkdll (prepostfix "dll" !output_c ext_dll) - !implib + "" (* no implib *) (sprintf "%s %s %s %s %s" (String.concat " " !c_objs) (String.concat " " !c_opts) @@ -216,7 +224,7 @@ let build_libs () = if !bytecode_objs <> [] then scommand (sprintf "%s -a %s -o %s.cma %s %s -dllib -l%s -cclib -l%s %s %s %s %s" - !ocamlc + (transl_path !ocamlc) (if !dynlink then "" else "-custom") !output (String.concat " " !caml_opts) @@ -230,7 +238,7 @@ let build_libs () = if !native_objs <> [] then scommand (sprintf "%s -a -o %s.cmxa %s %s -cclib -l%s %s %s %s %s" - !ocamlopt + (transl_path !ocamlopt) !output (String.concat " " !caml_opts) (String.concat " " !native_objs) diff --git a/toplevel/opttopdirs.ml b/toplevel/opttopdirs.ml new file mode 100644 index 000000000..5c6305226 --- /dev/null +++ b/toplevel/opttopdirs.ml @@ -0,0 +1,189 @@ +(***********************************************************************) +(* *) +(* Objective Caml *) +(* *) +(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *) +(* *) +(* Copyright 1996 Institut National de Recherche en Informatique et *) +(* en Automatique. All rights reserved. This file is distributed *) +(* under the terms of the Q Public License version 1.0. *) +(* *) +(***********************************************************************) + +(* $Id$ *) + +(* Toplevel directives *) + +open Format +open Misc +open Longident +open Path +open Types +open Opttoploop + +(* The standard output formatter *) +let std_out = std_formatter + +(* To quit *) + +let dir_quit () = exit 0 + +let _ = Hashtbl.add directive_table "quit" (Directive_none dir_quit) + +(* To add a directory to the load path *) + +let dir_directory s = + let d = expand_directory Config.standard_library s in + Config.load_path := d :: !Config.load_path + +let _ = Hashtbl.add directive_table "directory" (Directive_string dir_directory) +let _ = Hashtbl.add directive_table "show_dirs" + (Directive_none + (fun () -> + List.iter print_endline !Config.load_path + )) + +(* To change the current directory *) + +let dir_cd s = Sys.chdir s + +let _ = Hashtbl.add directive_table "cd" (Directive_string dir_cd) + +(* Load in-core a .cmxs file *) + +let load_file ppf name0 = + let name = + try Some (find_in_path !Config.load_path name0) + with Not_found -> None in + match name with + | None -> fprintf ppf "File not found: %s@." name0; false + | Some name -> + let fn,tmp = + if Filename.check_suffix name ".cmx" || Filename.check_suffix name ".cmxa" + then + let cmxs = Filename.temp_file "caml" ".cmxs" in + Asmlink.link_shared ppf [name] cmxs; + cmxs,true + else + name,false in + + let success = + (* The Dynlink interface does not allow us to distinguish between + a Dynlink.Error exceptions raised in the loaded modules + or a genuine error during dynlink... *) + try Dynlink.loadfile fn; true + with + | Dynlink.Error err -> + fprintf ppf "Error while loading %s: %s.@." + name (Dynlink.error_message err); + false + | exn -> + print_exception_outcome ppf exn; + false + in + if tmp then (try Sys.remove fn with Sys_error _ -> ()); + success + + +let dir_load ppf name = ignore (load_file ppf name) + +let _ = Hashtbl.add directive_table "load" (Directive_string (dir_load std_out)) + +(* Load commands from a file *) + +let dir_use ppf name = ignore(Opttoploop.use_file ppf name) + +let _ = Hashtbl.add directive_table "use" (Directive_string (dir_use std_out)) + +(* Install, remove a printer *) + +type 'a printer_type_new = Format.formatter -> 'a -> unit +type 'a printer_type_old = 'a -> unit + +let match_printer_type ppf desc typename = + let (printer_type, _) = + try + Env.lookup_type (Ldot(Lident "Topdirs", typename)) !toplevel_env + with Not_found -> + fprintf ppf "Cannot find type Topdirs.%s.@." typename; + raise Exit in + Ctype.init_def(Ident.current_time()); + Ctype.begin_def(); + let ty_arg = Ctype.newvar() in + Ctype.unify !toplevel_env + (Ctype.newconstr printer_type [ty_arg]) + (Ctype.instance desc.val_type); + Ctype.end_def(); + Ctype.generalize ty_arg; + ty_arg + +let find_printer_type ppf lid = + try + let (path, desc) = Env.lookup_value lid !toplevel_env in + let (ty_arg, is_old_style) = + try + (match_printer_type ppf desc "printer_type_new", false) + with Ctype.Unify _ -> + (match_printer_type ppf desc "printer_type_old", true) in + (ty_arg, path, is_old_style) + with + | Not_found -> + fprintf ppf "Unbound value %a.@." Printtyp.longident lid; + raise Exit + | Ctype.Unify _ -> + fprintf ppf "%a has a wrong type for a printing function.@." + Printtyp.longident lid; + raise Exit + +let dir_install_printer ppf lid = + try + let (ty_arg, path, is_old_style) = find_printer_type ppf lid in + let v = eval_path path in + let print_function = + if is_old_style then + (fun formatter repr -> Obj.obj v (Obj.obj repr)) + else + (fun formatter repr -> Obj.obj v formatter (Obj.obj repr)) in + install_printer path ty_arg print_function + with Exit -> () + +let dir_remove_printer ppf lid = + try + let (ty_arg, path, is_old_style) = find_printer_type ppf lid in + begin try + remove_printer path + with Not_found -> + fprintf ppf "No printer named %a.@." Printtyp.longident lid + end + with Exit -> () + +let _ = Hashtbl.add directive_table "install_printer" + (Directive_ident (dir_install_printer std_out)) +let _ = Hashtbl.add directive_table "remove_printer" + (Directive_ident (dir_remove_printer std_out)) + +let parse_warnings ppf iserr s = + try Warnings.parse_options iserr s + with Arg.Bad err -> fprintf ppf "%s.@." err + +let _ = +(* Control the printing of values *) + + Hashtbl.add directive_table "print_depth" + (Directive_int(fun n -> max_printer_depth := n)); + Hashtbl.add directive_table "print_length" + (Directive_int(fun n -> max_printer_steps := n)); + +(* Set various compiler flags *) + + Hashtbl.add directive_table "labels" + (Directive_bool(fun b -> Clflags.classic := not b)); + + Hashtbl.add directive_table "principal" + (Directive_bool(fun b -> Clflags.principal := b)); + + Hashtbl.add directive_table "warnings" + (Directive_string (parse_warnings std_out false)); + + Hashtbl.add directive_table "warn_error" + (Directive_string (parse_warnings std_out true)) diff --git a/toplevel/opttopdirs.mli b/toplevel/opttopdirs.mli new file mode 100644 index 000000000..800c6cf7b --- /dev/null +++ b/toplevel/opttopdirs.mli @@ -0,0 +1,31 @@ +(***********************************************************************) +(* *) +(* Objective Caml *) +(* *) +(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *) +(* *) +(* Copyright 1996 Institut National de Recherche en Informatique et *) +(* en Automatique. All rights reserved. This file is distributed *) +(* under the terms of the Q Public License version 1.0. *) +(* *) +(***********************************************************************) + +(* $Id$ *) + +(* The toplevel directives. *) + +open Format + +val dir_quit : unit -> unit +val dir_directory : string -> unit +val dir_cd : string -> unit +val dir_load : formatter -> string -> unit +val dir_use : formatter -> string -> unit +val dir_install_printer : formatter -> Longident.t -> unit +val dir_remove_printer : formatter -> Longident.t -> unit + +type 'a printer_type_new = Format.formatter -> 'a -> unit +type 'a printer_type_old = 'a -> unit + +(* For topmain.ml. Maybe shouldn't be there *) +val load_file : formatter -> string -> bool diff --git a/toplevel/opttoploop.ml b/toplevel/opttoploop.ml new file mode 100644 index 000000000..b7fbe01a4 --- /dev/null +++ b/toplevel/opttoploop.ml @@ -0,0 +1,444 @@ +(***********************************************************************) +(* *) +(* Objective Caml *) +(* *) +(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *) +(* *) +(* Copyright 1996 Institut National de Recherche en Informatique et *) +(* en Automatique. All rights reserved. This file is distributed *) +(* under the terms of the Q Public License version 1.0. *) +(* *) +(***********************************************************************) + +(* $Id$ *) + +(* The interactive toplevel loop *) + +open Path +open Lexing +open Format +open Config +open Misc +open Parsetree +open Types +open Typedtree +open Outcometree +open Lambda + +type res = Ok of Obj.t | Err of string +type evaluation_outcome = Result of Obj.t | Exception of exn + +external ndl_run_toplevel: string -> string -> res = "caml_natdynlink_run_toplevel" +external ndl_loadsym: string -> Obj.t = "caml_natdynlink_loadsym" + +let global_symbol id = + let sym = Compilenv.symbol_for_global id in + try ndl_loadsym sym + with _ -> fatal_error ("Opttoploop.global_symbol " ^ (Ident.unique_name id)) + +let need_symbol sym = + try ignore (ndl_loadsym sym); false + with _ -> true + +let dll_run dll entry = + match (try Result (Obj.magic (ndl_run_toplevel dll entry)) with exn -> Exception exn) with + | Exception _ as r -> r + | Result r -> + match Obj.magic r with + | Ok x -> Result x + | Err s -> fatal_error ("Opttoploop.dll_run " ^ s) + + +type directive_fun = + | Directive_none of (unit -> unit) + | Directive_string of (string -> unit) + | Directive_int of (int -> unit) + | Directive_ident of (Longident.t -> unit) + | Directive_bool of (bool -> unit) + + +(* Return the value referred to by a path *) + +let toplevel_value id = + let (glb,pos) = Translmod.nat_toplevel_name id in + (Obj.magic (global_symbol glb)).(pos) + +let rec eval_path = function + | Pident id -> + if Ident.persistent id || Ident.global id + then global_symbol id + else toplevel_value id + | Pdot(p, s, pos) -> + Obj.field (eval_path p) pos + | Papply(p1, p2) -> + fatal_error "Toploop.eval_path" + +(* To print values *) + +module EvalPath = struct + type value = Obj.t + exception Error + let eval_path p = try eval_path p with _ -> raise Error + let same_value v1 v2 = (v1 == v2) +end + +module Printer = Genprintval.Make(Obj)(EvalPath) + +let max_printer_depth = ref 100 +let max_printer_steps = ref 300 + +let print_out_value = Oprint.out_value +let print_out_type = Oprint.out_type +let print_out_class_type = Oprint.out_class_type +let print_out_module_type = Oprint.out_module_type +let print_out_sig_item = Oprint.out_sig_item +let print_out_signature = Oprint.out_signature +let print_out_phrase = Oprint.out_phrase + +let print_untyped_exception ppf obj = + !print_out_value ppf (Printer.outval_of_untyped_exception obj) +let outval_of_value env obj ty = + Printer.outval_of_value !max_printer_steps !max_printer_depth + (fun _ _ _ -> None) env obj ty +let print_value env obj ppf ty = + !print_out_value ppf (outval_of_value env obj ty) + +let install_printer = Printer.install_printer +let remove_printer = Printer.remove_printer + +(* Hooks for parsing functions *) + +let parse_toplevel_phrase = ref Parse.toplevel_phrase +let parse_use_file = ref Parse.use_file +let print_location = Location.print +let print_warning = Location.print_warning +let input_name = Location.input_name + +(* Hooks for initialization *) + +let toplevel_startup_hook = ref (fun () -> ()) + +(* Load in-core and execute a lambda term *) + +let phrase_seqid = ref 0 +let phrase_name = ref "TOP" + +open Lambda + +let load_lambda ppf (size, lam) = + if !Clflags.dump_rawlambda then fprintf ppf "%a@." Printlambda.lambda lam; + let slam = Simplif.simplify_lambda lam in + if !Clflags.dump_lambda then fprintf ppf "%a@." Printlambda.lambda slam; + + let dll = + if !Clflags.keep_asm_file then !phrase_name ^ ext_dll + else Filename.temp_file ("caml" ^ !phrase_name) ext_dll + in + let fn = Filename.chop_extension dll in + Asmgen.compile_implementation ~toplevel:need_symbol fn ppf (size, lam); + Asmlink.call_linker_shared [fn ^ ext_obj] dll; + Sys.remove (fn ^ ext_obj); + + let dll = + if Filename.is_implicit dll + then Filename.concat (Sys.getcwd ()) dll + else dll in + let res = dll_run dll !phrase_name in + (try Sys.remove dll with Sys_error _ -> ()); + (* note: under windows, cannot remove a loaded dll + (should remember the handles, close them in at_exit, and then remove + files) *) + res + +(* Print the outcome of an evaluation *) + +let rec pr_item env = function + | Tsig_value(id, decl) :: rem -> + let tree = Printtyp.tree_of_value_description id decl in + let valopt = + match decl.val_kind with + | Val_prim _ -> None + | _ -> + let v = + outval_of_value env (toplevel_value id) + decl.val_type + in + Some v + in + Some (tree, valopt, rem) + | Tsig_type(id, _, _) :: rem when Btype.is_row_name (Ident.name id) -> + pr_item env rem + | Tsig_type(id, decl, rs) :: rem -> + let tree = Printtyp.tree_of_type_declaration id decl rs in + Some (tree, None, rem) + | Tsig_exception(id, decl) :: rem -> + let tree = Printtyp.tree_of_exception_declaration id decl in + Some (tree, None, rem) + | Tsig_module(id, mty, rs) :: rem -> + let tree = Printtyp.tree_of_module id mty rs in + Some (tree, None, rem) + | Tsig_modtype(id, decl) :: rem -> + let tree = Printtyp.tree_of_modtype_declaration id decl in + Some (tree, None, rem) + | Tsig_class(id, decl, rs) :: cltydecl :: tydecl1 :: tydecl2 :: rem -> + let tree = Printtyp.tree_of_class_declaration id decl rs in + Some (tree, None, rem) + | Tsig_cltype(id, decl, rs) :: tydecl1 :: tydecl2 :: rem -> + let tree = Printtyp.tree_of_cltype_declaration id decl rs in + Some (tree, None, rem) + | _ -> None + +let rec item_list env = function + | [] -> [] + | items -> + match pr_item env items with + | None -> [] + | Some (tree, valopt, items) -> (tree, valopt) :: item_list env items + +(* The current typing environment for the toplevel *) + +let toplevel_env = ref Env.empty + +(* Print an exception produced by an evaluation *) + +let print_out_exception ppf exn outv = + !print_out_phrase ppf (Ophr_exception (exn, outv)) + +let print_exception_outcome ppf exn = + if exn = Out_of_memory then Gc.full_major (); + let outv = outval_of_value !toplevel_env (Obj.repr exn) Predef.type_exn in + print_out_exception ppf exn outv + +(* The table of toplevel directives. + Filled by functions from module topdirs. *) + +let directive_table = (Hashtbl.create 13 : (string, directive_fun) Hashtbl.t) + +(* Execute a toplevel phrase *) + +let execute_phrase print_outcome ppf phr = + match phr with + | Ptop_def sstr -> + let oldenv = !toplevel_env in + incr phrase_seqid; + phrase_name := Printf.sprintf "TOP%i" !phrase_seqid; + Compilenv.reset ?packname:None !phrase_name; + let _ = Unused_var.warn ppf sstr in + Typecore.reset_delayed_checks (); + let (str, sg, newenv) = Typemod.type_structure oldenv sstr Location.none + in + Typecore.force_delayed_checks (); + let res = Translmod.transl_store_phrases !phrase_name str in + Warnings.check_fatal (); + begin try + toplevel_env := newenv; + let res = load_lambda ppf res in + let out_phr = + match res with + | Result v -> + Compilenv.record_global_approx_toplevel (); + if print_outcome then + match str with + | [Tstr_eval exp] -> + let outv = outval_of_value newenv v exp.exp_type in + let ty = Printtyp.tree_of_type_scheme exp.exp_type in + Ophr_eval (outv, ty) + | [] -> Ophr_signature [] + | _ -> + Ophr_signature (item_list newenv + (Typemod.simplify_signature sg)) + + else Ophr_signature [] + | Exception exn -> + toplevel_env := oldenv; + if exn = Out_of_memory then Gc.full_major(); + let outv = + outval_of_value !toplevel_env (Obj.repr exn) Predef.type_exn + in + Ophr_exception (exn, outv) + in + !print_out_phrase ppf out_phr; + begin match out_phr with + | Ophr_eval (_, _) | Ophr_signature _ -> true + | Ophr_exception _ -> false + end + with x -> + toplevel_env := oldenv; raise x + end + | Ptop_dir(dir_name, dir_arg) -> + try + match (Hashtbl.find directive_table dir_name, dir_arg) with + | (Directive_none f, Pdir_none) -> f (); true + | (Directive_string f, Pdir_string s) -> f s; true + | (Directive_int f, Pdir_int n) -> f n; true + | (Directive_ident f, Pdir_ident lid) -> f lid; true + | (Directive_bool f, Pdir_bool b) -> f b; true + | (_, _) -> + fprintf ppf "Wrong type of argument for directive `%s'.@." dir_name; + false + with Not_found -> + fprintf ppf "Unknown directive `%s'.@." dir_name; + false + +(* Temporary assignment to a reference *) + +let protect r newval body = + let oldval = !r in + try + r := newval; + let res = body() in + r := oldval; + res + with x -> + r := oldval; + raise x + +(* Read and execute commands from a file *) + +let use_print_results = ref true + +let use_file ppf name = + try + let filename = find_in_path !Config.load_path name in + let ic = open_in_bin filename in + let lb = Lexing.from_channel ic in + Location.init lb filename; + (* Skip initial #! line if any *) + Lexer.skip_sharp_bang lb; + let success = + protect Location.input_name filename (fun () -> + try + List.iter + (fun ph -> + if !Clflags.dump_parsetree then Printast.top_phrase ppf ph; + if not (execute_phrase !use_print_results ppf ph) then raise Exit) + (!parse_use_file lb); + true + with + | Exit -> false + | Sys.Break -> fprintf ppf "Interrupted.@."; false + | x -> Opterrors.report_error ppf x; false) in + close_in ic; + success + with Not_found -> fprintf ppf "Cannot find file %s.@." name; false + +let use_silently ppf name = + protect use_print_results false (fun () -> use_file ppf name) + +(* Reading function for interactive use *) + +let first_line = ref true +let got_eof = ref false;; + +let read_input_default prompt buffer len = + output_string stdout prompt; flush stdout; + let i = ref 0 in + try + while true do + if !i >= len then raise Exit; + let c = input_char stdin in + buffer.[!i] <- c; + incr i; + if c = '\n' then raise Exit; + done; + (!i, false) + with + | End_of_file -> + (!i, true) + | Exit -> + (!i, false) + +let read_interactive_input = ref read_input_default + +let refill_lexbuf buffer len = + if !got_eof then (got_eof := false; 0) else begin + let prompt = + if !Clflags.noprompt then "" + else if !first_line then "# " + else if Lexer.in_comment () then "* " + else " " + in + first_line := false; + let (len, eof) = !read_interactive_input prompt buffer len in + if eof then begin + Location.echo_eof (); + if len > 0 then got_eof := true; + len + end else + len + end + +(* Toplevel initialization. Performed here instead of at the + beginning of loop() so that user code linked in with ocamlmktop + can call directives from Topdirs. *) + +let _ = + Sys.interactive := true; + Dynlink.init (); + Optcompile.init_path(); + Clflags.dlcode := true; + () + +let load_ocamlinit ppf = + match !Clflags.init_file with + | Some f -> if Sys.file_exists f then ignore (use_silently ppf f) + else fprintf ppf "Init file not found: \"%s\".@." f + | None -> + if Sys.file_exists ".ocamlinit" then ignore (use_silently ppf ".ocamlinit") + else try + let home_init = Filename.concat (Sys.getenv "HOME") ".ocamlinit" in + if Sys.file_exists home_init then ignore (use_silently ppf home_init) + with Not_found -> () +;; + +let set_paths () = + (* Add whatever -I options have been specified on the command line, + but keep the directories that user code linked in with ocamlmktop + may have added to load_path. *) + load_path := !load_path @ [Filename.concat Config.standard_library "camlp4"]; + load_path := "" :: (List.rev !Clflags.include_dirs @ !load_path); + () + +let initialize_toplevel_env () = + toplevel_env := Optcompile.initial_env() + +(* The interactive loop *) + +exception PPerror + +let loop ppf = + fprintf ppf " Objective Caml version %s - native toplevel@.@." Config.version; + initialize_toplevel_env (); + let lb = Lexing.from_function refill_lexbuf in + Location.input_name := ""; + Location.input_lexbuf := Some lb; + Sys.catch_break true; + load_ocamlinit ppf; + while true do + let snap = Btype.snapshot () in + try + Lexing.flush_input lb; + Location.reset(); + first_line := true; + let phr = try !parse_toplevel_phrase lb with Exit -> raise PPerror in + if !Clflags.dump_parsetree then Printast.top_phrase ppf phr; + ignore(execute_phrase true ppf phr) + with + | End_of_file -> exit 0 + | Sys.Break -> fprintf ppf "Interrupted.@."; Btype.backtrack snap + | PPerror -> () + | x -> Opterrors.report_error ppf x; Btype.backtrack snap + done + +(* Execute a script *) + +let run_script ppf name args = + let len = Array.length args in + if Array.length Sys.argv < len then invalid_arg "Toploop.run_script"; + Array.blit args 0 Sys.argv 0 len; + Obj.truncate (Obj.repr Sys.argv) len; + Arg.current := 0; + Optcompile.init_path(); + toplevel_env := Optcompile.initial_env(); + Sys.interactive := false; + use_silently ppf name diff --git a/toplevel/opttoploop.mli b/toplevel/opttoploop.mli new file mode 100644 index 000000000..aa86d2638 --- /dev/null +++ b/toplevel/opttoploop.mli @@ -0,0 +1,102 @@ +(***********************************************************************) +(* *) +(* Objective Caml *) +(* *) +(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *) +(* *) +(* Copyright 1996 Institut National de Recherche en Informatique et *) +(* en Automatique. All rights reserved. This file is distributed *) +(* under the terms of the Q Public License version 1.0. *) +(* *) +(***********************************************************************) + +(* $Id$ *) + +open Format + +(* Set the load paths, before running anything *) + +val set_paths : unit -> unit + +(* The interactive toplevel loop *) + +val loop : formatter -> unit + +(* Read and execute a script from the given file *) + +val run_script : formatter -> string -> string array -> bool + (* true if successful, false if error *) + +(* Interface with toplevel directives *) + +type directive_fun = + | Directive_none of (unit -> unit) + | Directive_string of (string -> unit) + | Directive_int of (int -> unit) + | Directive_ident of (Longident.t -> unit) + | Directive_bool of (bool -> unit) + +val directive_table : (string, directive_fun) Hashtbl.t + (* Table of known directives, with their execution function *) +val toplevel_env : Env.t ref + (* Typing environment for the toplevel *) +val initialize_toplevel_env : unit -> unit + (* Initialize the typing environment for the toplevel *) +val print_exception_outcome : formatter -> exn -> unit + (* Print an exception resulting from the evaluation of user code. *) +val execute_phrase : bool -> formatter -> Parsetree.toplevel_phrase -> bool + (* Execute the given toplevel phrase. Return [true] if the + phrase executed with no errors and [false] otherwise. + First bool says whether the values and types of the results + should be printed. Uncaught exceptions are always printed. *) +val use_file : formatter -> string -> bool +val use_silently : formatter -> string -> bool + (* Read and execute commands from a file. + [use_file] prints the types and values of the results. + [use_silently] does not print them. *) +val eval_path: Path.t -> Obj.t + (* Return the toplevel object referred to by the given path *) + +(* Printing of values *) + +val print_value: Env.t -> Obj.t -> formatter -> Types.type_expr -> unit +val print_untyped_exception: formatter -> Obj.t -> unit + +val install_printer : + Path.t -> Types.type_expr -> (formatter -> Obj.t -> unit) -> unit +val remove_printer : Path.t -> unit + +val max_printer_depth: int ref +val max_printer_steps: int ref + +(* Hooks for external parsers and printers *) + +val parse_toplevel_phrase : (Lexing.lexbuf -> Parsetree.toplevel_phrase) ref +val parse_use_file : (Lexing.lexbuf -> Parsetree.toplevel_phrase list) ref +val print_location : formatter -> Location.t -> unit +val print_warning : Location.t -> formatter -> Warnings.t -> unit +val input_name : string ref + +val print_out_value : + (formatter -> Outcometree.out_value -> unit) ref +val print_out_type : + (formatter -> Outcometree.out_type -> unit) ref +val print_out_class_type : + (formatter -> Outcometree.out_class_type -> unit) ref +val print_out_module_type : + (formatter -> Outcometree.out_module_type -> unit) ref +val print_out_sig_item : + (formatter -> Outcometree.out_sig_item -> unit) ref +val print_out_signature : + (formatter -> Outcometree.out_sig_item list -> unit) ref +val print_out_phrase : + (formatter -> Outcometree.out_phrase -> unit) ref + +(* Hooks for external line editor *) + +val read_interactive_input : (string -> string -> int -> int * bool) ref + +(* Hooks for initialization *) + +val toplevel_startup_hook : (unit -> unit) ref + diff --git a/toplevel/opttopmain.ml b/toplevel/opttopmain.ml new file mode 100644 index 000000000..4d228aba1 --- /dev/null +++ b/toplevel/opttopmain.ml @@ -0,0 +1,121 @@ +(***********************************************************************) +(* *) +(* Objective Caml *) +(* *) +(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *) +(* *) +(* Copyright 1996 Institut National de Recherche en Informatique et *) +(* en Automatique. All rights reserved. This file is distributed *) +(* under the terms of the Q Public License version 1.0. *) +(* *) +(***********************************************************************) + +(* $Id$ *) + +open Clflags + +let usage = "Usage: ocamlnat <options> <object-files> [script-file]\noptions are:" + +let preload_objects = ref [] + +let prepare ppf = + Opttoploop.set_paths (); + try + let res = + List.for_all (Opttopdirs.load_file ppf) (List.rev !preload_objects) + in + !Opttoploop.toplevel_startup_hook (); + res + with x -> + try Opterrors.report_error ppf x; false + with x -> + Format.fprintf ppf "Uncaught exception: %s\n" (Printexc.to_string x); + false + +let file_argument name = + let ppf = Format.err_formatter in + if Filename.check_suffix name ".cmxs" + || Filename.check_suffix name ".cmx" + || Filename.check_suffix name ".cmxa" + then preload_objects := name :: !preload_objects + else + begin + let newargs = Array.sub Sys.argv !Arg.current + (Array.length Sys.argv - !Arg.current) + in + if prepare ppf && Opttoploop.run_script ppf name newargs + then exit 0 + else exit 2 + end + +let print_version () = + Printf.printf "The Objective Caml toplevel, version %s\n" Sys.ocaml_version; + exit 0; +;; + +let main () = + Arg.parse (Arch.command_line_options @ [ + "-compact", Arg.Clear optimize_for_speed, " Optimize code size rather than speed"; + "-inline", Arg.Int(fun n -> inline_threshold := n * 8), + "<n> Set aggressiveness of inlining to <n>"; + "-I", Arg.String(fun dir -> + let dir = Misc.expand_directory Config.standard_library dir in + include_dirs := dir :: !include_dirs), + "<dir> Add <dir> to the list of include directories"; + "-init", Arg.String (fun s -> init_file := Some s), + "<file> Load <file> instead of default init file"; + "-labels", Arg.Clear classic, " Labels commute (default)"; + "-noassert", Arg.Set noassert, " Do not compile assertion checks"; + "-nolabels", Arg.Set classic, " Ignore labels and do not commute"; + "-noprompt", Arg.Set noprompt, " Suppress all prompts"; + "-nostdlib", Arg.Set no_std_include, + " do not add default directory to the list of include directories"; + "-principal", Arg.Set principal, " Check principality of type inference"; + "-rectypes", Arg.Set recursive_types, " Allow arbitrary recursive types"; + "-S", Arg.Set keep_asm_file, " Keep intermediate assembly file"; + "-unsafe", Arg.Set fast, " No bound checking on array and string access"; + "-version", Arg.Unit print_version, " Print version and exit"; + "-w", Arg.String (Warnings.parse_options false), + "<flags> Enable or disable warnings according to <flags>:\n\ + \032 A/a enable/disable all warnings\n\ + \032 C/c enable/disable suspicious comment\n\ + \032 D/d enable/disable deprecated features\n\ + \032 E/e enable/disable fragile match\n\ + \032 F/f enable/disable partially applied function\n\ + \032 L/l enable/disable labels omitted in application\n\ + \032 M/m enable/disable overriden method\n\ + \032 P/p enable/disable partial match\n\ + \032 S/s enable/disable non-unit statement\n\ + \032 U/u enable/disable unused match case\n\ + \032 V/v enable/disable hidden instance variable\n\ + \032 Y/y enable/disable suspicious unused variables\n\ + \032 Z/z enable/disable all other unused variables\n\ + \032 X/x enable/disable all other warnings\n\ + \032 default setting is \"Aelz\""; + "-warn-error" , Arg.String (Warnings.parse_options true), + "<flags> Treat the warnings of <flags> as errors, if they are enabled.\n\ + \032 (see option -w for the list of flags)\n\ + \032 default setting is a (all warnings are non-fatal)"; + + "-dparsetree", Arg.Set dump_parsetree, " (undocumented)"; + "-drawlambda", Arg.Set dump_rawlambda, " (undocumented)"; + "-dlambda", Arg.Set dump_lambda, " (undocumented)"; + "-dcmm", Arg.Set dump_cmm, " (undocumented)"; + "-dsel", Arg.Set dump_selection, " (undocumented)"; + "-dcombine", Arg.Set dump_combine, " (undocumented)"; + "-dlive", Arg.Unit(fun () -> dump_live := true; + Printmach.print_live := true), + " (undocumented)"; + "-dspill", Arg.Set dump_spill, " (undocumented)"; + "-dsplit", Arg.Set dump_split, " (undocumented)"; + "-dinterf", Arg.Set dump_interf, " (undocumented)"; + "-dprefer", Arg.Set dump_prefer, " (undocumented)"; + "-dalloc", Arg.Set dump_regalloc, " (undocumented)"; + "-dreload", Arg.Set dump_reload, " (undocumented)"; + "-dscheduling", Arg.Set dump_scheduling, " (undocumented)"; + "-dlinear", Arg.Set dump_linear, " (undocumented)"; + "-dstartup", Arg.Set keep_startup_file, " (undocumented)"; + ]) file_argument usage; + if not (prepare Format.err_formatter) then exit 2; + Opttoploop.loop Format.std_formatter + diff --git a/toplevel/opttopmain.mli b/toplevel/opttopmain.mli new file mode 100644 index 000000000..197f88bbc --- /dev/null +++ b/toplevel/opttopmain.mli @@ -0,0 +1,17 @@ +(***********************************************************************) +(* *) +(* Objective Caml *) +(* *) +(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *) +(* *) +(* Copyright 1996 Institut National de Recherche en Informatique et *) +(* en Automatique. All rights reserved. This file is distributed *) +(* under the terms of the Q Public License version 1.0. *) +(* *) +(***********************************************************************) + +(* $Id$ *) + +(* Start the [ocaml] toplevel loop *) + +val main: unit -> unit diff --git a/toplevel/opttopstart.ml b/toplevel/opttopstart.ml new file mode 100644 index 000000000..3e3fe58ba --- /dev/null +++ b/toplevel/opttopstart.ml @@ -0,0 +1,15 @@ +(***********************************************************************) +(* *) +(* Objective Caml *) +(* *) +(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *) +(* *) +(* Copyright 2002 Institut National de Recherche en Informatique et *) +(* en Automatique. All rights reserved. This file is distributed *) +(* under the terms of the Q Public License version 1.0. *) +(* *) +(***********************************************************************) + +(* $Id$ *) + +let _ = Opttopmain.main() diff --git a/utils/ccomp.ml b/utils/ccomp.ml index c44bb64c3..b76f69be4 100644 --- a/utils/ccomp.ml +++ b/utils/ccomp.ml @@ -38,11 +38,15 @@ let build_diversion lst = at_exit (fun () -> Misc.remove_file responsefile); "@" ^ responsefile +let need_diversion = match Sys.os_type with + | "Win32" (* | "Cygwin" *) -> true + | _ -> false + let quote_files lst = let s = String.concat " " (List.map (fun f -> if f = "" then f else Filename.quote f) lst) in - if Sys.os_type = "Win32" && String.length s >= 256 + if String.length s >= 256 && need_diversion then build_diversion lst else s @@ -89,7 +93,10 @@ let expand_libname name = let make_link_options optlist = let rec split linkopts otheropts = function | [] -> String.concat " " otheropts - ^ " /link /subsystem:console " + ^ " -- " ^ + (match Config.system with + | "win32" -> "/subsystem:console " + | _ -> "") ^ String.concat " " linkopts | opt :: rem -> if String.length opt >= 5 && String.sub opt 0 5 = "/link" @@ -97,16 +104,3 @@ let make_link_options optlist = otheropts rem else split linkopts (opt :: otheropts) rem in split [] [] optlist - -(* Handling of Visual C++ 2005 manifest files *) - -let merge_manifest exefile = - let manfile = exefile ^ ".manifest" in - if not (Sys.file_exists manfile) then 0 else begin - let retcode = - command (Printf.sprintf "mt -nologo -outputresource:%s -manifest %s" - (Filename.quote exefile) - (Filename.quote manfile)) in - Misc.remove_file manfile; - retcode - end diff --git a/utils/ccomp.mli b/utils/ccomp.mli index 22bc2e8d6..d5d49c772 100644 --- a/utils/ccomp.mli +++ b/utils/ccomp.mli @@ -21,4 +21,3 @@ val create_archive: string -> string list -> int val expand_libname: string -> string val quote_files: string list -> string val make_link_options: string list -> string -val merge_manifest: string -> int diff --git a/utils/clflags.ml b/utils/clflags.ml index cda46bd2e..b4ac5f47e 100644 --- a/utils/clflags.ml +++ b/utils/clflags.ml @@ -88,3 +88,7 @@ let std_include_flag prefix = let std_include_dir () = if !no_std_include then [] else [Config.standard_library] ;; + +let shared = ref false (* -shared *) +let dlcode = ref false (* -dlcode *) + diff --git a/utils/clflags.mli b/utils/clflags.mli index 728cd285c..84a001d4d 100644 --- a/utils/clflags.mli +++ b/utils/clflags.mli @@ -73,3 +73,5 @@ val inline_threshold : int ref val dont_write_files : bool ref val std_include_flag : string -> string val std_include_dir : unit -> string list +val shared : bool ref +val dlcode : bool ref diff --git a/yacc/Makefile.nt b/yacc/Makefile.nt index a4b59e6c0..8f603bb1e 100644 --- a/yacc/Makefile.nt +++ b/yacc/Makefile.nt @@ -23,7 +23,7 @@ OBJS= closure.$(O) error.$(O) lalr.$(O) lr0.$(O) main.$(O) \ all: ocamlyacc.exe ocamlyacc.exe: $(OBJS) - $(call MKEXE,ocamlyacc.exe,$(BYTECCLINKOPTS) $(OBJS) $(EXTRALIBS)) + $(call MKEXE,ocamlyacc.exe,$(OBJS) $(EXTRALIBS),$(BYTECCLINKOPTS)) version.h : ../VERSION echo "#define OCAML_VERSION \"`head -1 ../VERSION`\"" >version.h |