Unrecognized relocation error

Problem

Building a large project that involved linking with many libraries, I got this linking error:

Linking CXX shared library ../../lib/libfoobar.so
/usr/bin/ld: /somepath/opencv-2.4/lib/libopencv_imgproc.a(clahe.cpp.o): unrecognized relocation (0x2a) in section `.text._ZN12_GLOBAL__N_1L15CLAHE_Impl_infoEv'
/usr/bin/ld: final link failed: Bad value

Solution

At first I suspected some problem with the symbol that you see the linker complaining about above. But using nm I found that the symbol was present and was defined in the archive library file.

Only after eliminating all other possibilities did I discover that the problem was the compiler version. The archive library file had been compiled using GCC 4.8. The linking was being done on a different computer where the compiler was GCC 5.x. The C++ ABI had changed along with the major version difference between the two compilers and this was causing the problem.

Once I rebuilt OpenCV with GCC 5.x and used its archive library file, the linking proceeded smoothly.

How to set link directories in CMake

For most common libraries, CMake has inbuilt modules which find and include them for compilation and linking. But, there are situations where you need to use library files (say *.so) that are in a custom directory somewhere that need to be linked with the code you are building.

One or more of such paths which should be requested to search for library files while linking can be specified like this:

link_directories(
    /home/joe/bellringer/lib64
    /home/joe/globespin/libs
)

The library files in these directories can now be specified in link_libraries or target_link_libraries using the usual -l syntax.

Reference: link_directories

Tried with: CMake 2.8.12.2 and Ubuntu 14.04

Undefined reference error with __cxa_free_exception@@CXXABI_1.3

Problem

I was compiling some C++ and CUDA code using CMake on Ubuntu 14.04. The linking stage threw up this error:

/usr/bin/ld: foobar.cpp.o: undefined reference to symbol '__cxa_free_exception@@CXXABI_1.3'
//usr/lib/x86_64-linux-gnu/libstdc++.so.6: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status

I had used these same source and CMake files without any compile error on a Ubuntu 12.04 system.

Solution

Ubuntu 14.04 uses newer versions of the GCC compilers and libraries. The hint here is that its complaining about a core C++ symbol: __cxa_free_exception. Suggesting the linker to link with the standard C++ library fixed this error. You can do this by adding -lstdc++ to the linker invocation.

For my CMake, I did this by adding -lstdc++ to the linking options to the target as:

target_link_libraries(
    foobar
    -lsomelibrary
    -lstdc++
    )

Tried with: GCC 4.8.2, CMake 2.8.12.2 and Ubuntu 14.04

Undefined reference error with sincosf@@GLIBC_2.2.5 and sqrtf@@GLIBC_2.2.5

Problem

I was compiling some C++ and CUDA code using CMake on Ubuntu 14.04. The linking stage threw up this error:

/usr/bin/ld: foobar.cpp.o: undefined reference to symbol 'sincosf@@GLIBC_2.2.5'
//lib/x86_64-linux-gnu/libm.so.6: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status

Another error of the same form:

/usr/bin/ld: foobar.cpp.o: undefined reference to symbol 'sqrtf@@GLIBC_2.2.5'
//lib/x86_64-linux-gnu/libm.so.6: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status

I had used these same source and CMake files without any compile error on a Ubuntu 12.04 system.

Solution

Ubuntu 14.04 uses newer versions of the GCC compilers and libraries. The hint here is that its complaining about a mathematical symbol: sincosf. Suggesting the linker to link with the math library fixed this error. You can do this by adding -lm to the linker invocation.

For my CMake, I did this by adding -lm to the linking options to the target as:

target_link_libraries(
    foobar
    -lsomelibrary
    -lm
    )

Tried with: GCC 4.8.2, CMake 2.8.12.2 and Ubuntu 14.04

How to change compiler in Eclipse CDT

Eclipse CDT uses gcc, g++ and as as the C compiler, C++ compiler (and linker) and assembler by default. Sometimes, you may want to use a different version or different type of compiler, linker or assembler to build your code. Changing this in Eclipse CDT for your project is easy:

  • Go to Project > Properties > C/C++ Build > Settings > Tool Settings.

  • In this dialog, to change the C++ compiler, change the entry in Cross G++ Compiler > Command.

  • In this dialog, to change the C compiler, change the entry in Cross GCC Compiler > Command.

  • In this dialog, to change the C++ linker, change the entry in Cross G++ Linker > Command. This is typically the same as the C++ compiler command.

  • In this dialog, to change the assembler, change the entry in Cross GCC Assembler > Command.

Click Apply and OK. Build your code and you will see that the new tools are used.

Tried with: Eclipse 3.7.2

LNK2038 Linker Error in Visual C++

Problem

I got this error at the linking stage of compiling a Visual C++ project:

Error LNK2038: mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '0' doesn't match value '2' in main.obj

This project was being linked with other libraries and the error referred to the _ITERATOR_DEBUG_LEVEL was defined with different values in my application and the external library.

Solution

The difference in the _ITERATOR_DEBUG_LEVEL typically happens if a Release version of a library is linked against a Debug version of another library or application. Make the two have the same build type and this error should go away.

If you cannot do that, then set the _ITERATOR_DEBUG_LEVEL in your project to match the value used in the other library.

Tried with: Visual Studio 2010 and Windows 7 x64

CUDA: LNK2005 Linker Errors

The Problem

When building a Visual Studio solution which has CUDA source files (*.cu), LNK2005 linker errors of the following kind might be seen:

LIBCMT.lib(hooks.obj) : error LNK2005: "void __cdecl terminate(void)" (?terminate@@YAXXZ) already defined in MSVCRT.lib(MSVCR90.dll)

What does it mean?

This indicates a mismatch between the kind of C runtime library used by the CUDA Build Rule and that used for the rest of the Visual C++ project.

How to fix it?

This problem can be fixed by making both of these use the same kind of C runtime library. For example, if the Visual C++ project is compiled using Multi Threaded DLL (/MD) and the CUDA build rule has Multi Threaded (/MT), then change the CUDA build rule to use /MD too.

 

Tried with: CUDA 3.2 and Visual Studio 2008

LNK4098 Linker Warning in Visual C++

Problem

C++ code when compiled can produce the linker warning LNK4098 at the final linking stage. This warning is of the form:

warning LNK4098: defaultlib 'LIBCMTD' conflicts with use of other libs; use /NODEFAULTLIB:library

What does this mean?

It means thatΒ  more than one kind of C run-time library has been used in the project! This is the cause of the conflict. The different types of C run-time libraries can be seen here.

How to fix it?

One source of conflict is different source files being compiled with different options. Examine the Runtime Library properties of the each of the source files in the solution. Open Project > Properties and this option can be found at C/C++ > Code Generation > Runtime Library. There might be some files which differ in the Runtime Library they are using. For example, Foo.cpp might be compiled with Multi-threaded DLL (/MD) and Joe.cpp might be compiled with Multi-threaded (/MT). To fix this warning, change the Runtime Library settings so that they are uniform across all the files of the solution.
Example: I typically notice these warnings when there are external Build Rules being used in the solution. For example, CUDA files (.cu) are typically compiled with a different Build Rule that invokes the CUDA compiler (nvcc.exe). The Runtime Library option within this Build Rule might not be matching the Runtime Library option of the solution, thus resulting in this warning.

Another possibility is the external libraries being linked with the project. Examine the library files being explicitly linked with the project and ensure they are compiled with the same run-time library options as that of the project.

If the above options fail or are not feasible, use the /NODEFAULTLIB option set to ignore the specific library that is causing this warning. That is, LIBCMTD in this case. To do this, go to Project > Properties > Linker > Input > Ignore Specific Default Libraries and add the filename of the offending library. For example, add LIBCMTD.lib in this case. This generates a compile option /NODEFAULTLIB:LIBCMTD.lib during compile time that excludes this library during linking.