T-CREATOR

<div />

Flutter ビルドがこけるときの総合対処:Gradle/iOS コード署名/依存競合

Flutter ビルドがこけるときの総合対処:Gradle/iOS コード署名/依存競合

Flutter でアプリ開発をしていると、ビルドエラーに遭遇することは避けられません。特に Android の Gradle 関連エラー、iOS のコード署名エラー、依存関係の競合は開発者を悩ませる代表的な問題です。

この記事では、Flutter ビルドでよく遭遇する 3 つの主要なエラーパターンとその解決方法を、実際のエラーコードとともに詳しく解説します。初めてこれらのエラーに遭遇した方でも、段階的に問題を解決できるよう、具体的な手順とコマンドを示していきますね。

背景

Flutter のビルドプロセス

Flutter アプリケーションのビルドは、複数のツールチェーンが連携して動作する複雑なプロセスです。Android では Gradle が、iOS では Xcode とコード署名が、そして両プラットフォーム共通で pubspec.yaml に定義された依存関係の解決が必要になります。

以下の図は、Flutter ビルドプロセスの全体像を示しています。

mermaidflowchart TB
  dev["開発者"] -->|flutter build| cli["Flutter CLI"]
  cli -->|解析| pubspec["pubspec.yaml<br/>依存関係定義"]
  pubspec -->|pub get| deps["依存関係解決"]

  deps -->|Android| gradle["Gradle ビルド"]
  deps -->|iOS| xcode["Xcode ビルド"]

  gradle -->|ビルド成功| apk["APK/AAB 生成"]
  xcode -->|署名| sign["コード署名"]
  sign -->|ビルド成功| ipa["IPA 生成"]

  gradle -.->|エラー| gerr["Gradle エラー"]
  xcode -.->|エラー| xerr["Xcode エラー"]
  sign -.->|エラー| serr["署名エラー"]
  deps -.->|エラー| derr["依存競合エラー"]

図で理解できる要点

  • Flutter ビルドは CLI を起点に、依存解決とプラットフォーム固有ビルドに分岐します
  • Android と iOS で異なるビルドツールが使用されます
  • エラーは各段階で発生する可能性があります

ビルドエラーが発生する主な原因

Flutter のビルドエラーは、以下の 3 つのレイヤーで発生します。

#レイヤー主な原因影響範囲
1依存関係パッケージバージョン競合、Dart SDK バージョン不一致両プラットフォーム
2Android ビルドGradle バージョン、Java バージョン、NDK 設定Android のみ
3iOS ビルドコード署名証明書、プロビジョニングプロファイル、Xcode 設定iOS のみ

それぞれのレイヤーで発生するエラーは独立していることもあれば、連鎖的に影響を及ぼすこともあります。

環境による差異

開発環境によってビルドエラーの発生パターンが異なるのも、Flutter ビルドの難しさです。macOS、Windows、Linux でツールチェーンの構成が異なり、CI/CD 環境ではローカルでは発生しないエラーが起きることもあります。

課題

Gradle ビルドエラーの複雑さ

Android の Gradle ビルドエラーは、エラーメッセージが長大で原因特定が困難です。Gradle のバージョン、Android Gradle Plugin (AGP) のバージョン、Java のバージョンの 3 つが適切に組み合わさっている必要があり、1 つでもバージョンが合わないとビルドが失敗します。

以下は、Gradle ビルドで発生する典型的な問題の依存関係を示した図です。

mermaidflowchart LR
  gradle["Gradle バージョン"] -->|互換性要求| agp["Android Gradle<br/>Plugin (AGP)"]
  agp -->|互換性要求| java["Java バージョン"]
  gradle -->|互換性要求| java

  sdk["Android SDK"] -->|ビルドツール| agp
  ndk["Android NDK"] -.->|ネイティブコード| agp

  deps["依存パッケージ"] -->|minSdk 要求| sdk
  deps -->|コンパイル| agp

図で理解できる要点

  • Gradle、AGP、Java の 3 つは相互に互換性制約があります
  • 依存パッケージが要求する minSdk も考慮が必要です
  • NDK はネイティブコードを含むパッケージでのみ必要になります

iOS コード署名の複雑性

iOS のビルドで最も頻繁に発生するのがコード署名関連のエラーです。開発用証明書、配布用証明書、プロビジョニングプロファイル、Bundle Identifier の 4 つが正確に一致していないとビルドが失敗します。

特に以下のようなエラーメッセージに遭遇することが多いでしょう。

vbnetError: No profiles for 'com.example.app' were found
Xcode couldn't find any iOS App Development provisioning profiles matching 'com.example.app'

依存関係競合の検出困難性

pubspec.yaml に記載されたパッケージ間でバージョン要件が競合すると、pub get の段階でビルドが失敗します。しかし、どのパッケージとどのパッケージが競合しているのか、エラーメッセージから読み取るのは容易ではありません。

典型的なエラーは以下のような形式です。

csharpBecause package_a >=2.0.0 depends on package_c ^3.0.0 and package_b >=1.5.0 depends on package_c ^2.0.0, package_a >=2.0.0 is incompatible with package_b >=1.5.0.

このようなエラーは複数のパッケージが絡み合うと、非常に複雑になります。

解決策

Gradle ビルドエラーの解決手順

Gradle 関連のエラーは、バージョン互換性の確認から始めることで効率的に解決できます。以下の手順で段階的に対処していきましょう。

1. Gradle バージョンの確認と更新

まず、プロジェクトで使用している Gradle のバージョンを確認します。

bashcd android
./gradlew --version

次に、android/gradle/wrapper/gradle-wrapper.properties ファイルで Gradle のバージョンを確認・更新します。

properties# Gradle バージョンの指定
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-all.zip

推奨される組み合わせ(2024 年版)

#GradleAGPJavaFlutter
18.0+8.0+173.10+
27.5+7.4+113.7+
37.0+7.0+113.3+

2. Android Gradle Plugin (AGP) の更新

android/build.gradle ファイルで AGP のバージョンを確認します。

groovybuildscript {
    // 依存関係の定義
    dependencies {
        // AGP のバージョン指定
        classpath 'com.android.tools.build:gradle:8.0.2'
    }
}

AGP のバージョンは Gradle のバージョンと互換性がある必要があります。公式の互換性表を参照して適切なバージョンを選択しましょう。

3. Java バージョンの確認と設定

使用している Java のバージョンを確認します。

bashjava -version

もし必要なバージョンがインストールされていない場合は、以下のコマンドでインストールできます。

bash# macOS の場合(Homebrew を使用)
brew install openjdk@17

# パスの設定
export JAVA_HOME=/opt/homebrew/opt/openjdk@17

android/app/build.gradle で Java のコンパイルバージョンを指定します。

groovyandroid {
    compileOptions {
        // Java 17 を使用
        sourceCompatibility JavaVersion.VERSION_17
        targetCompatibility JavaVersion.VERSION_17
    }
}

4. Gradle キャッシュのクリア

Gradle のキャッシュが破損している場合、以下のコマンドでクリアします。

bash# Flutter のクリーンビルド
flutter clean

# Gradle のキャッシュクリア
cd android
./gradlew clean
./gradlew --stop

さらに深いクリアが必要な場合は、Gradle のキャッシュディレクトリを削除します。

bash# macOS/Linux の場合
rm -rf ~/.gradle/caches/
rm -rf ~/.gradle/wrapper/

# Windows の場合(PowerShell)
Remove-Item -Recurse -Force $env:USERPROFILE\.gradle\caches\
Remove-Item -Recurse -Force $env:USERPROFILE\.gradle\wrapper\

iOS コード署名エラーの解決手順

iOS のコード署名エラーは、証明書とプロビジョニングプロファイルの管理が鍵となります。

1. 開発証明書の確認

Xcode を開いて、開発証明書が正しくインストールされているか確認します。

bash# 証明書の一覧を表示
security find-identity -v -p codesigning

このコマンドで以下のような出力が得られれば、証明書は正しくインストールされています。

perl1) ABC123... "Apple Development: your.email@example.com (TEAM_ID)"
2) DEF456... "Apple Distribution: Your Team Name (TEAM_ID)"

証明書がない場合は、Apple Developer Portal から証明書を作成してダウンロードし、ダブルクリックでキーチェーンに追加します。

2. プロビジョニングプロファイルの設定

Xcode でプロジェクトを開き、Signing & Capabilities タブを確認します。

bash# Xcode でプロジェクトを開く
open ios/Runner.xcworkspace

以下の設定を確認しましょう。

Xcode での設定項目

#項目設定内容
1TeamApple Developer アカウントのチームを選択
2Bundle Identifier一意の識別子(例: com.example.app)
3Signing Certificate開発用または配布用証明書を選択
4Provisioning ProfileAutomatic または Manual で選択

開発時は「Automatically manage signing」にチェックを入れると、Xcode が自動的にプロビジョニングプロファイルを管理してくれます。

3. Bundle Identifier の一致確認

ios/Runner/Info.plist と Xcode の設定で Bundle Identifier が一致しているか確認します。

xml<!-- Bundle Identifier の定義 -->
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>

ios/Runner.xcodeproj/project.pbxproj でも確認します。

iniPRODUCT_BUNDLE_IDENTIFIER = com.example.app;

4. 証明書期限切れエラーの対処

証明書が期限切れの場合、以下のエラーが発生します。

typescriptError: Signing for "Runner" requires a development team. Select a development team in the Signing & Capabilities editor.
Code Signing Error: Code signing is required for product type 'Application' in SDK 'iOS 16.0'

この場合は、Apple Developer Portal で新しい証明書を発行し、Xcode で再設定する必要があります。

bash# 古い証明書を削除
security delete-certificate -c "Apple Development: old@example.com"

# 新しい証明書をインストール(ダウンロードした .cer ファイル)
open ~/Downloads/ios_development.cer

依存関係競合の解決手順

依存関係の競合は、pubspec.yaml の適切な管理と依存関係の理解で解決できます。

1. 依存関係ツリーの確認

まず、どのパッケージがどのパッケージに依存しているかを確認します。

bash# 依存関係ツリーを表示
flutter pub deps

このコマンドで、直接依存と間接依存の両方が表示されます。競合しているパッケージを見つけるのに役立ちますね。

diffdependencies:
- package_a 2.0.0
  - package_c 3.0.0
- package_b 1.5.0
  - package_c 2.5.0 (競合!)

2. dependency_overrides の使用

どうしてもバージョン競合が解決できない場合、dependency_overrides を使用して強制的にバージョンを指定できます。

pubspec.yaml に以下を追加します。

yaml# 依存関係の定義
dependencies:
  package_a: ^2.0.0
  package_b: ^1.5.0
yaml# 競合を解決するための上書き
dependency_overrides:
  package_c: ^3.0.0

ただし、この方法は最終手段として使用してください。互換性の問題が発生する可能性があります。

3. パッケージバージョンの調整

より安全な方法は、パッケージのバージョンを調整することです。

yamldependencies:
  # バージョン範囲を緩和
  package_a: '>=2.0.0 <3.0.0'
  # 特定バージョンに固定
  package_b: 1.5.0

バージョン指定の記号の意味を理解しておきましょう。

バージョン指定の記法

#記法意味
1^1.2.31.2.3 以上 2.0.0 未満^1.2.3 → 1.9.9 まで
2>=1.2.3 <2.0.01.2.3 以上 2.0.0 未満明示的な範囲指定
31.2.3厳密に 1.2.3 のみ完全固定
4any任意のバージョン非推奨

4. pubspec.lock のリセット

依存関係の解決がうまくいかない場合、pubspec.lock を削除して再解決します。

bash# pubspec.lock を削除
rm pubspec.lock

# 依存関係を再解決
flutter pub get

この操作により、すべてのパッケージが最新の互換バージョンで再解決されます。

具体例

事例 1: Gradle バージョン不一致エラー

以下のようなエラーメッセージが表示された場合を考えてみましょう。

エラーコード

vbnetFAILURE: Build failed with an exception.

* What went wrong:
An exception occurred applying plugin request [id: 'com.android.application']
> Failed to apply plugin 'com.android.internal.application'.
   > Android Gradle plugin requires Java 11 to run. You are currently using Java 1.8.

エラーメッセージ

このエラーは、Android Gradle Plugin が Java 11 を要求しているのに、Java 1.8 が使用されていることを示しています。

発生条件

  • Android Gradle Plugin 7.0 以上を使用している
  • Java のバージョンが 1.8(Java 8)になっている
  • Flutter プロジェクトを古い環境から移行した

解決方法

ステップ 1: Java 11 のインストール

bash# macOS の場合
brew install openjdk@11

# インストールされた Java のパスを確認
/usr/libexec/java_home -V

ステップ 2: JAVA_HOME の設定

シェルの設定ファイル(.zshrc または .bash_profile)に以下を追加します。

bash# Java 11 をデフォルトに設定
export JAVA_HOME=$(/usr/libexec/java_home -v 11)
export PATH=$JAVA_HOME/bin:$PATH

ステップ 3: 設定の反映

bash# 設定を再読み込み
source ~/.zshrc

# Java バージョンの確認
java -version

ステップ 4: ビルドの再実行

bash# クリーンビルド
flutter clean
cd android
./gradlew clean

# ビルド実行
cd ..
flutter build apk

これで Java 11 が使用され、ビルドが成功するはずです。

事例 2: iOS コード署名エラー

Apple Developer アカウントでチームに所属しているのに、コード署名でエラーが発生するケースです。

エラーコード

typescriptError (Xcode): Signing for "Runner" requires a development team. Select a development team in the Signing & Capabilities editor.

Error (Xcode): Code signing is required for product type 'Application' in SDK 'iOS 16.0'

エラーメッセージ

開発チームの選択が必要であることを示していますが、Xcode で選択しても解決しない場合があります。

発生条件

  • 複数の Apple Developer アカウントでログインしている
  • Xcode のキャッシュに古い証明書情報が残っている
  • プロビジョニングプロファイルが無効になっている

解決方法

ステップ 1: Xcode のアカウント確認

Xcode を開いて、Preferences > Accounts で正しいアカウントでログインしているか確認します。

bash# Xcode を起動
open -a Xcode

Preferences(⌘,)を開き、Accounts タブで Apple ID を確認します。

ステップ 2: プロビジョニングプロファイルのダウンロード

Accounts タブで対象のチームを選択し、「Download Manual Profiles」をクリックします。

ステップ 3: Derived Data の削除

Xcode のキャッシュをクリアします。

bash# Derived Data を削除
rm -rf ~/Library/Developer/Xcode/DerivedData/*

# Flutter の iOS ビルドキャッシュも削除
cd ios
rm -rf build/
pod cache clean --all

ステップ 4: CocoaPods の再インストール

依存関係を完全にクリーンにします。

bash# Podfile.lock と Pods を削除
rm -rf Podfile.lock Pods/

# pod install を実行
pod install --repo-update

ステップ 5: Xcode でチームを再選択

bash# Xcode でワークスペースを開く
open Runner.xcworkspace

プロジェクト設定の「Signing & Capabilities」タブで、「Automatically manage signing」にチェックを入れ、Team を再選択します。

ステップ 6: ビルドの実行

bash# Flutter プロジェクトルートに戻る
cd ..

# iOS ビルドを実行
flutter build ios

これで正しい証明書とプロビジョニングプロファイルが適用され、ビルドが成功します。

事例 3: 依存関係の競合エラー

複数のパッケージが同じパッケージの異なるバージョンを要求している場合です。

エラーコード

csharpBecause firebase_core >=2.0.0 depends on firebase_core_platform_interface ^4.5.0
and firebase_messaging >=14.0.0 depends on firebase_core_platform_interface ^4.0.0,
firebase_core >=2.0.0 is incompatible with firebase_messaging >=14.0.0.
So, because my_app depends on both firebase_messaging ^14.6.0 and firebase_core ^2.4.0,
version solving failed.

エラーメッセージ

firebase_core と firebase_messaging が firebase_core_platform_interface の異なるバージョンを要求しているため、バージョン解決に失敗しています。

発生条件

  • Firebase パッケージを個別にアップデートした
  • 異なるタイミングでパッケージを追加した
  • パッケージのメジャーバージョンアップが発生した

解決方法

ステップ 1: 依存関係ツリーの確認

どのパッケージがどのバージョンを要求しているか確認します。

bash# 依存関係の詳細を表示
flutter pub deps --style=compact

ステップ 2: 互換性のあるバージョンの特定

Firebase パッケージの場合、公式ドキュメントで推奨されるバージョンの組み合わせを確認します。

pubspec.yaml を以下のように調整します。

yamldependencies:
  flutter:
    sdk: flutter

  # Firebase パッケージを互換性のあるバージョンに統一
  firebase_core: ^2.4.0
  firebase_messaging: ^14.2.0
  firebase_analytics: ^10.1.0

ステップ 3: pubspec.lock の削除と再解決

bash# 既存の解決結果を削除
rm pubspec.lock

# pub cache もクリア
flutter pub cache repair

# 依存関係を再解決
flutter pub get

ステップ 4: それでも解決しない場合の対処

バージョン範囲を緩和するか、dependency_overrides を使用します。

yamldependencies:
  firebase_core: ^2.4.0
  firebase_messaging: ^14.2.0

# 最終手段として使用
dependency_overrides:
  firebase_core_platform_interface: ^4.5.0

ステップ 5: ビルドの確認

bash# Android ビルドで確認
flutter build apk --debug

# iOS ビルドで確認
flutter build ios --debug

両方のプラットフォームでビルドが成功することを確認しましょう。

事例 4: Multidex エラー(Android)

Android で大量のメソッドを含むアプリをビルドする際に発生するエラーです。

エラーコード

vbnetFAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:mergeDexDebug'.
> A failure occurred while executing com.android.build.gradle.internal.tasks.DexMergingTaskDelegate
   > Cannot fit requested classes in a single dex file (# methods: 67890 > 65536)

解決方法

android/app/build.gradle で Multidex を有効にします。

groovyandroid {
    defaultConfig {
        // その他の設定...

        // Multidex を有効化
        multiDexEnabled true
    }
}
groovydependencies {
    // Multidex ライブラリを追加
    implementation 'androidx.multidex:multidex:2.0.1'
}

これで 65536 メソッド以上のアプリでもビルドできるようになります。

まとめ

Flutter のビルドエラーは複雑に見えますが、体系的にアプローチすることで確実に解決できます。

この記事で解説した 3 つの主要なエラーパターンについて、重要なポイントをまとめます。

Gradle ビルドエラー

  • Gradle、AGP、Java のバージョン互換性を常に確認しましょう
  • エラーが発生したらまずキャッシュをクリアしてください
  • 公式の互換性表を参照して適切なバージョンを選択することが重要です

iOS コード署名エラー

  • 開発証明書とプロビジョニングプロファイルの有効期限を定期的に確認しましょう
  • Bundle Identifier の一致を徹底的にチェックしてください
  • Xcode の自動署名管理を活用すると設定が簡単になります

依存関係競合

  • flutter pub deps で依存関係ツリーを可視化しましょう
  • パッケージのバージョン範囲指定を適切に使い分けてください
  • dependency_overrides は最終手段として慎重に使用しましょう

ビルドエラーに遭遇したときは、エラーメッセージを丁寧に読み、該当するエラーパターンを特定することから始めてください。この記事で紹介した解決手順を段階的に実行すれば、ほとんどのビルドエラーは解決できるはずです。

トラブルシューティングの経験を積むことで、エラーメッセージから原因を素早く特定できるようになります。焦らず、一つずつ確認していくことが成功への近道ですね。

関連リンク

;