Ejemplo n.º 1
0
        private static void ParseBuildCommandLine(ref UwpBuildInfo buildInfo)
        {
            IBuildInfo iBuildInfo = buildInfo;

            UnityPlayerBuildTools.ParseBuildCommandLine(ref iBuildInfo);

            string[] arguments = Environment.GetCommandLineArgs();

            for (int i = 0; i < arguments.Length; ++i)
            {
                switch (arguments[i])
                {
                case "-buildAppx":
                    buildInfo.BuildAppx = true;
                    break;

                case "-rebuildAppx":
                    buildInfo.RebuildAppx = true;
                    break;

                case "-targetUwpSdk":
                    // Note: the min sdk target cannot be changed.
                    EditorUserBuildSettings.wsaUWPSDK = arguments[++i];
                    break;
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Do a build configured for UWP Applications to the specified path, returns the error from <see cref="BuildPlayer(UwpBuildInfo, CancellationToken)"/>
        /// </summary>
        /// <param name="showDialog">Should the user be prompted to build the appx as well?</param>
        /// <returns>True, if build was successful.</returns>
        public static async Task <bool> BuildPlayer(string buildDirectory, bool showDialog = true, CancellationToken cancellationToken = default)
        {
            if (UnityPlayerBuildTools.CheckBuildScenes() == false)
            {
                return(false);
            }

            var buildInfo = new UwpBuildInfo
            {
                OutputDirectory            = buildDirectory,
                Scenes                     = EditorBuildSettings.scenes.Where(scene => scene.enabled && !string.IsNullOrEmpty(scene.path)).Select(scene => scene.path),
                BuildAppx                  = !showDialog,
                GazeInputCapabilityEnabled = UwpBuildDeployPreferences.GazeInputCapabilityEnabled,

                // Configure Appx build preferences for post build action
                RebuildAppx     = UwpBuildDeployPreferences.ForceRebuild,
                Configuration   = UwpBuildDeployPreferences.BuildConfig,
                BuildPlatform   = EditorUserBuildSettings.wsaArchitecture,
                PlatformToolset = UwpBuildDeployPreferences.PlatformToolset,
                AutoIncrement   = BuildDeployPreferences.IncrementBuildVersion,
                Multicore       = UwpBuildDeployPreferences.MulticoreAppxBuildEnabled,
                ResearchModeCapabilityEnabled = UwpBuildDeployPreferences.ResearchModeCapabilityEnabled,
                AllowUnsafeCode = UwpBuildDeployPreferences.AllowUnsafeCode,

                // Configure a post build action that will compile the generated solution
                PostBuildAction = PostBuildAction
            };

            async void PostBuildAction(IBuildInfo innerBuildInfo, BuildReport buildReport)
            {
                if (buildReport.summary.result != BuildResult.Succeeded)
                {
                    EditorUtility.DisplayDialog($"{PlayerSettings.productName} WindowsStoreApp Build {buildReport.summary.result}!", "See console for details", "OK");
                }
                else
                {
                    var uwpBuildInfo = innerBuildInfo as UwpBuildInfo;
                    Debug.Assert(uwpBuildInfo != null);
                    UwpAppxBuildTools.AddCapabilities(uwpBuildInfo);
                    UwpAppxBuildTools.UpdateAssemblyCSharpProject(uwpBuildInfo);

                    if (showDialog &&
                        !EditorUtility.DisplayDialog(PlayerSettings.productName, "Build Complete", "OK", "Build AppX"))
                    {
                        EditorAssemblyReloadManager.LockReloadAssemblies = true;
                        await UwpAppxBuildTools.BuildAppxAsync(uwpBuildInfo, cancellationToken);

                        EditorAssemblyReloadManager.LockReloadAssemblies = false;
                    }
                }
            }

            return(await BuildPlayer(buildInfo, cancellationToken));
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Do a build configured for UWP Applications to the specified path, returns the error from <see cref="BuildPlayer(UwpBuildInfo, CancellationToken)"/>
        /// </summary>
        /// <param name="buildDirectory"></param>
        /// <param name="showDialog">Should the user be prompted to build the appx as well?</param>
        /// <param name="cancellationToken"></param>
        /// <returns>True, if build was successful.</returns>
        public static async Task <bool> BuildPlayer(string buildDirectory, bool showDialog = true, CancellationToken cancellationToken = default)
        {
            if (UnityPlayerBuildTools.CheckBuildScenes() == false)
            {
                return(false);
            }

            var buildInfo = new UwpBuildInfo
            {
                OutputDirectory = buildDirectory,
                Scenes          = EditorBuildSettings.scenes.Where(scene => scene.enabled).Select(scene => scene.path),
                BuildAppx       = !showDialog,

                // Configure a post build action that will compile the generated solution
                PostBuildAction = PostBuildAction
            };

            async void PostBuildAction(IBuildInfo innerBuildInfo, BuildReport buildReport)
            {
                if (buildReport.summary.result != BuildResult.Succeeded)
                {
                    EditorUtility.DisplayDialog($"{PlayerSettings.productName} WindowsStoreApp Build {buildReport.summary.result}!", "See console for details", "OK");
                }
                else
                {
                    if (showDialog &&
                        !EditorUtility.DisplayDialog(PlayerSettings.productName, "Build Complete", "OK", "Build AppX"))
                    {
                        var _buildInfo = innerBuildInfo as UwpBuildInfo;
                        Debug.Assert(_buildInfo != null);
                        EditorAssemblyReloadManager.LockReloadAssemblies = true;
                        await UwpAppxBuildTools.BuildAppxAsync(_buildInfo, cancellationToken);

                        EditorAssemblyReloadManager.LockReloadAssemblies = false;
                    }
                }
            }

            return(await BuildPlayer(buildInfo, cancellationToken));
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Build the Uwp Player.
        /// </summary>
        /// <param name="buildInfo"></param>
        /// <param name="cancellationToken"></param>
        public static async Task <bool> BuildPlayer(UwpBuildInfo buildInfo, CancellationToken cancellationToken = default)
        {
            #region Gather Build Data

            if (buildInfo.IsCommandLine)
            {
                ParseBuildCommandLine(ref buildInfo);
            }

            #endregion Gather Build Data

            BuildReport buildReport = UnityPlayerBuildTools.BuildUnityPlayer(buildInfo);

            bool success = buildReport != null && buildReport.summary.result == BuildResult.Succeeded;

            if (success && buildInfo.BuildAppx)
            {
                success &= await UwpAppxBuildTools.BuildAppxAsync(buildInfo, cancellationToken);
            }

            return(success);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Build the UWP appx bundle for this project.  Requires that <see cref="UwpPlayerBuildTools.BuildPlayer(string,bool,CancellationToken)"/> has already be run or a user has
        /// previously built the Unity Player with the WSA Player as the Build Target.
        /// </summary>
        /// <returns>True, if the appx build was successful.</returns>
        public static async Task <bool> BuildAppxAsync(UwpBuildInfo buildInfo, CancellationToken cancellationToken = default)
        {
            if (!EditorAssemblyReloadManager.LockReloadAssemblies)
            {
                Debug.LogError("Lock Reload assemblies before attempting to build appx!");
                return(false);
            }

            if (IsBuilding)
            {
                Debug.LogWarning("Build already in progress!");
                return(false);
            }

            if (Application.isBatchMode)
            {
                // We don't need stack traces on all our logs. Makes things a lot easier to read.
                Application.SetStackTraceLogType(LogType.Log, StackTraceLogType.None);
            }

            Debug.Log("Starting Unity Appx Build...");

            IsBuilding = true;
            string slnFilename = Path.Combine(buildInfo.OutputDirectory, $"{PlayerSettings.productName}.sln");

            if (!File.Exists(slnFilename))
            {
                Debug.LogError("Unable to find Solution to build from!");
                return(IsBuilding = false);
            }

            // Get and validate the msBuild path...
            var msBuildPath = await FindMsBuildPathAsync();

            if (!File.Exists(msBuildPath))
            {
                Debug.LogError($"MSBuild.exe is missing or invalid!\n{msBuildPath}");
                return(IsBuilding = false);
            }

            // Ensure that the generated .appx version increments by modifying Package.appxmanifest
            try
            {
                if (!UpdateAppxManifest(buildInfo))
                {
                    throw new Exception();
                }
            }
            catch (Exception e)
            {
                Debug.LogError($"Failed to update appxmanifest!\n{e.Message}");
                return(IsBuilding = false);
            }

            string storagePath         = Path.GetFullPath(Path.Combine(Path.Combine(Application.dataPath, ".."), buildInfo.OutputDirectory));
            string solutionProjectPath = Path.GetFullPath(Path.Combine(storagePath, $@"{PlayerSettings.productName}.sln"));

            int exitCode;

            // Building the solution requires first restoring NuGet packages - when built through
            // Visual Studio, VS does this automatically - when building via msbuild like we're doing here,
            // we have to do that step manually.
            // We use msbuild for nuget restore by default, but if a path to nuget.exe is supplied then we use that executable
            if (string.IsNullOrEmpty(buildInfo.NugetExecutablePath))
            {
                exitCode = await Run(msBuildPath,
                                     $"\"{solutionProjectPath}\" /t:restore {GetMSBuildLoggingCommand(buildInfo.LogDirectory, "nugetRestore.log")}",
                                     !Application.isBatchMode,
                                     cancellationToken);
            }
            else
            {
                exitCode = await Run(buildInfo.NugetExecutablePath,
                                     $"restore \"{solutionProjectPath}\"",
                                     !Application.isBatchMode,
                                     cancellationToken);
            }

            if (exitCode != 0)
            {
                IsBuilding = false;
                return(false);
            }

            // Need to add ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch to MixedRealityToolkit.vcxproj
            if (buildInfo.BuildPlatform == "arm64")
            {
                if (!UpdateVSProj(buildInfo))
                {
                    return(IsBuilding = false);
                }
            }

            // Now that NuGet packages have been restored, we can run the actual build process.
            exitCode = await Run(msBuildPath,
                                 $"\"{solutionProjectPath}\" {(buildInfo.Multicore ? "/m /nr:false" : "")} /t:{(buildInfo.RebuildAppx ? "Rebuild" : "Build")} /p:Configuration={buildInfo.Configuration} /p:Platform={buildInfo.BuildPlatform} {(string.IsNullOrEmpty(buildInfo.PlatformToolset) ? string.Empty : $"/p:PlatformToolset={buildInfo.PlatformToolset}")} {GetMSBuildLoggingCommand(buildInfo.LogDirectory, "buildAppx.log")}",
                                 !Application.isBatchMode,
                                 cancellationToken);

            AssetDatabase.SaveAssets();

            IsBuilding = false;
            return(exitCode == 0);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Build the UWP appx bundle for this project.  Requires that <see cref="UwpPlayerBuildTools.BuildPlayer(string,bool,CancellationToken)"/> has already be run or a user has
        /// previously built the Unity Player with the WSA Player as the Build Target.
        /// </summary>
        /// <param name="buildInfo"></param>
        /// <param name="cancellationToken"></param>
        /// <returns>True, if the appx build was successful.</returns>
        public static async Task <bool> BuildAppxAsync(UwpBuildInfo buildInfo, CancellationToken cancellationToken = default)
        {
            if (!EditorAssemblyReloadManager.LockReloadAssemblies)
            {
                Debug.LogError("Lock Reload assemblies before attempting to build appx!");
                return(false);
            }

            if (IsBuilding)
            {
                Debug.LogWarning("Build already in progress!");
                return(false);
            }

            if (Application.isBatchMode)
            {
                // We don't need stack traces on all our logs. Makes things a lot easier to read.
                Application.SetStackTraceLogType(LogType.Log, StackTraceLogType.None);
            }

            Debug.Log("Starting Unity Appx Build...");

            IsBuilding = true;
            string slnFilename = Path.Combine(buildInfo.OutputDirectory, $"{PlayerSettings.productName}.sln");

            if (!File.Exists(slnFilename))
            {
                Debug.LogError("Unable to find Solution to build from!");
                return(IsBuilding = false);
            }

            // Get and validate the msBuild path...
            var msBuildPath = await FindMsBuildPathAsync();

            if (!File.Exists(msBuildPath))
            {
                Debug.LogError($"MSBuild.exe is missing or invalid!\n{msBuildPath}");
                return(IsBuilding = false);
            }

            // Ensure that the generated .appx version increments by modifying Package.appxmanifest
            try
            {
                if (!UpdateAppxManifest(buildInfo))
                {
                    throw new Exception();
                }
            }
            catch (Exception e)
            {
                Debug.LogError($"Failed to update appxmanifest!\n{e.Message}");
                return(IsBuilding = false);
            }

            string storagePath         = Path.GetFullPath(Path.Combine(Path.Combine(Application.dataPath, ".."), buildInfo.OutputDirectory));
            string solutionProjectPath = Path.GetFullPath(Path.Combine(storagePath, $@"{PlayerSettings.productName}.sln"));

            // Now do the actual appx build
            var processResult = await new Process().StartProcessAsync(
                msBuildPath,
                $"\"{solutionProjectPath}\" /t:{(buildInfo.RebuildAppx ? "Rebuild" : "Build")} /p:Configuration={buildInfo.Configuration} /p:Platform={buildInfo.BuildPlatform} /verbosity:m",
                !Application.isBatchMode,
                cancellationToken);

            switch (processResult.ExitCode)
            {
            case 0:
                Debug.Log("Appx Build Successful!");

                if (Application.isBatchMode)
                {
                    Debug.Log(string.Join("\n", processResult.Output));
                }
                break;

            case -1073741510:
                Debug.LogWarning("The build was terminated either by user's keyboard input CTRL+C or CTRL+Break or closing command prompt window.");
                break;

            default:
            {
                if (processResult.ExitCode != 0)
                {
                    Debug.LogError($"{PlayerSettings.productName} appx build Failed! (ErrorCode: {processResult.ExitCode})");

                    if (Application.isBatchMode)
                    {
                        var buildOutput = "Appx Build Output:\n";

                        foreach (var message in processResult.Output)
                        {
                            buildOutput += $"{message}\n";
                        }

                        buildOutput += "Appx Build Errors:";

                        foreach (var error in processResult.Errors)
                        {
                            buildOutput += $"{error}\n";
                        }

                        Debug.LogError(buildOutput);
                    }
                }

                break;
            }
            }

            AssetDatabase.SaveAssets();

            IsBuilding = false;
            return(processResult.ExitCode == 0);
        }
        /// <summary>
        /// Build the UWP appx bundle for this project.  Requires that <see cref="UwpPlayerBuildTools.BuildPlayer(string,bool,CancellationToken)"/> has already be run or a user has
        /// previously built the Unity Player with the WSA Player as the Build Target.
        /// </summary>
        /// <param name="buildInfo"></param>
        /// <param name="cancellationToken"></param>
        /// <returns>True, if the appx build was successful.</returns>
        public static async Task <bool> BuildAppxAsync(UwpBuildInfo buildInfo, CancellationToken cancellationToken = default)
        {
            if (!EditorAssemblyReloadManager.LockReloadAssemblies)
            {
                Debug.LogError("Lock Reload assemblies before attempting to build appx!");
                return(false);
            }

            if (IsBuilding)
            {
                Debug.LogWarning("Build already in progress!");
                return(false);
            }

            if (Application.isBatchMode)
            {
                // We don't need stack traces on all our logs. Makes things a lot easier to read.
                Application.SetStackTraceLogType(LogType.Log, StackTraceLogType.None);
            }

            Debug.Log("Starting Unity Appx Build...");

            IsBuilding = true;
            string slnFilename = Path.Combine(buildInfo.OutputDirectory, $"{PlayerSettings.productName}.sln");

            if (!File.Exists(slnFilename))
            {
                Debug.LogError("Unable to find Solution to build from!");
                return(IsBuilding = false);
            }

            // Get and validate the msBuild path...
            var msBuildPath = await FindMsBuildPathAsync();

            if (!File.Exists(msBuildPath))
            {
                Debug.LogError($"MSBuild.exe is missing or invalid!\n{msBuildPath}");
                return(IsBuilding = false);
            }

            // Ensure that the generated .appx version increments by modifying Package.appxmanifest
            try
            {
                if (!UpdateAppxManifest(buildInfo))
                {
                    throw new Exception();
                }
            }
            catch (Exception e)
            {
                Debug.LogError($"Failed to update appxmanifest!\n{e.Message}");
                return(IsBuilding = false);
            }

            string storagePath         = Path.GetFullPath(Path.Combine(Path.Combine(Application.dataPath, ".."), buildInfo.OutputDirectory));
            string solutionProjectPath = Path.GetFullPath(Path.Combine(storagePath, $@"{PlayerSettings.productName}.sln"));

            // Building the solution requires first restoring NuGet packages - when built through
            // Visual Studio, VS does this automatically - when building via msbuild like we're doing here,
            // we have to do that step manually.
            int exitCode = await Run(msBuildPath, $"\"{solutionProjectPath}\" /t:restore", !Application.isBatchMode, cancellationToken);

            if (exitCode != 0)
            {
                IsBuilding = false;
                return(false);
            }

            // Now that NuGet packages have been restored, we can run the actual build process.
            exitCode = await Run(msBuildPath,
                                 $"\"{solutionProjectPath}\" /t:{(buildInfo.RebuildAppx ? "Rebuild" : "Build")} /p:Configuration={buildInfo.Configuration} /p:Platform={buildInfo.BuildPlatform} /verbosity:m",
                                 !Application.isBatchMode,
                                 cancellationToken);

            AssetDatabase.SaveAssets();

            IsBuilding = false;
            return(exitCode == 0);
        }