-
-
Notifications
You must be signed in to change notification settings - Fork 65
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
new ILPostProcessor is having issue with rewired. This allows the weaver to work in legacy mode: that is using the hooks. to use it, add LEGACY_ILPP to your defines <img width="1048" alt="Screen Shot 2021-01-24 at 11 30 25 AM" src="https://user-images.githubusercontent.com/466007/105638327-b2265180-5e37-11eb-9019-bae7af6f43b4.png">
- Loading branch information
Showing
11 changed files
with
374 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
using System.Runtime.CompilerServices; | ||
|
||
[assembly: InternalsVisibleTo("Mirror.Tests")] | ||
[assembly: InternalsVisibleTo("Unity.Mirror.CodeGen.Tests")] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
using System.IO; | ||
using Unity.CompilationPipeline.Common.ILPostProcessing; | ||
|
||
namespace Mirror.Weaver | ||
{ | ||
/// <summary> | ||
/// a compiled assembly, used to work around ILPP problems with rewired | ||
/// </summary> | ||
internal class ILPostProcessCompiledAssembly : ICompiledAssembly | ||
{ | ||
private readonly string m_AssemblyFilename; | ||
private readonly string m_OutputPath; | ||
private InMemoryAssembly m_InMemoryAssembly; | ||
|
||
public ILPostProcessCompiledAssembly(string asmName, string[] refs, string[] defines, string outputPath) | ||
{ | ||
m_AssemblyFilename = asmName; | ||
Name = Path.GetFileNameWithoutExtension(m_AssemblyFilename); | ||
References = refs; | ||
Defines = defines; | ||
m_OutputPath = outputPath; | ||
} | ||
|
||
public string Name { get; } | ||
public string[] References { get; } | ||
public string[] Defines { get; } | ||
|
||
public InMemoryAssembly InMemoryAssembly | ||
{ | ||
get | ||
{ | ||
if (m_InMemoryAssembly == null) | ||
{ | ||
m_InMemoryAssembly = new InMemoryAssembly( | ||
File.ReadAllBytes(Path.Combine(m_OutputPath, m_AssemblyFilename)), | ||
File.ReadAllBytes(Path.Combine(m_OutputPath, $"{Path.GetFileNameWithoutExtension(m_AssemblyFilename)}.pdb"))); | ||
} | ||
|
||
return m_InMemoryAssembly; | ||
} | ||
} | ||
} | ||
} |
11 changes: 11 additions & 0 deletions
11
Assets/Mirror/Weaver/ILPostProcessCompiledAssembly.cs.meta
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,247 @@ | ||
#if LEGACY_ILPP | ||
using System; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.Linq; | ||
using Unity.CompilationPipeline.Common.Diagnostics; | ||
using Unity.CompilationPipeline.Common.ILPostProcessing; | ||
using UnityEditor; | ||
using UnityEditor.Compilation; | ||
using UnityEngine; | ||
|
||
using Assembly = System.Reflection.Assembly; | ||
|
||
using ILPostProcessor = Mirror.Weaver.ILegacyPostProcessor; | ||
|
||
namespace Mirror.Weaver | ||
{ | ||
internal static class ILPostProcessProgram | ||
{ | ||
internal static ILPostProcessResult PostProcessResult; | ||
|
||
private static ILPostProcessor[] s_ILPostProcessors { get; set; } | ||
|
||
[InitializeOnLoadMethod] | ||
private static void OnInitializeOnLoad() | ||
{ | ||
CompilationPipeline.assemblyCompilationFinished += OnCompilationFinished; | ||
s_ILPostProcessors = FindAllPostProcessors(); | ||
|
||
// this is for bootstrapping the weaver. | ||
// the very first time this is loaded, some assemblies have already been built. | ||
// so the hook will not trigger for them. | ||
// we need to reload all assemblies after subscribing to teh hook so they will | ||
// be weaved too | ||
|
||
Bootstrap(); | ||
} | ||
|
||
private static void Bootstrap() | ||
{ | ||
if (SessionState.GetBool("MIRROR_BOOTSTRAP", false)) | ||
return; | ||
|
||
|
||
SessionState.SetBool("MIRROR_BOOTSTRAP", true); | ||
|
||
foreach (UnityEditor.Compilation.Assembly assembly in CompilationPipeline.GetAssemblies()) | ||
{ | ||
if (File.Exists(assembly.outputPath)) | ||
{ | ||
OnCompilationFinished(assembly.outputPath, new CompilerMessage[0]); | ||
} | ||
} | ||
|
||
Debug.Log("The weaver was bootstrapped. Please reimport Mirror.Runtime once"); | ||
|
||
EditorUtility.RequestScriptReload(); | ||
} | ||
|
||
private static ILPostProcessor[] FindAllPostProcessors() | ||
{ | ||
TypeCache.TypeCollection typesDerivedFrom = TypeCache.GetTypesDerivedFrom<ILPostProcessor>(); | ||
var localILPostProcessors = new List<ILPostProcessor>(typesDerivedFrom.Count); | ||
|
||
foreach (Type typeCollection in typesDerivedFrom) | ||
{ | ||
try | ||
{ | ||
localILPostProcessors.Add((ILPostProcessor)Activator.CreateInstance(typeCollection)); | ||
} | ||
catch (Exception exception) | ||
{ | ||
Debug.LogError($"Could not create ILPostProcessor ({typeCollection.FullName}):{Environment.NewLine}{exception.StackTrace}"); | ||
} | ||
} | ||
|
||
// Default sort by type full name | ||
localILPostProcessors.Sort((left, right) => string.Compare(left.GetType().FullName, right.GetType().FullName, StringComparison.Ordinal)); | ||
|
||
return localILPostProcessors.ToArray(); | ||
} | ||
|
||
private static void OnCompilationFinished(string targetAssembly, CompilerMessage[] messages) | ||
{ | ||
if (messages.Length > 0) | ||
{ | ||
if (messages.Any(msg => msg.type == CompilerMessageType.Error)) | ||
{ | ||
return; | ||
} | ||
} | ||
|
||
|
||
// Should not run on Unity Engine modules but we can run on the MLAPI Runtime DLL | ||
if (targetAssembly.Contains("com.unity") || Path.GetFileName(targetAssembly).StartsWith("Unity")) | ||
{ | ||
return; | ||
} | ||
|
||
Console.WriteLine($"Running Mirror ILPP on {targetAssembly}"); | ||
|
||
string outputDirectory = $"{Application.dataPath}/../{Path.GetDirectoryName(targetAssembly)}"; | ||
string unityEngine = string.Empty; | ||
string mlapiRuntimeAssemblyPath = string.Empty; | ||
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); | ||
bool usesMirror = false; | ||
bool foundThisAssembly = false; | ||
|
||
var depenencyPaths = new List<string>(); | ||
foreach (Assembly assembly in assemblies) | ||
{ | ||
// Find the assembly currently being compiled from domain assembly list and check if it's using unet | ||
if (assembly.GetName().Name == Path.GetFileNameWithoutExtension(targetAssembly)) | ||
{ | ||
foundThisAssembly = true; | ||
foreach (System.Reflection.AssemblyName dependency in assembly.GetReferencedAssemblies()) | ||
{ | ||
// Since this assembly is already loaded in the domain this is a no-op and returns the | ||
// already loaded assembly | ||
depenencyPaths.Add(Assembly.Load(dependency).Location); | ||
if (dependency.Name.Contains(MirrorILPostProcessor.RuntimeAssemblyName)) | ||
{ | ||
usesMirror = true; | ||
} | ||
} | ||
} | ||
|
||
try | ||
{ | ||
if (assembly.Location.Contains("UnityEngine.CoreModule")) | ||
{ | ||
unityEngine = assembly.Location; | ||
} | ||
|
||
if (assembly.Location.Contains(MirrorILPostProcessor.RuntimeAssemblyName)) | ||
{ | ||
mlapiRuntimeAssemblyPath = assembly.Location; | ||
} | ||
} | ||
catch (NotSupportedException) | ||
{ | ||
// in memory assembly, can't get location | ||
} | ||
} | ||
|
||
if (!foundThisAssembly) | ||
{ | ||
// Target assembly not found in current domain, trying to load it to check references | ||
// will lead to trouble in the build pipeline, so lets assume it should go to weaver. | ||
// Add all assemblies in current domain to dependency list since there could be a | ||
// dependency lurking there (there might be generated assemblies so ignore file not found exceptions). | ||
// (can happen in runtime test framework on editor platform and when doing full library reimport) | ||
foreach (Assembly assembly in assemblies) | ||
{ | ||
try | ||
{ | ||
if (!(assembly.ManifestModule is System.Reflection.Emit.ModuleBuilder)) | ||
{ | ||
depenencyPaths.Add(Assembly.Load(assembly.GetName().Name).Location); | ||
} | ||
} | ||
catch (FileNotFoundException) | ||
{ | ||
} | ||
} | ||
|
||
usesMirror = true; | ||
} | ||
|
||
// We check if we are the MLAPI! | ||
if (!usesMirror) | ||
{ | ||
// we shall also check and see if it we are ourself | ||
usesMirror = targetAssembly.Contains(MirrorILPostProcessor.RuntimeAssemblyName); | ||
} | ||
|
||
if (!usesMirror) | ||
{ | ||
return; | ||
} | ||
|
||
if (string.IsNullOrEmpty(unityEngine)) | ||
{ | ||
Debug.LogError("Failed to find UnityEngine assembly"); | ||
return; | ||
} | ||
|
||
if (string.IsNullOrEmpty(mlapiRuntimeAssemblyPath)) | ||
{ | ||
Debug.LogError("Failed to find mlapi runtime assembly"); | ||
return; | ||
} | ||
|
||
string assemblyPathName = Path.GetFileName(targetAssembly); | ||
|
||
var targetCompiledAssembly = new ILPostProcessCompiledAssembly(assemblyPathName, depenencyPaths.ToArray(), null, outputDirectory); | ||
|
||
foreach (ILPostProcessor i in s_ILPostProcessors) | ||
{ | ||
PostProcessResult = i.Process(targetCompiledAssembly); | ||
if (PostProcessResult == null) | ||
continue; | ||
|
||
if (PostProcessResult.Diagnostics.Count > 0) | ||
{ | ||
Debug.LogError($"ILPostProcessor - {i.GetType().Name} failed to run on {targetCompiledAssembly.Name}"); | ||
|
||
foreach (DiagnosticMessage message in PostProcessResult.Diagnostics) | ||
{ | ||
switch (message.DiagnosticType) | ||
{ | ||
case DiagnosticType.Error: | ||
Debug.LogError($"ILPostProcessor Error - {message.MessageData} {message.File} {message.Line} {message.Column}"); | ||
break; | ||
case DiagnosticType.Warning: | ||
Debug.LogWarning($"ILPostProcessor Warning - {message.MessageData} {message.File} {message.Line} {message.Column}"); | ||
break; | ||
} | ||
} | ||
|
||
continue; | ||
} | ||
|
||
// we now need to write out the result? | ||
WriteAssembly(PostProcessResult.InMemoryAssembly, outputDirectory, assemblyPathName); | ||
} | ||
} | ||
|
||
static void WriteAssembly(InMemoryAssembly inMemoryAssembly, string outputPath, string assName) | ||
{ | ||
Console.WriteLine($"Writing assembly {assName} to {outputPath}"); | ||
|
||
if (inMemoryAssembly == null) | ||
{ | ||
throw new ArgumentException("InMemoryAssembly has never been accessed or modified"); | ||
} | ||
|
||
string asmPath = Path.Combine(outputPath, assName); | ||
string pdbFileName = $"{Path.GetFileNameWithoutExtension(assName)}.pdb"; | ||
string pdbPath = Path.Combine(outputPath, pdbFileName); | ||
|
||
File.WriteAllBytes(asmPath, inMemoryAssembly.PeData); | ||
File.WriteAllBytes(pdbPath, inMemoryAssembly.PdbData); | ||
} | ||
} | ||
} | ||
#endif |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
using Unity.CompilationPipeline.Common.ILPostProcessing; | ||
|
||
namespace Mirror.Weaver | ||
{ | ||
public abstract class ILegacyPostProcessor | ||
{ | ||
public abstract bool WillProcess(ICompiledAssembly compiledAssembly); | ||
public abstract ILPostProcessResult Process(ICompiledAssembly compiledAssembly); | ||
public abstract ILegacyPostProcessor GetInstance(); | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.