Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ocamlopt tries to link shared runtime with static-lib extension #8922

Open
cspiel opened this issue Sep 6, 2019 · 2 comments

Comments

@cspiel
Copy link

commented Sep 6, 2019

I wanted to link a program with the shared runtime using a
recent native compiler

$ ocamlopt -version
4.10.0+dev0-2019-04-23
$ git show HEAD | head -1
commit bf240cbab534d8b0af2ff75c0d19064dd398024f

and therefore I said

ocamlopt -runtime-variant _shared hello.ml

but the compiler complained

File "caml_startup", line 1:
Error: Cannot find file libasmrun_shared.a

However, the compiler driver ought to link against
libasmrun_shared.so on this system:

$ ocamlopt -config | grep ^ext
ext_exe:
ext_obj: .o
ext_asm: .s
ext_lib: .a
ext_dll: .so
$ (cd `ocamlopt -where`; find . -name 'libasmrun*')
./libasmrun.a
./libasmrun_shared.so
./libasmrun_pic.a
./libasmrund.a
./libasmruni.a

After applying the following (terribly ad hoc) patch ocamlopt
references the correct shared-runtime library.

--- a/asmcomp/asmlink.ml
+++ b/asmcomp/asmlink.ml
@@ -109,7 +109,8 @@ let add_ccobjs origin l =
   end
 
 let runtime_lib () =
-  let libname = "libasmrun" ^ !Clflags.runtime_variant ^ ext_lib in
+  let ext = if !Clflags.runtime_variant = "_shared" then ext_dll else ext_lib in
+  let libname = "libasmrun" ^ !Clflags.runtime_variant ^ ext in
   try
     if !Clflags.nopervasives || not !Clflags.with_runtime then []
     else [ Load_path.find libname ]

We arrive at

$ ocamlopt -verbose -runtime-variant _shared hello.ml
+ as  -o 'hello.o' '/tmp/camlasm973446.s'
+ as  -o '/tmp/camlstartup8ef270.o' '/tmp/camlstartupfade15.s'
+ gcc -O2 -fno-strict-aliasing -fwrapv -g  -fno-omit-frame-pointer -Wall -Werror -fno-tree-vrp -ffunction-sections -D_FILE_OFFSET_BITS=64 -D_REENTRANT -DCAML_NAME_SPACE  -Wl,-E -o 'a.out'  '-L/home/cls/lib/ocaml'  '/tmp/camlstartup8ef270.o' '/home/cls/lib/ocaml/std_exit.o' 'hello.o' '/home/cls/lib/ocaml/stdlib.a' '/home/cls/lib/ocaml/libasmrun_shared.so' -lm -ldl
/usr/bin/ld: warning: type and size of dynamic symbol `caml_system__frametable' are not defined
$ ldd a.out 
	linux-vdso.so.1 (0x00007ffcfdacf000)
	/home/cls/lib/ocaml/libasmrun_shared.so (0x00007f44e0d12000)
	libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f44e0b5b000)
	libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f44e0b56000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f44e0995000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f44e0d93000)
$ ./a.out 
Hello, world!
@nojb

This comment has been minimized.

Copy link
Contributor

commented Sep 6, 2019

Someone will correct me if I am wrong, but I don't think linking to the runtime as a shared library is supported. Maybe if you explain what you are really trying to do it will be clearer if there is a problem or not.

@cspiel

This comment has been minimized.

Copy link
Author

commented Sep 6, 2019

@nojb: I have found the executable size of even tiny OCaml programs
shockingly large.

$ cat hello.ml
let _ =
  print_endline "Hello, world!"
$ ocamlopt -o hello-static hello.ml
$ ocamlopt -runtime-variant _shared -o hello-shared hello.ml
$ ls -l hello-static hello-shared
-rwxr-xr-x 1 cls cls  132752 Sep  6 15:12 hello-shared
-rwxr-xr-x 1 cls cls 1255920 Sep  6 15:12 hello-static

Obviously, linking against the shared runtime pays off size-wise.

IMHO, the binary is still large given the complexity 😉 of the
source, but it is a step in the right direction if you want lots of
small OCaml tools each (hopefully) solving one problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants
You can’t perform that action at this time.