Boost logo

Boost :

From: Gennadiy Rozental (rogeeff_at_[hidden])
Date: 2008-01-14 11:19:30


Jens Seidel <jensseidel <at> users.sf.net> writes:

>
> On Mon, Jan 14, 2008 at 01:16:51AM -0500, Gennadiy Rozental wrote:
> > "Benoit Sigoure" <tsuna <at> lrde.epita.fr> wrote in message
> > news:805924BB-31B0-44E8-88CE-9538D89B082C <at> lrde.epita.fr...
> > > On Jan 12, 2008, at 3:26 AM, Gennadiy Rozental wrote:
> > >
> > >> Benoit Sigoure <tsuna <at> lrde.epita.fr> writes:
> > >>> Thanks for your code. It grieves me that Boost.Test is the *only*
> > >>> library for which I have to write "special cases" only because it's
> > >>> not "well-behaved".
> > >>
> > >> In what sence? How do you define well behaved?
> > >
> > > What is this whole thread about? Boost.Test is non standard because
> > > it messes up your `main'
> >
> > Why do you care? how does it make Boost.Test behave badly?
>
> Normally one is able to test for the existence of a library by just
> calling a function inside main() or by creating an instance of a special
> type:

[...]

> Beeing forced to also write
>
> int main(int argc, char* argv[])
> {
>
> }
>
> is just not required for nearly all library tests and error prone. This

You are not required to do above with Boost.Test. In fact it's plain wrong
for your purposes.

> > > and must be used differently whether you're
> > > linking with it as a shared library or a static archive.
> >
> > As you have seen in my example, it is exactly the same for both usage
> > variants. The only difference is additional macro in makefile. But, than,
> > link command is going to be different anyway.
>
> No, you're wrong. There is no need to specify different link commands
> for shared or static libraries in general.

I disagree. In general you do need to specify what you want to link with. The
fact that your compiler allows some shortcuts and "smart" enough to have some
defaults doesn't make it general.
 
> I tried to compile your proposed test:
>
> #define BOOST_TEST_MODULE boost.m4
> #include <boost/test/unit_test.hpp>
>
> BOOST_AUTO_TEST_CASE( MyCase )
> {
> BOOST_ERROR( "expected" );
> }
>
> Normally (for at least 95% of all libraries) one just adds -l <libname>
> to get it compile:
>
> $ g++ test.cpp -lboost_unit_test_framework
> /usr/lib/gcc/i486-linux-gnu/4.2.3/../../../../lib/crt1.o: In function
`_start':
> (.text+0x18): undefined reference to `main'
> collect2: ld returned 1 exit status

You need to enforce static library here *with link options*.
 
> It works indeed well with
> $ g++ -DBOOST_TEST_DYN_LINK test.cpp -lboost_unit_test_framework

as expected
 
> Once I remove /usr/lib/libboost_unit_test_framework.so so that only
> the static library /usr/lib/libboost_unit_test_framework.a (which is a
> symbolic (filesystem) link to
> libboost_unit_test_framework-gcc41-1_34_1.a in Debian testing) exists
> one can also (normally) just specify -l <libname>. But I get:
>
> $ g++ -DBOOST_TEST_DYN_LINK test.cpp -lboost_unit_test_framework
> /tmp/ccKcB2Ps.o: In function `main':
> test.cpp:(.text+0x3d4): undefined reference to
`boost::unit_test::unit_test_main(bool (*)(),
> int,
> char**)'
> /usr/lib/gcc/i486-linux-
gnu/4.2.3/../../../../lib/libboost_unit_test_framework.a(framework.o):
> In function `boost::unit_test::framework::init(int, char**)':
> (.text+0x6fa): undefined reference to `init_unit_test_suite(int, char**)'
> collect2: ld returned 1 exit status

Why would you expect it to work? You specified dynamic library, but linking
with static.
 
> Without -DBOOST_TEST_DYN_LINK
> $ g++ test.cpp -lboost_unit_test_framework
> it works.

As expected. It would have work from the begininng would you specify -static
(if I am not mistaken) during linking.
 
> You're right that it is also possible to enforce using the static
> library (even if the shared one exists) by using different arguments:
> $ g++ test.cpp /usr/lib/libboost_unit_test_framework.a

You should be able to do it without absilute path to the library.

> But in general everyone probably just uses -l <libname> and let's the
> compiler decide (which defaults to shared library variant if available).
> This normally works even if only one variant of a library is installed
> except with Boost.Test.

The real cause of the problem is that both static and dynamic library have the
same name in *nix. So you need to specify which one you need explicetly. I
hope by now you should understand why static library behaves the way it is.

All you need to work without problem is to stop relying on linker guessing
what library to link with and explicetly specify it (and stop misusing the
library - saying you want dynamic, but supplying static is not gonna work).

Gennadiy


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk