9

I'm working in a iOS project that includes a static library created by another company. The library include an old version of AFNeworking and I don't have any source files.

Now i need to use a more recent (and less bugged) version of afneworking, but i cannot include the same class twice in the project (of course) because all the "duplicate symbols".

I understand that it's impossible replacing the version included in the library, but how can i include another version along the old one?

There is a (easy) way to refactor the entire framework before include in my project?

thanks

Slicedpan
  • 4,995
  • 2
  • 18
  • 33
TheObjCGuy
  • 687
  • 6
  • 15
  • hey... how u solved this ?? i have same problem.. please guide me – BhavikKama Jan 13 '14 at 05:59
  • 1
    i'm sorry but after some try with the trojanfoe solution (it works but is a bit dangerouse and very tricky) i ask my boss to request the original source code – TheObjCGuy Jan 14 '14 at 08:08

3 Answers3

3

I'm afraid this isn't easy to do. Very few environments allow you to link against two separate versions of the same framework at the same time, and Xcode / iOS is not one of them.

As I see it, you have three options:

1) Link against their library and use the same version of AFNetworking they use.

2) Link against their library, and manually load the newer version of AFNetworking and pull symbols from it. Be warned: this will get ugly fast and future maintainers will wonder what you were smoking.

3) Get them to update their library.

On a side note, I don't know the circumstances here, but in general they should be providing you with sources. It's a very backwards practice to provide only a static (static!) library and no way to know what it's doing inside. You'll have to sign a software license agreement and whatnot to protect their interests.

Michael Melanson
  • 1,325
  • 10
  • 21
3

You'll have to repackage the static library to remove the embedded AFNetworking files.

Unpack the library with:

$ ar x libwhatever.a

And re-package it, including all files except the AFNetworking object files:

$ ar cr libwhatever.a file1.o ... fileN.o

You will then have to link your executable with the new AFNetworking static library and hope that there haven't been API changes which will break the code in libwhatever.a. If there are then I doubt there is much you can do.

trojanfoe
  • 120,358
  • 21
  • 212
  • 242
  • 1
    This *may* work, but it's dependent on the ABI not changing between the version they linked against at compilation time and the one you're linking it against now. I wouldn't expect this to work if you're moving by more than a point version. – Michael Melanson Dec 18 '13 at 16:56
  • @MichaelMelanson The **ABI** changing? That changes, like, never. – trojanfoe Dec 18 '13 at 16:56
  • 1
    This seems dangerous, and there could easily be changes that would make this break. – Gavin Dec 18 '13 at 16:58
  • 1
    Yeah - I mention that. Worth a try though. – trojanfoe Dec 18 '13 at 16:59
  • Not sure what you mean. I'm referring to the Application Binary Interface, which can definitely change between two versions of a library even when the API doesn't change. If the new version introduces, removes, or rearranges ivars, for example, then all code that accesses or modifies any ivar in the class may be broken. – Michael Melanson Dec 18 '13 at 17:01
  • @MichaelMelanson I would consider what I think you are referring to as an API change, not ABI change, which is what I consider to be how the stack is configured etc during a function call. I mention that an API change will break this solution it in my answer. – trojanfoe Dec 18 '13 at 17:03
  • I accepted your answer, i didn't know ar command and it's very usefull. But it seems very dangerous and the library is a fat library :) i'm scared that application can crash at runtime for some missing symbols. – TheObjCGuy Dec 18 '13 at 17:29
  • @TheObjCGuy You shouldn't accept my answer if it didn't answer your question. However I don't think there is a simple answer to this problem. – trojanfoe Dec 18 '13 at 17:52
  • I think it's the right answer but this time i asked to the other company the source code (or a new binary). i'm still waiting ;) – TheObjCGuy Dec 20 '13 at 06:56
2

The best and most proper way of handling this would be to contact the the creator of the static library and get them to resolve the situation. They could resolve it either by updating the embedded version of AFNetworking, removing their dependence on AFNetworking, or adding a prefix for their embedded copy of AFNetworking. The last one is probably a good idea anyway when a third party library embeds a different library, because otherwise it would be impossible to use two libraries simultaneously that both include the same third party library.

You could also refactor the copy of AFNetworking that you include yourself to change the names of classes to have a prefix, although this should be unnecessary, as the static library vendor should have done this themselves already.

Lastly, you could find a different library that accomplishes the same thing as your current one but that doesn't embed AFNetworking.

Gavin
  • 8,204
  • 3
  • 32
  • 42