I want to compile a helloworld without stdlib.
In 4.14.2 I used the following command, but in 5.4 it complaints about undefined reference to `caml_globals_inited’.
ocamlopt.opt -dstartup -S hello.ml -nopervasives -verbose -ccopt -lasmrun -ccopt -lm
+ as -o 'hello.o' 'hello.s'
+ as -o '/tmp/camlstartupea4d27.o' 'a.out.startup.s'
+ gcc -Wl,-E -o 'a.out' '-L/mnt/mand/.opam/5.4.0+flambda/lib/ocaml' -lasmrun -lm '/tmp/camlstartupea4d27.o' 'hello.o'
/usr/bin/ld: /tmp/camlstartupea4d27.o: in function `caml_program':
:(.text+0x16): undefined reference to `caml_globals_inited'
collect2: error: ld returned 1 exit status
objdump -x `opam var lib`/ocaml/libasmrun.a | grep caml_globals_inited 5.4.0+flambda
0000000000000008 g O .bss 0000000000000008 caml_globals_inited
0000000000000007 R_X86_64_PC32 caml_globals_inited-0x0000000000000004
00000000000008e9 R_X86_64_64 caml_globals_inited
The problematic symbol should be in libasmrun.a (I think) but something goes wrong.
$ grep -r caml_globals_inited `opam var lib`/ocaml
grep: /mnt/mand/.opam/5.4.0+flambda/lib/ocaml/libasmrun_shared.so: binary file matches
grep: /mnt/mand/.opam/5.4.0+flambda/lib/ocaml/libasmrund.a: binary file matches
grep: /mnt/mand/.opam/5.4.0+flambda/lib/ocaml/libasmrun.a: binary file matches
grep: /mnt/mand/.opam/5.4.0+flambda/lib/ocaml/compiler-libs/ocamloptcomp.a: binary file matches
grep: /mnt/mand/.opam/5.4.0+flambda/lib/ocaml/compiler-libs/ocamloptcomp.cma: binary file matches
grep: /mnt/mand/.opam/5.4.0+flambda/lib/ocaml/compiler-libs/cmm_helpers.cmx: binary file matches
grep: /mnt/mand/.opam/5.4.0+flambda/lib/ocaml/libasmrun_pic.a: binary file matches
/mnt/mand/.opam/5.4.0+flambda/lib/ocaml/caml/stack.h:extern intnat caml_globals_inited;
grep: /mnt/mand/.opam/5.4.0+flambda/lib/ocaml/libasmruni.a: binary file matches
The problematic symbols is defined in ./runtime/dynlink_nat.c. Should I try to compile OCaml without dynlink (or something like this) for investigation? Should it be possible?
Edit: repo: riscv_amd64_demos/00orig at gc · Kakadu/riscv_amd64_demos · GitHub
Code
type out_channel
external open_descriptor_out : int -> out_channel
= "caml_ml_open_descriptor_out"
let stdout = open_descriptor_out 1
external flush : out_channel -> unit = "caml_ml_flush"
external format_int : string -> int -> string = "caml_format_int"
let string_of_int n = format_int "%d" n
external output_char : out_channel -> char -> unit = "caml_ml_output_char"
external unsafe_output_string : out_channel -> string -> int -> int -> unit
= "caml_ml_output"
external string_length : string -> int = "%string_length"
let output_string oc s =
unsafe_output_string oc s 0 (string_length s)
let print_endline s =
output_string stdout s; output_char stdout '\n'; flush stdout
let () = print_endline (string_of_int 42)