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.")
A .o file inside a library might contain symbols (functions, variables etc.) that are not used by your program. At link time, a static library can have unresolved symbols in it, as long as you don't need the unresolved symbols, and you don't need any symbol that is in a .o file that contains an unresolved symbol.
Static libraries are large in size as because external programs are built in the executable file. On other Shared libraries are much smaller as because there is only one copy of dynamic library that is kept in memory at the time of execution only otherwise its location is remote.
Static libraries resist vulnerability because it lives inside the executable file. The speed at run-time occurs faster because its object code (binary) is in the executable file. Thus, calls made to the functions get executed quicker.
The answer depends on the downsides your application can afford. If you have a lot of files, multiple copies of a static library means an increase in the executable file's size. If, however, the benefits of execution time outweigh the need to save space, the static library is the way to go.
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.
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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With