Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ObjC: How to compile static library that includes optional classes that depend on a third party library

I'm trying to find the best way to package a static library(lets call it Lib1) that includes an optional class(say, ClassA), which itself requires a second static library(Lib2). In other words, Lib2 is only needed if ClassA is referenced in the project's code. Things seem to work fine, unless Lib1 is used in a project that doesn't use ClassA(and hence does not include Lib2), but requires the -ObjC linker flag(because of other project dependencies, not mine).

I'm trying to come up with a an easy solution for the following three scenarios:
1) project includes my static lib, does NOT use the optional class, does not specify the -ObjC flag
2) project includes my static lib, does NOT use the optional class, but requires -ObjC flag
3) project includes my static lib + second static library, and DOES use the optional class (we don't care about the -ObjC flag at this point)

Is there a linker flag out there to strip my optional class out of the final project app so that it doesn't require the second static lib? I guess my other alternatives are to release multiple versions of my static lib, one that includes the option class(the standard choice), one that does not(the alternate, for projects with -ObjC requirements), or maybe supply a stub file, that supplies empty implementations of all the classes needed from the second static library? This seems like it could be a common problem in the static library world... is there a best practice for this scenario?

Thanks!


Solution:

1) Suggest to my -ObjC users that they use -force_load instead. (thanks Rob!)
2) For users that can't do 1, I'll have a alternate build that does not include ClassA

like image 548
Nick P. Avatar asked Sep 27 '12 21:09

Nick P.


1 Answers

The best practice is always to have the final binary link all the static libs required. You should never bundle one static library into another. You should absolutely never bundle a well-known (i.e. open-source) static library into a static library you ship. This can create incredible headaches for the final consumer because they can wind up with multiple versions of the same code. Tracking down the bugs that can come from this is insanely difficult. If they're lucky, they'll just get confusing compiler errors. If they're unlucky, their code will behave in unpredictable ways and randomly crash.

Ship all the static libraries separately. Tell your clients which ones they need to link for various configurations. Trying to avoid this just makes their lives difficult.

Some other discussions that may be useful:

  • Duplicate Symbol Error: SBJsonParser.o? (Example of a customer who ran into a vendor doing this to him)
  • Linking static libraries, that share another static library
  • Why don't iOS framework dependencies need to be explicitly linked to a static library project or framework project when they do for an app project?

The -ObjC flag should be preventing the automatic stripping of ClassA entirely, whether its used or not (see TN1490 for more details).

If ClassA is never used except in certain circumstances and you want to save space, you should probably move ClassA into its own static library. Or use #ifdef to conditionally compile it.

Alternately, you can remove the -ObjC flag and use -force_load to individually load any category-only compile units (which is the problem -ObjC is used to address).

like image 120
Rob Napier Avatar answered Dec 11 '22 02:12

Rob Napier