Static library、Dynamic library、Framework、XCFrameworkの違いなど

### Library と Framework

* Library
    * Static library (*.a)
    * Dynamic library (*.dylib)
* Framework
    * Static framework (*.framework)
    * Dynamic framework (*.framework)

|                 | with Bundle       | without Bundle  |
|:---------------:|:-----------------:|:---------------:|
| **Static Linking**  | Static framework  | Static library  |
| **Dynamic Linking** | Dynamic framework | Dynamic library |

### Universal framework と XCFramework

* Universal-architecture Framework
    * Universal framework (*.framework)
        * `$ xcodebuild` で バイナリ(framework or library)を複数個作成する。
        * `$ lipo` でひとつの *.frameworkファイルにまとめる
        * ※但し、同じアーキテクチャのバイナリを一つの*.frameworkにまとめることは出来ない
            * 例: iPhone/iPad (arm64)とM1 Mac iOS Simulator (arm64)をまとめるにはXCFramework対応が必須になる
    * XCFramework (*.xcframework) : Xcode 11.0 - Swift 5.1 で追加された
        * `$ xcodebuild` で バイナリ(framework or library)を複数個作成する。
        * `$ xcodebuild -create-xcframework` でひとつの *.xcframeworkファイルにまとめる

<table>
  <tbody>
    <tr>
      <td><b>Single Architecture</b></td>
      <td>Static library</td>
      <td>Dynamic library</td>
      <td>Static framework</td>
      <td>Dynamic framework</td>
    </tr>
    <tr>
      <td rowspan=2><b>Universal Architecture</b></td>
      <td colspan=4>Universal framework</td>
    </tr>
    <tr>
      <td colspan=4>XCFramework</td>
    </tr>
  </tbody>
</table>


## フレームワークに関連する技術
* Embedded Framework
* Umbrella Framework
* Modular と Module Map (*.modulemap)

## StaticとDynamicの違い。 LibraryとFrameworkの違い。 Embedded、Umbrella、Modularについて

> **動的および静的ライブラリ**
>
> まず第一にライブラリは、1つ以上のアーキテクチャ用にコンパイルされたリソースとコード自体の集まりです。
> 
> 動的および静的ライブラリとは何かについて簡単に触れ、主な違いを明確にしましょう。静的または動的という用語は、コンパイル済みコードがターゲットアプリケーションによって参照される方法を指します。
> 
> 静的ライブラリ（* .a）の場合、アプリケーションが使用するコードは、コンパイル時に静的リンカによって生成された実行可能ファイルにコピーされます。  
> 
> 動的ライブラリ（* .dylib）は、実行時にアプリの実行可能ファイルとリンクされますが、そこにコピーされないという点で静的ライブラリとは異なります。その結果、実行可能ファイルは小さくなり、コードは必要なときにのみロードされるため、起動時間は通常速くなります。
> 
> **動的および静的フレームワーク**
>
> フレームワークでは、最初に[Bundle](https://developer.apple.com/documentation/foundation/bundle)の概念を理解する必要があります（フレームワークは特定の種類のバンドルです）。バンドルには、内部のサブディレクトリとファイルディレクトリです。iOSでは、バンドルは関連ファイルを1つのパッケージにまとめて出荷するのに役立ちます。たとえば、画像、nib、コンパイル済みコードなどです。システムはそれを1つのファイルとして扱い、その内部構造を知らなくてもバンドルリソースにアクセスできます。
> 
> ライブラリは、追加のリソース（ヘッダー、ローカライゼーションファイル、画像、ドキュメントおよび実装例）も有することが出来ます。これらすべてを1つのバンドルにまとめることができます - そしてこの名前はフレームワークです。
> 
> 静的フレームワークには、そのリソースとともにパッケージ化された静的ライブラリが含まれています。動的フレームワークには、動的ライブラリとそのリソースが含まれています。それに加えて動的フレームワークは、同じフレームワーク内に、同じ動的ライブラリの異なるバージョンを含むことが出来るので便利です。
> 
> **Embedded、Umbrella、Modularフレームワークとは何でしょうか**
>
> 私たちは内部にリソースを持つフレームワーク（XIBや画像など）を出荷していますが、Xcodeはそれでもいくつかを無視します。フレームワークを埋め込むことで、これらのリソースファイルを使用できます。フレームワークを埋め込むには、Xcodeでターゲットをクリックして、[「フレームワークの埋め込み」セクションにフレームワークを追加するだけです](https://developer.apple.com/library/archive/technotes/tn2435/_index.html#//apple_ref/doc/uid/DTS40017543-CH1-EMBED_SECTION)。
> 
Umbrellaフレームワークの主な目的は、[開発者からのフレームワークとの間の複雑な依存関係を隠す](https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPFrameworks/Concepts/FrameworkAnatomy.html#//apple_ref/doc/uid/20002253-99314)ことです。それはあなたが1つのフレームワークとしていくつかのフレームワークを出荷することを可能にし、ターゲットアプリケーションにいくつかのヘッダだけを公開します。Umbrellaフレームワークを構築するには、Umbrella headerを含める必要があります。これは選択したインポートを含む、通常のヘッダファイルに他なりません。これらはフレームワークユーザーにとって重要です。
>
> フレームワークモジュラーを呼び出せるようにするには、モジュールのマップを含める必要があります。
> 
```swift
framework module ModularFramework {
   module Module1 {
       header "File1.h"
   }
   module Module2 {
       header "File2.h"
   }
}
```
> 
> その後、これで必要なモジュールだけをインポートすることができます。
> 
```
import ModularFramework.Module1
Import ModularFramework.Module2
```
> 
> [Overview: iOS Static and Dynamic Frameworks and Libraries](https://www.runtastic.com/blog/en/frameworks-ios/)

* [Pod Authors Guide to CocoaPods Frameworks - CocoaPods Blog](http://blog.cocoapods.org/Pod-Authors-Guide-to-CocoaPods-Frameworks/) (2014年12月25日)
    * [CocoaPods 1.5.0 — Swift Static Libraries - CocoaPods Blog](http://blog.cocoapods.org/CocoaPods-1.5.0/) (2018年4月4日)
* [All about linking libraries | try! Swift Tokyo 2019 2-11 - niwatakoのはてなブログ](http://niwatako.hatenablog.jp/entry/2019/03/22/153440)
* [【Xcode】Embedded Binaries と Linked Frameworks and Libraries の違いについて - Qiita](https://qiita.com/rockname/items/bdf932bc6758d8820141)
* [[iOSDC Japan 2019 リポート]「ライブラリのインポートとリンクの仕組み完全解説」というセッションを聞いてきました ｜ Developers.IO](https://dev.classmethod.jp/smartphone/iphone/iosdc2019-report-library-link-import/)

---

#### Static と Dynamic の指定方法

> **Mach-O Type (MACH_O_TYPE)**
> 
> This setting determines the format of the produced binary and how it can be linked when building other binaries. For information on binary types, see [Building Mach-O Files](https://developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/MachOTopics/1-Articles/building_files.html#//apple_ref/doc/uid/TP40001828-SW1) in [Mach-O Programming Topics](https://developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/MachOTopics/0-Introduction/introduction.html).
> 
> - *Executable:* Executables and standalone binaries and cannot be linked. `mh_execute`
> - *Dynamic Library:* Dynamic libraries are linked at build time and loaded automatically when needed. `mh_dylib`
> - *Bundle:* Bundle libraries are loaded explicitly at run time. `mh_bundle`
> - *Static Library:* Static libraries are linked at build time and loaded at execution time. `staticlib`
> - *Relocatable Object File:* Object files are single-module files that are linked at build time. `mh_object`
> 
> [Build settings reference - Xcode Help](https://help.apple.com/xcode/mac/11.0/index.html?localePath=en.lproj#/itcaec37c2a6)

---

## lipo とは

> lipoは、シングルアーキテクチャーファイルからユニバーサルファイルを作成し、シングルアーキテクチャーファイルを抽出するための多数のコマンドをサポートしています。

```
$ man lipo

NAME
       lipo - create or operate on universal files

SYNOPSIS
       lipo input_file command [option...]

DESCRIPTION
       The  lipo  tool  creates or operates on ``universal'' (multi-architecture) files. Generally, lipo reads a single input file
       and writes to a single output file, although some commands and options accept multiple input files.  lipo  will  only  ever
       write to a single output file, and input files are never modified in place.

       lipo supports a number of commands for creating universal files from single-architecture files, extracting single-architec-
       ture files from universal files, and displaying architecture information.  lipo can only perform  one  such  command  at  a
       time, although some command flags may appear more than once. Some commands support additional options that can be used with
       that command. In addition, there are global options that are supported by multiple commands.

       The arch_type arguments may be any of the supported architecture names listed in the man page arch(3).
```

---

## Linking とは

> TODO: If I feel like it

### Auto Linkin  について

- [ios - フレームワークをXCodeプロジェクトにリンクする必要はもうありませんか？](https://python5.com/q/pvcholxm)

Link Frameworks Automatically

### Weak Linking について

- [Frameworks and Weak Linking](https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPFrameworks/Concepts/WeakLinking.html)

#### Weak Linking の指定方法

- [iOS 13にしかないフレームワークを使用したアプリをiOS 12以下でも動くようにするには - 24/7 twenty-four seven](https://blog.kishikawakatsumi.com/entry/2019/06/18/152554)

## Framework とは

> A framework is a hierarchical directory that encapsulates a dynamic library, header files, and resources, such as storyboards, image files, and localized strings, into a single package. Apps using frameworks need to embed the framework in the app's bundle.
> 
> フレームワークは、動的ライブラリ、ヘッダーファイル及びストーリーボード、画像ファイル、ローカライズされた文字列などのリソースを1つのパッケージにカプセル化した階層ディレクトリです。フレームワークを使用するアプリは、フレームワークをアプリのバンドルに埋め込む必要があります。
> 
> [Technical Note TN2435: Embedding Frameworks In An App](https://developer.apple.com/library/archive/technotes/tn2435/_index.html)

## Universal framework とは

> TODO: If I feel like it


##### Universal Framework の作成方法

* [【Swift】Frameworkを作成する - Qiita](https://qiita.com/wai21/items/3a2a7a7170ab9c5c1952)

##### 既知の問題

* Xcode 10.0
    * [Xcode 10でのUniversal frameworkビルドエラーについて - Qiita](https://qiita.com/SCENEE/items/aeea41f160c3833d1b81)
* Xcode 10.2
    * 下記 (48635615)

> If you’re building a framework containing Swift code and using lipo to create a binary that supports both device and simulator platforms, you must also combine the generated Framework-Swift.h headers for each platform to create a header that supports both device and simulator platforms. (48635615)
> 
> Swiftコードを含むフレームワークを構築し、lipoを使用してデバイスとシミュレータの両方のプラットフォームをサポートするバイナリを作成する場合は、各プラットフォーム用に生成されたFramework-Swift.hヘッダを組み合わせてデバイスとシミュレータの両方をサポートするヘッダを作成する必要もあります。 プラットフォーム （48635615）
> 
> [Xcode 10.2 Release Notes | Apple Developer Documentation](https://developer.apple.com/documentation/xcode_release_notes/xcode_10_2_release_notes)

## XCFramework とは

> XCFrameworks make it possible to bundle a binary framework or library for multiple platforms —including iOS devices, iOS simulators, and UIKit for Mac — into a single distributable .xcframework bundle that your developers can use within their own applications. An .xcframework bundle can be added to an Xcode target’s Link Libraries phase and Xcode uses the right platform’s version of the included framework or library at build time. Creation of XCFrameworks is supported from the command line using xcodebuild -create-xcframework. Frameworks or libraries bundled in an XCFramework should be built with the Build Libraries for Distribution build setting set to YES. (49948269)
> 
> XCFrameworksを使用すると、iOSデバイス、iOSシミュレータ、およびUIKit for Macを含む複数のプラットフォーム用のバイナリフレームワークまたはライブラリを、開発者が独自のアプリケーション内で使用できる単一の配布可能な.xcframeworkバンドルにまとめることができます。 .xcframeworkバンドルをXcodeターゲットのLink Librariesフェーズに追加することができ、Xcodeはビルド時に適切なプラットフォームのバージョンの含まれているフレームワークまたはライブラリを使用します。 XCFrameworksの作成は、xcodebuild -create-xcframeworkを使用してコマンドラインからサポートされます。 XCFrameworkにバンドルされているフレームワークまたはライブラリーは、「配布用ライブラリーのビルド」ビルド設定を「はい」に設定してビルドする必要があります。 （49948269）
> 
> [Xcode 11 Beta 3 Release Notes | Apple Developer Documentation](https://developer.apple.com/documentation/xcode_release_notes/xcode_11_beta_3_release_notes)

* [Binary Frameworks in Swift - WWDC 2019 - Videos - Apple Developer](https://developer.apple.com/videos/play/wwdc2019/416/)
    * [WWDC Recap - Binary Framework in Swift - Speaker Deck](https://speakerdeck.com/kishikawakatsumi/wwdc-recap-binary-framework-in-swift)

#### ABI Stability (Swift 5.0+, Xcode 10.2+)

* [Swift.org - ABI Stability and More](https://swift.org/blog/abi-stability-and-more/) (2019年2月7日)
* [Swift.org - Evolving Swift On Apple Platforms After ABI Stability](https://swift.org/blog/abi-stability-and-apple/) (2019年2月11日)

#### Module Stability (Swift 5.1+, Xcode 11.0+)

* [Swift.org - ABI Stability and More](https://swift.org/blog/abi-stability-and-more/#module-stability) (2019年2月7日)
    * [Plan for module stability - Development / Compiler - Swift Forums](https://forums.swift.org/t/plan-for-module-stability/14551/)
    * [Update on Module Stability and Module Interface Files - Development / Compiler - Swift Forums](https://forums.swift.org/t/update-on-module-stability-and-module-interface-files/23337)

##### Embedded framework の作成方法

* TODO: If I feel like it

##### Umbrella framework の作成方法

* TODO: If I feel like it

#### バイナリ情報を確認する

```bash
$ file Sample.framework/Sample 
Sample.framework/Sample: Mach-O universal binary with 5 architectures: [x86_64:Mach-O 64-bit dynamically linked shared library x86_64] [arm64]
Sample.framework/Sample (for architecture x86_64):	Mach-O 64-bit dynamically linked shared library x86_64
Sample.framework/Sample (for architecture i386):	Mach-O dynamically linked shared library i386
Sample.framework/Sample (for architecture armv7):	Mach-O dynamically linked shared library arm_v7
Sample.framework/Sample (for architecture armv7s):	Mach-O dynamically linked shared library arm_v7s
Sample.framework/Sample (for architecture arm64):	Mach-O 64-bit dynamically linked shared library arm64
```
```bash
$ lipo -info Sample.framework/Sample 
Architectures in the fat file: Sample.framework/Sample are: x86_64 i386 armv7 armv7s arm64
```
```bash
$ otool -lv ./build/Sample.xcframework/ios-arm64/iOS.framework/iOS 
./build/Sample.xcframework/ios-arm64/iOS.framework/iOS | grep -A5 LC_BUILD
```