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

Foreign can't find symbols statically linked in #167

Closed
pqwy opened this issue Aug 1, 2014 · 4 comments
Closed

Foreign can't find symbols statically linked in #167

pqwy opened this issue Aug 1, 2014 · 4 comments

Comments

@pqwy
Copy link
Contributor

pqwy commented Aug 1, 2014

I have two files:

foo.c:

int foo () { return 42; }

bar.ml:

open Ctypes
let foo = Foreign.foreign "foo" (void @-> returning int)
let _ = print_int (foo ())

Compiling foo as shared works:

$ clang -shared -fPIC foo.c -o libfoo.so
$ ocamlfind ocamlopt -linkpkg -package ctypes,ctypes.foreign bar.ml -o bar
$ LD_PRELOAD=./libfoo.so ./bar
42
$

But not linking it in:

$ clang -c -fPIC foo.c
$ ocamlfind ocamlopt -linkpkg -package ctypes,ctypes.foreign foo.o bar.ml -o bar
$ ./bar
Fatal error: exception Dl.DL_error("./bar: undefined symbol: foo")

Binding it via:

external foo : unit -> int = "foo"

... picks it up, however.

Can I overcome this somehow?

@dsheets
Copy link
Contributor

dsheets commented Aug 1, 2014

I have been using, e.g.:

int unix_unistd_unlink(const char *pathname) {
  int retval;
  caml_release_runtime_system();
  retval = unlink(pathname);
  caml_acquire_runtime_system();
  return retval;
}

value unix_unistd_unlink_ptr(value _) {
  UNUSED(_);
  return caml_copy_int64((intptr_t)(void *)unix_unistd_unlink);
}
let local ?check_errno addr typ =
  coerce (ptr void) (funptr ?check_errno typ) (ptr_of_raw_address addr)

external unix_unistd_unlink_ptr : unit -> int64 = "unix_unistd_unlink_ptr"

let unlink =
  let c = local ~check_errno:true (unix_unistd_unlink_ptr ())
    PosixTypes.(string @-> returning int)
  in
  fun pathname ->
    try ignore (c pathname)
    with Unix.Unix_error(e,_,_) -> raise (Unix.Unix_error (e,"unlink",pathname))

@yallop
Copy link
Owner

yallop commented Aug 1, 2014

Adding -E to the linker command line does the trick for me:

$ clang -c -fPIC foo.c
$ ocamlfind ocamlopt -linkpkg -package ctypes,ctypes.foreign -cclib -Wl,-E foo.o bar.ml -o bar
$ ./bar
42

@dsheets
Copy link
Contributor

dsheets commented Aug 1, 2014

Sweet! 👍

@pqwy
Copy link
Contributor Author

pqwy commented Aug 1, 2014

Yes, that's the one. Thanks!

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

No branches or pull requests

3 participants