Question

I developed a couple of C++ libraries some years ago that were used by three C++ projects. I compiled the libraries as shared libraries as to not have to recompile/relink the program when the libs changed. I am porting their compilation process to CMake 3.0, but am having trouble with the compilation of one.

This library cannot provide some functionality; a couple of functions must be defined in the main program even though they are used inside the library. The reason is that the implementations of these functions depend on the program internal structure.

So the libraries have been compiled with a header declaring all these functions as extern. Here is an example coming from a header of the problematic's library:

extern char *  Get_Name(void *b);

I am declaring the functions using extern keyword. After reading more about it, it seems the extern might be superfluous.

On x86_64 linux, I've never had any issue and used this organisation for years.

But now, the compilation of the library fails on OSX Mavericks (clang: Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn)). It could be problem with my CMake files or worst, a quirk of OSX. The problem is that at linking time (when creating the .dynlib file) it can't find the definitions of the functions. The specific error is:

cmake VERBOSE=1
[...]
Linking CXX shared library libtiming.dylib
/Applications/CMake.app/Contents/bin/cmake -E cmake_link_script CMakeFiles/timingShared.dir/link.txt --verbose=1
/usr/bin/c++   -dynamiclib -Wl,-headerpad_max_install_names   -o libtiming.dylib -install_name @rpath/libtiming.dylib <list of .o files> /Users/me/usr/lib/libone.dylib  -Wl,-rpath,/Users/me/usr/lib
Undefined symbols for architecture x86_64:
"Function_Name(void*)", referenced from:
[...]
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

My questions are:

  1. Is it possible for a C++ library to use functions that are defined in the program using the library?
  2. If not, what is special about linux compilation that allowed me back then to compile the .so dynamic library even though some symbols are not defined in the objects (only in the main program)?
  3. If it is possible, am I doing something wrong with CMake? Is the linking command posted above just missing something? Should I be using something different than "linking" to get the library I need?

Thank you.

Was it helpful?

Solution 2

Thanks Chris Statton; I had to tell the linker to ignore undefined symbols at link time.

On OSX Mavericks, man ld states:

 -undefined treatment
             Specifies how undefined symbols are to
             be treated. Options are: error, warning,
             suppress, or dynamic_lookup.  The
             default is error.

Passing -undefined dynamic_lookup to the linking process of the question solved the issue.

For the CMake part, I had to add the following after the add_library():

set_target_properties(${PROJECT_NAME} PROPERTIES LINK_FLAGS "-undefined dynamic_lookup")

OTHER TIPS

Answer to 1:
The library may have unresolved symbols that need to be resolved. They can be resolved in another library or your program.

However, libraries need to be rebuilt in order to know what functions your program contains. So if a library needs to access a specific function in your program, it needs to be rebuilt with the declaration of that function.

In general, if a library is calling a function outside of its library, that function will be an unresolved symbol and should be declared in a header file.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top