[Boost-users] Mixing versions of boost

155 views
Skip to first unread message

dar...@gmail.com

unread,
Jun 25, 2008, 6:51:49 AM6/25/08
to boost...@lists.boost.org
Hi all,

I'm using header-only boost libs in two static libraries that will be linked into an executable.

No boost components are used in the interfaces of those libs, boost is only used in the implementation inside the libraries.

Is it possible to mix versions of boost in those two static libraries? Will the linker complain, or will it just get confused and mess up the executable?

The problem here is that one of those libraries is 'external', that is, I'm getting it compiled and with no source code (only .h for interface)

TIA

PS: I admit this is more a C++ linker question, but maybe someone out there has had to coexist with different versions of boost

Vladimir Prus

unread,
Jun 25, 2008, 7:46:53 AM6/25/08
to boost...@lists.boost.org
dar...@gmail.com wrote:

> Hi all,
>
> I'm using header-only boost libs in two static libraries that will be linked
> into an executable.
>
> No boost components are used in the interfaces of those libs, boost is only
> used in the implementation inside the libraries.
>
> Is it possible to mix versions of boost in those two static libraries? Will
> the linker complain, or will it just get confused and mess up the
> executable?

In general, this is highly risky business. On GCC, each static library
will contain a copy of every template function used by a static library.
If the linker finds that the same function is used in both static libraries,
it will put only one copy in the output executable, and if the definitions
of those functions differ, you're in trouble. See the attached example, which,
then run, produces:

a.cpp:say
a.cpp:say

Which is clearly wrong. This *might* work with shared libraries, but you
need to consult your toolchain documentation.

There's nothing Boost can do to help here, except maybe changing namespace
name with each version.

- Volodya

dup.zip

David Abrahams

unread,
Jun 25, 2008, 12:41:12 PM6/25/08
to boost...@lists.boost.org
Vladimir Prus wrote:
> dar...@gmail.com wrote:
>
>> Hi all,
>>
>> I'm using header-only boost libs in two static libraries that will be linked
>> into an executable.
>>
>> No boost components are used in the interfaces of those libs, boost is only
>> used in the implementation inside the libraries.
>>
>> Is it possible to mix versions of boost in those two static libraries? Will
>> the linker complain, or will it just get confused and mess up the
>> executable?
>
> In general, this is highly risky business. On GCC, each static library
> will contain a copy of every template function used by a static library.
> If the linker finds that the same function is used in both static libraries,
> it will put only one copy in the output executable, and if the definitions
> of those functions differ, you're in trouble. See the attached example, which,
> then run, produces:
>
> a.cpp:say
> a.cpp:say
>
> Which is clearly wrong. This *might* work with shared libraries, but you
> need to consult your toolchain documentation.

For the past few years we've had a GCC option that allows you to expose
from dynamic libs only those names you specify, sort of like declspec on
Windows. I don't remember the name of the flag, though.

--
Dave Abrahams
BoostPro Computing
http://www.boostpro.com
_______________________________________________
Boost-users mailing list
Boost...@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/boost-users

Ovanes Markarian

unread,
Jun 25, 2008, 1:03:40 PM6/25/08
to boost...@lists.boost.org
Why not to introduce an additional level of indirection ;) Just wrap
the 3d-Party lib in a DLL (or Shared Object under Linux), than you
should be find to use 2 libs with each other...

The only point to be careful about if 3d-party lib returns boost class
instances. These might be different in a newer version of the lib.


With Kind Regards,
Ovanes

Vladimir Prus

unread,
Jun 25, 2008, 1:25:44 PM6/25/08
to boost...@lists.boost.org
David Abrahams wrote:

> Vladimir Prus wrote:
>> dar...@gmail.com wrote:
>>
>>> Hi all,
>>>
>>> I'm using header-only boost libs in two static libraries that will be linked
>>> into an executable.
>>>
>>> No boost components are used in the interfaces of those libs, boost is only
>>> used in the implementation inside the libraries.
>>>
>>> Is it possible to mix versions of boost in those two static libraries? Will
>>> the linker complain, or will it just get confused and mess up the
>>> executable?
>>
>> In general, this is highly risky business. On GCC, each static library
>> will contain a copy of every template function used by a static library.
>> If the linker finds that the same function is used in both static libraries,
>> it will put only one copy in the output executable, and if the definitions
>> of those functions differ, you're in trouble. See the attached example, which,
>> then run, produces:
>>
>> a.cpp:say
>> a.cpp:say
>>
>> Which is clearly wrong. This *might* work with shared libraries, but you
>> need to consult your toolchain documentation.
>
> For the past few years we've had a GCC option that allows you to expose
> from dynamic libs only those names you specify, sort of like declspec on
> Windows. I don't remember the name of the flag, though.

-fvisibility, I believe. I actually though there's a way to cause a shared
library to prefer its own symbols -- but apparently it's not possible,
at least with gcc, in any easy way.

- Volodya

dar...@gmail.com

unread,
Jun 26, 2008, 3:35:45 AM6/26/08
to boost...@lists.boost.org
> Why not to introduce an additional level of indirection ;)
> Just wrap the 3d-Party lib in a DLL (or Shared Object under Linux),
> than you should be find to use 2 libs with each other...

Thanks for the idea. I'll give it a try, but ideally the application should be distributed as a single executable file.

About versioning the boost namespace, I suppose you mean something like changing boost namespace to e.g. boost_1_35_0. Any thoughts on how much work it would take me to patch a given version of boost to do that? Is it even possible?

Ovanes Markarian

unread,
Jun 26, 2008, 6:32:58 AM6/26/08
to boost...@lists.boost.org
On Thu, Jun 26, 2008 at 9:35 AM, <dar...@gmail.com> wrote:
[...]

>
> About versioning the boost namespace, I suppose you mean something like
> changing boost namespace to e.g. boost_1_35_0. Any thoughts on how much work
> it would take me to patch a given version of boost to do that? Is it even
> possible?
>
What I mean is:

Version 1.34 might have a class A with one field of type int. Version
1.35 might add to the class an additional field. What hapen if 1.34
returns this type's instance to 1.35. And 1.35 will try to access the
additional field...

1.34:
struct A
{
int i;
};

1.35
struct A
{
int i;
double d;
};


A* get_A_from_134()
{
...
}


void modify_A_from_134_in_135()
{
get_A_from_134()->d=10.0; //You write to a memory which does not belong to A
}

This is what I mean. Can crash your soft... Best Thing would be in
this case to not return boost class instances over the lib boundaries
if you know that these rely on different versions.


Best Regards,
Ovanes

dar...@gmail.com

unread,
Jun 26, 2008, 1:21:17 PM6/26/08
to boost...@lists.boost.org
Ovanes Markarian <om_boost <at> keywallet.com> writes:


>
> On Thu, Jun 26, 2008 at 9:35 AM,  <dariomt <at> gmail.com> wrote:
> [...]
> >
> > About versioning the boost namespace, I suppose you mean something like
> > changing boost namespace to e.g. boost_1_35_0. Any thoughts on how much work
> > it would take me to patch a given version of boost to do that? Is it even
> > possible?
> >
> What I mean is:
>
> Version 1.34 might have a class A with one field of type int. Version
> 1.35 might add to the class an additional field. What hapen if 1.34
> returns this type's instance to 1.35. And 1.35 will try to access the
> additional field...
>

What I thought you meant was this:

suppose boost namespace has a version number
namespace boost_1_34_1
{
    // here are boost classes functions etc...
}

Then some boost header has a compatibility alias as in
namespace boost = boost_1_34_1;

User code would just use boost namespace, but now when two libraries use different versions of boost, the linker does not mix things, i.e. libA has symbols in boost_1_34_1 and libB has symbols in boost_1_35_0

As I said in my OP, no boost components are exposed in the library interface, so that should not be an issue.

My question was regarding if namespace versioning was ever considered for boost, and if patching boost sources to produce it would be a lot of work or a piece of cake (with some automagic macro BOOST_VERSIONED_NAMESPACE ;).

Thanks for your answers

Reply all
Reply to author
Forward
0 new messages