Thursday, May 18, 2017

[iOS] Static libraries vs Dynamic Libraries

Linking Libraries

The act of linking libraries is a form of code dependency management. When any app is run, its executable code is loaded into memory. Additionally, any code libraries that it depends on are also loaded into memory. There are two type of linking: static, and dynamic. Both offer different benefits to the developer and should be used according to these benefits. This blog post will cover the benefits offered by each and then explain the basics of how to create and link your own libraries on OS X and iOS.

Dynamic Linking

Dynamic linking is most commonly used on OS X and iOS. When dynamic libraries are linked, none of the library's code is included directly into the linked target. Instead, the libraries are loaded into memory at runtime prior to having symbols getting resolved. 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. For more information on overview and design, see Apple's Dynamic Library Programming Topics.

• Libraries

Dynamic libraries are a type of Mach-O binary1 that is loaded at launch or runtime of an application. Since the executable code in a dynamic library isn't statically linked into target executable, this affords some benefits when needing to reuse the same code. For example, if you have an application and a daemon or extension that needs to make use of the same code, that code only has to exist in a single location -- the dynamic library, rather than in both the executable's binary and the daemon's binary. Since dynamic libraries are loaded at runtime, the library is responsible for telling the linker what additional code is needed. This removes the burden of managing what all of the code that you use needs to operate.

• How to verify it's static or dynamic

To use the following command line:
$ otool -L xx.a
Dynamic result:
@rpath/PWCore.framework/PWCore (compatibility version 1.0.0, current version 1.0.0)
/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 307.4.0)
/usr/lib/libicucore.A.dylib (compatibility version 1.0.0, current version 57.1.0)
/usr/lib/libsqlite3.dylib (compatibility version 9.0.0, current version 253.0.0)
/usr/lib/libxml2.2.dylib (compatibility version 10.0.0, current version 10.9.0)
/usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.8)
/System/Library/Frameworks/CFNetwork.framework/CFNetwork (compatibility version 1.0.0, current version 808.2.16)
Static result: 
Archive : XXCore
XXCore(XXAFURLRequestSerialization.o):
XXCore(XXAFHTTPSessionManager.o):
XXCore(XXCore.o):
XXCore(XXBundleManager.o):
XXCore(XXBluetoothHelper.o):
XXCore(XXErrors.o):

• Useful commands

Identify library files:
$ lipo -info libfat.a 
Build a new dynamic library:
$ libtool -dynamic *.o -o libfoo_dynamic-x86_64.dylib -framework CoreFoundation -lSystem