Libraries and Other Linker Inputs

VisualGDB uses the standard Linux way of specifying libraries used by the projects that relies on 3 different parameters:

  1. Library directories. These are the directories where the GNU linker will search for libraries specified in “Library names”. Locations like /usr/lib will be searched by default and do not need to be specified.
  2. Library names. This line contains short library names of libraries that should be linked with the project. The short library names do not contain the ‘lib‘ prefix or the .a extension. E.g. in order to link with libpthread.a and libm.a this line should contain “pthread m“. If you need to use a specific version of the library (e.g. libboost_system.so.1.61.0), you can specify it here prefixed with a colon (e.g. “:libboost_system.so.1.61.0“), or enter the full path to the library in the Additional Linker Inputs field.
  3. Additional linker inputs. This line can specify full paths to additional library or object files that should be linked with the project. This can be used to link against a specific version of a library, e.g. /usr/lib/i386-linux-gnu/libpthread.so. If you are using a cross-toolchain, use the ‘=’ prefix to specify a path inside the sysroot directory (e.g. =/usr/lib/arm-linux-gnueabihf/libboost_system.so.1.61.0 will expand to c:\SysGCC\raspberry\arm-linux-gnueabihf\sysroot\usr\lib\arm-linux-gnueabihf\libboost_system.so.1.61.0)

It is recommended to specify libraries using the short names and directories, however if this causes problems (e.g. when using cross-compilation toolchains), it may be helpful to specify full paths to all necessary libraries using the “Additional Linker Inputs” line.

Diagnosing Linker Problems

The 2 most common types of linker errors are:

  • “Undefined reference to <symbol>” error. It is typically caused by missing library names in linker settings. See this tutorial for detailed troubleshooting instructions.
  • “Cannot find <library>” error. It happens when a library is specified in the project settings, but is not physically present in the library search path. You can resolve it by locating the physical library file (lib<name>.a or lib<name>.so) and copying it into one of the standard library directories, or adding its directory to the library search path. Note that if you are using a cross-toolchain, the library must be copied to the machine with the toolchain. In most of the cases, it can be done by pressing the “Synchronize Sysroot” button in VisualGDB Project Properties.

You can force the linker to output a detailed log about the process of finding libraries. This can be accomplished by adding “-Wl,-verbose” to the linker command line (or using the “Verbose Mode” setting for MSBuild projects):Building the project with the -Wl,-verbose flag will produce a detailed output about each linker’s attempt to open a library:

attempt to open /usr/lib/gcc/i686-linux-gnu/4.8/../../../i386-linux-gnu/crt1.o succeeded
/usr/lib/gcc/i686-linux-gnu/4.8/../../../i386-linux-gnu/crt1.o
attempt to open /usr/lib/gcc/i686-linux-gnu/4.8/../../../i386-linux-gnu/crti.o succeeded
/usr/lib/gcc/i686-linux-gnu/4.8/../../../i386-linux-gnu/crti.o
attempt to open /usr/lib/gcc/i686-linux-gnu/4.8/crtbegin.o succeeded
/usr/lib/gcc/i686-linux-gnu/4.8/crtbegin.o
attempt to open VisualGDB/Debug/LibraryDemo.o succeeded
VisualGDB/Debug/LibraryDemo.o
attempt to open /usr/lib/gcc/i686-linux-gnu/4.8/libstdc++.so succeeded
-lstdc++ (/usr/lib/gcc/i686-linux-gnu/4.8/libstdc++.so)
attempt to open /usr/lib/gcc/i686-linux-gnu/4.8/libm.so failed
attempt to open /usr/lib/gcc/i686-linux-gnu/4.8/libm.a failed
attempt to open /usr/lib/gcc/i686-linux-gnu/4.8/../../../i386-linux-gnu/libm.so succeeded
-lm (/usr/lib/gcc/i686-linux-gnu/4.8/../../../i386-linux-gnu/libm.so)
attempt to open /usr/lib/gcc/i686-linux-gnu/4.8/libgcc_s.so succeeded
-lgcc_s (/usr/lib/gcc/i686-linux-gnu/4.8/libgcc_s.so)
attempt to open /usr/lib/gcc/i686-linux-gnu/4.8/libgcc.so failed
attempt to open /usr/lib/gcc/i686-linux-gnu/4.8/libgcc.a succeeded
attempt to open /usr/lib/gcc/i686-linux-gnu/4.8/libc.so failed
attempt to open /usr/lib/gcc/i686-linux-gnu/4.8/libc.a failed
attempt to open /usr/lib/gcc/i686-linux-gnu/4.8/../../../i386-linux-gnu/libc.so succeeded
opened script file /usr/lib/gcc/i686-linux-gnu/4.8/../../../i386-linux-gnu/libc.so
opened script file /usr/lib/gcc/i686-linux-gnu/4.8/../../../i386-linux-gnu/libc.so
attempt to open /lib/i386-linux-gnu/libc.so.6 succeeded
/lib/i386-linux-gnu/libc.so.6
attempt to open /usr/lib/i386-linux-gnu/libc_nonshared.a succeeded
(/usr/lib/i386-linux-gnu/libc_nonshared.a)elf-init.oS
attempt to open /lib/i386-linux-gnu/ld-linux.so.2 succeeded
/lib/i386-linux-gnu/ld-linux.so.2
attempt to open /usr/lib/gcc/i686-linux-gnu/4.8/libgcc_s.so succeeded
-lgcc_s (/usr/lib/gcc/i686-linux-gnu/4.8/libgcc_s.so)
attempt to open /usr/lib/gcc/i686-linux-gnu/4.8/libgcc.so failed
attempt to open /usr/lib/gcc/i686-linux-gnu/4.8/libgcc.a succeeded
attempt to open /usr/lib/gcc/i686-linux-gnu/4.8/crtend.o succeeded
/usr/lib/gcc/i686-linux-gnu/4.8/crtend.o
attempt to open /usr/lib/gcc/i686-linux-gnu/4.8/../../../i386-linux-gnu/crtn.o succeeded
/usr/lib/gcc/i686-linux-gnu/4.8/../../../i386-linux-gnu/crtn.o
libm.so.6 needed by /usr/lib/gcc/i686-linux-gnu/4.8/libstdc++.so
found libm.so at /usr/lib/gcc/i686-linux-gnu/4.8/../../../i386-linux-gnu/libm.so
ld-linux.so.2 needed by /usr/lib/gcc/i686-linux-gnu/4.8/libstdc++.so
found ld-linux.so.2 at /lib/i386-linux-gnu/ld-linux.so.2
libgcc_s.so.1 needed by /usr/lib/gcc/i686-linux-gnu/4.8/libstdc++.so
found libgcc_s.so at /usr/lib/gcc/i686-linux-gnu/4.8/libgcc_s.so