DEV Community

KOGA Mitsuhiro
KOGA Mitsuhiro

Posted on • Originally published at qiita.com

Unity2018.2 + il2cppでgRPCアプリをAndroid/iOS向けにビルドする

はじめに

UnityでgRPCアプリ(iOS, Android)をビルドできるようになった」でUnityのiOS, AndroidでもgRPCアプリを動かせるようになりました。
ここから更にil2cppでビルドする際に起きる問題の対処をまとめました。

共通

*.protooneofenumを使っている場合はSystem.Reflection.Emitが走って実行時エラーになってしまいます。
protocで生成したコード中のenumすべてを以下のTに指定すると回避できます。
oneofenumを使った場合はそのフィールドを含むクラスもこの対策が必要みたいです。RPC周りの例外メッセージにSystem.Reflection.Emitが出てきたら対象のクラスを指定すれば大丈夫だと思います。

一度だけ実行すればいいので静的コンストラクタなどに書いておくといいでしょう。

using Google.Protobuf.Reflection;

FileDescriptor.ForceReflectionInitialization<T>();
Enter fullscreen mode Exit fullscreen mode

Android向け

C#: Fix il2cpp build on Unity Android. #18039でダミー関数がマージされたのでコピー不要になりました。

DLLImportの名前が合わずにリンク時にビルドエラーが発生してしまいます。
Unity2018.2からPluginsフォルダにcppを配置するとビルドされるようになったので、以下のダミー関数のソースを配置しInclude PlatformsからiOSEditorを除外します。

/Assets/Plugins/Grpc.Core/runtimes/grpc_csharp_ext_stub.c
/Assets/Plugins/Grpc.Core/runtimes/grpc_csharp_ext_stub.c.meta

image.png

ネットワークアクセスがgRPCのみだとAndroidManifest.xmlINTERNETパーミッションが付与されません。
確実に有効にするためにPlayerSettings > Other Settings > Internet AccessRequireにします。

image.png

iOS向け

iOS向けのライブラリのアーキテクチャはx86_64とarm64だけなのでPlayerSettings > Other Settings > ArchitectureARM64にします。

image.png

また、bitcode非対応なのでXCodeのBuild SettingsENABLE_BITCODENOにします。
Enable bitcode for ios native libraries #20113でbitcodeに対応するビルドオプションが追加されたので対処不要になりました。
bitcode対応するとlibgrpc.aが250MB以上増えたのでv1.24.xブランチはRevert "Enable bitcode for ios native libraries" in v1.24.x #20233で、masterブランチはa2dbf0a99d1fc1c0059dbb28c4b530a58584cd71で差し戻されてしまいました。

リンク対象のライブラリにlibzが必要なのでBuild Phases > Link Binary With Librariesから追加します。

この操作は以下のエディタ拡張を配置すればビルド時に自動的に反映できます。

参考にしたBuildHelper.cslibresolv.tbdを追加していますがビルドエラーにならなかったので今も必要なのかよく分かりません…
参考にした先と公式ではビルドオプションが異なり、公式のライブラリを使うならlibresolv.tbdは不要でした。

#if UNITY_IPHONE

using System.IO;
using UnityEngine;
using UnityEditor;
using UnityEditor.Callbacks;
using UnityEditor.iOS.Xcode;

public class BuildHelper
{
    // Add libz.tbd and disable bitcode when building for iOS
    // Thanks to https://github.com/jsmouret/grpc-unity-package/blob/master/example/UnityGrpcClient/Assets/Scripts/Editor/BuildHelper.cs

    [PostProcessBuildAttribute(1)]
    public static void OnPostProcessBuild(BuildTarget target, string path)
    {
        if (target == BuildTarget.iOS)
        {
            var projectPath = PBXProject.GetPBXProjectPath(path);
            var project = new PBXProject();
            project.ReadFromString(File.ReadAllText(projectPath));
            var targetGUID = project.TargetGuidByName(PBXProject.GetUnityTargetName());

            project.AddFrameworkToProject(targetGUID, "libz.tbd", false);

            project.SetBuildProperty(targetGUID, "ENABLE_BITCODE", "NO");

            File.WriteAllText(projectPath, project.WriteToString());
        }
    }
}

#endif
Enter fullscreen mode Exit fullscreen mode

最後に

2018/10/15現在、このような対策が必要ですが今後不要になったり対策が変わるかもしれないのでgrpc/grpcprotocolbuffers/protobufのissuesなどで動向を追ってください。

※追記
Experimentalパッケージが出る前のバージョンは「UnityプロジェクトでのgRPC導入方法について」の手順でビルドすれば利用できるようです。

参考リンク

Top comments (0)