ビルド失敗のトラブルシューティング
プロジェクトにターゲット依存循環がある場合
新しいビルドシステムは、ターゲット間の依存関係の循環を検出します。
ビルドのステップには、フレームワークやライブラリターゲットなどの、低レベルのターゲットに応じて、アプリケーションターゲットなどの高レベルのターゲットが含まれることがよくあります。定レベルのターゲットが最初にビルドされるため、高レベルのターゲットは製品をリンクし、埋め込み、またはその他の方法で使用できます。
ターゲットが相互に依存している場合、循環が形成され、どちらかのターゲットを最初にビルドするかは正しくありません。これらの相互依存関係は直接的な場合もあれば、他の中間ターゲットを含むチェーンの一部である場合もあります。いずれの場合も、ビルドによって信頼できない結果が生成される可能性があります。
新しいビルドシステムは依存関係の循環を検出し、検出した循環を説明するビルドエラーを生成します。このエラーが発生した場合は、ターゲットまたはソースコードの構造を変更して、循環を排除する必要があります。
注意 : ビルドシステムを変更するには、ビルドシステムの選択 をご覧下さい。
ターゲット間の依存関係が原因でプロジェクトに依存関係循環が含まれている場合、ビルドは以下のようなエラーで失敗します。
error: Cycle in dependencies between targets 'B' and 'A'; building could produce unreliable results.
Cycle path: B → C → A → B
Cycle details:
→ Target 'B' has target dependency on Target 'C'
→ Target 'C' has target dependency on Target 'A'
→ Target 'A' has target dependency on Target 'B'
(エラー:ターゲット 'B' と 'A' の間の依存関係の循環。ビルドすると、信頼できない結果が生じる可能性があります。
サイクルパス:B→C→A→B
サイクルの詳細:
→ターゲット 'B' はターゲット 'C' にターゲット依存関係があります
→ターゲット 'C' はターゲット 'A' にターゲット依存関係があります
→ターゲット 'A' はターゲット 'B' にターゲット依存関係があります)
この場合、ターゲット B をビルドするためにターゲット A をビルドする必要がありますが、ターゲット A もターゲット B に依存します。
"Target Dependencies(ターゲットの依存関係)" ビルドフェーズ で明示的に宣言された依存関係に加えて、ターゲットの依存関係は、あるターゲットが別のターゲットによって生成されたフレームワークまたはライブラリ製品に対してリンクするときに暗黙的に作成されます。この診断にリストされているターゲットの依存関係は、明示的な依存関係または暗黙的な依存関係である可能性があります。
この問題を解決するには、以下の手順に従ってください。
- まず、不要なターゲットの依存関係を削除します。
- それでもビルドが失敗する場合は、プロジェクトのソースコードやターゲットを再構築して、依存関係が循環しないようにします。
並列ビルドを無効にする と、ビルドシステムは、すべての "ターゲット依存関係" ビルドフェーズ およびスキームの "ビルド" アクションでのターゲットの順序に基づいて、すべてのターゲットを固定された順序でビルドします。この順序で依存関係循環が生成される場合、ビルドは以下のようなエラーで失敗します。
error: Cycle in dependencies between targets 'A' and 'B'; building could produce unreliable results.
Cycle path: B → A → C → B
Cycle details:
Target build order preserved because “Parallelize Build” is off
→ Target 'B' has link command with output '/Users/user/Library/Developer/Xcode/DerivedData/A-crxjtmxdssvpmxbeissnxefqwqtp/Build/Products/Debug/B.framework/Versions/A/B'
○ Target 'B' has compile command with input '/Users/user/Library/Developer/Xcode/DerivedData/A-crxjtmxdssvpmxbeissnxefqwqtp/Build/Intermediates.noindex/A.build/Debug/A.build/DerivedSources/File.m'
○ That command depends on command in Target 'A': script phase “Generate File.m”
→ Target 'A' has target dependency on Target 'C' due to target order in a “Target Dependencies” build phase or the scheme
→ Target 'C' has target dependency on Target 'B' due to target order in a “Target Dependencies” build phase or the scheme
(エラー:ターゲット 'A' と 'B' の間の依存関係の循環。ビルドすると、信頼できない結果が生じる可能性があります。
サイクルパス:B→A→C→B
サイクルの詳細 :
"並行化したビルド" がオフになっているため、ターゲットのビルド順序が保持されます
→ターゲット 'B' には、出力 '/Users/user/Library/Developer/Xcode/DerivedData/A-crxjtmxdssvpmxbeissnxefqwqtp/Build/Products/Debug/B.framework/Versions/A/B' とのリンクコマンドがあります。
○ターゲット 'B' には、入力 '/Users/user/Library/Developer/Xcode/DerivedData/A-crxjtmxdssvpmxbeissnxefqwqtp/Build/Intermediates.noindex/A.build/Debug/A.build/DerivedSources/File.m' を含むコンパイルコマンドがあります。
○そのコマンドは、ターゲット 'A' のコマンドに依存します : スクリプトフェーズ "GenerateFile.m"
→ターゲット 'A' は、"ターゲット依存関係" ビルドフェーズまたはスキームでのターゲットの順序により、
ターゲット 'C' にターゲット依存関係があります
→ターゲット 'C' は、"ターゲット依存関係" ビルドフェーズまたはスキームでのターゲットの順序により、
ターゲット 'B' にターゲット依存関係があります)
この場合、ターゲット B はターゲット A によって生成されたファイルに依存しますが、プロジェクトで構成された順序では、ターゲット A の前にターゲット B をビルドする必要があります。
この問題を解決するには、以下の手順に従ってください。
- まず、並列ビルドを有効に します (スキーム内の [Parallelize Build(平衡化したビルド)] チェックボックスを有効にします)。
- ビルドが再度失敗する場合は、明示的に 必要なターゲット依存関係を追加 します。
- それでもビルドが失敗する場合は、スキームのビルドアクションでターゲットを再度並べ替えるか、依存するターゲットを再度並べ替えます。
ビルドの早い段階で必要なターゲットは、それらに依存するターゲットの前にリストする必要があります。
プロジェクト内のターゲットは、他のターゲットをビルドするために必要なソースファイルまたはリソースを生成する場合がありますが、他の依存関係によって決定されるものと競合する順序です。その場合、ビルドは以下のようなエラーで失敗します。
error: Cycle in dependencies between targets 'A' and 'B'; building could produce unreliable results.
Cycle path: A → B → A
Cycle details:
→ Target 'A' has target dependency on Target 'B'
→ Target 'B' has compile command with input '/Users/user/Library/Developer/Xcode/DerivedData/A-fwfactyalkdlasagytkmozogzans/Build/Intermediates.noindex/A.build/Debug/A.build/DerivedSources/File.m'
○ That command depends on command in Target 'A': script phase “Generate File.m”
(エラー:ターゲット'A' と 'B' の間の依存関係の循環。ビルドすると、信頼できない結果が生じる可能性があります。
循環のパス : A → B → A
循環の詳細 :
→ターゲット 'A' はターゲット 'B' にターゲット依存関係があります
→ターゲット 'B' には、入力 '/Users/user/Library/Developer/Xcode/DerivedData/A-fwfactyalkdlasagytkmozogzans/Build/Intermediates.noindex/A.build/Debug/A.build/DerivedSources/File.m' を含むコンパイルコマンドがあります。
○そのコマンドは、ターゲット 'A' のコマンドに依存します : スクリプトフェーズ 'GenerateFile.m')
この場合、ターゲット A はターゲット B に依存しますが、ターゲット B にはターゲット A によって生成されたソースファイルも必要です。
この問題を解決するには、以下の手順に従ってください。
- ターゲットの依存関係のビルドフェーズで、競合するターゲットの依存関係が必要かどうかを確認します。
- プロジェクトをビルドするためにすべての明示的なターゲット依存関係が必要な場合は、プロジェクトのソースコードまたはターゲットを再構築して、依存関係が循環しないようにします。
与えられたターゲットが別のターゲットの製品 (フレームワークなど) を全く必要としない場合は、ターゲットの依存関係を削除 します。
高速で正確な増分ビルドを可能にするために、最初のビルド後のすべてのビルドは、前のビルド中に発見された情報を使用して、含まれているヘッダやインポートされたモジュールなど、ソースコード内の追加の依存関係について学習します。これにより、最初のビルドが成功した後にのみ発見され、後続のビルドが以下のようなエラーで失敗する依存関係循環が発生する可能性があります。
error: Cycle in dependencies between targets 'A' and 'B'; building could produce unreliable results.
Cycle path: A → B → A
Cycle details:
→ Target 'A' has link command with output '/Users/user/Library/Developer/Xcode/DerivedData/A-exhexvayjuazkmeqbiuraugfrmyy/Build/Products/Debug/A.framework/Versions/A/A'
○ Target 'A' has compile command with input '/Users/user/Desktop/A/A/File.m'
→ Target 'B' has write command with output /Users/user/Library/Developer/Xcode/DerivedData/A-exhexvayjuazkmeqbiuraugfrmyy/Build/Intermediates.noindex/A.build/Debug/B.build/module.modulemap
○ Target 'B' has target dependency on Target 'A'
(エラー:ターゲット 'A' と 'B' の間の依存関係の循環。ビルドすると、信頼できない結果が生じる可能性があります。
循環パス : A → B → A
循環の詳細 :
→ターゲット 'A' には、出力 '/Users/user/Library/Developer/Xcode/DerivedData/A-exhexvayjuazkmeqbiuraugfrmyy/Build/Products/Debug/A.framework/Versions/A/A' とのリンクコマンドがあります。
○ターゲット 'A' には、入力 '/Users/user/Desktop/A/A/File.m' を含むコンパイルコマンドがあります
→ターゲット 'B' には、出力 '/Users/user/Library/Developer/Xcode/DerivedData/A-exhexvayjuazkmeqbiuraugfrmyy/Build/Intermediates.noindex/A.build/Debug/B.build/module.modulemap' を含む書き込みコマンドがあります
○ターゲット 'B' はターゲット 'A' にターゲット依存関係があります)
この場合、File.m はターゲット A の一部としてコンパイルされており、モジュール B が含まれていますが、ターゲット B からターゲット A への明示的なターゲット依存関係もあります。
注意 : [Enable Module(モジュールの有効化)] ビルド設定がオンの場合、モジュールから任意のヘッダーをインポートすると、モジュール全体がインポートされます。これが、循環診断がモジュールマップの書き込みコマンドをサイクルの潜在的な要素としてリストする理由です。
この問題を解決するには、以下の手順に従ってください。
- 競合するターゲットの依存関係が必要かどうかを確認します。
- 循環の一部としてリストされているコマンドによってコンパイルされているファイルのインポート文を確認してください。
- それでも問題が解決しない場合は、プロジェクトのソースコードまたはターゲットを再構築して、依存関係が循環しないようにします。
与えられたターゲットが別のターゲットの製品 (フレームワークなど) を必要としない場合は、ターゲットの依存関係を削除 します。
一部のインポート文が不要であり、それらを削除すると依存関係循環が解決される可能性があります。