public static BeeDriver Make(RunnableProgram buildProgram, string dagName, string dagDirectory, bool useScriptUpdater, string projectDirectory, ProgressAPI progressAPI = null, RunnableProgram beeBackendProgram = null) { var sourceFileUpdaters = useScriptUpdater ? new[] { new UnityScriptUpdater(projectDirectory) } : Array.Empty <SourceFileUpdaterBase>(); var processSourceFileUpdatersResult = new UnitySourceFileUpdatersResultHandler(); NPath dagDir = dagDirectory ?? "Library/Bee"; RecreateDagDirectoryIfNeeded(dagDir); NPath profilerOutputFile = UnityBeeDriverProfilerSession.GetTraceEventsOutputForNewBeeDriver() ?? $"{dagDir}/fullprofile.json"; var result = new BeeDriver(buildProgram, beeBackendProgram ?? UnityBeeBackendProgram(), projectDirectory, dagName, dagDir.ToString(), sourceFileUpdaters, processSourceFileUpdatersResult, progressAPI ?? new UnityProgressAPI("Script Compilation"), profilerOutputFile: profilerOutputFile.ToString()); result.DataForBuildProgram.Add(new ConfigurationData { Il2CppDir = IL2CPPUtils.GetIl2CppFolder(), Il2CppPath = IL2CPPUtils.GetExePath("il2cpp"), UnityLinkerPath = IL2CPPUtils.GetExePath("UnityLinker"), NetCoreRunPath = NetCoreRunProgram.NetCoreRunPath, EditorContentsPath = EditorApplication.applicationContentsPath, Packages = GetPackageInfos(NPath.CurrentDirectory.ToString()), UnityVersion = Application.unityVersion, UnityVersionNumeric = new BeeBuildProgramCommon.Data.Version(Application.unityVersionVer, Application.unityVersionMaj, Application.unityVersionMin), UnitySourceCodePath = Unsupported.IsSourceBuild(false) ? Unsupported.GetBaseUnityDeveloperFolder() : null, AdvancedLicense = PlayerSettings.advancedLicense, Batchmode = InternalEditorUtility.inBatchMode, EmitDataForBeeWhy = (Debug.GetDiagnosticSwitch("EmitDataForBeeWhy").value as bool?) ?? false, }); return(result); }
internal bool Build(EditorCompilation editorCompilation) { if (editorCompilation.IsCompilationTaskCompiling() || editorCompilation.IsAnyAssemblyBuilderCompiling()) { return(false); } if (status != AssemblyBuilderStatus.NotStarted) { throw new Exception(string.Format("Cannot start AssemblyBuilder with status {0}. Expected {1}", status, AssemblyBuilderStatus.NotStarted)); } var assembly = editorCompilation.CreateScriptAssembly(this); var assemblies = assembly.AllRecursiveScripAssemblyReferencesIncludingSelf().ToArray(); // Start clean everytime const string beeAssemblyBuilderDirectory = "Library/BeeAssemblyBuilder"; string beeAssemblyBuilderDirectoryInProjectDirectory = string.IsNullOrEmpty(editorCompilation.projectDirectory) ? beeAssemblyBuilderDirectory : Path.Combine(editorCompilation.projectDirectory, beeAssemblyBuilderDirectory); if (Directory.Exists(beeAssemblyBuilderDirectoryInProjectDirectory)) { Directory.Delete(beeAssemblyBuilderDirectoryInProjectDirectory, true); } var debug = compilerOptions.CodeOptimization == CodeOptimization.Debug; var buildRequest = UnityBeeDriver.BuildRequestFor(EditorCompilation.ScriptCompilationBuildProgram, editorCompilation, $"{(int)assembly.BuildTarget}{"AB"}", beeAssemblyBuilderDirectory); buildRequest.DataForBuildProgram.Add(() => BeeScriptCompilation.ScriptCompilationDataFor(editorCompilation, assemblies, debug, assembly.OutputDirectory, assembly.BuildTarget, true)); buildRequest.Target = Constants.ScriptAssembliesTarget; activeBeeBuild = new BeeScriptCompilationState { assemblies = new[] { assembly }, ActiveBuild = BeeDriver.BuildAsync(buildRequest), editorCompilation = editorCompilation, }; editorCompilation.AddAssemblyBuilder(this); InvokeBuildStarted(); return(true); }
CanUpdateAny ContainsUpdatableCompilerMessage(NodeResult nodeResult, BeeDriver beeDriver) { if (!nodeResult.annotation.StartsWith("Csc")) { return(CanUpdateAny.No); } var compilerMessages = BeeScriptCompilation.ParseCompilerOutput(nodeResult); bool IsOnlyMessageForThisFileLineAndColumn(CompilerMessage compilerMessage) { //we want to see if this is the only error on this location. we will make an enumerable that matches all compilermessages that match this location //We do Skip(1).Any() as a bit of an unconventional way to express what we care about: is there more than 1 or not. return(!compilerMessages.Where(m => MatchesFileLineAndColumn(compilerMessage, m)).Skip(1).Any()); } var upgradableMessages = compilerMessages.Where(c => c.message.Contains("(UnityUpgradable")).ToArray(); //Some (UnityUpgradable) errors can be paired with a genuine user error on the same line/column. When this happens it is a known problem //that we are unable to upgrade the UnityUpgradable error. So we'll only return Certainly if there is not an other compilermessage pointing to the //same file,line,column. otherwise, we return maybe, so that a failure to do the update won't print a console message saying there is a bug. if (upgradableMessages.Any(IsOnlyMessageForThisFileLineAndColumn)) { return(CanUpdateAny.Certainly); } if (upgradableMessages.Any()) { return(CanUpdateAny.Maybe); } //The "unknown type or namespace" genre of messages we are not sure about. Some of these are legit user programming errors, some of them //are caused because we moved/renamed a type. In this case we will run the script updater to figure out, and if no updates were produced then //apparently it was a real user programming mistake instead of an updatable error; if (PotentiallyUpdatableErrorMessages.IsAnyPotentiallyUpdatable(compilerMessages, nodeResult, beeDriver)) { return(CanUpdateAny.Maybe); } return(CanUpdateAny.No); }
public static void AddScriptCompilationData(BeeDriver beeDriver, EditorCompilation editorCompilation, ScriptAssembly[] assemblies, bool debug, string outputDirectory, BuildTarget buildTarget, bool buildingForEditor, string[] extraScriptingDefines = null) { // Need to call AssemblyDataFrom before calling CompilationPipeline.GetScriptAssemblies, // as that acts on the same ScriptAssemblies, and modifies them with different build settings. var cachedAssemblies = AssemblyDataFrom(assemblies); AssemblyData[] codeGenAssemblies; using (new ProfilerMarker("GetScriptAssembliesForCodeGen").Auto()) { codeGenAssemblies = buildingForEditor ? null : AssemblyDataFrom(CodeGenAssemblies(CompilationPipeline.GetScriptAssemblies(editorCompilation, AssembliesType.Editor, extraScriptingDefines))); } var movedFromExtractorPath = EditorApplication.applicationContentsPath + $"/Tools/ScriptUpdater/ApiUpdater.MovedFromExtractor.exe"; var dotNetSdkRoslynPath = EditorApplication.applicationContentsPath + $"/DotNetSdkRoslyn"; var localization = "en-US"; if (LocalizationDatabase.currentEditorLanguage != SystemLanguage.English && EditorPrefs.GetBool("Editor.kEnableCompilerMessagesLocalization", false)) { localization = LocalizationDatabase.GetCulture(LocalizationDatabase.currentEditorLanguage); } var assembliesToScanForTypeDB = new HashSet <string>(); var searchPaths = new HashSet <string>(BuildPlayerDataGenerator.GetStaticSearchPaths(buildTarget)); var options = EditorScriptCompilationOptions.BuildingIncludingTestAssemblies; if (buildingForEditor) { options |= EditorScriptCompilationOptions.BuildingForEditor; } foreach (var a in editorCompilation.GetAllScriptAssemblies(options, extraScriptingDefines)) { if (!a.Flags.HasFlag(AssemblyFlags.EditorOnly)) { var path = a.FullPath.ToNPath(); assembliesToScanForTypeDB.Add(path.ToString()); searchPaths.Add(path.Parent.ToString()); } } var precompileAssemblies = editorCompilation.PrecompiledAssemblyProvider.GetPrecompiledAssembliesDictionary( buildingForEditor, BuildPipeline.GetBuildTargetGroup(buildTarget), buildTarget, extraScriptingDefines); if (precompileAssemblies != null) { foreach (var a in precompileAssemblies) { if (!a.Value.Flags.HasFlag(AssemblyFlags.EditorOnly)) { var path = a.Value.Path.ToNPath(); assembliesToScanForTypeDB.Add(path.ToString()); searchPaths.Add(path.Parent.ToString()); } } } beeDriver.DataForBuildProgram.Add(new ScriptCompilationData { OutputDirectory = outputDirectory, DotnetRuntimePath = NetCoreProgram.DotNetRuntimePath.ToString(), DotnetRoslynPath = dotNetSdkRoslynPath, MovedFromExtractorPath = movedFromExtractorPath, Assemblies = cachedAssemblies, CodegenAssemblies = codeGenAssemblies, Debug = debug, BuildTarget = buildTarget.ToString(), Localization = localization, EnableDiagnostics = editorCompilation.EnableDiagnostics, BuildPlayerDataOutput = $"Library/BuildPlayerData/{(buildingForEditor ? "Editor" : "Player")}", ExtractRuntimeInitializeOnLoads = !buildingForEditor, AssembliesToScanForTypeDB = assembliesToScanForTypeDB.OrderBy(p => p).ToArray(), SearchPaths = searchPaths.OrderBy(p => p).ToArray() }); }
public static AssemblyData_Out FindOutputDataAssemblyInfoFor(NodeResult nodeResult, BeeDriver beeDriver) { var scriptCompilationDataOut = beeDriver.DataFromBuildProgram.Get <ScriptCompilationData_Out>(); var outputfileForwardSlash = new NPath(nodeResult.outputfile).ToString(); var assemblyDataOut = scriptCompilationDataOut.Assemblies.FirstOrDefault(a => a.Path == outputfileForwardSlash); return(assemblyDataOut ?? throw new ArgumentException($"Unable to find entry for {outputfileForwardSlash} in dataFromBuildProgram")); }
public override Task StartIfYouCanFixProblemsInTheseMessages(NodeResult nodeResult, BeeDriver beeDriver) { var containsUpdatableCompilerMessage = ContainsUpdatableCompilerMessage(nodeResult, beeDriver); if (containsUpdatableCompilerMessage == CanUpdateAny.No) { return(null); } var assemblyInfo = Helpers.FindOutputDataAssemblyInfoFor(nodeResult, beeDriver); return(new UnityScriptUpdaterTask(assemblyInfo.ScriptUpdaterRsp, ProjectRoot, _scriptUpdaterProgram, nodeResult, containsUpdatableCompilerMessage == CanUpdateAny.Certainly)); }
public static bool IsAnyPotentiallyUpdatable(CompilerMessage[] messages, NodeResult nodeResult, BeeDriver beeDriver) { var matches = messages.Select(m => MicrosoftCSharpCompilerOutputParser.sCompilerOutput.Match(m.message)).Where(m => m.Success).ToArray(); var typeNames = matches.Select(MissingTypeNameFor).Where(t => t != null).ToArray(); if (!typeNames.Any()) { return(false); } var assemblyData = Helpers.FindOutputDataAssemblyInfoFor(nodeResult, beeDriver); var lines = new NPath(assemblyData.MovedFromExtractorFile).ReadAllLines(); return(typeNames.Any(t => lines.Contains(t))); }