So erstellen Sie Unity3D-Projekte für Holo-Lens mit Jenkins und MsBuild unter Windows

1098
derHugo

Tor

Wir möchten automatisierte Builds für unsere Unity-Projekte mit MSBuild und dem MSBuild-Plug-In für Jenkins einrichten.

Meine Konfiguration

Der entsprechende Build-Step sieht so aus

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 [ ] 

und die MSBuild-Konfiguration ist MSBuild-Konfiguration

Wo ich MSBuild von unserer VisualStudio 2017-Installation verwende.
Dies führt am Ende zu einem Batchbefehl wie

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%% 

Ich möchte nur sagen, dass meine Frage nicht direkt von Jenkins abhängt.


Mein Problem:

Ich erhalte 72 Fehlermeldungen, die meisten sehen aus wie

2> Eigenschaften \ AssemblyInfo.cs (8,12): Fehler CS0246: Der Typ oder Namespace "AssemblyTitleAttribute" wurde nicht gefunden (wahrscheinlich fehlt eine using-Direktive oder eine Assemblyreferenz).

einige von ihnen mögen auch

2> Eigenschaften \ AssemblyInfo.cs (9,32): Fehler CS0518: Der vordefinierte Typ "System.String" ist nicht definiert oder importiert.


Vielleicht ein Hinweis? Wenn ich dasselbe Projekt direkt baue (ich habe den Jenkins-Job gestoppt, nachdem git fertig gestellt wurde), werden direkt in VisualStudio 2 Warnungen über einige veraltete Aufrufe ausgegeben, das AppPackage wird jedoch ohne Fehler erstellt.

Und das Merkwürdige :
Nachdem ich das Projekt einmal erfolgreich in VisualStudio erstellt habe, kann ich das Projekt auch mit MSBuild von der Kommandozeile aus erstellen, dieselbe Ausgabe erhalten (2 Warnungen, aber keine Fehler) und mein AppPackage aufgebaut haben.


FRAGE

Was mache ich falsch?
Was unterscheidet VisualStudio von der grafischen Benutzeroberfläche von MSBuild von der Befehlszeile?
Vermisse ich vielleicht einen Schritt oder eine Option für MSbuild?

1
Ich denke, Sie sollten unityeditor.exe verwenden, um ein Unity-Projekt über die Befehlszeile zu erstellen. Zu diesem Zweck müssen Sie eine spezielle Klasse erstellen, die von Unity aufgerufen wird. npocmaka vor 6 Jahren 0
Natürlich geschah dies bereits vor diesem Schritt. Andernfalls müsste keine .sln-Datei erstellt werden derHugo vor 6 Jahren 0
ahaam..Ok dann.Jeder Fortschritt auf dieser? Ich möchte auch msbuild mit unity verwenden (im Grunde für Codeanalysen, weil ich nicht weiß, wie man eine fxCop-Befehlszeile erzeugt, aber msbuild weiß ...) npocmaka vor 6 Jahren 0
Hey @npocmaka Ich habe das eigentlich schon vor einiger Zeit gelöst;) Ich habe einige Zeit gebraucht, um meine Frage zu beantworten, siehe unten;) derHugo vor 6 Jahren 0

1 Antwort auf die Frage

1
derHugo

Das Problem war, dass ich Nuget-Packages vor dem Bauen mit MSBuild nicht wiederhergestellt habe. (Das Öffnen von Visual-Studio in der GUI scheint diesen Schritt automatisch auszuführen.)

Hier nun die vollständige Lösung von einem Unity-Projekt bis zu einem Holo-Lens-App-Paket, das endlich für mich funktioniert hat:

Erstellen Sie das Unity CommandLineBuild-Paket

Um ein Unity-Projekt über die Befehlszeile erstellen zu können, benötigen Sie eine spezielle Klasse.

Dies muss in /Assets/EditorIhrem Projekt platziert werden:

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; } } } 

Da Sie dieses Paket jedoch nicht in jedes Projekt importieren möchten, lassen Sie es von Jenkins im laufenden Betrieb importieren.

Dafür habe ich die Klasse in einem leeren Projekt angelegt AutoBuilder.cs in einem leeren Unity-Projekt

und exportieren Sie es als AutoBuilder.unityproject:

  1. right-clickein Assetsund klicken Sie aufExport package...
  2. Wählen Sie einen Ort, an dem Sie ihn speichern möchten
    (ich lege meinen unter E:\UnityPackage\AutoBuilder.unitypackage.)

Schritte bauen

Das Unity-Pluginund MSBuild-Pluginfunktionierte nicht gut für mich, daher mache ich jeden Schritt in einer dedizierten Batch-Datei.

1. Importieren Sie AutoBuild.unitypackage in das Projekt

Zunächst müssen wir das Unitypackage vor dem Erstellen in das eigentliche geklonte Projekt importieren.

Lauf

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

Unity - Manual: Befehlszeilenargumente

  • -quit: Nach Abschluss des Imports Unity beenden
  • -batchmode: Öffnen / laden Sie die GUI nicht und beenden Sie bei einem Fehler sofort 1
  • (optional) -usernameund -password: Geben Sie Ihre Anmeldeinformationen an, damit Unity Ihre Lizenz nachschlagen kann (falls erforderlich).
  • (optional) -logFile: Schreibe die Ausgabe in eine Protokolldatei (da Unity im Batch-Modus sie nicht anzeigt!)
  • -importPackage: Schließlich sagen Sie der Einheit, was sie tun soll. In diesem Fall importieren Sie unsere Unitypackage-Datei (Ändern Sie dies in den Speicherort, an dem Sie gespeichert haben AutoBuilder.unitypackage).

2. Führen Sie den Unity-Build für eine Visual-Studio-Lösung (.sln) aus.

Nun kann das Projekt per Kommandozeile zu einer .slnLösung zusammengestellt werden.

Lauf

<\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: Befehlszeilenargumente

  • -quit: Nach Abschluss des Imports Unity beenden
  • -batchmode: Öffnen / laden Sie die GUI nicht und beenden Sie bei einem Fehler sofort 1
  • (optional) -usernameund -password: Geben Sie Ihre Anmeldeinformationen an, damit Unity Ihre Lizenz nachschlagen kann (falls erforderlich).
  • (optional) -logFile: Schreibe die Ausgabe in eine Protokolldatei (da Unity im Batch-Modus sie nicht anzeigt!)
  • -buildTarget: Wechseln Sie vor dem Laden des Projekts zum entsprechenden Build-Ziel. Für App-Pakete ist es zwsaplayer
  • -executeMethod: Schließlich sagen Sie der Einheit, was sie tun soll. In diesem Fall führen Sie die Methode aus unserer zuvor importierten AutoBuilder-Klasse aus
  • -appName %JOB_NAME%und -buildFolder %WORKSPACE%\00_BUILD: Die von uns aufgerufene Methode benötigt Argumente von der Kommandozeile aus.
    • -appNameklingt ein wenig irreführend, da es eigentlich nur der Unterordner ist, in den Unity erstellt wird. %JOB_NAME%ist die globale Jenkins-Umgebungsvariable für den tatsächlichen Jobnamen.
    • -buildFolderist der Hauptordner, in den Unity erstellt wird. %WORKSPACE%ist die globale Jenkins-Umgebungsvariable für den Arbeitsbereichsordner des aktuellen Jobs.

HINWEIS
Vor den folgenden letzten beiden Schritten müssen Sie wissen, wie die .slnDatei nach dem Unity-Build aufgerufen wird.

Ich werde davon ausgehen, dass YourProject.slnin der Variablen etwas enthalten ist, App_Nameda es in Unity definiert ist:

Gehe zu Edit-> Project Settings-> Player Settings Gehen Sie zu Bearbeiten -> Projekteinstellungen -> Player-Einstellungen und ändereProduct Name Produktname ändern


3. Nuget-Pakete wiederherstellen (dies war hauptsächlich der Schritt, den ich zuvor vermisst hatte)

Zum Wiederherstellen von Nuget-Paketen (dies wird normalerweise beim Öffnen der Lösung in der GUI automatisch von Visual-Studio ausgeführt)

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-Befehlszeilenreferenz

  • /m: Gibt die maximale Anzahl gleichzeitiger Prozesse an, die beim Erstellen verwendet werden sollen. Wenn Sie diesen Schalter nicht angeben, ist der Standardwert 1. Wenn Sie diesen Schalter ohne Angabe eines Werts einschließen, verbraucht MSBuild die Anzahl der Prozessoren im Computer.
  • /t: Erstellen Sie die angegebenen Ziele im Projekt.
  • /p: Legen Sie die angegebenen Eigenschaften auf Projektebene fest oder überschreiben Sie sie, wobei name der Eigenschaftsname und value der Eigenschaftswert ist. (-> für Holo-Lens ist es Configuration=Releaseund Plattform=x86)
  • WORKSPACE: Jenkins 'globale Umgebungsvariable für den Arbeitsbereichsordner des aktuellen Jobs
  • 00_BUILD: Wir haben dies als Parameter -buildFolderan den Unity-Build-Schritt übergeben.
  • JOB_NAME: Jenkins 'globale Umgebungsvariable für den tatsächlichen Jobnamen
  • App_Name: wie bereits erwähnt, der Name der erstellten Visual-Studio-Solution ( .sln)

Dies wird nur die Wiederherstellung durchführen und das Projekt noch nicht erstellen.

4. Erstellen Sie das endgültige App-Paket mit MSBuild

Ich mochte die MSBuild-Pluginfor jenkins nicht, also habe ich sie in einer Batch-Datei erstellt und den Befehl verwendet, der zuvor vom Plugin erzeugt wurde. Aber wenn ich es in einer Batch-Datei mache, habe ich mehr Flexibilität in Bezug auf die Definition der Zieldatei.

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-Befehlszeilenreferenz

  • /m: Gibt die maximale Anzahl gleichzeitiger Prozesse an, die beim Erstellen verwendet werden sollen. Wenn Sie diesen Schalter nicht angeben, ist der Standardwert 1. Wenn Sie diesen Schalter ohne Angabe eines Werts einschließen, verbraucht MSBuild die Anzahl der Prozessoren im Computer.
  • /t: Erstellen Sie die angegebenen Ziele im Projekt.
  • /p: Legen Sie die angegebenen Eigenschaften auf Projektebene fest oder überschreiben Sie sie, wobei name der Eigenschaftsname und value der Eigenschaftswert ist. (-> für Holo-Lens ist es Configuration=Releaseund Plattform=x86)
  • WORKSPACE: Jenkins 'globale Umgebungsvariable für den Arbeitsbereichsordner des aktuellen Jobs
  • 00_BUILD: Wir haben dies als Parameter -buildFolderan den Unity-Build-Schritt übergeben.
  • JOB_NAME: Jenkins 'globale Umgebungsvariable für den tatsächlichen Jobnamen
  • App_Name: wie bereits erwähnt, der Name der erstellten Visual-Studio-Solution ( .sln)

Nach dem Beenden sollten Sie jetzt das endgültige App-Paket haben

%WORKSPACE%\000_BUILD\%JOB_NAME%\%App_Name%\AppPackages