Boost logo

Boost Users :

Subject: Re: [Boost-users] [Boost.Test] Linker chooses “wrong” main function
From: Richard (legalize+jeeves_at_[hidden])
Date: 2012-08-28 22:44:38


[Please do not mail me a copy of your followup]

boost-users_at_[hidden] spake the secret code
<CAEWUs4gQjT2KxEb90t=u3jRdT352n0KWYnfPpeYk38VwcMEBWA_at_[hidden]> thusly:

>Since my project did not have a main() function, [...]

Well, obviously your project has a main function, otherwise you would
get a link error.

What boost.test does is define a main() function depending on how it
is compiled. In my projects, I have a main.cpp that looks like this:

#define BOOST_TEST_MAIN
#include <boost/test/unit_test.hpp>

and this provides the canned implementation of main().

>The linker chose that one
>as my "test" application. Thus, non of my tests run.

You don't say how you are linking with Boost.Test, but if you are
linking with a static library then what you need to do is make sure
Boost.Test is listed in the linker search order before the png
library.

However, libpng doesn't include a main():

shell 47> nm .libs/libpng15.a | fgrep -i main
shell 48> nm .libs/libpng15.so | fgrep -i main

So, wherever you're getting your implementation of main(), doesn't
come from libpng. If you're on unix, use nm to find out who is
supplying main. If you're on Windows, use dumpbin to find out who is
supplying main.

The key to understanding how to resolve unexpected linker errors is to
understand that the linker is really not a complicated program and
only does things in response to the command line arguments given to
it.

The linker only does two things:
i) identify unresolved symbols
ii) resolve unresolved symbols

If you don't supply a definition of a referenced symbol, then i)
issues an undefined symbol error.

If you violate the one definition rule, then ii) issues a multiply
defined symbol error. That you *don't* get a multiple undefined
symbol error, but instead get "the wrong main", tells me that however
you're linking against Boost.Test you aren't getting a main from it.

When linking against libraries, you need to understand how step ii)
works:
  The linker examines each supplied link input, in the order supplied,
  and looks for an object defining the desired symbol.

So when the linker looks for a definition of main (which it always
will when you are linking a final executable and not a library), it
starts examining the inputs you've given it, one by one, starting at
the first and proceeding towards the last until it finds a definition.

Since your link succeeded, it found one. Look at the command-line for
your linker step (the WHOLE command line, not some simplified view of
it) and use nm/dumpbin to examine the inputs one-by-one until you find
the one that is supplying main.

-- 
"The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline>
     The Computer Graphics Museum <http://computergraphicsmuseum.org>
         The Terminals Wiki <http://terminals.classiccmp.org>
  Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com>

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net