Как создавать Unity3D-проекты для Holo-Lens, используя Jenkins и MsBuild на Windows

Цель

Мы хотим настроить автоматические сборки для наших проектов Unity, используя MSBuild и MSBuild-Plug-In на Jenkins.

Моя конфигурация

Соответственно Build-Step выглядит

Build a Visual Studio project or solution using MSBuild


MSBuild Version                    VisualStudio-MSBuild-15

MSBuild Build File                 E:\Jenkins\workspace\000_BUILD\<MyProjectName>

Command Line Arguments             /m /p:Configuration=Release /p:Plattform=x86

Pass build variables as properties [x]

Do not use chcp command            [ ]

и конфигурация MSBuild

где я использую MSBuild из нашей установки VisualStudio 2017.
Это приводит в итоге к пакетной команде, такой как

cmd.exe /C " chcp 1252 & E:\VisualStudio\MSBuild\15.0\Bin\msbuild.exe /m /p:Configuration=Release /p:Platform=x86 "E:\Jenkins\workspace\000_BUILDS\MY_PROJECT\My Project.sln" " && exit %%ERRORLEVEL%%

Просто скажу это, чтобы прояснить, что мой вопрос напрямую не зависит от Дженкинса.


Моя проблема:

Я получаю 72 сообщения об ошибках, большинство из которых выглядят как (перевод с немецкого)

2> Свойства \AssemblyInfo.cs(8,12): ошибка CS0246: Тип или пространство имен "AssemblyTitleAttribute" не найдены (возможно, отсутствует директива using или ссылка на сборку).

некоторым из них тоже нравится (перевод с немецкого)

2> Свойства \AssemblyInfo.cs(9,32): ошибка CS0518: предопределенный тип "System.String" не определен или не импортирован.


Может быть, намек? Если я создаю тот же проект (я остановил задание jenkins после завершения извлечения из git) непосредственно в VisualStudio, он выдает 2 предупреждения о некоторых устаревших вызовах, но AppPackage создается без каких-либо ошибок.

И странная вещь:
После того, как я успешно собрал проект в VisualStudio, я также могу построить проект с помощью MSBuild из командной строки, получить тот же вывод (2 предупреждения, но без ошибок) и собрать свой AppPackage.


ВОПРОС

Что я делаю неправильно?
Чем VisualStudio из GUI отличается от MSBuild из командной строки?
Возможно, мне не хватает шага или опции для MSbuild?

1 ответ

Решение

Проблема была в том, что я не восстанавливал Nuget-Packages перед сборкой с использованием MSBuild. (При открытии Visual-Studio в графическом интерфейсе кажется, что этот шаг выполняется автоматически.)

Итак, вот полное решение от Unity-проекта до пакета приложений Holo-Lens, которое наконец-то сработало для меня:

Создать пакет Unity CommandLineBuild

Прежде всего, чтобы иметь возможность создавать Unity-проект через командную строку, вам нужен специальный класс.

Это должно быть помещено в /Assets/Editor вашего проекта:

using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;
using System;

namespace JENKINS
{
    public class AutoBuilder : ScriptableObject
    {
        static string[] SCENES = FindEnabledEditorScenes();

        // Use real app name here
        /* Anyway the App will have the name as configured within the Unity-Editor
           This Appname is just for the Folder in which to Build */
        static string APP_NAME;
        static string TARGET_DIR;

        [MenuItem("Custom/CI/Windows Mixed Reality Build (UWP)")]
        public static void PerformWindowsMixedRealityBuild()
        {
            APP_NAME = GetArg("-appName");
            TARGET_DIR = GetArg("-buildFolder");
            Debug.Log("Jenkins-Build: APP_NAME: " + APP_NAME + " TARGET_DIR: " + TARGET_DIR);

            GenericBuild(SCENES, TARGET_DIR + "/" + APP_NAME, BuildTargetGroup.WSA, BuildTarget.WSAPlayer, BuildOptions.AllowDebugging);
        }

        private static string[] FindEnabledEditorScenes()
        {
            List<string> EditorScenes = new List<string>();

            foreach (EditorBuildSettingsScene scene in EditorBuildSettings.scenes)
            {
                if (!scene.enabled) continue;
                EditorScenes.Add(scene.path);
            }

            return EditorScenes.ToArray();
        }

        private static void GenericBuild(string[] scenes, string app_target, BuildTargetGroup build_target_group, BuildTarget build_target, BuildOptions build_options)
        {
            EditorUserBuildSettings.SwitchActiveBuildTarget(build_target_group, BuildTarget.WSAPlayer);

            string res = BuildPipeline.BuildPlayer(scenes, app_target, build_target, build_options);
            if (res.Length > 0)
            {
                throw new Exception("BuildPlayer failure: " + res);
            }
        }

        /**
         * Get Arguments from the command line by name
         */
        private static string GetArg(string name)
        {
            var args = System.Environment.GetCommandLineArgs();

            for (int i = 0; i < args.Length; i++)
            {
                if (args[i] == name && args.Length > i + 1)
                {
                    return args[i + 1];
                }
            }

            return null;
        }
    }
}

Но так как вы не хотите импортировать этот пакет в каждый ваш проект, пусть Jenkins импортирует его на лету.

Для этого я создал класс в пустом проекте

и экспортировать это как AutoBuilder.unityproject:

  1. щелкните правой кнопкой мыши на Assets и нажмите на Export package...
  2. Выберите место для сохранения
    (Я положил свой под E:\UnityPackage\AutoBuilder.unitypackage.)

Шаги сборки

Unity-Plugin а также MSBuild-Plugin у меня не получилось, поэтому я делаю каждый шаг в отдельном Batch-файле.

1. Импортировать пакет AutoBuild.unity в проект

Сначала нам нужно импортировать пакет before create unity to клонированный проект.

Бежать

<\Path\To\Your\Unity\Installation\>Editor\Unity.exe -quit -batchmode -username 'xxxxxxxxxxxxx' -password 'xxxxxxxxxxx' -logFile uniytImportLog.txt -importPackage E:\UnityPackage\AutoBuilder.unitypackage

Unity - Manual: аргументы командной строки

  • -quit: Сделать выход из Unity после завершения импорта
  • -batchmode: Не открывайте / не загружайте графический интерфейс и сразу выходите из 1 при любой ошибке
  • (необязательный) -username а также -password: Предоставьте свои учетные данные, чтобы Unity могла найти вашу лицензию (при необходимости)
  • (необязательный) -logFile: Записать вывод в файл журнала (поскольку Unity в пакетном режиме его не показывает!)
  • -importPackage: Наконец скажите Unity, что делать; в этом случае импортируйте наш файл unitypackage (измените его на место, где вы сохранили AutoBuilder.unitypackage к)

2. Запустите Unity-Build для Visual-Studio-Solution (.sln)

Теперь проект готов для сборки через командную строку .sln решение.

Бежать

<\Path\To\Your\Unity\Installation\>Editor\Unity.exe -quit -batchmode -username 'xxxxxxxxxxxxx' -password 'xxxxxxxxxxx' -logFile uniytBuildLog.txt -buildTarget wsaplayer -executeMethod JENKINS.AutoBuilder.PerformWindowsMixedRealityBuild  -appName %JOB_NAME% -buildFolder %WORKSPACE%\00_BUILD

Unity - Manual: аргументы командной строки

  • -quit: Сделать выход из Unity после завершения импорта
  • -batchmode: Не открывайте / не загружайте графический интерфейс и сразу выходите из 1 при любой ошибке
  • (необязательный) -username а также -password: Предоставьте свои учетные данные, чтобы Unity могла найти вашу лицензию (при необходимости)
  • (необязательный) -logFile: Записать вывод в файл журнала (поскольку Unity в пакетном режиме его не показывает!)
  • -buildTarget: Переключитесь на соответствующую цель сборки перед загрузкой проекта. Для пакетов приложений это, например, wsaplayer
  • -executeMethod: Наконец скажите Unity, что делать; в этом случае выполните метод из нашего ранее импортированного класса AutoBuilder
  • -appName %JOB_NAME% а также -buildFolder %WORKSPACE%\00_BUILD: Метод, который мы вызываем, принимает / требует аргументов из командной строки.
    • -appName звучит немного обманчиво, так как на самом деле это единственная подпапка, в которую будет строиться Unity. %JOB_NAME% глобальная переменная среды Jenkins для фактического имени задания.
    • -buildFolder является основной папкой, в которую будет собираться Unity. %WORKSPACE% является глобальной переменной среды Jenkins для папки рабочего пространства фактического задания.

НОТА
Перед последними последними двумя шагами, вы должны знать, как .sln Файл вызывается после Unity-Build.

Я приду отсюда что-то вроде YourProject.sln хранится в переменной App_Name потому что это определено в Unity:

Зайдите в Редактировать -> Настройки проекта -> Настройки плеера и изменить Product Name


3. Восстановите Nuget-пакеты (это был в основном шаг, который я пропустил раньше)

Чтобы восстановить nuget-пакеты (Visual-Studio обычно делает это автоматически при открытии решения в графическом интерфейсе), запустите

cmd.exe /C " chcp 1252 & <Path\To\Your\Visual-Studio\Installation>\MSBuild\15.0\Bin\msbuild.exe /m /t:restore /p:Configuration=Release /p:Platform=x86 "%WORKSPACE%\00_BUILD\%JOB_NAME%\%App_Name%" "

Справочник по командной строке MSBuild

  • /m: Определяет максимальное количество одновременных процессов для использования при сборке. Если этот параметр не включен, значение по умолчанию равно 1. Если этот параметр включен без указания значения, MSBuild будет использовать вплоть до числа процессоров в компьютере.
  • /t: Построить указанные цели в проекте.
  • /p: Установите или переопределите указанные свойства уровня проекта, где name - это имя свойства, а value - значение свойства. (-> для голо-линз это Configuration=Release а также Plattform=x86)
  • WORKSPACE: Глобальная переменная среды Jenkins для текущей папки рабочего пространства Job
  • 00_BUILD: мы передали это как параметр -buildFolder на шаг построения Unity.
  • JOB_NAME: Глобальная переменная среды Jenkins для фактического имени задания
  • App_Name: как уже упоминалось ранее название построенного Visual-Studio-Solution (.sln)

Это только сделает восстановление и пока не построит проект.

4. Создайте окончательный пакет приложений с помощью MSBuild.

Мне не понравилось MSBuild-Plugin для Дженкинса, поэтому я сделал это в командном файле и использовал команду, которая была произведена плагином ранее. Но выполнение этого в командном файле дало мне больше гибкости с точки зрения определения, например, целевого файла.

cmd.exe /C " chcp 1252 & <Path\To\Your\Visual-Studio\Installation>\MSBuild\15.0\Bin\msbuild.exe /m /t:restore /p:Configuration=Release /p:Platform=x86 "%WORKSPACE%\00_BUILD\%JOB_NAME%\%App_Name%" "

Справочник по командной строке MSBuild

  • /m: Определяет максимальное количество одновременных процессов для использования при сборке. Если этот параметр не включен, значение по умолчанию равно 1. Если этот параметр включен без указания значения, MSBuild будет использовать вплоть до числа процессоров в компьютере.
  • /t: Построить указанные цели в проекте.
  • /p: Установите или переопределите указанные свойства уровня проекта, где name - это имя свойства, а value - значение свойства. (-> для голо-линз это Configuration=Release а также Plattform=x86)
  • WORKSPACE: Глобальная переменная среды Jenkins для текущей папки рабочего пространства Job
  • 00_BUILD: мы передали это как параметр -buildFolder на шаг построения Unity.
  • JOB_NAME: Глобальная переменная среды Jenkins для фактического имени задания
  • App_Name: как уже упоминалось ранее название построенного Visual-Studio-Solution (.sln)

После завершения вы должны иметь окончательный пакет приложений под

%WORKSPACE%\000_BUILD\%JOB_NAME%\%App_Name%\AppPackages
Другие вопросы по тегам