您的位置:首页 > 其它

Avoiding duplicate symbol errors during linking by removing classes from static libraries

2015-07-27 11:27 417 查看
[http://atnan.com/blog/2012/01/12/avoiding-duplicate-symbol-errors-during-linking-by-removing-classes-from-static-libraries]


Avoiding duplicate symbol errors during linking by removing classes from static libraries

Jan 12th, 2012

If you’re using a static library in your project and specifying the
-all_load
flag to ensure files containing Objective-C categories
are loaded correctly, you’ll likely experience “duplicate symbol” errors at link time if the static library includes the same classes used in your project or another library.

e.g. A third party has provided you with a static library (
libProprietary.a
) which usesKissXML internally
for parsing & generating XML. You also have an internal static library (
libBitsAndBobs.a
) which also uses
KissXML
.
If you use both libraries, you’ll get duplicate symbol errors for all the
KissXML
classes (
DDXMLDocument
,
DDXMLElement
&
DDXMLNode
).

A brutish yet simple workaround is to remove the offending classes from one of the libraries, so I’ll show you how it’s done.

Firstly, we need to see if the static library is a “fat file”, which means it contains code for multiple architectures. You’ll find most iOS static libraries are fat files, since they need to work both on the device (
armv6
/
armv7
)
and in the Simulator (
i386
).
$ lipo -info libProprietary.a
Architectures in the fat file: libProprietary.a are: armv6 i386


As you can see, we have a fat file on our hands.

The tools we’ll be using require us to split the static library into seperate files for each architecture if it’s a fat file. To do that, we’ll use
lipo
again.
$ lipo -thin armv6 libProprietary.a -output libProprietary-armv6.a


We can now use
ar
to peek inside one of these thin archive files, listing the included object files.
$ ar -t libProprietary-armv6.a
__.SYMDEF SORTED
FOOBar.o
DDXMLDocument.o
DDXMLElement.o
DDXMLElementAdditions.o
DDXMLNode.o


As expected, in addition to the
FOOBar.o
file containing code specific to
libProprietary.a
,
we also have object files for each of the classes defined in the
KissXML
project. To delete those, we’ll need to unpack the
object files from the archive, delete the object files we don’t want, and repack the archive.

First, the extraction:
$ mkdir libProprietary-armv6
$ cd libProprietary-armv6
$ ar -x ../libProprietary-armv6.a


We now have a directory containing the contents of the archive:
$ ls -1
DDXMLDocument.o
DDXMLElement.o
DDXMLElementAdditions.o
DDXMLNode.o
FOOBar.o
__.SYMDEF SORTED


Simply remove the
KissXML
related object files and repack the archive like so:
$ rm DDXML*.o
$ libtool  -static *.o -output ../libProprietary-armv6.a


And to confirm we’ve successfully removed the correct object files from our archive, we can list the contents again:
$ ar -t ../libProprietary-armv6.a
__.SYMDEF SORTED
FOOBar.o


So far we’ve only stripped the
armv6
archive, so we need to repeat the process for the
i386
archive:
$ lipo -thin i386 libProprietary.a -output libProprietary-i386.a
$ mkdir libProprietary-i386 && cd libProprietary-i386
$ ar -x ../libProprietary-i386.a
$ rm DDXML*.o
$ libtool  -static *.o -output ../libProprietary-i386.a


Now for the final step, we recombine the thin files into a fat file again:
lipo -create libProprietary-armv6.a libProprietary-i386.a -output libProprietary-noKissXML.a


If you’ve done everything correctly you can now replace
libProprietary.a
with
libProprietary-noKissXML.a
and
you won’t have any more duplicate symbol errors.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: