2

I have a C++ project with many libraries that is built with Clang using CMake. The purpose of this project is to compile library X which I distribute to clients along with its API headers. The API itself is completely 'isolated' and depends only on C++ standard headers.

When building a static library for iOS I compile all the libraries (make install) and then combine them into single static library using libtool -static. When distributing it to clients I've faced a problem.

Suppose the libraries on which public library X depends on internally are named A and B. Also, suppose library A is a popular library used by many people and the client happens to be linking library A of different version to his executable along with library X (which already has A object files inside).

This results either in duplicate symbols or even worse - our library X somehow starts calling functions from client's A of different version sometimes resulting in crash (that happened with libpng library).

Question. What is a proper way to create such an isolated static library that would expose (via nm command and especially during the linking stage to the final executable) only the symbols that are present in the X public API?

Would be great if it would be a compiler command that I could add to CMake configuration. Also, I really don't want to modify the source code (e.g. add namespaces and so on) as it's complicated for third party libraries.

I've been looking into symbol visibility, relocatable pre-linking, striping and other techniques but I'm not sure I'm on the right track as this problem must have happened before to many people and it's strange I failed to find a solution after many days of searching and experimenting.

dreamzor
  • 5,795
  • 4
  • 41
  • 61
  • this is what namespaces are for – Richard Hodges Jan 13 '17 at 11:57
  • @RichardHodges thanks, I've updated the question. I want to avoid namespaces as the solution must be project-wide. The public API `X` is of course namespaced. – dreamzor Jan 13 '17 at 12:00
  • google the `visibility` option for gcc/clang. There is a similar thing for microsoft. It allows you to mark some symbols as visible outside the library and some not. – Richard Hodges Jan 13 '17 at 12:04
  • @RichardHodges how can visibility be specified for static libraries? I can't get it to work. If I set `fvisibility=hidden` for the whole project then nothing changes. – dreamzor Jan 13 '17 at 14:31
  • Some ancient words of wisdom from the apple dev team here: https://developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/CppRuntimeEnv/Articles/SymbolVisibility.html – Richard Hodges Jan 13 '17 at 14:38
  • @RichardHodges I've been reading this article for a while now, I'm confused by the part in the beginning where they say "In a shared library containing many files, though,...". Do you have an experience of actually controlling symbol visibility for static libraries? – dreamzor Jan 13 '17 at 14:42
  • I have seen the results of it when compiling boost statically for use with iOS applications (you get a load of linker warnings about symbol visibility when using boost.log get). However, I have always chosen the route of using internal namespaces for my own separation in static libraries. – Richard Hodges Jan 13 '17 at 14:45
  • So far it seems that visibility specification doesn't work for static libraries. – dreamzor Jan 23 '17 at 11:45
  • I guess namespaces is the way to go then? – Richard Hodges Jan 23 '17 at 11:47

0 Answers0