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

Cannot link an object file #236

Closed
pdonadeo opened this issue Dec 23, 2014 · 5 comments
Closed

Cannot link an object file #236

pdonadeo opened this issue Dec 23, 2014 · 5 comments

Comments

@pdonadeo
Copy link

It's probably something I don't get right, but I can't compile a very simple program in which I try to link together a piece of OCaml and a piece of C code. The code is here:

https://gist.github.com/pdonadeo/bbc4a1ea176110ab93dd/

The program compiles but ctypes seems to ignore the linked symbols... or the command line for ocamlopt is wrong.

$ ./foo_ml_linked_a
Fatal error: exception Dl.DL_error("./foo_ml_linked_a: undefined symbol: my_foo_function")
@dbuenzli
Copy link
Contributor

It seems you are trying to statically link things in. I don't know on which platform but this may help:

#41 (comment)

@pdonadeo
Copy link
Author

@dbuenzli yes, I have a bunch of object files compiled outside my project, so I'm trying to link them and to make functions available to OCaml.

@yallop
Copy link
Owner

yallop commented Dec 24, 2014

As @dbuenzli suggests, this is often a matter of finding the right linker flags. The first problem is that the symbols aren't being included in the executable at all:

$ nm foo_ml_linked_a  | grep foo
$ 

On my platform I can force the symbols to be included by passing --whole-archive to the linker. In practice this means bracketing the archive of interest on the command-line as follows:

-cclib -Wl,--whole-archive libfoo_c.a -cclib -Wl,--no-whole-archive

After this change the symbol of interest is included in the executable:

$ nm foo_ml_linked_a  | grep foo
000000000046006f T my_foo_function
$

Unfortunately the program still doesn't work:

$ ./foo_ml_linked_a
Fatal error: exception Dl.DL_error("./foo_ml_linked_a: undefined symbol: my_foo_function")

The problem is that the symbol isn't included in the dynamic symbol table, which is where Foreign.foreign (which uses dlsym) looks for it. The -D flag to nm prints the dynamic symbol table:

$ nm -D foo_ml_linked_a  | grep foo
$ 

On my platform passing -E (or --export-dynamic) to the linker adds the symbols to the dynamic symbol table. Here's the modified command-line fragment:

-cclib -Wl,--whole-archive libfoo_c.a -cclib -Wl,--no-whole-archive -cclib -Wl,-E

After this change the symbol of interest is found in the dynamic symbol table of the executable:

$ nm -D foo_ml_linked_a  | grep foo
00000000004925ef T my_foo_function

Even better, the program actually works:

$ ./foo_ml_linked_a
This is printed by OCaml
This is printed by C

@yallop
Copy link
Owner

yallop commented Jan 2, 2015

@pdonadeo, did the suggestions above solve your problem?

@pdonadeo
Copy link
Author

pdonadeo commented Jan 3, 2015

@yallop sorry for the delay, I just came back from holidays. Yes, your suggestion works, I'm closing this "issue" which is more a documentation issue than a problem with ctypes itself.

@pdonadeo pdonadeo closed this as completed Jan 3, 2015
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