前回、Azure DevOps で HoloLens のビルド環境を行うこと、Microsoft-hosted Agent が今ならいいということを書きました。
今回は、MRTKとMRTKv2 を Microsoft-hosted Agent で現実的にビルドすることを考えてみましょう。 内容としては、次の記事が近いです。
この記事では、MRTKv1とMRTKv2 それぞれについてリポジトリとAzure Devops Pipeline の YAMLを示しつつ、現実にビルドしていくことに必要なことをカバーします。
目次
Unity のビルドエラーがわからない
Windows上でUnityのバッチビルドをしたときに困るのが、Unity ビルドの経過、ログが標準出力に出ないことです。*1
結果Unity 内部でどのようなエラーが起こってもエラーの詳細がわからないので、記事にあるUnityBuildTask@2
を使う方法は現実的ではありません。*2
コンパイルエラーでどこでコンパイルエラー出たかわからないとか絶望です。
そのため、Unity Tools for Azure DevOps
でUnity ビルドを行うのは厳しいものがあります。
- task: UnityBuildTask@2 displayName: 'Unity Build WindowsStoreApps' name: 'unityBuild' inputs: buildTarget: 'WindowsStoreApps' unityEditorsPathMode: 'unityHub' unityProjectPath: '$(unityProjectPath)' commandLineArgumentsMode: 'default'
代わりに「Unityビルド呼び出しつつlogファイルに吐いたログを読み込んで標準出力に吐く」ラッパーアプリケーションを用意する方法をよく採用されています。
お手伝い先で必要になり一年前に作り使っていただいているのが UnityBuildRunner
です。*3
dotnet global tool として公開してあるので、dotnet tool install -g UnityBuildRunner
でWindows/Mac問わずサクッとインストールできます。
使い方は単純です。Unity のバッチビルドは次のフォーマットです。
Unity.exe [args]
この引数をUnityBuildRunnerにそのまま渡せばokです。 加えてタイムアウトにも対応してあります。
UnityBuildRunner [-UnityPath|-unityPath|-u] [-timeout|-t 00:60:00] [-version] [-help] [args]
たとえば、MRTKv2 でビルドするならこのように書けます。
UnityBuildRunner -UnityPath "C:\Program Files\Unity\Hub\Editor\2018.3.13f1\Editor\Unity.exe" -quit -batchmode -projectPath パス -buildTarget WSAPlayer -logfile Editor.log -executeMethod Microsoft.MixedReality.Toolkit.Build.Editor.UnityPlayerBuildTools.StartCommandLineBuild
Unityパスは環境変数から読むこともできるので次のようにも書けます。
set unityPath=C:\Program Files\Unity\Hub\Editor\2018.3.13f1\Editor\Unity.exe UnityBuildRunner -quit -batchmode -projectPath パス -buildTarget WSAPlayer -logfile Editor.log -executeMethod Microsoft.MixedReality.Toolkit.Build.Editor.UnityPlayerBuildTools.StartCommandLineBuild
MRTKv1 のビルドを行う
MRTK のビルドは、HoloToolkit.Unity.BuildDeployTools.BuildSLN
メソッドを使います。*4
MRTKv2を使ったビルドとYAML定義を含んだリポジトリです。
Azure DevOps でのビルド結果も示します。
ビルドのYAML定義を見てみましょう。
途中のコメントを外すとsln一式がartifacts から取得できます。
# if you want to build locally # - task: PublishPipelineArtifact@0 # displayName: 'Publish Pipeline Artifact' # inputs: # artifactName: 'UWP_Sln' # targetPath: 'UWP'
ちなみにMRTKv1 のシンプルなシーンをビルドしてみると、ビルドに30min、長い。
プロジェクト固有の情報を知らずビルドするコツとして、VSビルド時にslnファイルを指定するのではなくslnのあるフォルダを指定 + /
と書くことでslnビルドできます。/
がないとsln が見つからないので注意です。
MRTKv2 のビルドを行う
MRTKv2 は、Windows SDK 18362 が必要ですが、これがHosted Agent に来てビルドできるようになったのは6/25です。 Sprint 153 で追加対応が来てから、自分たちのAgent にくるまで約2週間かかりました。
MRTKv2のビルドは、Microsoft.MixedReality.Toolkit.Build.Editor.UnityPlayerBuildTools.StartCommandLineBuild
メソッドを使います。
相変わらずDevelopment ビルドの指定ができないのがアレなのでラッパーを書くことになるでしょう。
MRTKv1を使ったビルドとYAML定義を含んだリポジトリです。
Azure DevOps でのビルド結果も示します。
ビルド定義のYAMLは次のようになります。
途中のコメントを外すとsln一式がartifacts から取得できます。
# if you want to build locally #- task: PublishPipelineArtifact@0 # displayName: 'Publish Pipeline Artifact' # inputs: # artifactName: 'sln' # targetPath: 'Builds/WSAPlayer'
MRTKv2 のサンプルシーンをビルドしてみると、ビルドに30min、長い。
プロジェクト固有の情報を知らずビルドするコツとして、VSビルド時にslnファイルを指定するのではなくslnのあるフォルダを指定
と書くことでslnビルドできます。先ほどと違い、/
で終わるとsln が見つからないので注意です。
学び
Unityのインストールにかかる時間
Microsft-hosted Agent にはUnity がインストールされていません。 そのためこのYAML ではUnityを都度インストールしています。
このUnityの準備にかかる時間をリードタイムとしてみると、10min 程度かかります。 毎ビルドで10min かかるのはアレでもあり、その程度で済むならいいかもしれません。((よくない)))
Output変数が定義されたタスクの変数はnameを指定することでとれるようになる
UnityGetProjectVersionTask@1 で取得したUnityバージョンを変数に出力します。 これを使うことでUnityプロジェクトのバージョンを知ることなく、同じYAMLをどのUnityバージョンでも変わらず使えます。
さて、UI と違って YAML では reference variable の設定はサポートされていません。
しかしTASKで出力変数が設定されている場合は、name
をつけることで取得できます。
- task: DinomiteStudios.64e90d50-a9c0-11e8-a356-d3eab7857116.custom-unity-get-project-version-task.UnityGetProjectVersionTask@1 displayName: 'Unity Get Project Version' name: unitygetprojectversion
これで、後段のstep において $(unitygetprojectversion.projectVersion)
で参照できます。
教えてもらって気づきました、これはむりげー。