public DotsRuntimeCSharpProgramConfiguration(CSharpCodeGen csharpCodegen, CodeGen cppCodegen, //The stevedore global manifest will override DownloadableCsc.Csc72 artifacts and use Csc73 ToolChain nativeToolchain, ScriptingBackend scriptingBackend, string identifier, bool enableUnityCollectionsChecks, NativeProgramFormat executableFormat = null) : base(csharpCodegen, DownloadableCsc.Csc72, HostPlatform.IsWindows ? (DebugFormat)DebugFormat.Pdb : DebugFormat.PortablePdb, nativeToolchain.Architecture is x86Architecture ? nativeToolchain.Architecture : null) { NativeProgramConfiguration = new DotsRuntimeNativeProgramConfiguration(cppCodegen, nativeToolchain, identifier, this, executableFormat: executableFormat); Identifier = identifier; EnableUnityCollectionsChecks = enableUnityCollectionsChecks; ScriptingBackend = scriptingBackend; }
static int SetScriptingBackend(ScriptingBackend scriptingBackend, string projectPath) { var filePath = $"{projectPath}/ProjectSettings/ProjectSettings.asset"; if (!File.Exists(filePath)) { RunLogger.LogError($"Could not find {filePath} to set scriptingBackend in"); return(-1); } var file = File.ReadAllLines(filePath).ToList(); var sectionEmptyIndex = -1; var foundSection = false; for (var i = 0; i < file.Count; i++) { var line = file[i]; var trimmed = line.Trim(); if (!foundSection) { if (!trimmed.StartsWith("scriptingBackend")) { continue; } foundSection = true; if (trimmed.EndsWith("}")) { sectionEmptyIndex = i; file[i] = " scriptingBackend: "; file.Insert(i + 1, $" Standalone: {(int)scriptingBackend}"); break; } } if (!trimmed.StartsWith("Standalone: ")) { continue; } file[i] = $" Standalone: {(int)scriptingBackend}"; break; } File.WriteAllLines(filePath, file); return(0); }
private ScriptingBackend GetScriptingBackend() { if (PlatformStructure != null) { ScriptingBackend backend = PlatformStructure.GetScriptingBackend(); if (backend != ScriptingBackend.Unknown) { return(backend); } } if (MixedStructure != null) { ScriptingBackend backend = MixedStructure.GetScriptingBackend(); if (backend != ScriptingBackend.Unknown) { return(backend); } } return(ScriptingBackend.Unknown); }
private void SetScriptingBackend(PlatformGameStructure structure) { ScriptingBackend backend = structure.GetScriptingBackend(); if (backend == ScriptingBackend.Unknown) { return; } if (FileCollection.AssemblyManager.ScriptingBackend == backend) { return; } if (FileCollection.AssemblyManager.ScriptingBackend == ScriptingBackend.Unknown) { FileCollection.AssemblyManager.ScriptingBackend = backend; } else { throw new Exception("Scripting backend is already set"); } }
public DotsRuntimeCSharpProgramConfiguration( CSharpCodeGen csharpCodegen, CodeGen cppCodegen, ToolChain nativeToolchain, ScriptingBackend scriptingBackend, TargetFramework targetFramework, string identifier, bool enableUnityCollectionsChecks, bool enableManagedDebugging, bool waitForManagedDebugger, bool multiThreadedJobs, DotsConfiguration dotsConfiguration, bool enableProfiler, bool useBurst, IEnumerable <string> defines = null, NPath finalOutputDirectory = null) : base( csharpCodegen, null, DebugFormat.PortablePdb, nativeToolchain.Architecture is IntelArchitecture ? nativeToolchain.Architecture : null) { NativeProgramConfiguration = new DotsRuntimeNativeProgramConfiguration( cppCodegen, nativeToolchain, identifier, this); _identifier = identifier; EnableUnityCollectionsChecks = enableUnityCollectionsChecks; DotsConfiguration = dotsConfiguration; MultiThreadedJobs = multiThreadedJobs; EnableProfiler = enableProfiler; UseBurst = useBurst; EnableManagedDebugging = enableManagedDebugging; WaitForManagedDebugger = waitForManagedDebugger; ScriptingBackend = scriptingBackend; TargetFramework = targetFramework; Defines = defines?.ToList(); FinalOutputDirectory = finalOutputDirectory; }
/// <summary> /// Gets the correct platform template file path. /// </summary> /// <param name="platform">The platform of the requested template.</param> /// <param name="configuration">The configuration of the requested template.</param> /// <returns>The absolute file path for the platform template to use.</returns> public FileInfo GetTemplateFilePathForPlatform(string platform, string configuration, ScriptingBackend scriptingBackend) { if (PlatformTemplates.TryGetValue($"{platform}.{configuration}.{scriptingBackend.ToString()}.props.template", out FileInfo templatePath) || PlatformTemplates.TryGetValue($"{platform}.{configuration}.Any.props.template", out templatePath) || PlatformTemplates.TryGetValue($"{platform}.Configuration.Any.props.template", out templatePath)) { return(templatePath); } else { return(PlatformPropsTemplatePath); } }
static int Main(string[] args) { var options = new OptionSet { { "batchmode", "Run Unity in batch mode. This should always be used in conjunction with the other command line arguments, because it ensures no pop-up windows appear and eliminates the need for any human intervention. When an exception occurs during execution of the script code, the Asset server updates fail, or other operations that fail, Unity immediately exits with return code 1. \nNote that in batch mode, Unity sends a minimal version of its log output to the RunLogger However, the Log Files still contain the full log information. Opening a project in batch mode while the Editor has the same project open is not supported; only a single instance of Unity can run at a time.", v => Flags |= Flag.Batchmode }, { "quit", "Quit the Unity Editor after other commands have finished executing. Note that this can cause error messages to be hidden (however, they still appear in the Editor.log file).", v => Flags |= Flag.Quit }, { "nographics", "When running in batch mode, do not initialize the graphics device at all. This makes it possible to run your automated workflows on machines that don’t even have a GPU (automated workflows only work when you have a window in focus, otherwise you can’t send simulated input commands). Please note that -nographics does not allow you to bake GI, since Enlighten requires GPU acceleration.", v => Flags |= Flag.NoGraphics }, { "automated", "This flag enables some extra logging when running tests. Like when a test is started/finished/etc which is helpful for identifying which test is logging something or what the result of the test was if you don't want to parse the testresults file.", v => Flags |= Flag.Automated }, { "silentcrashes", "Don’t display a crash dialog.", v => Flags |= Flag.SilentCrashes }, { "ignoreErrorsOnArtifactCreation", "Workaround to a random compilation issue introduced in 2018.2+ on slower machines. In that you sometimes get random compilation errors but artifacts are still being produced. So this flag will ignore the errors if the testresults or standalone build artifacts has been generated.", v => Flags |= Flag.IgnoreErrorsOnArtifactCreation }, { "warningsaserrors", "Treat warnings as errors.", v => Flags |= Flag.WarningsAsErrors }, { "runtests", "Executes tests in the project", v => Flags |= Flag.RunTests }, { "unityexecutable=", "Path to unity executable that should run this command", v => UnityExecutable = v }, { "expectedexitcode=", "If you for some reason don't expect to get exit code 0 from the run and want to enforce it", v => ExpectedExitCode = int.Parse(v) }, { "projectpath=", "Open the project at the given path.", v => ProjectPath = v }, { "logfile=", "Specify where the Editor or Windows/Linux/OSX standalone log file are written.", v => LogFile = v }, { "cleanedLogFile=", "Logs file that should only contain important messages (warnings, errors, assertions). If this is set and the specified file is not empty after the run the run will be flagged as failed.", v => CleanedLogFile = v }, { "testresults=", "The path indicating where the result file should be saved. The result file is saved in Project’s root folder by default.", v => TestResults = v }, { "scriptingBackend=", "Will hack in the scripting backend for standalone in the ProjectSettings.asset so you can easily toggle it in CI. Valid values are: mono, il2cpp", v => ScriptingBackendOverride = Enum.Parse <ScriptingBackend>(v) }, { "displayResolutionDialog=", "Will hack in if the display resolution dialog should be enabled or not in built players into the ProjectSettings.asset. Valid values are: enabled, disabled", v => DisplayResolutionDialogOverride = Enum.Parse <DisplayResolutionDialog>(v) }, { "buildLinuxUniversalPlayer=", "Build a combined 32-bit and 64-bit standalone Linux player (for example, -buildLinuxUniversalPlayer path/to/your/build).", v => buildLinuxUniversalPlayer = v }, { "buildOSXUniversalPlayer=", "Build a combined 32-bit and 64-bit standalone Mac OSX player (for example, -buildOSXUniversalPlayer path/to/your/build.app).", v => buildOSXUniversalPlayer = v }, { "registryoverride=", "If you for some reason need to use a custom npm registry than the one in the manifest.json (maybe you have a fast one for your build system). Empty string removes the field", v => RegistryOverride = v }, { "buildWindows64Player=", "Build a 64-bit standalone Windows player (for example, -buildWindows64Player path/to/your/build.exe).", v => buildWindows64Player = v }, { "timeout=", "Timeout the execution after the supplied seconds. Will fail run if -timeoutIgnore is not set and it times out", v => ExecutionTimeout = int.Parse(v) }, { "timeoutIgnore", "Indicates that if the execution times out it should not flag it as a failure if everything else is ok", v => Flags |= Flag.TimeoutIgnore }, { "scene=", "Modifies the scene list to build with only the scene listed here. Needs to be the relative path to the file from the project path", v => SceneOverride = v }, { "addPackage=", "Modifies the Packages/manifest.json of the project to include the package specified. Use the format packagename@version. Ex: [email protected]. Command can be repeated for multiple packages", v => AddPackages.Add(v) }, { "buildTarget=", $"Allows the selection of an active build target before loading a project. Possible options are: {string.Join(", ", Enum.GetNames(typeof(BuildTargets)).ToList())}.", v => BuildTarget = v } }; try { ExtraArgs = options.Parse(args); } catch (OptionException e) { RunLogger.LogError(e.Message); RunLogger.Dump(); options.WriteOptionDescriptions(Console.Out); throw; } if (ExtraArgs.Any()) { RunLogger.LogInfo($"Unknown commands passed. These will be passed a long to the process:\n {string.Join(" ", ExtraArgs)}"); } if (!IsValidPath("unityexecutable", UnityExecutable)) { RunLogger.Dump(); options.WriteOptionDescriptions(Console.Out); return(-1); } if (!IsValidPath("projectpath", ProjectPath)) { RunLogger.Dump(); options.WriteOptionDescriptions(Console.Out); return(-1); } if (string.IsNullOrEmpty(LogFile)) { RunLogger.LogError("logfile must be set"); RunLogger.Dump(); options.WriteOptionDescriptions(Console.Out); return(-1); } var result = UpdateProjectSettings(ProjectPath); if (result != 0) { RunLogger.Dump(); return(-1); } result = UpdateManifest(ProjectPath, AddPackages); if (result != 0) { RunLogger.Dump(); return(-1); } if (!IsValidPath("logfile", new FileInfo(LogFile).Directory.FullName)) { RunLogger.Dump(); return(-1); } var sb = new StringBuilder(); sb.Append($"-logFile \"{Path.GetFullPath(LogFile)}\" "); sb.Append($"-projectPath \"{Path.GetFullPath(ProjectPath)}\" "); if (!string.IsNullOrEmpty(CleanedLogFile)) { sb.Append($"-cleanedLogFile \"{Path.GetFullPath(CleanedLogFile)}\" "); } if (ExtraArgs.Any()) { sb.Append(string.Join(" ", ExtraArgs)); sb.Append(" "); } if ((Flags & Flag.Batchmode) != Flag.None) { RunLogger.LogInfo("Batchmode is set"); sb.Append("-batchmode "); } if ((Flags & Flag.NoGraphics) != Flag.None) { RunLogger.LogInfo("Nographics is set"); sb.Append("-nographics "); } if ((Flags & Flag.SilentCrashes) != Flag.None) { RunLogger.LogInfo("silentcrashes is set"); sb.Append("-silent-crashes "); } if ((Flags & Flag.WarningsAsErrors) != Flag.None) { RunLogger.LogInfo("warningsaserrors is set"); } if ((Flags & Flag.TimeoutIgnore) != Flag.None) { RunLogger.LogInfo("timeoutIgnore is set"); } if ((Flags & Flag.IgnoreErrorsOnArtifactCreation) != Flag.None) { RunLogger.LogInfo("ignoreErrorsOnArtifactCreation is set"); } if ((Flags & Flag.Automated) != Flag.None) { RunLogger.LogInfo("automated is set"); sb.Append("-automated "); } if (!string.IsNullOrEmpty(BuildTarget)) { if (!Enum.TryParse <BuildTargets>(BuildTarget, out var parsedEnum)) { RunLogger.LogError($"{BuildTarget} is not a valid buildtarget. It has to be one of:\n{string.Join(", ", Enum.GetNames(typeof(BuildTargets)))}"); return(-1); } sb.Append($"-buildTarget {BuildTarget} "); } if ((Flags & Flag.RunTests) != Flag.None) { RunLogger.LogInfo("runtests is set"); sb.Append("-runTests "); if (string.IsNullOrEmpty(TestResults)) { RunLogger.LogWarning("It is not recommended to set runtests but not testresults. It will not be able to parse the test results as part of the report"); } else { sb.Append($"-testResults \"{Path.GetFullPath(TestResults)}\" "); } } if ((Flags & Flag.Quit) != Flag.None) { RunLogger.LogInfo("Quit is set"); if ((Flags & Flag.RunTests) != Flag.None) { RunLogger.LogWarning("quit and runtests cannot be set at once. Ignoring quit command"); } else { sb.Append("-quit "); } } if (!string.IsNullOrEmpty(buildWindows64Player)) { RunLogger.LogInfo("buildWindows64Player is set"); sb.Append($"-buildWindows64Player {buildWindows64Player} "); ExpectedBuildArtifact = $"{ProjectPath}/{buildWindows64Player}"; } if (!string.IsNullOrEmpty(buildLinuxUniversalPlayer)) { RunLogger.LogInfo("buildLinuxUniversalPlayer is set"); sb.Append($"-buildLinuxUniversalPlayer {buildLinuxUniversalPlayer} "); ExpectedBuildArtifact = $"{ProjectPath}/{buildLinuxUniversalPlayer}"; } if (!string.IsNullOrEmpty(buildOSXUniversalPlayer)) { RunLogger.LogInfo("buildOSXUniversalPlayer is set"); sb.Append($"-buildOSXUniversalPlayer {buildOSXUniversalPlayer} "); ExpectedBuildArtifact = $"{ProjectPath}/{buildOSXUniversalPlayer}"; } var stopwatch = new Stopwatch(); stopwatch.Start(); var runResult = UnityLauncher.Run(sb.ToString()); RunLogger.LogResultInfo($"Command execution took: {stopwatch.Elapsed}"); RestoreProjectSettings(ProjectPath); if (runResult == RunResult.FailedToStart) { RunLogger.Dump(); return(-1); } if (!LogParser.Parse()) { runResult = RunResult.Failure; } if (runResult != RunResult.Success && ShouldOverrideOverrideBuildFailure()) { runResult = RunResult.Success; } if ((Flags & Flag.RunTests) != Flag.None) { if (File.Exists(TestResults)) { RunLogger.LogInfo($"Parsing {TestResults}"); if (CheckTestResults.Parse(TestResults) != RunResult.Success) { runResult = RunResult.Failure; } } else { RunLogger.LogError($"Could not find {TestResults}"); runResult = RunResult.Failure; } } runResult = ParseCleanedLogFileForErrors(runResult); if (runResult != RunResult.Success) { RunLogger.LogResultError("Run has failed"); RunLogger.Dump(); return(-1); } if (!string.IsNullOrEmpty(ExpectedBuildArtifact) && !(File.Exists(ExpectedBuildArtifact) || Directory.Exists(ExpectedBuildArtifact))) { RunLogger.LogResultError($"Expected to find {ExpectedBuildArtifact} after the execution but it is missing. Check the log for what could have gone wrong"); RunLogger.Dump(); return(-1); } RunLogger.LogResultInfo("Everything looks good. Run has passed"); RunLogger.Dump(); return(0); }
public AssemblyManager(ScriptingBackend backend, AssetLayout layout, Action <string> requestAssemblyCallback) { m_manager = backend == ScriptingBackend.Mono ? new MonoManager(this) : null; Layout = layout; m_requestAssemblyCallback = requestAssemblyCallback ?? throw new ArgumentNullException(nameof(requestAssemblyCallback)); }
private static IPlatformPropsExporter CreateWSAPlayerExporter(IUnityProjectExporter exporter, FileInfo outputFile, ScriptingBackend scriptingBackend) { IWSAPlayerPlatformPropsExporter uwpExporter = exporter.CreateWSAPlayerPlatformPropsExporter(outputFile, scriptingBackend); string minUWPPlatform = EditorUserBuildSettings.wsaMinUWPSDK; if (string.IsNullOrWhiteSpace(minUWPPlatform) || new Version(minUWPPlatform) < MSBuildTools.DefaultMinUWPSDK) { minUWPPlatform = MSBuildTools.DefaultMinUWPSDK.ToString(); } string targetUWPPlatform = EditorUserBuildSettings.wsaUWPSDK; if (string.IsNullOrWhiteSpace(targetUWPPlatform)) { targetUWPPlatform = Utilities.GetUWPSDKs().Max().ToString(4); } uwpExporter.MinimumUWPVersion = minUWPPlatform; uwpExporter.TargetUWPVersion = targetUWPPlatform; return(uwpExporter); }
public IWSAPlayerPlatformPropsExporter CreateWSAPlayerPlatformPropsExporter(FileInfo path, ScriptingBackend scriptingBackend) { if (!FileTemplate.TryParseTemplate(TemplateFiles.Instance.GetTemplateFilePathForPlatform("WSA", "Player", scriptingBackend), out FileTemplate fileTemplate)) { throw new InvalidOperationException("Failed to parse template file for common props."); } return(new TemplatedWSAPlayerPlatformPropsExporter(fileTemplate, path)); }
public IPlatformPropsExporter CreatePlatformPropsExporter(FileInfo path, string unityConfiguration, string unityPlatform, ScriptingBackend scriptingBackend) { if (!FileTemplate.TryParseTemplate(TemplateFiles.Instance.GetTemplateFilePathForPlatform(unityPlatform, unityConfiguration, scriptingBackend), out FileTemplate fileTemplate)) { throw new InvalidOperationException("Failed to parse template file for common props."); } return(new TemplatedPlatformPropsExporter(fileTemplate, path)); }