Improve -output-obj: can now build directly a dynamic library (with all the ccobjs/ccopts); can also produces simply the uncompiled .c file (e.g. to debug). The output name (-o) is now mandatory when -output-obj is used, and only an extension amongst .c, EXT_OBJ, EXT_DLL is allowed.

git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@8522 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
master
Alain Frisch 2007-11-15 15:18:28 +00:00
parent 1b059475c8
commit 223f7bbfea
14 changed files with 79 additions and 19 deletions

View File

@ -359,6 +359,7 @@ utils/config.ml: utils/config.mlp config/Makefile
-e 's|%%ASM%%|$(ASM)|' \
-e 's|%%MKDLL%%|$(MKDLL)|' \
-e 's|%%MKEXE%%|$(MKEXE)|' \
-e 's|%%MKMAINDLL%%|$(MKMAINDLL)|' \
utils/config.mlp > utils/config.ml
@chmod -w utils/config.ml

View File

@ -330,6 +330,7 @@ utils/config.ml: utils/config.mlp config/Makefile
-e 's|%%ASM%%|$(ASM)|' \
-e 's|%%MKDLL%%|$(MKDLL)|' \
-e 's|%%MKEXE%%|$(MKEXE)|' \
-e 's|%%MKMAINDLL%%|$(MKMAINDLL)|' \
-e 's|%%CC_PROFILE%%||' \
utils/config.mlp > utils/config.ml
@chmod -w utils/config.ml

View File

@ -485,17 +485,28 @@ let link objfiles output_name =
remove_file prim_name;
raise x
end else begin
let c_file =
Filename.chop_suffix output_name Config.ext_obj ^ ".c" in
let basename = Filename.chop_extension output_name in
let c_file = basename ^ ".c"
and obj_file = basename ^ Config.ext_obj in
if Sys.file_exists c_file then raise(Error(File_exists c_file));
let temps = ref [] in
try
link_bytecode_as_c tolink c_file;
if Ccomp.compile_file c_file <> 0
then raise(Error Custom_runtime);
remove_file c_file
if not (Filename.check_suffix output_name ".c") then begin
temps := c_file :: !temps;
if Ccomp.compile_file c_file <> 0 then raise(Error Custom_runtime);
if not (Filename.check_suffix output_name Config.ext_obj) then begin
temps := obj_file :: !temps;
if not (
Ccomp.call_linker Ccomp.MainDll output_name
([obj_file] @ List.rev !Clflags.ccobjs @ ["-lcamlrun"])
Config.bytecomp_c_libraries
) then raise (Error Custom_runtime);
end
end;
List.iter remove_file !temps
with x ->
remove_file c_file;
remove_file output_name;
List.iter remove_file !temps;
raise x
end

View File

@ -99,6 +99,7 @@ FLEXDIR=$(shell $(FLEXLINK) -where)
IFLEXDIR=-I"$(FLEXDIR)"
MKDLL=$(FLEXLINK)
MKEXE=$(FLEXLINK) -exe
MKMAINDLL=$(FLEXLINK) -maindll
### How to build a static library
MKLIB=rm -f $(1); ar rcs $(1) $(2)

View File

@ -98,6 +98,7 @@ FLEXDIR=$(shell $(FLEXLINK) -where)
IFLEXDIR=-I"$(FLEXDIR)"
MKDLL=$(FLEXLINK)
MKEXE=$(FLEXLINK) -exe
MKMAINDLL=$(FLEXLINK) -maindll
### How to build a static library
MKLIB=link /lib /nologo /out:$(1) $(2)

View File

@ -102,6 +102,7 @@ FLEXDIR=$(shell $(FLEXLINK) -where)
IFLEXDIR=-I"$(FLEXDIR)"
MKDLL=$(FLEXLINK)
MKEXE=$(FLEXLINK) -exe
MKMAINDLL=$(FLEXLINK) -maindll
### How to build a static library
MKLIB=link /lib /nologo /machine:AMD64 /out:$(1) $(2)

6
configure vendored
View File

@ -507,6 +507,7 @@ if test $withsharedlibs = "yes"; then
*-*-cygwin*)
cmxs="cmxs"
mksharedlib="$flexlink"
mkmaindll="$flexlink -maindll"
shared_libraries_supported=true;;
*-*-linux-gnu|*-*-linux|*-*-freebsd[3-9]*|*-*-openbsd*|*-*-netbsd*|*-*-gnu*)
cmxs="cmxs"
@ -593,6 +594,10 @@ if test $withsharedlibs = "yes"; then
esac
fi
if test -z "$mkmaindll"; then
mkmaindll=$mksharedlib
fi
# Further machine-specific hacks
case "$host" in
@ -1530,6 +1535,7 @@ echo "TOOLCHAIN=cc" >> Makefile
echo "CMXS=$cmxs" >> Makefile
echo "MKEXE=$mkexe" >> Makefile
echo "MKDLL=$mksharedlib" >> Makefile
echo "MKMAINDLL=$mkmaindll" >> Makefile
rm -f tst hasgot.c
rm -f ../m.h ../s.h ../Makefile

View File

@ -137,12 +137,13 @@ module Options = Main_args.Make_options (struct
let anonymous = anonymous
end)
let fatal err =
prerr_endline err;
exit 2
let extract_output = function
| Some s -> s
| None ->
prerr_endline
"Please specify the name of the output file, using option -o";
exit 2
| None -> fatal "Please specify the name of the output file, using option -o"
let default_output = function
| Some s -> s
@ -151,6 +152,12 @@ let default_output = function
let main () =
try
Arg.parse Options.list anonymous usage;
if
List.length (List.filter (fun x -> !x)
[make_archive;make_package;compile_only;output_c_object]) > 1
then
fatal "Please specify at most one of -pack, -a, -c, -output-obj";
if !make_archive then begin
Compile.init_path();
Bytelibrarian.create_archive (List.rev !objfiles)
@ -162,8 +169,24 @@ let main () =
(extract_output !output_name)
end
else if not !compile_only && !objfiles <> [] then begin
let target =
if !output_c_object then
let s = extract_output !output_name in
if (Filename.check_suffix s Config.ext_obj
|| Filename.check_suffix s Config.ext_dll
|| Filename.check_suffix s ".c")
then s
else
fatal
(Printf.sprintf
"The extension of the output file must be .c, %s or %s"
Config.ext_obj Config.ext_dll
)
else
default_output !output_name
in
Compile.init_path();
Bytelink.link (List.rev !objfiles) (default_output !output_name)
Bytelink.link (List.rev !objfiles) target
end;
exit 0
with x ->

View File

@ -215,9 +215,9 @@ let main () =
]) (process_file ppf) usage;
if
List.length (List.filter (fun x -> !x)
[make_archive;make_package;shared;compile_only]) > 1
[make_archive;make_package;shared;compile_only;output_c_object]) > 1
then begin
prerr_endline "Please specify at most one of -pack, -a, -shared, -c";
prerr_endline "Please specify at most one of -pack, -a, -shared, -c, -output-obj";
exit 2
end;
if !make_archive then begin

View File

@ -1,3 +1,5 @@
include ../../config/Makefile
OCAMLC = ../../ocamlc
OCAMLOPT = ../../ocamlopt
@ -5,8 +7,15 @@ test:
$(OCAMLC) -c main.ml
$(OCAMLC) -c entry.c
$(OCAMLC) -c plugin.ml
$(OCAMLC) -output-obj -o main_obj.obj dynlink.cma main.cmo
flexlink -merge-manifest -maindll -o main.dll main_obj.obj entry.obj ../../byterun/libcamlrun.lib -v
$(OCAMLC) -output-obj -o main_obj.$(O) dynlink.cma main.cmo
$(MKDLL) -maindll -o main.dll main_obj.$(O) entry.$(O) ../../byterun/libcamlrun.$(A) $(BYTECCLIBS) -v
csc /out:main.exe main.cs
./main.exe
test2:
$(OCAMLC) -c main.ml
$(OCAMLC) -c plugin.ml
$(OCAMLC) -output-obj -o main.dll dynlink.cma main.cmo entry.c
csc /out:main.exe main.cs
./main.exe
@ -14,8 +23,8 @@ testopt:
$(OCAMLOPT) -c main.ml
$(OCAMLC) -c entry.c
$(OCAMLOPT) -o plugin.cmxs -shared plugin.ml
$(OCAMLOPT) -output-obj -o main_obj.obj dynlink.cmxa main.cmx
flexlink -merge-manifest -maindll -o main.dll main_obj.obj entry.obj ../../asmrun/libasmrun.lib -v
$(OCAMLOPT) -output-obj -o main_obj.$(O) dynlink.cmxa main.cmx
flexlink -merge-manifest -maindll -o main.dll main_obj.$(O) entry.$(O) ../../asmrun/libasmrun.lib -v
csc /out:main.exe main.cs
./main.exe

View File

@ -86,6 +86,7 @@ let expand_libname name =
type link_mode =
| Exe
| Dll
| MainDll
let call_linker mode output_name files extra =
let files = quote_files files in
@ -94,6 +95,7 @@ let call_linker mode output_name files extra =
(match mode with
| Exe -> Config.mkexe
| Dll -> Config.mkdll
| MainDll -> Config.mkmaindll
)
(Filename.quote output_name)
(if !Clflags.gprofile then Config.cc_profile else "")

View File

@ -25,5 +25,6 @@ val quote_files: string list -> string
type link_mode =
| Exe
| Dll
| MainDll
val call_linker: link_mode -> string -> string list -> string -> bool

View File

@ -49,7 +49,9 @@ val native_pack_linker: string
val mkdll: string
(* The linker command line to build dynamic libraries. *)
val mkexe: string
(* The linker command line to executables. *)
(* The linker command line to build executables. *)
val mkmaindll: string
(* The linker command line to build main programs as dlls. *)
val ranlib: string
(* Command to randomize a library, or "" if not needed *)
val cc_profile : string

View File

@ -40,6 +40,7 @@ let ranlib = "%%RANLIBCMD%%"
let cc_profile = "%%CC_PROFILE%%"
let mkdll = "%%MKDLL%%"
let mkexe = "%%MKEXE%%"
let mkmaindll = "%%MKMAINDLL%%"
let exec_magic_number = "Caml1999X008"
and cmi_magic_number = "Caml1999I011"