Explaining Clang dynamic/static library linking process - ios

I'm building my own library and I'm quite confused with how does the final executable linking process work.
I have a MyLibrary.framework which uses CoreLocation header.
When I set Mach-o type to static the framework builds without problem, even though I didn't link the CoreLocation.framework in "Linked Frameworks and Libraries".
When I link MyLibrary.framework to my iOS test project, I have to add CoreLocation.framework, because otherwise I get unreferenced symbols errors.
Question
Why doesn't building my static library need the reference the CoreLocation, and why does building my app require linking to CoreLocation ? What happens there ?

The answer from Mecki here:
Objective-C categories in static library
Explains the compiling/linking process very well. A .a file is an (.a)rchive of .o files.
each .o files contains not only the symbols it has, but also the symbols it needs.
Only during the executable linking process the linker resolves all the symbols in the executable file, which references a static library, which references the CoreLocation library.

Related

Symbols not found for architecture when building Cocoa Framework used in Static Library subproject

I built a pretty simple Cocoa Framework in Xcode for use on an iOS device (not simulator). I dropped this framework into another project that builds a static library. When I build this static library it succeeds without error. No problems yet.
NOW:
I have an actual iOS app project that includes the static library project as a subproject.
When I try building this app I get 'no symbols found for architecture' errors regarding the two classes I am trying to use that are defined in my cocoa framework:
I'm not only building the framework for the active architecture:
I've verified that it is indeed built for both armv7 and arm64 in Terminal:
Kevins-MBP-2:ASI.framework kevin$ lipo -info ASI
Architectures in the fat file: ASI are: armv7 arm64
The only way to get this building successfully is if I also drop my cocoa framework into the iOS app project, in addition to it already existing in my static library project. I feel like I shouldn't have to have the framework in both projects. Only the static library actually uses the framework. The iOS app project does not need to know about the framework.
Static libraries don't contain dependent libraries, so whenever you link against a static library you need to supply the dependent libraries they use to the linker.
Basically you do need to also link the executable against this Cocoa Framework as you have stated in the last sentence of your question.

Linker error in iOS build when including static library

I am working on importing a static library on our company's project. While I see so many questions on this topic, I tried all of them and none solved my problem.
Here is what I tried.
1) I have added the libraries in Build settings -> Link Binary with libraries. The static libraries are there.
2) I added the path of the static libraries ( They are fat static libraries for armv7, armv7s & arm64 ) in Search paths.
3) I tried turning on/off Build Active Architecture only.Valiant.
I am very new to iOS development and would be grateful with some help. Right now, I am just trying to import the library and build it. I have attached screenshots of my settings.
It looks like that library is calling c++ functions (std::new, std::string, etc.) You need to link to the C++ standard library. You can do this by by going into your project's build settings and look for "C++ Standard Library" and set it to libc++

Duplicate symbol in .framework and .a

I am developing a library .a file in Which i am using AFNetworking classes ... This library does also include one .framework which also using the AFNetworking classes (Adding this framework is optional)
Due to this I am getting following errors
duplicate symbol _OBJC_IVAR_$_AFHTTPRequestOperation._responseSerializer in:
.../KonySDK.framework/KonySDK(AFHTTPRequestOperation.o)
.../Core.a(AFHTTPRequestOperation.o)
Options i have already considered is removing AF***.o from one of the file lipo -thin and ar -d -sv commands
Using this Link
But this library is configurable from server and adding that particular .framework is optional.
My question is ... Is there any otherway by which i can resolve this issue ? ALso i can would rather not prefer to remove .m files of AFNetworking from my library source as the entire process of generating library is fully automatic and configurable in many ways
I have also tried to resolve this by removing -all_load from other linker flags but this resulted in crash as categories of some classes are not loaded due to this.
You will get the duplicate symbol linker error whenever you have included a binary version of a class. The way to get rid of it is to remove the superfluous object.
For building your library you only need the .h files of AFNetworking because those tell the compiler which classes and methods are available. You do not need to compile the AFNetworking source code because a .a file is essentially a collection of .o files which each contain the compiled versions of .m files.
Libraries are not linked
Only apps get linked and therefore need to have the symbols/objects present. i.e. if you provide your library without AFNetworking compiled in, then the developer using it needs to add AFNetworking via library, framework or cocoapod.

Can the -ObjC flag be applied selectively to static libraries?

TL;DR
How can I make the -ObjC linker flag target a specific static library and not all the static libraries I am linking against in order to avoid unused object files being linked in with my app?
Too Long; Did Read
So you are developing a new iOS app and you add in your homegrown "objcutil" static library which contains a variety of useful Objective-C classes (not implemented as categories) to do various things that have been useful in the past. So far, so good, and only those object files that are being referenced in the utility library are being linked with the app.
Then you decide to integrate the Google Maps SDK which wants you to use the -ObjC Other Linker Flags and all of a sudden dependencies in the utility library fail to be resolved, because you haven't configured Xcode to link to those libraries.
OK I can resolve the missing dependencies easily enough, however you now have unused object files and library dependencies that you don't need and you'd like to be a bit tidier than that.
So how do you avoid OCD overload?
Some reference from the ld manpage:
-ObjC Loads all members of static archive libraries that define an Objective C class or a category. This option does not apply to dynamic
shared libraries.
Xcode Version: 5.1.1
OSX Version: 10.9.4
OK so the answer is to use -force_load instead of -ObjC as -force_load is more focused.
So WRT to the Google Maps SDK, if you followed the instructions and copied the static framework into the app project directory, then the framework will be in the project root directory and you can remove -ObjC from the Other Linker Flags and replace it with
-force_load GoogleMaps.framework/Versions/Current/GoogleMaps:
Nothing else needs changing.
For other libraries you will need to use the full static library path as the argument to -force_load.

Adding static library to project >> Undefined symbols

I have created a static library which I added to another project in the same workspace in XCode. The library builds fine, both for Simulator and an actual device.
All errors refer to classes in the library, so it's not about another framework.
I get two undefined symbols errors that both refer to "_OBJC_CLASS_$_Campaign"
When I build for an actual device I get Undefined symbols for architecture armv7s
When I build for a simulator I get Undefined symbols for architecture i386
I tried creating a fat library: same issue.
I toggled "build for active architecture only" on and off: doesn't help.
I deleted and rebuilt the XCode workspace: no solution.
I'm very sure I added the correct .m files to the "compile sources" of the library, and I properly added the library to the other project through "Link binary with libraries". I also tried just dragging the .lib to the Frameworks folder.
I added the header file of the .lib to the project.
I would be glad with any suggestion!
The problem is likely caused by the fact that your static library import something from another library.
You need to figure out what symbols are missing exactly and add library that defines them. Build log output should be very helpful in this regard.
EDIT: Based on discussion in comments, problem is caused by the fat that there's no implementation for Campaign class. Without implementation, compiler doesn't generate class and this results in linking error. There are no compile-time errors because interface of the class is declared though.
You should add such implementation, either in a separate Campaign.m file, or in one of already existing files.

Resources