private static ScriptAssembly[] CodeGenAssemblies(ScriptAssembly[] assemblies) => assemblies .Where(assembly => UnityCodeGenHelpers.IsCodeGen(FileUtil.GetPathWithoutExtension(assembly.Filename))) .SelectMany(assembly => assembly.AllRecursiveScripAssemblyReferencesIncludingSelf()) .Distinct() .OrderBy(a => a.Filename) .ToArray();
public static bool ShouldAddTestRunnerReferences(TargetAssembly targetAssembly) { if (UnityCodeGenHelpers.IsCodeGen(targetAssembly.Filename)) { return(false); } bool referencesTestRunnerAssembly = false; foreach (var reference in targetAssembly.References) { referencesTestRunnerAssembly = reference.Filename.Equals(k_EditorTestRunnerAssemblyName, StringComparison.Ordinal) || reference.Filename.Equals(k_EngineTestRunnerAssemblyName, StringComparison.Ordinal); if (referencesTestRunnerAssembly) { break; } } return(!referencesTestRunnerAssembly && !targetAssembly.Filename.Equals(k_EditorTestRunnerAssemblyName, StringComparison.Ordinal) && !targetAssembly.Filename.Equals(k_EngineTestRunnerAssemblyName, StringComparison.Ordinal) && (PlayerSettings.playModeTestRunnerEnabled || (targetAssembly.Flags & AssemblyFlags.EditorOnly) == AssemblyFlags.EditorOnly)); }
public static bool ShouldAddTestRunnerReferences(EditorBuildRules.TargetAssembly targetAssembly) { if (UnityCodeGenHelpers.IsCodeGen(targetAssembly.Filename)) { return(false); } return(!targetAssembly.References.Any(x => x.Filename.Contains(k_EngineTestRunnerAssemblyName) || x.Filename.Contains(k_EditorTestRunnerAssemblyName)) && !targetAssembly.Filename.Contains(k_EngineTestRunnerAssemblyName) && !targetAssembly.Filename.Contains(k_EditorTestRunnerAssemblyName) && (PlayerSettings.playModeTestRunnerEnabled || (targetAssembly.Flags & AssemblyFlags.EditorOnly) == AssemblyFlags.EditorOnly)); }
public List <CompilerMessage> PostProcess(ScriptAssembly assembly, List <CompilerMessage> messages, string outputTempPath) { var hasCompileError = messages.Any(m => m.type == CompilerMessageType.Error); if (hasCompileError) { return(messages); } if (UnityCodeGenHelpers.IsCodeGen(assembly.Filename)) { return(messages); } if (!HasPostProcessors) { return(messages); } try { List <DiagnosticMessage> diagnostics = RunILPostProcessors(assembly, outputTempPath); foreach (var message in diagnostics) { if (message.DiagnosticType == DiagnosticType.Error) { hasCompileError = true; } messages.Add(new CompilerMessage { assemblyName = message.File, column = message.Column, line = message.Line, message = message.MessageData, type = message.DiagnosticType == DiagnosticType.Error ? CompilerMessageType.Error : CompilerMessageType.Warning, }); } } catch (Exception exception) { messages.Add(new CompilerMessage { assemblyName = assembly.Filename, message = $"Something went wrong while Post Processing the assembly ({assembly.Filename}) : {Environment.NewLine} {exception.Message} {Environment.NewLine}{exception.StackTrace}", type = CompilerMessageType.Error, }); } return(messages); }
public void ValidateFields() { if (string.IsNullOrEmpty(name)) throw new System.Exception("Required property 'name' not set"); if ((excludePlatforms != null && excludePlatforms.Length > 0) && (includePlatforms != null && includePlatforms.Length > 0)) throw new System.Exception("Both 'excludePlatforms' and 'includePlatforms' are set."); if (autoReferenced && UnityCodeGenHelpers.IsCodeGen(name, includesExtension: false)) { throw new Exception($"Assembly '{name}' is a CodeGen assembly and cannot be Auto Referenced"); } }
internal static ScriptAssembly[] ToScriptAssemblies( IDictionary <TargetAssembly, DirtyTargetAssembly> targetAssemblies, ScriptAssemblySettings settings, CompilationAssemblies assemblies, ICompilationSetupWarningTracker warningSink, ISafeModeInfo safeModeInfo) { var scriptAssemblies = new ScriptAssembly[targetAssemblies.Count]; var targetToScriptAssembly = new Dictionary <TargetAssembly, ScriptAssembly>(); int index = 0; bool buildingForEditor = settings.BuildingForEditor; var safeModeWhiteList = new HashSet <string>(safeModeInfo.GetWhiteListAssemblyNames()); foreach (var entry in targetAssemblies) { var targetAssembly = entry.Key; var dirtyTargetAssembly = entry.Value; var scriptAssembly = new ScriptAssembly(); // Setup TargetAssembly -> ScriptAssembly mapping for converting references scriptAssemblies[index] = scriptAssembly; targetToScriptAssembly[targetAssembly] = scriptAssemblies[index++]; // Setup ScriptAssembly scriptAssembly.Flags = targetAssembly.Flags; scriptAssembly.BuildTarget = settings.BuildTarget; scriptAssembly.OriginPath = targetAssembly.PathPrefix; scriptAssembly.Filename = targetAssembly.Filename; scriptAssembly.SkipCodeGen = safeModeWhiteList.Contains(targetAssembly.Filename); scriptAssembly.RootNamespace = targetAssembly.Type == TargetAssemblyType.Predefined ? settings.ProjectRootNamespace : targetAssembly.RootNamespace; scriptAssembly.OutputDirectory = settings.OutputDirectory; scriptAssembly.Defines = targetAssembly.Defines == null ? s_CSharpVersionDefines : targetAssembly.Defines.Concat(s_CSharpVersionDefines).ToArray(); scriptAssembly.Files = dirtyTargetAssembly.SourceFiles.ToArray(); scriptAssembly.TargetAssemblyType = targetAssembly.Type; scriptAssembly.AsmDefPath = targetAssembly.AsmDefPath; if (scriptAssembly.TargetAssemblyType == TargetAssemblyType.Predefined) { scriptAssembly.CompilerOptions = new ScriptCompilerOptions(settings.PredefinedAssembliesCompilerOptions); } else { scriptAssembly.CompilerOptions = targetAssembly.CompilerOptions; } scriptAssembly.CompilerOptions.RoslynAnalyzerDllPaths = new string[0]; scriptAssembly.CompilerOptions.RoslynAnalyzerRulesetPath = string.Empty; scriptAssembly.CompilerOptions.AdditionalCompilerArguments = settings.AdditionalCompilerArguments; var editorOnlyTargetAssembly = (targetAssembly.Flags & AssemblyFlags.EditorOnly) == AssemblyFlags.EditorOnly; if (editorOnlyTargetAssembly) { scriptAssembly.CompilerOptions.ApiCompatibilityLevel = ApiCompatibilityLevel.NET_Unity_4_8; } else { scriptAssembly.CompilerOptions.ApiCompatibilityLevel = settings.PredefinedAssembliesCompilerOptions.ApiCompatibilityLevel; } if ((settings.CompilationOptions & EditorScriptCompilationOptions.BuildingUseDeterministicCompilation) == EditorScriptCompilationOptions.BuildingUseDeterministicCompilation) { scriptAssembly.CompilerOptions.UseDeterministicCompilation = true; } else { scriptAssembly.CompilerOptions.UseDeterministicCompilation = false; } scriptAssembly.CompilerOptions.CodeOptimization = settings.CodeOptimization; } // Don't add the auto-referenced engine assemblies if the assembly either has the flag set, or // is a codegen assembly AutoReferencedPackageAssemblies.AddReferences(assemblies.CustomTargetAssemblies, settings.CompilationOptions, t => { var hasNoEngineReferencesFlag = (t.Flags & AssemblyFlags.NoEngineReferences) == AssemblyFlags.NoEngineReferences; if (hasNoEngineReferencesFlag) { return(false); } return(!UnityCodeGenHelpers.IsCodeGen(t.Filename)); }); // Setup ScriptAssembly references index = 0; foreach (var entry in targetAssemblies) { var scriptAssembly = scriptAssemblies[index++]; AddScriptAssemblyReferences(ref scriptAssembly, entry.Key, settings, assemblies, targetToScriptAssembly, warningSink); if (UnityCodeGenHelpers.IsCodeGen(entry.Key.Filename) || UnityCodeGenHelpers.IsCodeGenTest(entry.Key.Filename) || CompilationPipelineCommonHelper.ShouldAdd(entry.Key.Filename)) { CompilationPipelineCommonHelper.UpdateScriptAssemblyReference(ref scriptAssembly); } if (!buildingForEditor) { PlatformSupportModuleHelpers.AddAdditionalPlatformSupportData(settings.CompilationExtension, ref scriptAssembly); } } if ((settings.CompilationOptions & EditorScriptCompilationOptions.BuildingWithRoslynAnalysis) != 0) { var analyzers = assemblies.RoslynAnalyzerDllPaths; foreach (var a in analyzers) { var targetAssemblyOwningAnalyzer = assemblies.CustomTargetAssemblies.Values .OrderBy(c => c.PathFilter(a)).LastOrDefault(); if (targetAssemblyOwningAnalyzer?.PathFilter(a) <= 0) { targetAssemblyOwningAnalyzer = null; } foreach (var scriptAssembly in scriptAssemblies) { if (ShouldUseAnalyzerForScriptAssembly(scriptAssembly, targetAssemblyOwningAnalyzer)) { scriptAssembly.CompilerOptions.RoslynAnalyzerDllPaths = scriptAssembly.CompilerOptions.RoslynAnalyzerDllPaths.Concat(new[] { a }).ToArray(); scriptAssembly.CompilerOptions.RoslynAnalyzerRulesetPath = scriptAssembly.TargetAssemblyType == TargetAssemblyType.Predefined ? RuleSetFileCache.GetRuleSetFilePathInRootFolder(Path.ChangeExtension(scriptAssembly.Filename, null)) : RuleSetFileCache.GetPathForAssembly(scriptAssembly.OriginPath); } } } } return(scriptAssemblies); }
// Returns true when compilation is finished due to one of these reasons // * Was stopped (CompilationTask.Stopped will be true) // * Compilation had errors (CompilationTask.CompileErrors will be true) // * Compilation succesfully completed without errors. public bool Poll() { HandleOnCompilationTaskStarted(); if (Stopped) { HandleOnCompilationTaskFinished(); return(true); } Dictionary <ScriptAssembly, ScriptCompilerBase> finishedCompilerTasks = null; // Check if any compiler processes are finished. foreach (var task in compilerTasks) { var compiler = task.Value; // Did compiler task finish? if (compiler.Poll()) { if (finishedCompilerTasks == null) { finishedCompilerTasks = new Dictionary <ScriptAssembly, ScriptCompilerBase>(); } var assembly = task.Key; finishedCompilerTasks.Add(assembly, compiler); } } // Save compiler messages from finished compiler processes and check for compile errors. if (finishedCompilerTasks != null) { foreach (var task in finishedCompilerTasks) { var assembly = task.Key; var compiler = task.Value; var messages = compiler.GetCompilerMessages(); var messagesList = messages.ToList(); compiledAssemblies.Add(assembly, messagesList.ToArray()); bool havePostProcessors = ilPostProcessing != null && ilPostProcessing.HasPostProcessors; bool isCodeGenAssembly = codeGenAssemblies.Contains(assembly); bool hasCompileErrors = messagesList.Any(m => m.type == CompilerMessageType.Error); if (isCodeGenAssembly) { if (hasCompileErrors) { notCompiledCodeGenAssemblies.Add(assembly); } else { compiledCodeGenAssemblies.Add(assembly); } } if (havePostProcessors && notCompiledCodeGenAssemblies.Count == 0 && !hasCompileErrors && !isCodeGenAssembly) { var assemblySourcePath = AssetPath.Combine(buildOutputDirectory, assembly.Filename); var pdbSourcePath = AssetPath.Combine(buildOutputDirectory, assembly.PdbFilename); try { if (assemblySourcePath != assembly.FullPath) { File.Copy(assemblySourcePath, assembly.FullPath, true); } if (pdbSourcePath != assembly.PdbFullPath) { File.Copy(pdbSourcePath, assembly.PdbFullPath, true); } var postProcessorTask = new PostProcessorTask(assembly, messagesList, buildOutputDirectory, ilPostProcessing); pendingPostProcessorTasks.Add(postProcessorTask); } catch (IOException e) { UnityEngine.Debug.LogError($"Fail to copy {assemblySourcePath} or {pdbSourcePath} to {AssetPath.GetDirectoryName(assembly.FullPath)} before post processing the assembly. Skipping post processing.\n{e}"); // OnCompilationFinished callbacks might add more compiler messages OnCompilationFinished?.Invoke(assembly, messagesList); processedAssemblies.Add(assembly, messagesList.ToArray()); } } else { // OnCompilationFinished callbacks might add more compiler messages OnCompilationFinished?.Invoke(assembly, messagesList); processedAssemblies.Add(assembly, messagesList.ToArray()); } if (!CompileErrors) { CompileErrors = messagesList.Any(m => m.type == CompilerMessageType.Error); } // If a codgen / IL Post processor has compile errors, clear // pending assemblies waiting for compilation and assemblies // waiting to get post processed. if (isCodeGenAssembly && hasCompileErrors) { pendingPostProcessorTasks.Clear(); pendingAssemblies.Clear(); } compilerTasks.Remove(assembly); compiler.Dispose(); } } if (ilPostProcessing != null && ilPostProcessing.HasPostProcessors) { PollPostProcessors(); } // If StopOnFirstError is set, do not queue assemblies for compilation in case of compile errors. bool stopOnFirstError = (compilationTaskOptions & CompilationTaskOptions.StopOnFirstError) == CompilationTaskOptions.StopOnFirstError; if (stopOnFirstError && CompileErrors) { foreach (var pendingAssembly in pendingAssemblies) { if (UnityCodeGenHelpers.IsCodeGen(pendingAssembly.Filename)) { notCompiledCodeGenAssemblies.Add(pendingAssembly); } } pendingAssemblies.Clear(); if (FinishedCompilation) { HandleOnCompilationTaskFinished(); } return(FinishedCompilation); } // Queue pending assemblies for compilation if we have no running compilers or if compilers have finished. if (compilerTasks.Count == 0 || (finishedCompilerTasks != null && finishedCompilerTasks.Count > 0)) { QueuePendingAssemblies(); } if (FinishedCompilation) { HandleOnCompilationTaskFinished(); } return(FinishedCompilation); }