diff --git a/Changes b/Changes index 9e19cbd89333..95386c59cc7e 100644 --- a/Changes +++ b/Changes @@ -220,8 +220,11 @@ ___________ - #13???: Introduce a RuntimeID for use in filename mangling to allow different configurations and different versions of ocamlrun and the shared runtime - libraries to coexist harmoniously on a single system. A portable version is - used in launcher header for bytecode executables. + libraries to coexist harmoniously on a single system. The RuntimeID is used, + along with the host triplet to mangle the names of stub libraries so that + stub libraries compiled for a given configuration of the runtime will only be + sought by that runtime. A portable version of the RuntimeID containing only + the release number is used in the launcher header for bytecode executables. (David Allsopp, review by ???) ### Code generation and optimizations: diff --git a/boot/ocamlc b/boot/ocamlc index 3fb10ea2e00b..16f94ec3b9db 100755 Binary files a/boot/ocamlc and b/boot/ocamlc differ diff --git a/boot/ocamllex b/boot/ocamllex index f055442e1bbf..6b2f509b452f 100755 Binary files a/boot/ocamllex and b/boot/ocamllex differ diff --git a/bytecomp/bytelink.ml b/bytecomp/bytelink.ml index 44054b366368..6c8e1fa5d0af 100644 --- a/bytecomp/bytelink.ml +++ b/bytecomp/bytelink.ml @@ -487,13 +487,28 @@ let link_bytecode ?final_name tolink exec_name standalone = let start_code = pos_out outchan in Symtable.init(); clear_crc_interfaces (); - let sharedobjs = List.map Dll.extract_dll_name !Clflags.dllibs in + let (tocheck, sharedobjs) = + let process_dllib ((suffixed, name) as dllib) (tocheck, sharedobjs) = + let resolved_name = Dll.extract_dll_name dllib in + let partial_name = + if suffixed then + if String.starts_with ~prefix:"-l" name then + (suffixed, "dll" ^ String.sub name 2 (String.length name - 2)) + else + dllib + else + (false, resolved_name) + in + (resolved_name::tocheck, partial_name::sharedobjs) + in + List.fold_right process_dllib !Clflags.dllibs ([], []) + in let check_dlls = standalone && Config.target = Config.host in if check_dlls then begin (* Initialize the DLL machinery *) Dll.init_compile !Clflags.no_std_include; Dll.add_path (Load_path.get_path_list ()); - try Dll.open_dlls Dll.For_checking sharedobjs + try Dll.open_dlls Dll.For_checking tocheck with Failure reason -> raise(Error(Cannot_open_dll reason)) end; let output_fun buf = @@ -508,11 +523,20 @@ let link_bytecode ?final_name tolink exec_name standalone = (* DLL stuff *) if standalone then begin (* The extra search path for DLLs *) - output_string outchan (concat_null_terminated !Clflags.dllpaths); - Bytesections.record toc_writer DLPT; + if !Clflags.dllpaths <> [] then begin + output_string outchan (concat_null_terminated !Clflags.dllpaths); + Bytesections.record toc_writer DLPT + end; (* The names of the DLLs *) - output_string outchan (concat_null_terminated sharedobjs); - Bytesections.record toc_writer DLLS + if sharedobjs <> [] then begin + let output_sharedobj (suffixed, name) = + output_char outchan (if suffixed then '-' else ':'); + output_string outchan name; + output_byte outchan 0 + in + List.iter output_sharedobj sharedobjs; + Bytesections.record toc_writer DLLS + end end; (* The names of all primitives *) Symtable.output_primitive_names outchan; diff --git a/bytecomp/dll.ml b/bytecomp/dll.ml index c8b280f9a012..1c3c4969cfa6 100644 --- a/bytecomp/dll.ml +++ b/bytecomp/dll.ml @@ -51,13 +51,20 @@ let remove_path dirs = (* Extract the name of a DLLs from its external name (xxx.so or -lxxx) *) -let extract_dll_name file = - if Filename.check_suffix file Config.ext_dll then +let extract_dll_name (suffixed, file) = + if not suffixed && Filename.check_suffix file Config.ext_dll then Filename.chop_suffix file Config.ext_dll - else if String.length file >= 2 && String.sub file 0 2 = "-l" then - "dll" ^ String.sub file 2 (String.length file - 2) else - file (* will cause error later *) + let file = + if String.starts_with ~prefix:"-l" file then + "dll" ^ String.sub file 2 (String.length file - 2) + else + file + in + if suffixed then + Printf.sprintf "%s-%s-%s" file Config.target Config.bytecode_runtime_id + else + file (* Open a list of DLLs, adding them to opened_dlls. Raise [Failure msg] in case of error. *) diff --git a/bytecomp/dll.mli b/bytecomp/dll.mli index f87554ff8fb7..38a517572f49 100644 --- a/bytecomp/dll.mli +++ b/bytecomp/dll.mli @@ -16,7 +16,7 @@ (* Handling of dynamically-linked libraries *) (* Extract the name of a DLLs from its external name (xxx.so or -lxxx) *) -val extract_dll_name: string -> string +val extract_dll_name: bool * string -> string type dll_mode = | For_checking (* will just check existence of symbols; diff --git a/driver/compenv.ml b/driver/compenv.ml index e704ba0ab718..ad693e8eab8a 100644 --- a/driver/compenv.ml +++ b/driver/compenv.ml @@ -622,7 +622,7 @@ type deferred_action = | ProcessCFile of string | ProcessOtherFile of string | ProcessObjects of string list - | ProcessDLLs of string list + | ProcessDLLs of bool * string list let c_object_of_filename name = Filename.chop_suffix (Filename.basename name) ".c" ^ Config.ext_obj @@ -655,8 +655,8 @@ let process_action ccobjs := obj_name :: !ccobjs | ProcessObjects names -> ccobjs := names @ !ccobjs - | ProcessDLLs names -> - dllibs := names @ !dllibs + | ProcessDLLs (suffixed, names) -> + dllibs := (List.map (fun n -> (suffixed, n)) names) @ !dllibs | ProcessOtherFile name -> if Filename.check_suffix name ocaml_mod_ext || Filename.check_suffix name ocaml_lib_ext then @@ -669,7 +669,7 @@ let process_action ccobjs := name :: !ccobjs end else if not !native_code && Filename.check_suffix name Config.ext_dll then - dllibs := name :: !dllibs + dllibs := (false, name) :: !dllibs else match Compiler_pass.of_input_filename name with | Some start_from -> diff --git a/driver/compenv.mli b/driver/compenv.mli index a5958554e76e..7260eb8affb5 100644 --- a/driver/compenv.mli +++ b/driver/compenv.mli @@ -52,7 +52,7 @@ type deferred_action = | ProcessCFile of string | ProcessOtherFile of string | ProcessObjects of string list - | ProcessDLLs of string list + | ProcessDLLs of bool * string list val c_object_of_filename : string -> string diff --git a/driver/main_args.ml b/driver/main_args.ml index d592882be4a1..ebeec9152e4c 100644 --- a/driver/main_args.ml +++ b/driver/main_args.ml @@ -89,6 +89,11 @@ let mk_custom f = let mk_dllib f = "-dllib", Arg.String f, " Use the dynamically-loaded library " +let mk_dllib_suffixed f = + "-dllib-suffixed", Arg.String f, + " Use the dynamically-loaded library , with runtime suffix \ + appended to the name" + let mk_dllpath f = "-dllpath", Arg.String f, " Add to the run-time search path for shared libraries" @@ -906,6 +911,7 @@ module type Bytecomp_options = sig val _custom : unit -> unit val _no_check_prims : unit -> unit val _dllib : string -> unit + val _dllib_suffixed : string -> unit val _dllpath : string -> unit val _make_runtime : unit -> unit val _vmthread : unit -> unit @@ -1040,6 +1046,7 @@ struct mk_config_var F._config_var; mk_custom F._custom; mk_dllib F._dllib; + mk_dllib_suffixed F._dllib_suffixed; mk_dllpath F._dllpath; mk_dtypes F._annot; mk_for_pack_byt F._for_pack; @@ -1915,7 +1922,9 @@ third-party libraries such as Lwt, but with a different API." let _custom = set custom_runtime let _dcamlprimc = set keep_camlprimc_file let _dinstr = set dump_instr - let _dllib s = Compenv.defer (ProcessDLLs (Misc.rev_split_words s)) + let _dllib s = Compenv.defer (ProcessDLLs (false, Misc.rev_split_words s)) + let _dllib_suffixed s = + Compenv.defer (ProcessDLLs (true, Misc.rev_split_words s)) let _dllpath s = dllpaths := ((!dllpaths) @ [s]) let _make_runtime () = custom_runtime := true; make_runtime := true; link_everything := true diff --git a/driver/main_args.mli b/driver/main_args.mli index 7268c70d5c7b..3d525eb52ac5 100644 --- a/driver/main_args.mli +++ b/driver/main_args.mli @@ -154,6 +154,7 @@ module type Bytecomp_options = sig val _custom : unit -> unit val _no_check_prims : unit -> unit val _dllib : string -> unit + val _dllib_suffixed : string -> unit val _dllpath : string -> unit val _make_runtime : unit -> unit val _vmthread : unit -> unit diff --git a/file_formats/cmo_format.mli b/file_formats/cmo_format.mli index a4dbfce082e9..4a893bf57032 100644 --- a/file_formats/cmo_format.mli +++ b/file_formats/cmo_format.mli @@ -67,7 +67,7 @@ type library = how they end up being used on the command line. *) lib_ccobjs: string list; (* C object files needed for -custom *) lib_ccopts: string list; (* Extra opts to C compiler *) - lib_dllibs: string list } (* DLLs needed *) + lib_dllibs: (bool * string) list } (* DLLs needed *) (* Format of a .cma file: magic number (Config.cma_magic_number) diff --git a/ocamltest/ocaml_actions.ml b/ocamltest/ocaml_actions.ml index e2e5266b1caa..3c2e033c20ba 100644 --- a/ocamltest/ocaml_actions.ml +++ b/ocamltest/ocaml_actions.ml @@ -597,6 +597,7 @@ let mklib log env = [ Ocaml_commands.ocamlrun_ocamlmklib; "-ocamlc '" ^ ocamlc_command ^ "'"; + "-suffixed"; "-o " ^ program ] @ modules env in let expected_exit_status = 0 in diff --git a/otherlibs/Makefile.otherlibs.common b/otherlibs/Makefile.otherlibs.common index f08dd13ef8cc..a96f4f985e31 100644 --- a/otherlibs/Makefile.otherlibs.common +++ b/otherlibs/Makefile.otherlibs.common @@ -53,6 +53,7 @@ CLIBNAME ?= $(LIBNAME) ifeq "$(C_SOURCES)" "" STUBSLIB= +STUBSDLL= else COBJS_BYTECODE = $(C_SOURCES:.c=.b.$(O)) COBJS_NATIVE = $(C_SOURCES:.c=.n.$(O)) @@ -61,6 +62,7 @@ COBJS = $(COBJS_BYTECODE) $(COBJS_NATIVE) CLIBNAME_BYTECODE=$(CLIBNAME)byt CLIBNAME_NATIVE=$(CLIBNAME)nat STUBSLIB_BYTECODE=lib$(CLIBNAME_BYTECODE).$(A) +STUBSDLL=dll$(CLIBNAME_BYTECODE)-$(TARGET)-$(BYTECODE_RUNTIME_ID)$(EXT_DLL) STUBSLIB_NATIVE=lib$(CLIBNAME_NATIVE).$(A) endif @@ -75,7 +77,7 @@ ifeq "$(COBJS)" "" $(V_LINKC)$(CAMLC) -o $@ -a -linkall $(CAMLOBJS) $(LINKOPTS) else $(V_OCAMLMKLIB)$(MKLIB) -o $(LIBNAME) -oc $(CLIBNAME_BYTECODE) -ocamlc '$(CAMLC)' \ - -linkall $(CAMLOBJS) $(LINKOPTS) + -linkall $(CAMLOBJS) $(LINKOPTS) -suffixed endif $(LIBNAME).cmxa: $(CAMLOBJS_NAT) @@ -83,14 +85,14 @@ ifeq "$(COBJS)" "" $(V_OCAMLOPT)$(CAMLOPT) -o $@ -a -linkall $(CAMLOBJS_NAT) $(LINKOPTS) else $(V_OCAMLMKLIB)$(MKLIB) -o $(LIBNAME) -oc $(CLIBNAME_NATIVE) -ocamlopt '$(CAMLOPT)' \ - -linkall $(CAMLOBJS_NAT) $(LINKOPTS) + -linkall $(CAMLOBJS_NAT) $(LINKOPTS) -suffixed endif $(LIBNAME).cmxs: $(LIBNAME).cmxa $(STUBSLIB_NATIVE) $(V_OCAMLOPT)$(CAMLOPT) -shared -o $(LIBNAME).cmxs -I . $(LIBNAME).cmxa lib$(CLIBNAME_BYTECODE).$(A): $(COBJS) - $(V_OCAMLMKLIB)$(MKLIB) -oc $(CLIBNAME_BYTECODE) $(COBJS_BYTECODE) $(LDOPTS) + $(V_OCAMLMKLIB)$(MKLIB) -oc $(CLIBNAME_BYTECODE) $(COBJS_BYTECODE) $(LDOPTS) -suffixed lib$(CLIBNAME_NATIVE).$(A): $(COBJS) $(V_OCAMLMKLIB)$(MKLIB) -oc $(CLIBNAME_NATIVE) $(COBJS_NATIVE) $(LDOPTS) @@ -98,11 +100,11 @@ lib$(CLIBNAME_NATIVE).$(A): $(COBJS) INSTALL_LIBDIR_LIBNAME = $(INSTALL_LIBDIR)/$(LIBNAME) install:: - if test -f dll$(CLIBNAME_BYTECODE)$(EXT_DLL); then \ +ifneq "$(STUBSLIB_BYTECODE)" "" + if test -f $(STUBSDLL); then \ $(INSTALL_PROG) \ - dll$(CLIBNAME_BYTECODE)$(EXT_DLL) "$(INSTALL_STUBLIBDIR)"; \ + $(STUBSDLL) "$(INSTALL_STUBLIBDIR)"; \ fi -ifneq "$(STUBSLIB_BYTECODE)" "" $(INSTALL_DATA) $(STUBSLIB_BYTECODE) "$(INSTALL_LIBDIR)/" endif # If installing over a previous OCaml version, ensure the library is removed diff --git a/otherlibs/dynlink/byte/dynlink_symtable.ml b/otherlibs/dynlink/byte/dynlink_symtable.ml index e275a2856466..be60fd006761 100644 --- a/otherlibs/dynlink/byte/dynlink_symtable.ml +++ b/otherlibs/dynlink/byte/dynlink_symtable.ml @@ -89,17 +89,25 @@ let primitives : (string, int) Hashtbl.t = Hashtbl.create 100 #52 "bytecomp/dll.ml" (* Extract the name of a DLLs from its external name (xxx.so or -lxxx) *) -let extract_dll_name file = - if Filename.check_suffix file Config.ext_dll then +let extract_dll_name (suffixed, file) = + if not suffixed && Filename.check_suffix file Config.ext_dll then Filename.chop_suffix file Config.ext_dll - else if String.length file >= 2 && String.sub file 0 2 = "-l" then - "dll" ^ String.sub file 2 (String.length file - 2) else - file (* will cause error later *) -#100 "otherlibs/dynlink/byte/dynlink_symtable.ml" + let file = + if String.starts_with ~prefix:"-l" file then + "dll" ^ String.sub file 2 (String.length file - 2) + else + file + in + if suffixed then + Printf.sprintf "%s-%s-%s" file Config.target Config.bytecode_runtime_id + else + file +#107 "otherlibs/dynlink/byte/dynlink_symtable.ml" (* Specialized version of [Dll.{open_dll,open_dlls,find_primitive}] for the execution mode. *) let open_dll name = + (* XXX Adding ext_dll equivalent here to elsewhere? *) let name = (extract_dll_name name) ^ Config.ext_dll in let fullname = if Filename.is_implicit name then @@ -233,12 +241,12 @@ let patch_object buff patchlist = (* Functions for toplevel use *) (* Update the in-core table of globals *) -#237 "otherlibs/dynlink/byte/dynlink_symtable.ml" +#245 "otherlibs/dynlink/byte/dynlink_symtable.ml" module Meta = struct #16 "bytecomp/meta.ml" external global_data : unit -> Obj.t array = "caml_get_global_data" external realloc_global_data : int -> unit = "caml_realloc_global" -#242 "otherlibs/dynlink/byte/dynlink_symtable.ml" +#250 "otherlibs/dynlink/byte/dynlink_symtable.ml" end #332 "bytecomp/symtable.ml" let update_global_table () = @@ -264,7 +272,7 @@ external get_bytecode_sections : unit -> bytecode_sections = let init_toplevel () = let sect = get_bytecode_sections () in global_table := sect.symb; -#268 "otherlibs/dynlink/byte/dynlink_symtable.ml" +#276 "otherlibs/dynlink/byte/dynlink_symtable.ml" Dll.init ~dllpaths:sect.dlpt ~prims:sect.prim; #358 "bytecomp/symtable.ml" sect.crcs @@ -317,7 +325,7 @@ let current_state () = !global_table #412 "bytecomp/symtable.ml" let hide_additions (st : global_map) = if st.cnt > !global_table.cnt then -#321 "otherlibs/dynlink/byte/dynlink_symtable.ml" +#329 "otherlibs/dynlink/byte/dynlink_symtable.ml" failwith "Symtable.hide_additions"; #415 "bytecomp/symtable.ml" global_table := diff --git a/otherlibs/dynlink/byte/dynlink_symtable.mli b/otherlibs/dynlink/byte/dynlink_symtable.mli index 686cb4c44d41..8db93a27de68 100644 --- a/otherlibs/dynlink/byte/dynlink_symtable.mli +++ b/otherlibs/dynlink/byte/dynlink_symtable.mli @@ -31,7 +31,7 @@ module Global : sig val description: Format.formatter -> t -> unit end -val open_dlls : string list -> unit +val open_dlls : (bool * string) list -> unit val patch_object: (char, Bigarray.int8_unsigned_elt, Bigarray.c_layout) Bigarray.Array1.t -> diff --git a/otherlibs/dynlink/dynlink_config.ml.in b/otherlibs/dynlink/dynlink_config.ml.in index 60132fe50356..e51fa45bc383 100644 --- a/otherlibs/dynlink/dynlink_config.ml.in +++ b/otherlibs/dynlink/dynlink_config.ml.in @@ -24,3 +24,7 @@ let ext_dll = "." ^ {@QS@|@SO@|@QS@} and cmo_magic_number = {@QS@|@CMO_MAGIC_NUMBER@|@QS@} and cma_magic_number = {@QS@|@CMA_MAGIC_NUMBER@|@QS@} and cmxs_magic_number = {@QS@|@CMXS_MAGIC_NUMBER@|@QS@} + +let bytecode_runtime_id = {@QS@|@bytecode_runtime_id@|@QS@} + +let target = {@QS@|@target@|@QS@} diff --git a/otherlibs/dynlink/dynlink_config.mli b/otherlibs/dynlink/dynlink_config.mli index ad44848ebc20..30dbdf4df6bf 100644 --- a/otherlibs/dynlink/dynlink_config.mli +++ b/otherlibs/dynlink/dynlink_config.mli @@ -21,3 +21,7 @@ val ext_dll: string val cmo_magic_number: string val cma_magic_number: string val cmxs_magic_number: string + +val bytecode_runtime_id: string + +val target : string diff --git a/otherlibs/systhreads/Makefile b/otherlibs/systhreads/Makefile index c2a4a64caf88..ab764c8118e2 100644 --- a/otherlibs/systhreads/Makefile +++ b/otherlibs/systhreads/Makefile @@ -50,8 +50,10 @@ CMIFILES=$(MLIFILES:.mli=.cmi) all: lib$(LIBNAME).$(A) $(LIBNAME).cma $(CMIFILES) +DLLTHREADS = dllthreads-$(TARGET)-$(BYTECODE_RUNTIME_ID)$(EXT_DLL) + ifeq "$(SUPPORTS_SHARED_LIBRARIES)" "true" -all: dll$(LIBNAME)$(EXT_DLL) +all: $(DLLTHREADS) endif allopt: lib$(LIBNAME)nat.$(A) $(LIBNAME).cmxa $(CMIFILES) @@ -63,20 +65,20 @@ endif lib$(LIBNAME).$(A): OC_CFLAGS = $(OC_BYTECODE_CFLAGS) lib$(LIBNAME).$(A): st_stubs.b.$(O) - $(V_OCAMLMKLIB)$(MKLIB) -custom -o $(LIBNAME) $^ + $(V_OCAMLMKLIB)$(MKLIB) -custom -suffixed -o $(LIBNAME) $^ st_stubs_shared.b.$(O): OC_CFLAGS = $(OC_BYTECODE_CFLAGS) -dll$(LIBNAME)$(EXT_DLL): st_stubs_shared.b.$(O) +$(DLLTHREADS): st_stubs_shared.b.$(O) $(V_MKDLL)$(MKDLL) -o $@ $^ lib$(LIBNAME)nat.$(A): OC_CFLAGS = $(OC_NATIVE_CFLAGS) lib$(LIBNAME)nat.$(A): st_stubs.n.$(O) - $(V_OCAMLMKLIB)$(MKLIB) -custom -o $(LIBNAME)nat $^ + $(V_OCAMLMKLIB)$(MKLIB) -custom -suffixed -o $(LIBNAME)nat $^ $(LIBNAME).cma: $(THREADS_BCOBJS) - $(V_OCAMLMKLIB)$(MKLIB) -o $(LIBNAME) -ocamlc '$(CAMLC)' -linkall $^ + $(V_OCAMLMKLIB)$(MKLIB) -o $(LIBNAME) -ocamlc '$(CAMLC)' -linkall $^ -suffixed # See remark above: force static linking of libthreadsnat.a $(LIBNAME).cmxa: $(THREADS_NCOBJS) @@ -118,8 +120,8 @@ distclean: clean INSTALL_THREADSLIBDIR=$(INSTALL_LIBDIR)/$(LIBNAME) install: - if test -f dllthreads$(EXT_DLL); then \ - $(INSTALL_PROG) dllthreads$(EXT_DLL) "$(INSTALL_STUBLIBDIR)"; \ + if test -f $(DLLTHREADS); then \ + $(INSTALL_PROG) $(DLLTHREADS) "$(INSTALL_STUBLIBDIR)"; \ fi $(INSTALL_DATA) libthreads.$(A) "$(INSTALL_LIBDIR)" $(MKDIR) "$(INSTALL_THREADSLIBDIR)" diff --git a/runtime/dynlink.c b/runtime/dynlink.c index 45404d8e30a6..46ed23d09961 100644 --- a/runtime/dynlink.c +++ b/runtime/dynlink.c @@ -141,10 +141,24 @@ CAMLexport char_os * caml_parse_ld_conf(void) Abort on error. */ static void open_shared_lib(char_os * name) { - char_os * realname; + char_os * realname, * suffixed = NULL; char * u8; void * handle; + if (*name == '\0') + caml_fatal_error("corrupt DLLS section"); + + if (*name == '-') { + char * suffix = + caml_stat_strconcat(4, "-", HOST, "-", BYTECODE_RUNTIME_ID); + char_os * suffix_os = caml_stat_strdup_to_os(suffix); + name = suffixed = caml_stat_strconcat_os(2, name + 1, suffix_os); + caml_stat_free(suffix_os); + caml_stat_free(suffix); + } else { + name++; + } + realname = caml_search_dll_in_path(&caml_shared_libs_path, name); u8 = caml_stat_strdup_of_os(realname); caml_gc_message(0x100, "Loading shared library %s\n", u8); @@ -161,6 +175,7 @@ static void open_shared_lib(char_os * name) caml_dlerror() ); caml_ext_table_add(&shared_libs, handle); + caml_stat_free(suffixed); caml_stat_free(realname); } diff --git a/tools/objinfo.ml b/tools/objinfo.ml index 83e36593141b..85fc153db580 100644 --- a/tools/objinfo.ml +++ b/tools/objinfo.ml @@ -72,6 +72,12 @@ let print_cmo_infos cu = let print_spaced_string s = printf " %s" s +let dllib (suffixed, name) = + if suffixed then + Printf.sprintf "%s--" name + else + name + let print_cma_infos (lib : Cmo_format.library) = printf "Force custom: %s\n" (if lib.lib_custom then "YES" else "no"); printf "Extra C object files:"; @@ -81,7 +87,7 @@ let print_cma_infos (lib : Cmo_format.library) = List.iter print_spaced_string (List.rev lib.lib_ccopts); printf "\n"; print_string "Extra dynamically-loaded libraries:"; - List.iter print_spaced_string (List.rev lib.lib_dllibs); + List.iter print_spaced_string (List.rev_map dllib lib.lib_dllibs); printf "\n"; List.iter print_cmo_infos lib.lib_units diff --git a/tools/ocamlmklib.ml b/tools/ocamlmklib.ml index f6b2a2d16ec9..d0813f88c5e9 100644 --- a/tools/ocamlmklib.ml +++ b/tools/ocamlmklib.ml @@ -51,6 +51,7 @@ and output_c = ref "" (* Output name for C part of library *) and rpath = ref [] (* rpath options *) and debug = ref false (* -g option *) and verbose = ref false +and suffixed = ref false (* -suffixed option; becomes true in 5.02 *) let starts_with s pref = String.length s >= String.length pref && @@ -164,6 +165,8 @@ let parse_arguments argv = c_opts := s :: !c_opts else if s = "-framework" then (let a = next_arg s in c_opts := a :: s :: !c_opts) + else if s = "-suffixed" then + suffixed := true else if starts_with s "-" then prerr_endline ("Unknown option " ^ s) else @@ -210,6 +213,7 @@ Options are: -oc Generated C library is named dll.so or lib.a -rpath Same as -dllpath -R Same as -rpath + -suffixed Append runtime ID to any generated shared libraries -verbose Print commands before executing them -v same as -verbose -version Print version and exit @@ -284,13 +288,19 @@ let flexdll_dirs = List.map f dirs let build_libs () = + let suffix = + if !suffixed then + Printf.sprintf "-%s-%s" Config.target Config.bytecode_runtime_id + else + "" + in if !c_objs <> [] then begin if !dynlink then begin let retcode = command (Printf.sprintf "%s %s -o %s %s %s %s %s %s %s" Config.mkdll (if !debug then "-g" else "") - (prepostfix "dll" !output_c Config.ext_dll) + (prepostfix "dll" (!output_c ^ suffix) Config.ext_dll) (String.concat " " !c_objs) (String.concat " " !c_opts) (String.concat " " !ld_opts) @@ -308,7 +318,7 @@ let build_libs () = end; if !bytecode_objs <> [] then scommand - (sprintf "%s -a %s %s %s -o %s.cma %s %s -dllib -l%s -cclib -l%s \ + (sprintf "%s -a %s %s %s -o %s.cma %s %s -dllib%s -l%s -cclib -l%s \ %s %s %s %s" (transl_path !ocamlc) (if !debug then "-g" else "") @@ -317,6 +327,7 @@ let build_libs () = !output (String.concat " " !caml_opts) (String.concat " " !bytecode_objs) + (if !suffixed then "-suffixed" else "") (Filename.basename !output_c) (Filename.basename !output_c) (String.concat " " (prefix_list "-ccopt " !c_opts)) diff --git a/utils/clflags.ml b/utils/clflags.ml index 566ad639d01b..51178c8feaea 100644 --- a/utils/clflags.ml +++ b/utils/clflags.ml @@ -38,9 +38,10 @@ module Float_arg_helper = Arg_helper.Make (struct end end) -let objfiles = ref ([] : string list) (* .cmo and .cma files *) -and ccobjs = ref ([] : string list) (* .o, .a, .so and -cclib -lxxx *) -and dllibs = ref ([] : string list) (* .so and -dllib -lxxx *) +let objfiles = ref ([] : string list) (* .cmo and .cma files *) +and ccobjs = ref ([] : string list) (* .o, .a, .so and -cclib -lxxx *) +and dllibs = ref ([] : (bool * string) list) (* .so, -dllib -lxxx and + '-dllib-suffixed -lxxx *) let cmi_file = ref None diff --git a/utils/clflags.mli b/utils/clflags.mli index c8ac8e970767..5338aed1daf8 100644 --- a/utils/clflags.mli +++ b/utils/clflags.mli @@ -70,7 +70,7 @@ val use_inlining_arguments_set : ?round:int -> inlining_arguments -> unit val objfiles : string list ref val ccobjs : string list ref -val dllibs : string list ref +val dllibs : (bool * string) list ref val cmi_file : string option ref val compile_only : bool ref val output_name : string option ref