はじめに
こちらの記事は 前編 の続編となります。事前にこちらの記事もご覧ください。
今回もどこかで発表したわけでもないでも関わらずスライドを多用して説明していきますので、最後まで見ていただけると嬉しいです!
前編の振り返り
前回はこのような考察でまとめていました。
詳細は「SwiftUI 導入で LLVM のドキュメント読む羽目になった話」を御覧ください。
前編の訂正
まずは訂正をさせてください。エラー文の解釈を間違えておりました。
実はここ、かなり重要なことを教えてくれています。カバレッジを取得するためのランタイムライブラリが呼び出せなかったと言ってくれていました。
Linker flags に -fprofile-instr-generate
を追加すると動く理由
早速ではありますが、前回からハッキリしなかった理由について解説していきます。
説明の都合上、理想の挙動から説明していくことにします。
Swift コンパイラである swiftc に対して -fprofile-instr-generate
を指定してアプリのソースコードをビルドすることによって、カバレッジ情報を取得するための処理がアプリのコードに挿入されます。この「カバレッジ情報を取得する処理」というのは、コードカバレッジランタイムライブラリ内の関数呼び出しがメインです。
先程の図では点線の矢印で表現していましたが、これには理由があります。 swiftc によるコンパイル時には 呼び出し処理 が追加されるだけで実際の処理が含まれないからです。
なので、 Linker に対して「コードカバレッジランタイムライブラリのリンク」を命じなければならないのです。したがって、 Linker に対して渡される -fprofile-instr-generate
はコードカバレッジランタイムライブラリとリンクさせるためのものだったのです。
先程、 Linker に対して -fprofile-instr-generate
を指定すると説明しましたが、本来これは Xcode が自動で行っているはずです。その証拠に、 XcodePreviews 以外ではカバレッジを有効にした状態でも正常にビルドができます。
結論ですが、 Xcode のバグ(と思われる)で XcodePreviews のためのビルドのときのみ、コードカバレッジの設定を反映する処理(コードカバレッジが有効であれば Linker に対して -fprofile-instr-generate
を渡す処理)が欠如しているのだと思います※。
なので、 Linker flags に対して明示的に -fprofile-instr-generate
を指定してあげなければならなかったのです。
※ Static Framework が含まれる場合に発生したように、ここに記載していないものも含む一定の条件で発生するものだと思われます。
学び
今回、この結論にいたるまでに多くの方からアドバイスなどをいただきました。
本当にありがとうございます!!
さいごに
学びとして書いてますが、そもそもカバレッジは日常的に有効にしておくべきではありません。
そんなミスをしていたからこそ遭遇してしまった問題だったわけですが、すごく勉強になりました!この記事も「この問題の解決策!」ではないですが、知識として多くのエンジニアに届けばと思います。
最後まで読んでいただき、ありがとうございます!