Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting undefined reference error but nm shows symbol present

I am building a large application using libkml. I am using the cmake port of libkml from here: https://github.com/rashadkm/libkml

I am getting a stranged undefined reference to symbol error even thought the symbol appears to be referenced and defined.

This is the make command:

/usr/bin/c++ -fPIC -Werror=return-type -Werror=return-type -Wall 
-Werror=parentheses -Werror=uninitialized -Werror=missing-braces 
-fPIC -O0 -Wall -fPIC -fvisibility=hidden -fno-strict-aliasing 
-Wno-long-long -m64 -g -D_DEBUG --coverage -Wl,-Bsymbolic -Wl,--
no-undefined -shared -o GPS2KML.plb CMakeFiles/GPS2KML.dir
/gps.cpp.o CMakeFiles/GPS2KML.dir/kml.cpp.o CMakeFiles/GPS2KML.dir
/stdafx.cpp.o  /trunk/src/filter/GPS2KML/external/libkml/lib/cmake
/libkml/../../libkmlconvenience.so.1.3.1 /trunk/src/filter/GPS2KML
/external/libkml/lib/cmake/libkml/../../libkmlengine.so.1.3.1 
/trunk/src/filter/GPS2KML/external/libkml/lib/cmake/libkml/../..
/libkmldom.so.1.3.1 /trunk/src/filter/GPS2KML/external/libkml
/lib/cmake/libkml/../../libkmlbase.so.1.3.1 -lminizip -luriparser 
-lexpat

The make output:

CMakeFiles/GPS2KML.dir/kml.cpp.o: In function `cKML::~cKML()':
/trunk/src/filter/GPS2KML/src/kml.cpp:55: undefined reference to `*kmldom::SerializePretty(boost::intrusive_ptr<kmldom::Element> const&)*'
collect2: error: ld returned 1 exit status

Now if i do this: daniyal@daniyal-Inspiron-5521:/$ nm --demangle --extern-only --defined-only ../trunk/src/filter/GPS2KML/external/libkml/lib/libkmldom.so | grep SerializePretty

It clearly shows:

000000000013c9aa T kmldom::SerializePretty[abi:cxx11](boost::intrusive_ptr<kmldom::Element> const&)

Now I fail to understand what is the problem. I have check the existing questions on stackoverflow regarding this, I found four solutions in the existing questions:

  1. In some cases the demangled symbol name did not match with the symbol that was causing error. This is clearly not my case.
  2. Use -llibrary at the end of the command after putting the name of the .o file. So that when the linker encounters the library it has an undefined symbol present in that library. This is clearly not a solution for me as I have the libraries present at the end of the command.
  3. In some cases the symbol is present in the shared library but does not have external linkage or is not defined. This can be confirmed by using nm with --extern-only and --defined-only. And hence this is also not a solution for me.

Edit: Additional Info:

This is the cmake file I am using:

find_package(LibKML REQUIRED)

include_directories(${LIBKML_INCLUDE_DIRS})

add_filter(${PROJECT}
        gps.h
        gps.cpp
        kml.h
        kml.cpp
        #can2gps.h
        #can2gps.cpp
        stdafx.h 
        stdafx.cpp )


target_link_libraries (${PROJECT} ${LIBKML_LIBRARIES})

add_filter roughly translates to this macro:

add_library(${NAME} MODULE ${ARGN} ${${NAME}_MOC} ${${NAME}_UI} ${${NAME}_QRC})

target_link_libraries(${NAME} ${BUILD_LIBS} ${QT_LIBRARIES}  ${ADTF_OPENGL_LIBRARY} ${ADTF_ADDITIONAL_UTILS_LIBS})
set_target_properties(${NAME}
PROPERTIES
SUFFIX ".plb"
)
if(UNIX)
set_target_properties(${NAME}
PROPERTIES
PREFIX ""

)

like image 279
Daniyal Yasin Avatar asked Jun 12 '17 13:06

Daniyal Yasin


People also ask

How do you fix undefined reference error?

So when we try to assign it a value in the main function, the linker doesn't find the symbol and may result in an “unresolved external symbol” or “undefined reference”. The way to fix this error is to explicitly scope the variable using '::' outside the main before using it.

What does U mean in NM?

An undefined symbol is a symbol that the library uses but was not defined in any of the object files that went into creating the library. Usually the symbol is defined in another library which also needs to be linked in to your application.

What is undefined symbol error?

When generating an executable output file, the link-editor's default behavior is to terminate with an appropriate error message should any symbols remain undefined. A symbol remains undefined when a symbol reference in a relocatable object is never matched to a symbol definition.

What kind of error is unresolved external symbol?

The compiler can identify when a symbol isn't declared, but it can't tell when the symbol isn't defined. It's because the definition may be in a different source file or library. If a symbol is referred to but never defined, the linker generates an unresolved external symbol error.


1 Answers

It looks like you have an ABI mismatch issue. ABI is "Application Binary Interface", basically the specification for exactly how arguments make it onto the stack (or are put in registers) and various other things like that.

Try making sure your code is compiled with the -std=c++11 (or -std=gnu++11 if you use any GNU extensions) flag. It looks like that's how libkml was compiled. C++11 has a bunch of new features that require an ABI compatibility break with pre-C++11. C++14 and C++1z are less drastic changes, but they may also break ABI compatibility, I'm not sure. In this case though, the demangled symbol is clear, libkml wants at least C++11.

like image 120
Omnifarious Avatar answered Oct 19 '22 04:10

Omnifarious