Xcode から Bazel への移行

問題を報告 ソースを表示

このページでは、Bazel を使用して Xcode プロジェクトをビルドまたはテストする方法について説明します。Xcode と Bazel の違いと、Xcode プロジェクトを Bazel プロジェクトに変換する手順について説明します。また、一般的なエラーに対処するためのトラブルシューティングの解決策についても説明します。

Xcode と Bazel の違い

  • Bazel では、すべてのビルド ターゲットとその依存関係に加えて、ビルドルールを使用して対応するビルド設定を明示的に指定する必要があります。

  • Bazel では、プロジェクトが依存するすべてのファイルがワークスペース ディレクトリに存在するか、WORKSPACE ファイルでインポートとして指定されている必要があります。

  • Bazel を使用して Xcode プロジェクトをビルドすると、BUILD ファイルが信頼できる情報源になります。Xcode でプロジェクトを扱う場合は、BUILD ファイルを更新するたびに、rules_xcodeproj を使用して、BUILD ファイルと一致する新しいバージョンの Xcode プロジェクトを生成する必要があります。ターゲットへの依存関係の追加など、BUILD ファイルに対する特定の変更では、プロジェクトを再生成する必要がないため、開発を高速化できます。Xcode を使用しない場合、bazel build コマンドと bazel test コマンドはビルドとテストの機能を提供しますが、このガイドで後述します。

始める前に

始める前に、次のことを行います。

  1. Bazel をインストールします(まだインストールしていない場合)。

  2. Bazel とそのコンセプトに慣れていない場合は、iOS アプリのチュートリアルをご覧ください)。WORKSPACE ファイルと BUILD ファイルなどの Bazel ワークスペースと、ターゲット、ビルドルール、Bazel パッケージのコンセプトを理解している必要があります。

  3. プロジェクトの依存関係を分析して理解する。

プロジェクトの依存関係を分析する

Xcode とは異なり、Bazel では、BUILD ファイル内のすべてのターゲットについて、すべての依存関係を明示的に宣言する必要があります。

外部依存関係の詳細については、外部依存関係の操作をご覧ください。

Bazel を使用して Xcode プロジェクトをビルドまたはテストする

Bazel を使用して Xcode プロジェクトをビルドまたはテストする手順は次のとおりです。

  1. WORKSPACE ファイルを作成する

  2. (試験運用版)SwiftPM の依存関係を統合する

  3. BUILD ファイルを作成します。

    a. アプリケーションのターゲットを追加する

    b. (省略可)テスト ターゲットを追加する

    c. ライブラリ ターゲットを追加する

  4. (省略可)ビルドを粒度化する

  5. ビルドを実行する

  6. rules_xcodeproj を使用して Xcode プロジェクトを生成する

ステップ 1: WORKSPACE ファイルを作成する

新しいディレクトリに WORKSPACE ファイルを作成します。このディレクトリが Bazel ワークスペースのルートになります。プロジェクトで外部依存関係を使用しない場合、このファイルは空にできます。プロジェクトがプロジェクトのディレクトリにないファイルまたはパッケージに依存している場合は、これらの外部依存関係を WORKSPACE ファイルに指定します。

ステップ 2: (試験運用版)SwiftPM の依存関係を統合する

swift_bazel を使用して SwiftPM の依存関係を Bazel ワークスペースに統合するには、次のチュートリアルで説明するように、Bazel パッケージに変換する必要があります。

ステップ 3: BUILD ファイルを作成する

ワークスペースと外部依存関係を定義したら、プロジェクトの構造を Bazel に伝える BUILD ファイルを作成する必要があります。Bazel ワークスペースのルートに BUILD ファイルを作成し、次のようにプロジェクトの初期ビルドを実行するように構成します。

ヒント: パッケージとその他の Bazel のコンセプトについては、ワークスペース、パッケージ、ターゲットをご覧ください。

ステップ 3a: アプリケーションのターゲットを追加する

macos_application または ios_application ルールのターゲットを追加します。このターゲットにより、それぞれ macOS または iOS のアプリケーション バンドルがビルドされます。ターゲットでは、少なくとも次のものを指定します。

  • bundle_id - バイナリのバンドル ID(リバース DNS パスの後にアプリ名が続く)。

  • provisioning_profile - Apple Developer アカウントのプロビジョニング プロファイル(iOS デバイス デバイス用にビルドする場合)。

  • families(iOS のみ)- iPhone、iPad、またはその両方用にアプリケーションをビルドするかどうか。

  • infoplists - 最終的な Info.plist ファイルにマージする .plist ファイルのリスト。

  • minimum_os_version - アプリケーションがサポートする macOS または iOS の最小バージョン。これにより、Bazel は正しい API レベルでアプリケーションをビルドできます。

ステップ 3b: (省略可)テスト ターゲットを追加する

Bazel の Apple ビルドルールは、すべての Apple プラットフォームでの単体テストと UI テストの実行をサポートしています。次のようにテスト ターゲットを追加します。

  • macos_unit_test: macOS でライブラリベースおよびアプリケーション ベースの単体テストを実行します。

  • iOS でライブラリベースの単体テストをビルドして実行するための ios_unit_test

  • ios_ui_test: iOS シミュレータでユーザー インターフェース テストをビルドして実行します。

  • tvOSwatchOSvisionOS にも同様のテストルールがあります。

少なくとも minimum_os_version 属性の値を指定します。bundle_identifierinfoplists などの他のパッケージング属性はデフォルトでよく使用される値になりますが、これらのデフォルト値がプロジェクトに対応していることを確認し、必要に応じて調整してください。iOS シミュレータが必要なテストでは、test_host 属性の値として ios_application ターゲット名も指定します。

ステップ 3c: ライブラリ ターゲットを追加する

各 Objective-C ライブラリに objc_library ターゲットを追加し、アプリやテストが依存する各 Swift ライブラリに swift_library ターゲットを追加します。

次のようにライブラリ ターゲットを追加します。

  • アプリケーション ライブラリ ターゲットを依存関係としてアプリケーション ターゲットに追加します。

  • テスト ターゲットに、テスト ライブラリ ターゲットを依存関係として追加します。

  • srcs 属性に実装ソースをリストします。

  • hdrs 属性にヘッダーをリストします。

さまざまな種類のアプリケーションの既存のサンプルを、rules_apple のサンプル ディレクトリで直接参照できます。例:

ビルドルールの詳細については、Apple の Bazel ルールをご覧ください。

この時点で、ビルドをテストすることをおすすめします。

bazel build //:<application_target>

ステップ 4: (省略可)ビルドを粒度化する

プロジェクトが大きい場合や拡大する場合は、複数の Bazel パッケージに分割することを検討してください。このように細かく設定することで、次のようなことが可能になります。

  • ビルドのインクリメンタリティの向上

  • ビルドタスクの並列化の強化、

  • 将来のユーザーにとっての保守性の向上、

  • ターゲットとパッケージ全体でソースコードの可視性をより適切に制御します。これにより、実装の詳細を含むライブラリが公開 API に漏洩するなどの問題を防止できます。

プロジェクトをきめ細かく設定するためのヒント:

  • 各ライブラリを独自の Bazel パッケージに格納します。最小限の依存関係を必要とするものから開始し、依存関係ツリーの上位に進みます。

  • BUILD ファイルを追加してターゲットを指定するときに、これらの新しいターゲットを依存するターゲットの deps 属性に追加します。

  • glob() 関数はパッケージの境界を越えないため、パッケージの数が増えると、glob() によって照合されるファイルは小さくなります。

  • BUILD ファイルを main ディレクトリに追加する場合は、対応する test ディレクトリにも BUILD ファイルを追加します。

  • パッケージ全体に正常な公開設定の上限を適用します。

  • BUILD ファイルに大幅な変更を加えるたびにプロジェクトをビルドし、エラーが発生した場合はビルドエラーを修正します。

ステップ 5: ビルドを実行する

完全に移行されたビルドを実行して、エラーや警告が発生せずに完了していることを確認します。すべてのアプリケーションとテスト ターゲットを個別に実行することで、発生するエラーの原因をより簡単に特定できます。

例:

bazel build //:my-target

ステップ 6: rules_xcodeproj を使用して Xcode プロジェクトを生成する

Bazel でビルドする場合、WORKSPACE ファイルと BUILD ファイルがビルドに関する信頼できる情報源になります。Xcode がこの問題を認識できるようにするには、rules_xcodeproj を使用して Bazel と互換性のある Xcode プロジェクトを生成する必要があります。

トラブルシューティング

Bazel エラーは、アップデートを適用したときなど、選択した Xcode バージョンと同期しなくなると発生することがあります。Xcode でエラー(Apple CROSSTOOL を使用するには Xcode バージョンを指定する必要があります)などのエラーが発生した場合は、以下をお試しください。

  • Xcode を手動で実行し、利用規約に同意します。

  • Xcode セレクトを使用して正しいバージョンを指定し、ライセンスを受け入れ、Bazel の状態をクリアします。

  sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
  sudo xcodebuild -license
  bazel sync --configure
  • それでもうまくいかない場合は、bazel clean --expunge を実行してみてください。