概要
Unityでスマホゲーム作っててiOS向けのリリースがひと段落したのでAndroid向けビルドしたらめっちゃエラー出て泣いた。
つら…
環境
- OS:Windows 10
- Unity:2019.1.0f2
Macでも同様のエラー出たので、OS依存のエラーではないことは検証済み。
エラー内容を確認する
ビルド失敗時に表示されるUnity Editorのダイアログには、何もメッセージが表示されず無事死亡。
Consoleを確認するとUnityEditor.BuildPlayerWindow+BuildMethodException: 145 errors
という素敵なログが出ていた。
UnityEditor.BuildPlayerWindow+BuildMethodException: 145 errors
at UnityEditor.BuildPlayerWindow+DefaultBuildMethods.BuildPlayer (UnityEditor.BuildPlayerOptions options) [0x00242] in C:\buildslave\unity\build\Editor\Mono\BuildPlayerWindowBuildMethods.cs:194
at UnityEditor.BuildPlayerWindow.CallBuildMethods (System.Boolean askForBuildLocation, UnityEditor.BuildOptions defaultBuildOptions) [0x0007f] in C:\buildslave\unity\build\Editor\Mono\BuildPlayerWindowBuildMethods.cs:97
UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr)
エラー145個て。初代のポケモン図鑑ならもう少しでコンプやぞ。
UnityEditor.BuildPlayerWindow+BuildMethodException
でググると結構情報出てくるけど、PlayServicesResolver
だけで解決するパターンばかり。どれも今回のエラーとはちょっと違いそうな雰囲気だ。
もう少し手前のログを見ると、Gradle buildでコケていることがわかった。
CommandInvokationFailure: Gradle build failed.
C:\Program Files\Unity\Hub\Editor\2019.1.0f2\Editor\Data\PlaybackEngines\AndroidPlayer/Tools\OpenJDK\Windows\bin\java.exe -classpath "C:\Program Files\Unity\Hub\Editor\2019.1.0f2\Editor\Data\PlaybackEngines\AndroidPlayer\Tools\gradle\lib\gradle-launcher-4.6.jar" org.gradle.launcher.GradleMain "-Dorg.gradle.jvmargs=-Xmx4096m" "assembleRelease"
stderr[
D8: Program type already present: com.facebook.unity.FBDialogUtils
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':transformDexArchiveWithExternalLibsDexMergerForRelease'.
> com.android.builder.dexing.DexArchiveMergerException: Error while merging dex archives:
...
以下、つらつらと導入ライブラリの一覧が羅列されていた。
stderrにはFacebookのFBDialogUtils
がすでに存在しているとのメッセージが。
D8: Program type already present: com.facebook.unity.FBDialogUtils
Facebook SDKで何か引っかかっているのかな?
正直これだけでは具体的な原因が特定できない。
とりあえず現状得られたエラーメッセージでググってみると、SDKの重複に起因して発生するエラーっぽい情報がでてきた。
D8: Program type already present: com.facebook.unity.Constants - Unity Answers
Program type already present error when gradle build - Unity Forum
そういえばAndroidアプリのビルドでいろんなSDK入れると、バージョン違いの重複ライブラリが存在してしまい「どっち見ればええねん」的なエラーが出るのを何度も経験していた…
ライブラリの依存関係を調査する
おおよその目星がついたので深掘ってみる。Androidプロジェクト吐いてgradlew dependencies
コマンド叩くと、ライブラリの依存関係を確認できるらしい。
【Android】ライブラリの依存関係を調査する方法(gradle) - テクノモンキーのアプリ開発日記
知らなかった。
Build Settingsで [Export Project] にチェックを付けてAndroidプロジェクトを出力。
Android Studioでプロジェクト開いてgradlew sync実行。エラー出てたら解消させとく。
コマンドプロンプト(Macの場合はターミナル)でAndroidプロジェクトのフォルダに移動してgradlew dependencies
コマンドを叩く。ライブラリ一覧や依存関係がズラリと表示される。


細かい部分はスルーするが、同名のバージョン違いが存在したりplay-services
系で被っているものがいくつかあった。
ライブラリの競合を解決する
おそらく以下3つのライブラリが重複対象として該当。
- play-services-ads-identifier
- play-services-basement
- facebook-android-wrapper
対応方法としては
- バージョンを合わせる
- 依存関係を無効化する
- 重複ライブラリを除外する
といった案が考えられるようだ。
重複ライブラリを除外する
Androidプロジェクト上ではbuild.gradle
のdependencies
から対象のimplementationを削除することで、ビルドエラーが解消されapkの生成ができた。
dependencies {
...
implementation(name: 'play-services-ads-identifier-16.0.0', ext:'aar')
implementation(name: 'play-services-basement-16.0.1', ext:'aar')
implementation(name: 'facebook-android-wrapper-7.16.1', ext:'aar')
...
}
とはいえ毎回UnityからAndroidプロジェクト吐いてAndroid Studioでビルドするのはダル過ぎる。そんなのはiOSだけで十分です。
軽く調べてみると、Unityプロジェクト上ではmainTemplate.gradle
を自前で用意して依存関係を書かなければならないらしい。
ちょっと時間も無くて「なるほどわからん」って感じだったので、重複してるaarファイルのバージョン低い方を削除するという力技でUnity上でもビルドエラーを解決(^ω^)
その後、対象ライブラリが関係している広告まわりを実装。ひと通りの動作確認でも問題なさそうだったのでクローズとした。
Androidのビルドエラー解消しんどい
Androidのライブラリ競合問題、5年くらい前から悩まされてた気がするけど、未だにサクッと解消できなくてつらい。はやくAIに仕事奪われたい。