ライブラリの import と link について理解する
今回は iOS 開発における Library および Framework のインポートおよび、リンクの仕組みについて学んだことをまとめていきたいと思います。
これらのことを学ぶことで、今まで Xcode が暗黙的に行っていた処理がどのようになっているのかが分かり、ライブラリを使用する際に Error が発生した際にも適切に対応することができるようになるかと思います✍️
Import とは?
Import とは、ライブラリをプロジェクトのコードベースで利用可能にするための言語機能で、それぞれのライブラリが公開しているシンボルを参照できるようにします。各ファイルはコンパイルする時点で解決され、ruby
や js
などのインポートとは違い、ビルド時点で全て解決されている必要があります。
Link とは?
Link とは、プロジェクトのソースコードをコンパイルして生成されたオブジェクトファイルや外部ライブラリなどを全て連結(リンク)して実行ファイルまたは、ライブラリを生成する機能で、リンカ が行います。これらはソースコードが全てコンパイルされた後に実行され、シンボルが全て解決されます。
Xcode での設定
Framewoks, Libraries, and Embedded Content
に、Framework を追加した際に Xcode 側では下記のようなことが行われます。
FRAME_WORK_SEARCH_PATHS
に Framework があるディレクトリの親ディレクトリを追加するLink Binary With Libraries
に Framework を追加する- Build Phase の
Embed Frameworks
に Framework を追加して Framework を Application バンドルにコピーする
FRAME_WORK_SEARCH_PATHS
を設定する
FRAME_WORK_SEARCH_PATHS
はライブラリのインポートに必要な Module を見つけてソースコードで利用可能にするために必要な Path ですが、ここについてはまた別の記事でまとめようかと思います。
Link Binary With Libraries
に Framework を追加する
Link Binary With Libraries
に Framework が追加されることで、コンパイル後にリンカがリンクを正常に行うことができるようになります。このことから、Link Binary With Libraries
から Framework の設定を削除した場合、リンクエラーになるかと考えられますが、Swift の Automatic Linking
という機能によって、ライブラリを Import した時点で、コンパイルが自動でライブラリのリンクをはるので、Error にはならずに Build が完了します。また、これらのコンパイルオプションは Build Settings > Linking > Other Linker Flags
から手動で渡すこともできます。
Embed Frameworks
に Framework を追加する
Embed Frameworks
に Framework が追加されることで、システムがアプリケーションバンドルからライブラリへのリンクをすることができるようになります。つまり、dynamic framework・library のような動的リンクが必要なものは、この設定がないとランタイムにライブラリへのリンクをすることができずに、一度は見たことがあるであろう下記のような Runtime Error を引き起こします。反対に、ビルド時にリンクが完了しているような static framework・library などの場合は、Embed Frameworks
の設定がなくても正常に動作することが可能です。
dyld: Library not loaded: @rpath/RxSwift.framework/RxSwift Referenced from: /private/var/containers/Bundle/Application/C70206BC-1D89-4AFF-A02B-8423C521AA64/MyApp.app/MyApp Reason: image not found
これらビルド時にアプリケーションバンドル の Frameworks にコピーされた Framework を確認するには、プロジェクトの Products
ディレクトリの XX.app
を右クリックし Show in Finder を選択します。Finder で表示されたコンテンツを右クリックして パッケージの内容を表示 を選択します。その中の Frameworks ディレクトリの中身がバンドルされた Framework になります。
参考
Swiftにおけるインポートとリンクの仕組みを探る - Speaker Deck