Version française
Home     About     Download     Resources     Contact us    
Browse thread
Embedding the ocaml runtime in a shared library on amd64/x86_64
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Joost Yervante Damad <joost@d...>
Subject: Re: [Caml-list] Embedding the ocaml runtime in a shared library on amd64/x86_64 [update]
Hello all,

a short update on my efforts to embed the ocaml runtime on amd64:

static linking the ocaml runtime works rather fine like this:

1. -fPIC

Make sure all files in asmrun are compiled with -fPIC by adapting the Makefile.

2) asmrun/amd64.S

    use an adapted amd64.S where 3 symbols are marked with @PLT:
    caml_program, caml_apply2, caml_apply3 like this:
        leaq    G(caml_program)@PLT(%rip), %r12
        leaq    G(caml_apply2)@PLT(%rip), %r12  /* code pointer */
        leaq    G(caml_apply3)@PLT(%rip), %r12  /* code pointer */

3) link the shared library

    # ocaml test code:
    ocamlopt -verbose -g -c mod.ml
    # wrapper code in C:
    ocamlopt -verbose -g -ccopt -fPIC -c mod_wrap.c
    # linking of lib, including needed packages
    ocamlfind ocamlopt -ccopt -Wl,-Bsymbolic -verbose -o modlib.native.so -
ccopt -shared mod.cmx mod_wrap.o -package unix -package bigarray -linkpkg

4) using the shared library
    # compile a main:
    ocamlopt -verbose -g -ccopt -Iinclude -c main.c
    # link a main:
    gcc -g -o main main.o -l:modlib.native.so -L. -Wl,-rpath=.

However, dynamic linking has more troubles:

I used an approach simular to the one already used for libcamlrun_shared.so to 
end up with a libasmrun_shared.so.

Whenever I try to use this by means of using -output-obj and then linking with 
g++ I always end
up with a program that crashes in caml_oldify_local_roots
during GC in a non-trivial program.

I finally got it working correctly by running ocamlopt with the verbose flag and 
adapting
the output to do something like this:

gcc -o 'libembedded.so'   '-L/usr/lib/ocaml/threads' '-L/usr/lib/ocaml' 
'/tmp/camlstartup.o' '/usr/lib/ocaml/std_exit.o' 'client.o' 'client.a' 
'/usr/lib/ocaml/bigarray.a' '/usr/lib/ocaml/dbm.a' '/usr/lib/ocaml/str.a' 
'/usr/lib/ocaml/threads/threads.a' '/usr/lib/ocaml/unix.a' 
'/usr/lib/ocaml/stdlib.a' '-lbigarray' '-lmldbm' '-lgdbm_compat' '-lgdbm' '-
lstr' '-lthreadsnat' '-lpthread' '-lunix' 'client_wrap.o' -L/usr/lib/ocaml -
lasmrun_shared -lm  -ldl -L../../../target/foo/ -lfoo -L. -lbar -L. baz.o -
shared -Wl,-Bsymbolic -ggdb3 -Wall -Wextra
Where I first used on of the old camlstartup*.s that was still lying around and 
compiling that to camlstartup.o:
as -o /tmp/camlstartup.o /tmp/camlstartupaf7c1e.s

The end result seems to work without crashing. It seems to me that in order to 
have a usable libasmrun_shared.so some changes to the toolchain (ocamlopt) are 
needed.

Given this result I'll stick to statically linking in libasmrun.a until there 
is a proper solution within the toolchain. Unless someone steps in and tells 
me I did something wrong ;-)

Greetings and happy new year, Joost Damad

-- 
Joost Yervante Damad - http://damad.be/joost/