Undefine Reference for Libraries, So How Could I Find The Right Path

Undefined reference to error when .so libraries are involved while building the executable

Doesn't dynamic linking means that when I start the executable using ./executable_name then if the linker not able to locate the .so file on which executable depends it should crash?

No, linker will exit with "No such file or directory" message.

Imagine it like this:

  • Your executable stores somewhere a list of shared libraries it needs.
  • Linker, think of it as a normal program.
  • Linker opens your executable.
  • Linker reads this list. For each file.

    • It tries to find this file in linker paths.
    • If it finds the file, it "loads" it.
    • If it can't find the file, it get's errno with No Such file or directory from open() call. And then prints a message that it can't find the library and terminates your executable.
  • When running the executable, linker dynamically searches for a symbol in shared libraries.

    • When it can't find a symbol, it prints some message and the executable teerminates.

You can for example set LD_DEBUG=all to inspect what linker is doing. You can also inspect your executable under strace to see all the open calls.

What actually is dynamic linking if all external entity references are resolved while
building?

Dynamic linking is when you run the executable then the linker loads each shared library.

When building, your compiler is kind enough to check for you, that all symbols that you use in your program exist in shared libraries. This is just for safety. You can for example disable this check with ex. --unresolved-symbols=ignore-in-shared-libs.

Is it some sort of pre-check performed by dynamic linker?

Yes.

Else dynamic linker can make use of LD_LIBRARY_PATH to get additional libraries to resolve the undefined symbols.

LD_LIBRARY_PATH is just a comma separated list of paths to search for the shared library. Paths in LD_LIBRARY_PATH are just processed before standard paths. That's all. It doesn't get "additional libraries", it gets additional paths to search for the libraries - libraries stay the same.

undefined reference to the shared library function

It's a linker error (although I don't think it usually includes the 'char*' bit), so it seems that it either cannot find your library or the library does not contain the function. The latter might also mean that it does contain the actual function, but with a different name; make sure both projects a compiled as C and not C++.

Edit: I missed that you program is C++ (which also explains the more detailed linker message). In this case you should add extern "C" (conditionally, so it is only used when using C++) to the declaration of CEDD if the library is in C.

X11 functions with undefined reference but It seens to be ok. IDE does not complains about those libraries

Run ldd on the path of some other dynamically linked X program on your system to see where the libs are loaded from. E.g.

ldd /usr/bin/gnome-session

Undefined reference when trying to use external library

The best approach is to avoid complicated src/Makevars file altogether.

One easy-ish approach around this: use configure to build your static library, then once you actually build just refer to it in src/Makevars.

I use that scheme in Rblpapi (where we copy an externally supplied library in) and in nloptr where we download nlopt sources and build it 'when needed' (ie when no libnlopt is on the system).

Undefined references even though library is linking and it contains correct symbols

The fact that linker reports unresolved external symbols as ptp_usb_sendreq(_PTPParams*, _PTPContainer*) means that those symbols are mangled in C++ way (otherwise, function arguments would not be visible).

At the same time, nm reports the symbol as ptp_usb_sendreq, which means, it is not mangled.

Most likely solution: check and make sure your function signature (likely in a header file) is wrapped in extern "C" specifier.

gcc: undefined reference to `fy_library_version'

GCC has two major components: the compiler and the linker. Including the headers is the part you are doing right, and you are basically letting the compiler know that fy_library_version is invoked with the correct arguments and return type.

However, the compiler does not know what happens after calling such function, and the duty of checking that any code for that function exists is deferred to a later stage: the linker.

The linker is indeed what is throwing the error you see

ld returned 1 exit status

This is because the linker does not know which libraries you are using and hence can't know where to find the code for you functions. To fix that you should tell gcc which libraries you are using:

gcc test.c -lfyaml -o test

undefined reference because I can't find the according source files

According to CMake documentation we shouldn't use the global settings for include directories or such anymore, but use the target_ versions. And to be honest, I don't think, that the second, complicated CMakeLists.txt is used (or needed), it doesn't seem to be included with the first one (but it is hard to say without knowing the directory structure.

But, never the less, if you want to use some library, you need two things: the header file(s) with the declaration of the provided items and usually the compiled library containing the definition/implementation of the items (static or dynamic library). In principle, you can also compile the library on your own, if you have access to the libraries source files. In this case my suggestion would be:

add_library(ids_peak
${IDS_PEAK_SOURCE_FILES}
)
target_include_directories(ids_peak PUBLIC /usr/include/ids_peak-1.3.0)
...
add_executable(open_camera
src/open_camera.cpp
)
target_include_directories(open_camera PRIVATE ${catkin_INCLUDE_DIRS})
target_link_libraries(open_camera PRIVATE ids_peak)

This will define two targets to compile:

  • a library target, compiling any source files which are in the list ${ID_PEAK_SOURCE_FILES} and with the corresponding include directories attached
  • an executable target, compiling your open_camera.cpp source file. There is this catkin include directory attached (perhaps we should opt for an other library target here? Are there sources to compile or is there only a lib+headers?). Last but not least a dependency is added to this target.

Since the include directories of the library target are declared public, they are forwarded to all targets, that depend on it (same happens with target_compile_definitions, target_link_libraries, target_link_options, etc.).

These links could be of interest to you:

  • https://cmake.org/cmake/help/latest/command/add_library.html
  • https://cmake.org/cmake/help/latest/command/add_executable.html
  • https://cmake.org/cmake/help/latest/command/target_include_directories.html
  • https://cmake.org/cmake/help/latest/command/target_link_libraries.html
  • What do linkers do?

And, if you'd be so kind as to drop the FILE(GLOB...) call. I was told by some CMake contributor once, that this feature wasn't released, but escaped and shouldn't be used at all being pretty error prone. I know it comes in handy, but you can't really control, what your build is really doing. It is better to name the files explicitly. Or, in case of install (https://cmake.org/cmake/help/latest/command/install.html#directory) or copy, you can apply to whole directories.

Library path is definitely correct and can create an instance of said library, but get Undefined reference when calling any function

Add

MATHLIBRARY_API

infront of your class name to export all public members in your dll. During export the dllexport part should be set and during import the dllimport part of course.

Here's a link that explains how to export classes from a dll:
https://www.codeproject.com/Articles/28969/HowTo-Export-C-classes-from-a-DLL



Related Topics



Leave a reply



Submit