20

I am writing a reusable static library for the iPhone, following the directions provided here.

I want to use minizip in my library internally, but don't want to expose it to the user.

It should be possible for the user to include minizip themselves, possibly a different version, and not cause clashes with my "inner" minizip version.

Is this possible?

Edit:

I've tried adding -fvisibility=hidden to additional compiler flags for minizip files and changing functions to be __private_extern__ and __attribute__((visibility("hidden"))), but it still seems to produce defined external symbols:

00000918 T _unzOpen
0000058e T _unzOpen2
00001d06 T _unzOpenCurrentFile
00001d6b T _unzOpenCurrentFile2
...

Edit #2:

Apparently the symbols marked with these annotations are only made private by the linker, which never happens when Xcode builds the sources, since it adds the -c parameter ("Compile or assemble the source files, but do not link.")

Jaka Jančar
  • 11,386
  • 9
  • 53
  • 74
  • Are you able/willing to modify your internal copy of minizip, and does the iPhone support Mach-O's two-level symbol namespace? I expect the answer to both should be yes. – ephemient Oct 21 '09 at 16:16
  • I'm willing to modify my copy, sure. Maybe I could just have all the symbols prepended with the prefix that I use for my library, somehow? I wouldn't mind doing my_. I don't know whether two-level symbol namespaces are supported on the iPhone. – Jaka Jančar Oct 21 '09 at 16:58
  • 1
    Just for future Googler's, you may want to see this, it might be helpful: http://stackoverflow.com/a/14863432/311567 – dashesy Feb 27 '13 at 20:09

2 Answers2

13

You could rename all exported symbol from minizip with objcopy.

something like

objcopy -redefine-sym=minizip.syms yourstaticlibray.a 

and minizip.syms

_unzOpen     _yourownprefix_unzOpen
_unzOpen2    _yourownprefix_unzOpen2
...          ...

No clash if an executable is linked with an other minizip.a and yourstaticlibray.a, and because you renamed all the symbol in yourstaticlibray.a your call inside yourstaticlibray.a to minizip will use the prefixed symbol, and not the unzOpen one.

Nimlar
  • 655
  • 7
  • 15
5

Since static library is nothing more than a set of .o files (which are not linked yet, as you have mentioned), the only way to completely hide presence of minizip from the outside world is to somehow compile minizip and your library together as a single compilation unit and make minizip functions/variables static.

You could have a look at how does SQLite do the "amalgamation" process which turns library source code into single .c file for further compilation: The SQLite Amalgamation.

As a bonus you'll get better optimization (really recent GCC and Binutils are able to make link-time optimizations, but this functionality is not released yet).

dottedmag
  • 853
  • 6
  • 16
  • You're on the right track, but you don't have to go through the pain of merging into a single compilation unit, since the Xcode tools linker can do a "single-object prelink" to achieve the same result after compilation and archiving. See http://stackoverflow.com/a/18949281/316487. – bleater Jul 29 '15 at 22:47