1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
|
From: Stephane Glondu <steph@glondu.net>
Date: Thu, 21 Apr 2011 18:39:31 +0200
Subject: Avoid multiple declarations in generated .c files in -output-obj
In -output-obj mode, <caml/mlvalues.h> (which contains some
primitives) is included in the generated .c file, leading to errors
when compiling with g++ (multiple declarations).
There are probably better implementations (in particular, in this one,
care must be taken when changing the list of primitives available in
mlvalues.h), but this is a small and (not too) intrusive patch.
Bug: http://caml.inria.fr/mantis/view.php?id=5254
Signed-off-by: Stephane Glondu <steph@glondu.net>
---
bytecomp/bytelink.ml | 18 ++++++++++++++++--
bytecomp/symtable.ml | 8 +++++---
bytecomp/symtable.mli | 2 +-
3 files changed, 22 insertions(+), 6 deletions(-)
diff --git a/bytecomp/bytelink.ml b/bytecomp/bytelink.ml
index 2f5c0ec..9c972a7 100644
--- a/bytecomp/bytelink.ml
+++ b/bytecomp/bytelink.ml
@@ -439,6 +439,20 @@ let output_cds_file outfile =
remove_file outfile;
raise x
+(* List of primitives declared in caml/mlvalues.h, to avoid duplicate
+ declarations in generated .c files *)
+
+let mlvalues_primitives = [
+ "caml_get_public_method";
+ "caml_hash_variant";
+ "caml_string_length";
+ "caml_Double_val";
+ "caml_Store_double_val";
+ "caml_Int64_val";
+ "caml_atom_table";
+ "caml_set_oo_id";
+]
+
(* Output a bytecode executable as a C file *)
let link_bytecode_as_c ppf tolink outfile =
@@ -481,7 +495,7 @@ let link_bytecode_as_c ppf tolink outfile =
(Marshal.to_string sections []);
output_string outchan "\n};\n\n";
(* The table of primitives *)
- Symtable.output_primitive_table outchan;
+ Symtable.output_primitive_table outchan mlvalues_primitives;
(* The entry point *)
output_string outchan "\
\nvoid caml_startup(char ** argv)\
@@ -562,7 +576,7 @@ let link ppf objfiles output_name =
#else\n\
typedef long value;\n\
#endif\n";
- Symtable.output_primitive_table poc;
+ Symtable.output_primitive_table poc [];
output_string poc "\
#ifdef __cplusplus\n\
}\n\
diff --git a/bytecomp/symtable.ml b/bytecomp/symtable.ml
index a0ce273..d94863d 100644
--- a/bytecomp/symtable.ml
+++ b/bytecomp/symtable.ml
@@ -115,15 +115,17 @@ let output_primitive_names outchan =
open Printf
-let output_primitive_table outchan =
+let output_primitive_table outchan blacklist =
let prim = all_primitives() in
for i = 0 to Array.length prim - 1 do
- fprintf outchan "extern value %s();\n" prim.(i)
+ let p = prim.(i) in
+ if not (List.mem p blacklist) then
+ fprintf outchan "extern value %s();\n" p
done;
fprintf outchan "typedef value (*primitive)();\n";
fprintf outchan "primitive caml_builtin_cprim[] = {\n";
for i = 0 to Array.length prim - 1 do
- fprintf outchan " %s,\n" prim.(i)
+ fprintf outchan " (primitive)%s,\n" prim.(i)
done;
fprintf outchan " (primitive) 0 };\n";
fprintf outchan "const char * caml_names_of_builtin_cprim[] = {\n";
diff --git a/bytecomp/symtable.mli b/bytecomp/symtable.mli
index ffc878b..887f25a 100644
--- a/bytecomp/symtable.mli
+++ b/bytecomp/symtable.mli
@@ -23,7 +23,7 @@ val require_primitive: string -> unit
val initial_global_table: unit -> Obj.t array
val output_global_map: out_channel -> unit
val output_primitive_names: out_channel -> unit
-val output_primitive_table: out_channel -> unit
+val output_primitive_table: out_channel -> string list -> unit
val data_global_map: unit -> Obj.t
val data_primitive_names: unit -> string
|