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

974
derHugo

Цель

Мы хотим настроить автоматические сборки для наших проектов 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

где я использую 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> Properties \ 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
Я думаю, что вы должны использовать unityeditor.exe для создания проекта Unity из командной строки. Для этого вам нужно будет создать специальный класс, который будет вызываться с помощью Unity. npocmaka 6 лет назад 0
Конечно, это уже произошло до этого шага. В противном случае не было бы файла .sln для сборки. derHugo 6 лет назад 0
ахам..хорошо. любой прогресс в этом? Я также хочу использовать msbuild с единицей (в основном для анализа кода, потому что я не знаю, как генерировать командную строку fxCop, но msbuild знает ...) npocmaka 6 лет назад 0
Эй, @npocmaka Я действительно решил это довольно давно;) Мне потребовалось некоторое время, чтобы ответить на мой вопрос, поэтому, пожалуйста, смотрите ниже;) derHugo 6 лет назад 0

1 ответ на вопрос

1
derHugo

Проблема была в том, что я не восстанавливал 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.cs in an empty Unity-Project

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

  1. right-clickна Assetsи нажмитеExport package... enter image description hereenter image description here
  2. Выберите место, где сохранить его
    (я поставил под E:\UnityPackage\AutoBuilder.unitypackage.)

Шаги сборки

Unity-PluginИ MSBuild-Pluginне работает хорошо для меня, так что я делаю каждый шаг в выделенном пакетном файле.

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 для текущей папки рабочего пространства Job.

ПРИМЕЧАНИЕ
Перед последними двумя последними шагами вы должны знать, как .slnфайл вызывается после Unity-Build.

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

Перейти к Edit-> Project Settings-> Player Settings Go to Edit -> Project Settings -> Player Settings и изменитьProduct Name Change 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-Pluginfor jenkins, поэтому я сделал это в командном файле и использовал команду, созданную плагином ранее. Но выполнение этого в командном файле дало мне больше гибкости с точки зрения определения, например, целевого файла.

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