Creating a static library of static libraries in XCode - xcode

I have a need to create a static library which will some of it's own code and it will also contain a number of other static libraries I have written.
So normally I have a main project A.xcodeproj which depends on B.xcodeproj which in turn depends on C, D, E etc.
My company has a requirement to distribute only a static library with a simple app, and for there to only be one library sent out, not a multitude of libC.a libD.a etc.
So I create A_static.xcodeproj which has simple application API calls and links to libB.a but everytime I try this libB.a only contains the symbols for B.xcodeproj, I can not get to it also contain libC.a libD.a etc.
Is there an easy way to do this in XCode that I'm missing?
Thanks

It sounds very much like you need to use frameworks. Allows you to bundle multiple libraries and files together into 1 bundle that other parties can include. I'm in the same boat where I work. I've used this guide on github to get our frameworks up and running. Worked great for me.
iOS Framework

Related

Proper way to link against libraries with dependencies?

I'm working on a fairly simple OS X app that uses a couple third-party libraries (SoX and TwoLAME) to do some audio converting. TwoLAME relies on libsndfile, and SoX relies on sndfile plus a number of other libraries.
For development, I simply installed the two libraries with Homebrew, which took care of the dependencies, and then linked right to them (ie in /usr/local/Cellar/...). Now that I'm ready to deploy, I need to figure out a way to get everything packaged up.
I know frameworks are a bit ambiguous in Cocoa (fake ones, dynamic ones, etc), but it seems like ideally I would end up with some frameworks of one kind or another that I can drop into the project and everything would work.
I've read through a lot of different docs and tutorials about frameworks, and tried a number of approaches, but I seem to be missing some core concept for getting this all to work together.
I have been able to make frameworks from the libraries that sort of work, in the sense that I compile from source, take the static (.a) library and put it in a "fake" framework with the headers, and the app will run with those. Those static libraries are still referencing the dependencies on my local path, though. So, eg, if I uninstall Lame from Homebrew, the SoX static library in my framework will fail.
I'm really struggling to figure out what the best way cleanly get all these libraries and their dependencies into this app. The tutorials I've seen about building dynamic Cocoa libraries from scratch have been very hard to do with the source code for these pre-existing libraries. The other option I have considered it build dylibs and then use install_name_tool to change paths to be relative just ship everything with the app and try to match everything up.
There's got to be some better way that I'm just missing, and would really appreciate any help.

Linking static libraries, that share another static library

I currently have a single Xcode project for a very large code base, I'll call it Project X, which I am dividing into a bunch of sub projects ( Projects A, B, C ).
So far, each of these projects compiles, on their own, just fine. They all produce static libraries. Project B and Project C are dependent on the static library produced by Project A in order to build.
I have another xcode project, Project Z, that requires the static libraries produced by Projects B and C. Herein lies the problem. When Project Z enters the linker phase, things blow up - duplicate symbols are found within the libs for Projects B and C for the code they originally linked against in Project A!
I'm pretty new to the world of static libraries, and I'm unsure of how to move forward with Project Z, or how to modify the other projects so that they are linking against the same Project A lib. I have a feeling it's not possible. What are my options here?
Edit:
I should clarify that Project B and Project C need to build into separate static libs because some clients will only require one or the other.
Also, I'm having this dilemma on both OSX and iOS platforms.
I realize that I could solve this problem on OSX by building the projects as dynamic libraries. However, I'd prefer not to do this, and it still leaves me with same issue on iOS.
Static libraries should never include other static libraries (or third party code in general). A static library is just a bundle of .o files glued together. So if you have multiple copies of the same information, it's going to blow up.
Each static library should just have its own code in it. The final application is responsible for linking all the required libraries together (including libraries required by libraries). This way there is exactly one copy of each thing linked.
This sounds like exactly the sort of problem CoacoaPods was created to solve. If you define pods for each of theses projects then Z should be able to determine and link against all of its dependencies all the way up the chain without introducing duplicate symbols.

Including a framework without embedding it in the app bundle

I'm still not 100% sure with the framework linking process, but from what I've seen here before nobody has asked a similar question, perhaps because this could be a silly question, but I'll give it a go anyway.
In my current X-Code project, I'm using a custom framework, say example.framework. At the moment, as far as I'm aware of, in order for the program to function with the framework, I need to have it either in /Library/Frameworks, or I need to have it copied into the bundle resources in the build phase.
Would anybody know about adding a framework to a project in a way that it gets compiled into the executable, so I don't have to include the raw framework with the app? I'd rather not share the whole framework...
Thank you in advance! Any suggestions are also welcome!
A Mac OS X framework is basically a shared library, meaning it's a separate binary.
Basically, when your main executable is launched, the OS will load the framework/dylib into memory, and map the symbols, so your main executable can access them.
Note that a framework/dylib (bundled into the application or not), does not need to contain the header files, as those are only needed at compilation time.
With Xcode, you can actually decide whether or not to include the header files, when you are copying the framework to its installation directory (see your build phases).
If you don't copy header files, people won't be able to use your framework/dylib (unless they reverse-engineer it, of course).
If you still think a framework is not suitable for your needs, you may want to create a static library instead.
A static library is a separate object file (usually .a) that is «included» with your final binary, at link time.
This way, you only have a single binary file, containing the code from the library and from your project.

Why would I want to use a static library?

I understand for non-iOS targets, using shared libraries can lead to lower memory usage, and also that some companies distribute a library and headers (like Superpin) and a static library allows them to not distribute the source of their product. But outside of those, what are the reasons you'd want to use a static library? I use git for all of my projects, and I usually add external libraries (open source ones) as a submodule. This means they take up disk space locally, but they do not clutter up the repo. Also since iOS doesn't support shared libraries, the benefits of building libraries to promote code reuse seems diminished.
Basically, is there any reason outside of selling closed source libraries that it makes sense to build/use static libraries for iOS?
organization, reuse, and easy integration into other programs.
if you have a library which is used by multiple apps or targets multiple platforms, then you will have to maintain the build for each app. with a library, you let the library maintainer set up the build correctly, then you just link to the result (if it's developed internally, then you'll want to add it as a dependency too).
it's like DRY, but for projects.
libraries become more useful as projects become more complex. you should try to identify what programs (functions, class hierarchies, etc) are reusable outside of your app's context, and put it in a library for easy reuse - like pattern recognition.
once your codebase has hundreds or thousands of files, you will want to minimize what you use, and you will not want to maintain the dependencies manually for each project.
Also since iOS doesn't support shared
libraries, the benefits of building
libraries to promote code reuse seems
diminished.
There's no reason you can't build your own static library to use across multiple projects.
Other than for that purpose and the ones you mentioned I don't think there's much else.
Static libraries allow you to have truly standalone executables. Since all library code is actually, physically present in the executable, you don't have to worry about the exec failing to run because there's a too-old version of some library, or a too-new one, or it's completely missing, etc. And you don't have to worry about your app suddenly breaking because some library got replaced. It cuts down on dependencies and lets your app be more encapsulated.

How do I add a library compiled in XCode into Monotouch so that it works for both simulator and device?

There are appear to be methods of creating a fat static library ala "http://stackoverflow.com/questions/3520977/build-fat-static-library-device-simulator-using-xcode-and-sdk-4". Is this recommended? Any special steps (i.e., disabling thumb)
Also, if I do use the fat static library, will monotouch/xcode clear out any unused code in the final product?
You definitely need to turn Thumb code off so you can link properly against the library. As far as creating the fat static library goes, I can only say that anecdotally I've done this for a few third-party libraries that I've used and haven't run into issues.
I assume you already know that you need to create the bindings necessary to make calls to the objective-c library from your MonoTouch code and add extra gcc flags in the project properties to link in the static lib. If not, you can get that information on how to do that from the MonoTouch website.

Resources