Be taught every part about Swift modules, libraries, packages, closed supply frameworks, command line instruments and extra.
Fundamental definitions
Initially you need to have a transparent understanding in regards to the primary phrases. Should you already know what’s the distinction between a module, package deal, library or framework you possibly can skip this part. Nevertheless for those who nonetheless have some blended emotions about this stuff, please learn forward, you received’t remorse it. 😉
Package deal
A package deal consists of Swift supply information and a manifest file.
A package deal is a set of Swift supply information. In case you are utilizing Swift Package deal Supervisor you even have to supply a manifest file in an effort to make an actual package deal. If you wish to study extra about this instrument, you need to examine my Swift Package deal Supervisor tutorial.
Instance: that is your package deal:
Sources
my-source-file.swift
Package deal.swift
You too can try the open sourced swift-corelibs-foundation package deal by Apple, which is used to construct the Basis framework for Swift.
Library
Library is a packaged assortment of object information that program can hyperlink in opposition to.
So a library is a bunch of compiled code. You possibly can create two sorts of libraries:
From a extremely easy perspective the one distinction between them is the strategy of “integrating” aka. linking them into your venture. Earlier than I let you know extra about this course of, first we must always discuss object information.
Mach-O file format
To create applications, builders convert supply code to object information. The thing information are then packaged into executable code or static libraries.
Once you’re compiling the supply information you’re mainly making object information, utilizing the Mach-O (MachObject) file format. These information are the core constructing blocks of your functions, frameworks, and libraries (each dynamic and static).
Linking libraries
Linking refers back to the creation of a single executable file from a number of object information.
In different phrases:
After the compiler has created all the article information, one other program is named to bundle them into an executable program file. That program is named a linker and the method of bundling them into the executable is named linking.
Linking is simply combining all of your object information into an executable and resolving all of the externals, so the system will be capable of name all of the features contained in the binary.
Static linking
The supply code of the library is actually going to be copied into the appliance’s supply. It will end in an enormous executable, it’ll take extra time to load, so the binary can have a slower startup time. Oh, did I point out that if you’re making an attempt to hyperlink the identical library greater than as soon as, the method will fail due to duplicated symbols?

This technique has benefits as nicely, for instance the executable will all the time include the proper model of the library, and solely these elements shall be copied into the principle utility which can be actually used, so that you don’t should load the entire stuff, nevertheless it looks like dynamic linking goes to be higher in some instances.
Dynamic linking
Dynamic libraries aren’t embedded into the supply of the binary, they’re loaded at runtime. Because of this apps may be smaller and startup time can considerably be quicker due to the light-weight binary information. As a free of charge dynamic libraries may be shared with a number of executables to allow them to have decrease reminiscence footprints. That’s why typically they’re being referred as shared libraries.

In fact if the dynamic library will not be out there – or it’s out there however their model is incompatible – your utility received’t run or it’ll crash. Alternatively this may be a bonus, as a result of the creator of the dynamic library can ship fixes and your app can profit from these, with out recompilation.
Happily system libraries like UIKit are all the time out there, so that you don’t have to fret an excessive amount of about this problem…
Framework
A framework is a hierarchical listing that encapsulates shared sources, comparable to a dynamic shared library, nib information, picture information, localized strings, header information, and reference documentation in a single package deal.
So let’s make this easy: frameworks are static or dynamic libraries packed right into a bundle with some additional belongings, meta description for versioning and extra. UIKit is a framework which wants picture belongings to show among the UI parts, additionally it has a model description, by the best way the model of UIKit is identical because the model of iOS.
Module
Swift organizes code into modules. Every module specifies a namespace and enforces entry controls on which elements of that code can be utilized outdoors of the module.
With the import key phrase you’re actually importing exterior modules into your sorce. In Swift you’re all the time utilizing frameworks as modules, however let’s return in time for some time to know why we would have liked modules in any respect.
import UIKit
import my-awesome-module
Earlier than modules you needed to import framework headers instantly into your code and also you additionally needed to hyperlink manually the framework’s binary inside Xcode. The #import macro actually copy-pasted the entire resolved dependency construction into your code, and the compiler did the work on that vast supply file.
It was a fragile system, issues might go incorrect with macro definitions, you can simply break different frameworks. That was the rationale for outlining prefixed uppercased very lengthy macro names like: NS_MYSUPERLONGMACRONAME… 😒
There was an different problem: the copy-pasting resulted in non-scalable compile instances. So as to clear up this, precompiled header (PCH) information have been born, however that was solely a partial resolution, as a result of they polluted the namespace (you recognize for those who import UIKit in a PCH file it will get out there in in every single place), and no-one actually maintained them.
Modules and module maps
The holy grail was already there, with the assistance of module maps (defining what sort of headers are a part of a module and what’s the binary that has the implementation) we’ve received encapsulated modular frameworks. 🎉 They’re individually compiled as soon as, the header information are defining the interface (API), and the (routinely) linked dylib file accommodates the implementation. Hurray, no have to parse framework headers throughout compilation time (scalability), so native macro definitions received’t break something. Modules can include submodules (inheritance), and also you don’t should hyperlink them explicitly inside your (Xcode) venture, as a result of the .modulemap file has all the data that the construct system wants.
Finish of the story, now you recognize what occurs below the hood, while you import Basis or import UIKit.
Now that you recognize the logic behind the entire dynamic modular framework system, we must always begin inspecting the instruments that make this infrastructure doable.
At all times learn the person pages, aka. RTFM! Should you don’t prefer to learn that a lot, you possibly can obtain the instance venture from GitLab and open the makefiles for the essence. There shall be 3 predominant classes: C, Swift and Xcode venture examples.
clang
the Clang C, C++, and Goal-C compiler
Clang is a compiler frontend for C languages (C, C++, Goal-C). When you have ever tried to compiled C code with gcc throughout your college years, you possibly can think about that clang is kind of the identical as gcc, however these days it may well do much more.
clang -c predominant.c -o predominant.o #compiles a C supply file
LLVM: compiler backend system, which may compile and optimize the intermediate illustration (IR) code generated by clang or the Swift compiler for instance. It’s language unbiased, and it may well accomplish that many issues that would match right into a guide, however for now let’s say that LLVM is making the ultimate machine code in your executable.
swiftc
The Swift compiler, there is no such thing as a guide entry for this factor, however don’t fear, simply fireplace up swiftc -h and see what can provide to you.
swiftc predominant.swift #compiles a Swift supply file
As you possibly can see this instrument is what really can compile the Swift supply information into Mach-O’s or ultimate executables. There’s a brief instance within the connected repository, you need to examine on that for those who’d prefer to study extra in regards to the Swift compiler.
ar
The ar utility creates and maintains teams of information mixed into an archive. As soon as an archive has been created, new information may be added and current information may be extracted, deleted, or changed.
So, in a nutshell you possibly can zip Mach-O information into one file.
ar -rcs myLibrary.a *.o
With the assistance of ar you have been in a position to create static library information, however these days libtool have the identical performance and much more.
ranlib
ranlib generates an index to the contents of an archive and shops it within the archive. The index lists every image outlined by a member of an archive that could be a relocatable object file.
ranlib can create an index file contained in the static lib, so issues are going to be quicker while you’re about to make use of your library.
ranlib myLibrary.a
So ranlib & ar are instruments for sustaining static libraries, often ar takes care of the indexing, and also you don’t should run ranlib anymore. Nevertheless there’s a higher possibility for managing static (and dynamic) libraries that you need to study…
libtool
create libraries
With libtool you possibly can create dynamically linked libraries, or statically linked (archive) libraries. This instrument with the -static possibility is meant to switch ar & ranlib.
libtool -static *.o -o myLibrary.a
These days libtool is the principle possibility for build up library information, you need to positively study this instrument for those who’re into the subject. You possibly can examine the instance venture’s Makefile for more information, or as often you possibly can learn the manuals (man libtool). 😉
ld
The ld command combines a number of object information and libraries, resolves references, and produces an ouput file. ld can produce a ultimate linked picture (executable, dylib, or bundle).
Let’s make it easy: that is the linker instrument.
ld predominant.o -lSystem -LmyLibLocation -lmyLibrary -o MyApp
It could possibly hyperlink a number of information right into a single entity, so from the Mach-O’s you’ll be capable of make an executable binary. Linking is important, as a result of the system must resolve the addresses of every technique from the linked libraries. In different phrases, the executable will be capable of run and all your features shall be out there for calling. 📱
nm
show identify record (image desk)
With nm you possibly can see what symbols are inside a file.
nm myLibrary.a
# 0000000000001000 A __mh_execute_header
# U _factorial
# 0000000000001f50 T _main
# U _printf
# U dyld_stub_binder
As you possibly can see from the output, some form of reminiscence addresses are related for a few of symbols. People who have addresses are literally resolved, all of the others are coming from different libraries (they’re not resolved but). So which means that they’ll be resolved at runtime. The opposite possibility is that it’s a must to hyperlink them. 😅
otool
object file displaying instrument
With otool you possibly can look at the contents of Mach-O information or libraries.
otool -L myLibrary.a
otool -tV myLibrary.a
For instance you possibly can record the linked libraries, or see the disassembled textual content contents of the file. It’s a extremely useful instrument for those who’re accustomed to the Mach-O file format, additionally good one to make use of for reverse-engineer an current utility.
lipo
create or function on common information
With the assistance of the lipo instrument you possibly can create common (multi-architecture) information. Often this instrument is used for creating common frameworks.
lipo -create -output myFramework.framework units.framework simulator.framework
Think about the next situation: you construct your sources each for arm7 and i386. On an actual gadget you’d have to ship the arm7 model, however for the iOS simulator you’ll want the i386 one. With the assistance of lipo you possibly can mix these architectures into one, and ship that framework, so the top consumer don’t have to fret about this problem anymore.
Learn on the article to see the way it’s executed. 👇
These instruments may be invoked from the command line as nicely, however they’re way more associated to Xcode than those earlier than. Let’s have a fast walk-through.
xcode-select
Manages the energetic developer listing for Xcode and BSD instruments. When you have a number of variations of Xcode in your machine this instrument can simply change between the developer instruments offered by the induvidual variations.
xcode-select --switch path/to/Xcode.app
xcrun
Run or find improvement instruments and properties. With xcrun you possibly can mainly run something that you could handle from Xcode.
xcrun simctl record #record of simulators
codesign
Create and manipulate code signatures
It could possibly signal your utility with the correct signature. Often this factor failed while you have been making an attempt to signal your app earlier than computerized signing was launched.
codesign -s "Your Firm, Inc." /path/to/MyApp.app
codesign -v /path/to/MyApp.app
xcodebuild
construct Xcode initiatives and workspaces
That’s it. It’ll parse the Xcode venture or workspace file and executes the suitable buid instructions primarily based on it.
xcodebuild -project Instance.xcodeproj -target Instance
xcodebuild -list
xcodebuild -showsdks
FAT frameworks
The right way to make a closed supply common FATtened (multi-architecture) Swift framework for iOS?
So we’re right here, the entire article was made for studying the logic behind this tutorial.
Initially, I don’t wish to reinvent the wheel, as a result of there’s a superbly written article that you need to learn. Nevertheless, I’d like to present you some extra detailed rationalization and a little bit modification for the scripts.
Skinny vs. FAT frameworks
Skinny frameworks accommodates compiled code for just one structure. FAT frameworks however are containing “slices” for a number of architectures. Architectures are mainly referred as slices, so for instance the i386 or arm7 slice.
This implies, for those who compile a framework just for i386 and x86_64 architectures, it would work solely on the simulator and horribly fail on actual units. So if you wish to construct a really common framework, it’s a must to compile for ALL the prevailing architectures.
Constructing a FAT framework
I’ve a excellent news for you. You simply want one little construct section script and an combination goal in an effort to construct a multi-architecture framework. Right here it’s, shamelessly ripped off from the supply article, with some additional adjustments… 😁
set -e
BUILD_PATH="${SRCROOT}/construct"
DEPLOYMENT_PATH="${SRCROOT}"
TARGET_NAME="Console-iOS"
FRAMEWORK_NAME="Console"
FRAMEWORK="${FRAMEWORK_NAME}.framework"
FRAMEWORK_PATH="${DEPLOYMENT_PATH}/${FRAMEWORK}"
# clear the construct folder
if [ -d "${BUILD_PATH}" ]; then
rm -rf "${BUILD_PATH}"
fi
# construct the framework for each structure utilizing xcodebuild
xcodebuild -target "${TARGET_NAME}" -configuration Launch
-arch arm64 -arch armv7 -arch armv7s
only_active_arch=no defines_module=sure -sdk "iphoneos"
xcodebuild -target "${TARGET_NAME}" -configuration Launch
-arch x86_64 -arch i386
only_active_arch=no defines_module=sure -sdk "iphonesimulator"
# take away earlier model from the deployment path
if [ -d "${FRAMEWORK_PATH}" ]; then
rm -rf "${FRAMEWORK_PATH}"
fi
# copy freshly constructed model to the deployment path
cp -r "${BUILD_PATH}/Launch-iphoneos/${FRAMEWORK}" "${FRAMEWORK_PATH}"
# merge all of the slices and create the fats framework
lipo -create -output "${FRAMEWORK_PATH}/${FRAMEWORK_NAME}"
"${BUILD_PATH}/Launch-iphoneos/${FRAMEWORK}/${FRAMEWORK_NAME}"
"${BUILD_PATH}/Launch-iphonesimulator/${FRAMEWORK}/${FRAMEWORK_NAME}"
# copy Swift module mappings for the simulator
cp -r "${BUILD_PATH}/Launch-iphonesimulator/${FRAMEWORK}/Modules/${FRAMEWORK_NAME}.swiftmodule/"
"${FRAMEWORK_PATH}/Modules/${FRAMEWORK_NAME}.swiftmodule"
# clear up the construct folder once more
if [ -d "${BUILD_PATH}" ]; then
rm -rf "${BUILD_PATH}"
fi
You possibly can all the time look at the created framework with the lipo instrument.
lipo -info Console.framework/Console
#Architectures within the fats file: Console.framework/Console are: x86_64 i386 armv7 armv7s arm64
Utilization
You simply should embed your model new framework into the venture that you simply’d like to make use of and set some paths. That’s it. Nearly…

Transport to the App Retailer
There is just one problem with fats architectures. They include slices for the simulator as nicely. If you wish to submit your app to the app retailer, it’s a must to reduce off the simulator associated codebase from the framework. The rationale behind that is that no precise actual gadget requires this chunk of code, so why submit it, proper?
APP_PATH="${TARGET_BUILD_DIR}/${WRAPPER_NAME}"
# take away unused architectures from embedded frameworks
discover "$APP_PATH" -name '*.framework' -type d | whereas learn -r FRAMEWORK
do
FRAMEWORK_EXECUTABLE_NAME=$(defaults learn "$FRAMEWORK/Data.plist" CFBundleExecutable)
FRAMEWORK_EXECUTABLE_PATH="$FRAMEWORK/$FRAMEWORK_EXECUTABLE_NAME"
echo "Executable is $FRAMEWORK_EXECUTABLE_PATH"
EXTRACTED_ARCHS=()
for ARCH in $ARCHS
do
echo "Extracting $ARCH from $FRAMEWORK_EXECUTABLE_NAME"
lipo -extract "$ARCH" "$FRAMEWORK_EXECUTABLE_PATH" -o "$FRAMEWORK_EXECUTABLE_PATH-$ARCH"
EXTRACTED_ARCHS+=("$FRAMEWORK_EXECUTABLE_PATH-$ARCH")
executed
echo "Merging extracted architectures: ${ARCHS}"
lipo -o "$FRAMEWORK_EXECUTABLE_PATH-merged" -create "${EXTRACTED_ARCHS[@]}"
rm "${EXTRACTED_ARCHS[@]}"
echo "Changing authentic executable with thinned model"
rm "$FRAMEWORK_EXECUTABLE_PATH"
mv "$FRAMEWORK_EXECUTABLE_PATH-merged" "$FRAMEWORK_EXECUTABLE_PATH"
executed
This little script will take away all of the pointless slices from the framework, so that you’ll be capable of submit your app by way of iTunesConnect, with none points. (ha-ha-ha. 😅)
NOTE: You need to add this final script to your utility’s construct phases.
If you wish to get accustomed to the instruments behind the scenes, this text will enable you to with the fundamentals. I couldn’t discover one thing like this however I needed to dig deeper into the subject, so I made one. I hope you loved the article. 😉

