views:

159

answers:

2

I'm trying to link my mac application to the wonderful libancillary library. However, I have changed the library build script to create a shared library. I can inspect the symbols in this library using nm libancillary.dylib - the result is:

libancillary.dylib(single module):
         U ___sF
         U __keymgr_get_and_lock_processwide_ptr
         U __keymgr_get_and_lock_processwide_ptr_2
         U __keymgr_set_and_unlock_processwide_ptr
         U _abort
00002cfe T _ancil_recv_fd
00002c87 T _ancil_recv_fds
00002b6a T _ancil_recv_fds_with_buffer
00002e9e T _ancil_send_fd
00002e27 T _ancil_send_fds
00002d3f T _ancil_send_fds_with_buffer
         U _calloc
         U _dlopen
         U _dlsym
         U _fflush
         U _fprintf
         U _free
         U _malloc
         U _recvmsg
         U _sendmsg

However, when I try and link my application, the output I get is:

g++ -headerpad_max_install_names -framework AppKit -framework Cocoa -framework IOKit -framework CoreFoundation -framework Carbon -framework OpenGL -framework SystemConfiguration -framework Security -Wl,-bind_at_load -arch i386 -o MyApp build/app.o build/client.o build/util.o -F/Library/Frameworks -L/Library/Frameworks -L../ancillary -lancillary
Undefined symbols:
  "ancil_recv_fd(int, int*)", referenced from:
      CIPCUnixUtils::readFD(int, int&) constin utils.o
  "ancil_send_fd(int, int)", referenced from:
      CIPCUnixUtils::writeFD(int, int) constin utils.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
make: *** [ABClient] Error 1

(I have edited this slightly to remove the very long list of object files).

What could cause this linkage to fail? The symbol exists, and is public, and there's no error about not being able to find the library, or any other error messages.

+5  A: 

Those symbols are unmangled C symbols. As you have tagged this as C++, I assume you are compiling with C++. If you do that you may need to wrap your libraries header files in an extern block in your code:

extern "C" {
#include "library.h"
}

where library.h is the name of the library's header file(s), to prevent them being mangled in the calling code.

anon
Doh - I should have thought of that. Thanks.
Thomi
+1  A: 

I wonder if it's a C++ name-mangling problem?

Try running nm on the utils.o file, and see what symbol it's actually looking for.

You might have to wrap the header in extern C.

Douglas Leeder