What's the difference between `*.framework`, `*.dylib` and `*.a` libs - ios

I have a project, in the Framework, there have *.framework, *.dylib, *.a libs.
I want to know what's them? and the difference between them.

Dynamic and static libraries
First of all, a library is a collection of resources and the code itself, compiled for one or more architectures.
Static libraries (*.a):
In the case of static libraries (*.a), the code that the app uses is
copied to the generated executable file by a static linker during
compilation time.
Dynamic libraries (*.dylib):
Dynamic libraries (*.dylib) are different from static libraries in the
sense that they are linked with the app’s executable at runtime, but
not copied into it. As a result, the executable is smaller and,
because the code is loaded only when it is needed, the startup time is
typically faster.
Dynamic and static frameworks:
For frameworks, we first need to understand the bundle concept (as a
framework is a specific kind of a bundle). A bundle is a file
directory with subdirectories inside. On iOS, bundles serve to
conveniently ship related files together in one package – for
instance, images, nibs, or compiled code. The system treats it as one
file and you can access bundle resources without knowing its internal
structure.
The library may also have additional resources: headers, localization
files, images, documentation, and examples of usage. We can bundle all
of this together in one bundle – and the name of this is the framework.
Static frameworks contain a static library packaged with its
resources. Dynamic frameworks contain the dynamic library with its
resources. In addition to that, dynamic frameworks may conveniently
include different versions of the same dynamic library in the same
framework!
Other useful references:
Hackernoon
Runtastic
Static library
Software framework
Update:
Thanks for accepting my answer!
Compiled for one or more architectures?
Every architecture requires a different binary, and when you build an
app Xcode will build the correct architecture for whatever you’re
currently working with. For instance, if you’ve asked it to run in the
simulator, then it’ll only build the i386 version (or x86_64 for
64-bit).
This means that builds are as fast as they can be. When you archive an
app or build in release mode, then Xcode will build for all three ARM
architectures, thus allowing the app to run on most devices. What
about the other builds though?
Naturally, when you build your framework, you’ll want developers to be
able to use it for all possible architectures, right? Of course you do
since that’ll mean you can earn the respect and admiration of your
peers.
Therefore you need to make Xcode build for all five architectures.
This process creates a so-called fat binary, which contains a slice
for each of the architectures.
arm7: Used in the oldest iOS 7-supporting devices
arm7s: As used in iPhone 5 and 5C
arm64: For the 64-bit ARM processor in iPhone 5S
i386: For the 32-bit simulator
x86_64: Used in 64-bit simulator
Raywenderlich: Multi-Architecture

Related

"no matching architecture in universal wrapper", but file has it

Note: There are a lot of SO questions with a similar problem, but almost all of them have an issue running in the Simulator because they failed to build universal libraries. In this case, I have a universal library, I just can't figure out why the device loader doesn't like the architecture in the wrapper.
We build some C++ code that uses Tensorflow Lite on multiple platforms. I'm trying to link it into our iOS build. I created a universal shared library with a couple of shared libraries built by that team. They build them as individual shared libraries with one architecture per file (one for macOS, one for iOS arm64, and one for iOS x86). I put the two iOS files together using lipo, and I was able to link and run in the Simulator. Unfortunately, I can't exercise that code path in the Simulator (for other reasons), so I built and ran on a device.
But when I try to run on a device, I get
dyld: Library not loaded: #rpath/libtensorflowlite.so
Referenced from: /private/var/containers/Bundle/Application/E3E3B0E9-B36E-4ADB-9FFC-CA2D6D2A8AC8/MyApp.app/MyApp
Reason: no suitable image found. Did find:
/private/var/containers/Bundle/Application/E3E3B0E9-B36E-4ADB-9FFC-CA2D6D2A8AC8/MyApp.app/Frameworks/libtensorflowlite.so: no matching architecture in universal wrapper
I know the App Store doesn't like x86 bits in universal shared libraries, so I used lipo in an Xcode build phase to remove the x86 part, and now my file looks like:
$ file /Users/rmann/Library/Developer/Xcode/DerivedData/MyApp-fdskkibuvbsubudkmqtgsjxmyqme/Build/Products/Debug-iphoneos/MyApp.app/Frameworks/libtensorflowlite.so
/Users/rmann/Library/Developer/Xcode/DerivedData/MyApp-fdskkibuvbsubudkmqtgsjxmyqme/Build/Products/Debug-iphoneos/MyApp.app/Frameworks/libtensorflowlite.so: Mach-O universal binary with 1 architecture: [arm64:Mach-O 64-bit dynamically linked shared library arm64]
/Users/rmann/Library/Developer/Xcode/DerivedData/MyApp-fdskkibuvbsubudkmqtgsjxmyqme/Build/Products/Debug-iphoneos/MyApp.app/Frameworks/libtensorflowlite.so (for architecture arm64): Mach-O 64-bit dynamically linked shared library arm64
But it still doesn't see it.
I do something similar with another library we get from a third party, and everything works fine. How can I inspect this further to determine what the issue is? Thanks.

What is the difference between .dylib and .a lib in ios?

I know what is compile and runtime in Objective c, (method swizzling is a runtime) but I want to know what draws the line between these two library? one .a and .dylib ? What purpose do they serve, other than stating one is static and the other is dynamic? When would we need one over the other?
Static Library(.a)
Static libraries allow an application to load code into its address space at compile time.This results in a larger size on disk and slower launch times. Because the library's code is added directly to the linked target's binary, it means that to update any code in the library, the linked target would also have to be rebuilt.
Dynamic Library(.dylib)
Dynamic libraries allow an application to load code into its address space when it’s actually needed at run time. Because the code isn't statically linked into the executable binary, there are some benefits from loading at runtime. Mainly, the libraries can be updated with new features or bug-fixes without having to recompile and relink executable. In addition, being loaded at runtime means that individual code libraries can have their own initializers and clean up after their own tasks before being unloaded from memory
.a stands for Static library
.dylib stands for dynamic library
A Static library (.a)
A Static library (.a) is a pack of compiled classes, functions which can be used together with iOS app development project. It is a compiled binary or fat file and can be shared between projects.
You might want to create a static library for different reasons.
For example:
You want to bundle a number of classes that you and/or your colleagues in your team use regularly and share those easily around.
You want to be able to keep some common code centralized so you can easily add bugfixes or updates.
You’d like to share a library with a number of people, but not allow them to see your code. -
Dynamic Library
A file ending in the extension .dylib is a dynamic library: it's a library that's loaded at runtime instead of at compile time. If you're familiar with DLLs from Windows or DSOs, it's more or less the same type of thing with a few twists.
dylib are analogous to a windows *.dll file. They contain generic, unmodifiable code intended to be reused by many applications.

What is the correct process for linking static libraries that have common static libraries?

I am working on a static library, called Silicon, that I use for all of my iOS apps.
Because I don't want to create one massive static library that could become hard to maintain I create lots of smaller static libraries that I attach as submodules.
As of the time of this writing the dependency tree for Silicon is as follows:
Silicon
|
|==> FDKeychain
|==> FDDataClient
|
|=> FDRequestClient
|
|=> FDFoundationKit
|==> FDSQLiteDatabase
|
|=> FDFoundationKit
As you can see both FDRequestClient and FDSQLiteDatabase have FDFoundationKit as a common static library.
What seems to happen is that when a project using Silicon is built it builds all of Silicon's target dependencies to the projects build directory. The same thing happens for FDDataClient and FDSQLiteDatabase. So at some point FDFoundationKit from FDRequestClient is built and copied to the build directory as well as FDFoundationKit from FDSQLiteDatabase. Whichever one is built last just overwrites the previous one.
Just by sheer luck FDFoundationKit hasn't been changing in any serious ways such that FDRequestClient and FDSQLiteDatabase can't always be using the same version but I can't guarantee it will be like this forever.
I am trying to figure out if there is a way for Silicon to specify which version of FDFoundationKit to use so it can be Silicon's responsibility to ensure that the the version used will work for both FDRequestClient, FDSQLiteDatabase and any other dependencies I add in the future.
I know CocoaPods attempts to solve this problem but I do not want to make someone have to setup all of that just to get my library working. If I could just find someway of having Silicon define which version of FDFoundationKit to use everything would work perfectly.
You could (as we do) place all of your libraries into frameworks, as frameworks support versioning. Frameworks are just a directory tree configured in a common manner. Xcode does not directly support the creation of frameworks, so you have to create them in a script, typically as the last of your build phases. An example (thanks to jverkoey) can be found at IOS- framework
Within a framework you may store all versions of each static library within the
myLibrary.framework->Versions->n.n folders.
The myLibary.framework->Versions->Current is a link to the folder of the latest version.
Since you are using static libraries, Silicon itself cannot specify the versions (that would require dynamic libraries), however the build, linker or environment flags used for the building of Silicon certainly can.
In this manner, by default, Apps will always use the latest version of the library, but the actual version linked may be easily overridden by linker flags when building. Also, all users will simply include the Silicon framework in their project in the same manner as any other framework, so it's very simple for developers.
There looks to be only two answers to this problem:
1) Use a dependency manager like CocoaPods or Carthage.
2) Any static libraries or frameworks you release should not have any target dependencies. They should link against any dependencies you have and it is the responsibility of person integrating your library to also integrated the required dependencies.

Integrating .a library file types with XCode

I am testing an image capture library that sent over their code library as a regular header file and a file ending in a "*.a" extension. I am not familiar with using a file in this format and can't seem to find the right "magic" to search for.
What does this file extension stand for?
What if any extra steps are needed to get it integrated with my XCode project?
Maybe a bit more of theory can get you in the right track so you'll know how to search next time:
.a files are archives of object (.o) files. These object files are generally produced by an assembler, compiler, or other language translator; They contain machine code that is usually not directly executable, but are used by linker tools to generate an executable or yet another library by combining parts of these object files.
Another important thing you should know is that since these files contain machine code, they must have been compiled for the correct architecture you're targeting for (ex.: armv7, i386, etc). That can be the reason why sometimes you will be able build your project for one device but not to another if you don't have the right set of files for the targeted platform (e.g. iPhone simulator vs. actual iPhone).
It is also possible to have "universal binaries", which are files that in turn package together archives of object files (.a) for different architectures (e.g. using tools such as lipo), so that the same library file can be given to the linker for multiple architectures. Or, you may have a different linker configuration for each target (e.g. using conditional build settings in XCode). All of these files can be analyzed with certain tools (e.g. "file", "otool", "lipo -info", etc), and each has several parameters to play with. Debuggers will also check the symbols within these files for their own purposes.
When you drag the '.a' file to your project's directory within Xcode, you can notice that it will automatically add this file to the list of "Link Binary With Libraries" items under your target's "Build Phases".
Since the header files allows us to separate certain elements of a program's source code into reusable files, that commonly contain forward declarations of classes, subroutines, variables, and other identifiers that are needed for reference during the compilation step, it is common to have libraries provided as archives of compiled objects (.o) in ".a" files along with their respective headers. For instance, as soon as you include the headers files in your XCode project, the editor will provide auto-complete for these new functions.
Sometimes, you might also consider having the actual source code of the library instead of binaries inside your project as this * might * make debugging easier in case an unexpected behavior is happening inside that "library" package. Many times this is not an option though (when you have no access to the sources) when the binary distribution is made in purpose to hide implementation details (commercial libraries).
.a stands for archive. It is also known as a static library. I believe you should be able just to drag it and the header files into Xcode. Xcode should pick up the right thing to do from its extension.
Example, see appr. from 30 sec here
http://memention.com/ac3dreader/usage/quickstart.html
Another example from Google Analytics, under Setup
Drag GANTracker.h and libGoogleAnalytics.a from the SDK's Library directory into your new project.
https://developers.google.com/analytics/devguides/collection/ios/devguide

In Xcode project target build settings, What is Mach-O Type?

After getting tired of numerous Match-O linker error, I want to know that this thing means. Instead of trial and error solution, I would like to know the concept behind these things. Specifically I want to know the difference between :
Executable
Dynamic Library
Bundle
Static Library
Relocatable Object File
These are the options presented when I click on Mach-O Type settings on Linking section. Some small definition or some link to appropriate content is ok too.
Mach-O, short for Mach object file format, is a file format for executables, object code, shared libraries, dynamically-loaded code, and core dumps. For unix users this is like a.out but with improvements. This is the format used in Mac OS X and iPhone OS libraries for executable files.
As you know iOS devices (iPhone, iPad etc.) have different architectures ARMv6 (iPhone 2G + 3G, iPod Touch) and ARMv7 (iPhone 3GS, iPod Touch 2G + 3G) but the simulators used in Xcode runs mostly on i386 platform. This means the that the library clients have to setup separate targets for the simulator and device. The separate targets duplicate most information, and only differ in the static libraries included. So if you are getting a Mach-O linker error what it means is that xcode is having trouble linking to one of the libraries for that target device; as a result of which compilation fails.
Now your definitions -
Executable - compiled machine targeted program ready to be run in binary format.
Dynamic Library - are linked during runtime -- a program with references to a dynamic library will load and link with the library when it starts up (or on demand).
Bundles - and bundle identifier let iOS and OSX recognise any updates to your app. It gives it a unique presence in the app.
Static Library - files are linked at build time. code is copied into the executable. Code in the library that isn't referenced by your program is removed. A program with only static libraries doesn't have any dependencies during runtime.
Relocatable Object File - is another word for a dynamic library. When you link with a dynamic library, the addresses of the functions contained within are computed, based on where the library is loaded in memory. They are "relocatable" because the addresses of the contained functions are not determined at link time. (In a static library, the addresses are computed during link time.)
As per apple documentation,
Check this for more details Building Mach-O Files and Xcode Build Setting Reference

Resources