Statically link a private library into a public one to hide symbols [closed]
Asked Answered
C

1

12

Consider the following:

  • I am developing a static library X in C++ that, internally, uses the famous static library Y v2.0;
  • I want to distribute only one library X', that is X with Y statically linked/merged for its internal use;
  • A developer wants to use X' in his executable;
  • Also, he needs Y v1.0 (not v2.0, as I do);
  • Y v1.0 and v2.0 has some symbols in common, and some of these common symbols also behave differently.

I developed X with the strict requirement to use Y v2.0 for some it's internal business. This is to say that I cannot by any means revert to Y v1.0.
On the other side, the developer has similar restrictions to use Y v1.0.

As you can already argue, the question is: how can I link Y inside X without exporting Y symbols to avoid collisions? Y is well established, and possibly I'd not want to modify its source code or build settings (if publicly available).

To put things more onto Earth, I am in the process of designing an SDK that will for sure need some 3rd party libraries, let's say zlib. In my development I'll rely on zlib v1.2.3.4.5.rc6 because I extensively and successfully used and tested it, and I cannot afford the SDK testing/fixing required if I change version.
All the statically or dinamically linked libraries the SDK will offer must hide the 3rd party static ones.

The potential customer could undergo similar restrictions (he needs zlib v7.8.9), so how can I avoid symbol collisions? Again, possibly without changing the original source code (namespacing etc.).

To complicate things, the SDK is multiplatform, implying I'd need different ways to solve the problem depending on the platform (Windows, Linux, Mac OS, iOS, Android, ...) and compiler used (e.g., MSVC++ and g++).

Thank you.

Update
It seems I am VENDOR2 of this question: Linking with multiple versions of a library
bstpierre's answer seems a viable solution, but I'm not sure it works or if it can be reproduced on OSes other than *nix.

Colan answered 12/10, 2012 at 16:2 Comment(5)
(Anonymous) namespaces, perhaps?Knackwurst
That's what I'd like to avoid, i.e. modifying the source code of the 3rd party libs (assuming I have access to it).Colan
windows, linux, os x, ios, android... the code is almost completely platform-independent, should a platform-dependent thing arise, it will be implemented for all the supported OSes.Colan
try "attribute ((visibility("default")))" for your public functions of your library X and while compiling with g++ use "g++ -fvisibility=hidden test.cpp -o test".Sharpe
If you have clash for names with external linkage, and taking into account your restrictions (don't modify code in any way, don't do platform-dependent stuff) then it is just One Definition Rule violation.Ib
A
1

I've had this problem many times with static libs, most recently with MSVCRT. With a single executable, the One Definition Rule gets in the way, as one commenter points out. There's really no way around this, that I can think of, short of patching binaries. And you'd have to do this "deeply" - catching all internal references that static library Y (zlib) makes to its own external-linkage objects.

In this case, I'd suggest using a dynamic library (DLL or SO). It will add a bit of deployment complexity. But it provides an executable "firewall", permitting global objects with the same name to reside in each binary without colliding. Even so, it can pose problems if both app and DLL have conflicting third-party dependencies. Still, probably the best option.

Apostasy answered 30/4, 2013 at 23:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.