(* Output a bytecode executable as a C file *)
-let link_bytecode_as_c tolink outfile =
+let link_bytecode_as_c tolink outfile with_main =
let outchan = open_out outfile in
Misc.try_finally
~always:(fun () -> close_out outchan)
(* The table of primitives *)
Symtable.output_primitive_table outchan;
(* The entry point *)
- output_string outchan "\
+ if with_main then begin
+ output_string outchan "\
+\nint main(int argc, char_os **argv)\
+\n{\
+\n caml_startup_code(caml_code, sizeof(caml_code),\
+\n caml_data, sizeof(caml_data),\
+\n caml_sections, sizeof(caml_sections),\
+\n /* pooling */ 0,\
+\n argv);\
+\n return 0; /* not reached */\
+\n}\n"
+ end else begin
+ output_string outchan "\
\nvoid caml_startup(char_os ** argv)\
\n{\
\n caml_startup_code(caml_code, sizeof(caml_code),\
\n caml_sections, sizeof(caml_sections),\
\n /* pooling */ 1,\
\n argv);\
-\n}\
+\n}\n"
+ end;
+ output_string outchan "\
\n#ifdef __cplusplus\
\n}\
\n#endif\n";
Clflags.dllibs := !lib_dllibs @ !Clflags.dllibs; (* put user's DLLs first *)
if not !Clflags.custom_runtime then
link_bytecode tolink output_name true
+ else if not !Clflags.output_c_object && not !Clflags.make_runtime then
+ let c_file = Filename.temp_file "camlobj" ".c" in
+ Misc.try_finally
+ ~always:(fun () -> remove_file c_file)
+ (fun () ->
+ link_bytecode_as_c tolink c_file true;
+ let exec_name = fix_exec_name output_name in
+ if not (build_custom_runtime c_file exec_name)
+ then raise(Error Custom_runtime)
+ )
else if not !Clflags.output_c_object then begin
let bytecode_name = Filename.temp_file "camlcode" "" in
let prim_name =
Misc.try_finally
~always:(fun () -> List.iter remove_file !temps)
(fun () ->
- link_bytecode_as_c tolink c_file;
+ link_bytecode_as_c tolink c_file false;
if not (Filename.check_suffix output_name ".c") then begin
temps := c_file :: !temps;
if Ccomp.compile_file ~output:obj_file ?stable_name c_file <> 0 then
let cmpbyt file1 file2 =
let ic1 = open_in_bin file1 in
- let (toc1, pos1) = readtoc ic1 in
let ic2 = open_in_bin file2 in
- let (toc2, pos2) = readtoc ic2 in
- seek_in ic1 pos1;
- seek_in ic2 pos2;
- let rec cmpsections t1 t2 =
- match t1, t2 with
- | [], [] ->
- true
- | (name1, len1) :: t1, t2 when skip_section name1 ->
- seek_in ic1 (pos_in ic1 + len1);
- cmpsections t1 t2
- | t1, (name2, len2) :: t2 when skip_section name2 ->
- seek_in ic2 (pos_in ic2 + len2);
- cmpsections t1 t2
- | [], _ ->
- eprintf "%s has more sections than %s\n" file2 file1;
- false
- | _, [] ->
- eprintf "%s has more sections than %s\n" file1 file2;
- false
- | (name1, len1) :: t1, (name2, len2) :: t2 ->
- if name1 <> name2 then begin
- eprintf "Section mismatch: %s (in %s) / %s (in %s)\n"
- name1 file1 name2 file2;
- false
- end else if len1 <> len2 then begin
- eprintf "Length of section %s differ: %d (in %s) / %d (in %s)\n"
- name1 len1 file1 len2 file2;
- false
- end else begin
- match cmpbytes ic1 ic2 len1 0 with
- | Differ ofs ->
- eprintf "Files %s and %s differ: section %s, offset %d\n"
- file1 file2 name1 ofs;
- false
- | Same ->
- cmpsections t1 t2
- end
+ let len1 = in_channel_length ic1 in
+ let len2 = in_channel_length ic2 in
+ let res =
+ if len1 = len2 && cmpbytes ic1 ic2 len1 0 = Same then
+ true
+ else
+ let (toc1, pos1) = readtoc ic1 in
+ let (toc2, pos2) = readtoc ic2 in
+ seek_in ic1 pos1;
+ seek_in ic2 pos2;
+ let rec cmpsections t1 t2 =
+ match t1, t2 with
+ | [], [] ->
+ true
+ | (name1, len1) :: t1, t2 when skip_section name1 ->
+ seek_in ic1 (pos_in ic1 + len1);
+ cmpsections t1 t2
+ | t1, (name2, len2) :: t2 when skip_section name2 ->
+ seek_in ic2 (pos_in ic2 + len2);
+ cmpsections t1 t2
+ | [], _ ->
+ eprintf "%s has more sections than %s\n" file2 file1;
+ false
+ | _, [] ->
+ eprintf "%s has more sections than %s\n" file1 file2;
+ false
+ | (name1, len1) :: t1, (name2, len2) :: t2 ->
+ if name1 <> name2 then begin
+ eprintf "Section mismatch: %s (in %s) / %s (in %s)\n"
+ name1 file1 name2 file2;
+ false
+ end else if len1 <> len2 then begin
+ eprintf "Length of section %s differ: %d (in %s) / %d (in %s)\n"
+ name1 len1 file1 len2 file2;
+ false
+ end else begin
+ match cmpbytes ic1 ic2 len1 0 with
+ | Differ ofs ->
+ eprintf "Files %s and %s differ: section %s, offset %d\n"
+ file1 file2 name1 ofs;
+ false
+ | Same ->
+ cmpsections t1 t2
+ end
+ in
+ cmpsections toc1 toc2
in
- let res = cmpsections toc1 toc2 in
close_in ic1; close_in ic2;
res