boost test - 'undefined reference' errors

女生的网名这么多〃 提交于 2019-11-30 10:03:31
Mihai Rotaru

With help from @llonesmiz, a number of issues were identified.

1. Libraries need to be specified after objects and sources which use them.

As described here:

The traditional behavior of linkers is to search for external functions from left to right in the libraries specified on the command line. This means that a library containing the definition of a function should appear after any source files or object files which use it. This includes libraries specified with the short-cut -l option, as shown in the following command:

$ gcc -Wall calc.c -lm -o calc (correct order)

With some linkers the opposite ordering (placing the -lm option before the file which uses it) would result in an error,

$ cc -Wall -lm calc.c -o calc (incorrect order)
main.o: In function 'main':
main.o(.text+0xf): undefined reference to 'sqrt'

because there is no library or object file containing sqrt after ‘calc.c’. The option -lm should appear after the file ‘calc.c’

2. Library paths should be explicitly specified.

If no lib paths are specified, the linker might look for the libs in a series of default folders, thus loading a different library then intended. This is what happened in my case - I wanted to link boost_unit_test_framework, but did not specify a path because I assumed the linker would look in the current folder. That's what happens at runtime, after all - if the dll is in the same folder with the exe, it will find it.

I found it a little bit strange the linker would find the lib, since it was named ibboost_unit_test_framework-mgw47-mt-1_52.dll. When I tried to link to a non-existing lib, the linker complained though, so I assumed this isn't an issue, and MinGW 's linker ignores those suffixes.

After some more research, I found this article about MinGW library paths. The folders MinGW searches for libs can be found in the output of gcc -print-search-dirs. The article also contains some bash magic to make sense of that output:

gcc -print-search-dirs | sed '/^lib/b 1;d;:1;s,/[^/.][^/]*/\.\./,/,;t 1;s,:[^=]*=,:;,;s,;,;  ,g' | tr \; \\012 | grep -v '^ */'

This will print a nice list of those folders. gcc will not, by default, look in the current directory for libs. I looked in each of them, and found the lib that was being loaded - libboost_unit_test_framework.a, a static lib.

This brings into light another issue worth mentioning:

3. Static versus dynamic linking

I did not specify whether I want boost_unit_test_framework linked statically or dynamically. In this case, gcc prefers dynamic linking:

Because of these advantages gcc compiles programs to use shared libraries by default on most systems, if they are available. Whenever a static library ‘libNAME.a’ would be used for linking with the option -lNAME the compiler first checks for an alternative shared library with the same name and a ‘.so’ extension.

(so is the extension for dynamic libraries on Unix - on Windows, the equivalent is dll.)

So, what happened is that gcc looked for libboost_unit_test_framework.dll in all it's default folders, but couldn't find it. Then it looked for libboost_unit_test_framework.a, and statically linked that. This resulted in linking errors because the sources have #define BOOST_TEST_DYN_LINK, and therefore expect to have the lib dynamically linked.

To enforce static or dynamic linking, the -Wl,-Bstatic and -Wl,-Bdynamic linker options come into play, described here.

If I tell the linker that I want dynamic linking:

$ g++ -I/e/code/boost_1_52_0 runner.cpp test1.cpp -o runner -Wl,Bdynamic -lboost_unit_test_framework

This will fail, because the linker will not be able to find the dll.

4.Summary

The issues were:

  1. libraries where specified before the sources which used them
  2. the lib path wasn't specified
  3. the type of linking wasn't specified
  4. the name of the library was not correct

Final, working command:

$ g++ -I/e/code/boost_1_52_0 -o runner runner.cpp test1.cpp -L. -Wl,-Bdynamic -lboost_unit_test_framework-mgw47-mt-1_52
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!