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

camlCamlinternalOO module is not linked when using Dynlink #7754

Closed
vicuna opened this issue Mar 16, 2018 · 4 comments
Closed

camlCamlinternalOO module is not linked when using Dynlink #7754

vicuna opened this issue Mar 16, 2018 · 4 comments

Comments

@vicuna
Copy link

vicuna commented Mar 16, 2018

Original bug ID: 7754
Reporter: cyocum
Status: acknowledged (set by @xavierleroy on 2018-04-06T18:06:09Z)
Resolution: open
Priority: normal
Severity: minor
OS: Fedora Linux
OS Version: 27
Version: 4.06.0
Category: dynlink and natdynlink
Monitored by: @nojb @dbuenzli

Bug description

I have a system which uses Dynlink to dynamically load some code (.cmxs). The problem that I am having is that you cannot use the Object system in OCaml with Dynlink when naively compiling. This is because the camlCamlinternalOO is not linked. The error is below:

undefined symbol: camlCamlinternalOO__create_object_opt_1533

Steps to reproduce

To reproduce you need to files.

obj_test.ml

class istack = object
val mutable v = [0; 2]

method pop =
  match v with
  | hd :: tl ->
      v <- tl;
      Some hd
  | [] -> None

method push hd =
  v <- hd :: v

end

which is complied thus: ocamlfind opt -shared -o obj_test.cmxs obj_test.ml

main.ml

let load_test_plugin fname =
let fname = Dynlink.adapt_filename fname in
try
Dynlink.loadfile fname
with
| (Dynlink.Error err) as e ->
print_endline ("ERROR loading plugin: " ^ (Dynlink.error_message err));
raise e

let _ =
load_test_plugin Sys.argv.(1)

which is compiled thus: ocamlfind opt -package dynlink -linkpkg main.ml

When you try to run the code: ./a.out obj_test.cmxs, you will get the error indicated above.

Additional information

See Also https://discuss.ocaml.org/t/objects-and-dynlink/1720

There is a workaround by adding this to main.ml:

let _obj = object end in

@vicuna
Copy link
Author

vicuna commented Mar 16, 2018

Comment author: @alainfrisch

In general, you need to make sure that modules used by dynlinked code are linked in the main program. You'd have the same problem if the dynlinked code wanted to use, say, Hasthbl, assuming this module is not required by your main program.
I'd recommend using -linkall for application that rely on Dynlink to avoid such problems.

The reported issue is a bit specific in that the module is referenced implicitly. One could perhaps force a link dependency from Dynlink to all camlinternal* modules, but I'm not sure it is worth it.

@vicuna
Copy link
Author

vicuna commented Mar 16, 2018

Comment author: @xclerc

The reported issue is a bit specific in that the module is referenced implicitly.

Indeed, the user has to be aware of an implementation detail, and cannot
e.g. use ocamldep to determine the set of needed modules.

@vicuna
Copy link
Author

vicuna commented Mar 16, 2018

Comment author: @dbuenzli

If you assume .cmxa's are built the same way you can catch these dependencies with ocamlobjinfo.

@vicuna
Copy link
Author

vicuna commented Apr 6, 2018

Comment author: @xavierleroy

I strongly recommend to link programs that use Dynlink with "-linkall", so that the dynamically-loaded modules have access to all the libraries that are visible to the main program (and not just to the parts of those libraries that are actually used in the main program).

Perhaps we could document the issue and the -linkall fix prominently?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant