From 9e87a2eeb5acea9ba8502fd353860ab3af144949 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Laban?= Date: Thu, 17 Jan 2019 10:01:24 -0500 Subject: [PATCH] Remove RuntimeInformation invalid workaroung --- .../RemoteSourceGeneratorEngine.cs | 9 ++- ...o.SourceGeneration.Engine.Shared.projitems | 1 + .../Uno.SourceGeneration.Host.csproj | 9 +-- .../Tasks/SourceGenerationTask.cs | 57 ++++++++++++++++++- 4 files changed, 67 insertions(+), 9 deletions(-) rename src/{Uno.SourceGeneration.Host/Engine => Uno.SourceGeneration.Engine.Shared}/RemoteSourceGeneratorEngine.cs (97%) diff --git a/src/Uno.SourceGeneration.Host/Engine/RemoteSourceGeneratorEngine.cs b/src/Uno.SourceGeneration.Engine.Shared/RemoteSourceGeneratorEngine.cs similarity index 97% rename from src/Uno.SourceGeneration.Host/Engine/RemoteSourceGeneratorEngine.cs rename to src/Uno.SourceGeneration.Engine.Shared/RemoteSourceGeneratorEngine.cs index 829bd3c..104c9f2 100644 --- a/src/Uno.SourceGeneration.Host/Engine/RemoteSourceGeneratorEngine.cs +++ b/src/Uno.SourceGeneration.Engine.Shared/RemoteSourceGeneratorEngine.cs @@ -29,7 +29,6 @@ using Uno.SourceGeneratorTasks.Helpers; using Uno.SourceGeneratorTasks.Logger; using System.Diagnostics; using System.Globalization; -using Uno.SourceGeneration.Host.Server; namespace Uno.SourceGeneratorTasks { @@ -85,8 +84,12 @@ namespace Uno.SourceGeneratorTasks _remoteLoggerProvider.TaskLog = logger; return new SourceGeneratorEngine( - environment: environment, - assemblyReferenceProvider: DesktopGenerationServerHost.SharedAssemblyReferenceProvider + environment: environment +#if IS_BUILD_HOST + , assemblyReferenceProvider: Uno.SourceGeneration.Host.Server.DesktopGenerationServerHost.SharedAssemblyReferenceProvider +#else + , null +#endif ).Generate(); } diff --git a/src/Uno.SourceGeneration.Engine.Shared/Uno.SourceGeneration.Engine.Shared.projitems b/src/Uno.SourceGeneration.Engine.Shared/Uno.SourceGeneration.Engine.Shared.projitems index ea14188..476f6e8 100644 --- a/src/Uno.SourceGeneration.Engine.Shared/Uno.SourceGeneration.Engine.Shared.projitems +++ b/src/Uno.SourceGeneration.Engine.Shared/Uno.SourceGeneration.Engine.Shared.projitems @@ -13,6 +13,7 @@ + \ No newline at end of file diff --git a/src/Uno.SourceGeneration.Host/Uno.SourceGeneration.Host.csproj b/src/Uno.SourceGeneration.Host/Uno.SourceGeneration.Host.csproj index ce22836..1956907 100644 --- a/src/Uno.SourceGeneration.Host/Uno.SourceGeneration.Host.csproj +++ b/src/Uno.SourceGeneration.Host/Uno.SourceGeneration.Host.csproj @@ -3,7 +3,7 @@ Exe netcoreapp2.1;net461 - $(DefineConstants);HAS_BINLOG + $(DefineConstants);HAS_BINLOG;IS_BUILD_HOST true true true @@ -60,9 +60,6 @@ 1.3.1 - - 4.0.1 - 4.4.0 @@ -161,6 +158,10 @@ + + + + diff --git a/src/Uno.SourceGeneratorTasks.Dev15.0/Tasks/SourceGenerationTask.cs b/src/Uno.SourceGeneratorTasks.Dev15.0/Tasks/SourceGenerationTask.cs index ad73ed4..552db0d 100644 --- a/src/Uno.SourceGeneratorTasks.Dev15.0/Tasks/SourceGenerationTask.cs +++ b/src/Uno.SourceGeneratorTasks.Dev15.0/Tasks/SourceGenerationTask.cs @@ -84,6 +84,7 @@ namespace Uno.SourceGeneratorTasks public string[] GenereratedFiles { get; set; } private CancellationTokenSource _sharedCompileCts; + private TaskLoggerProvider _taskLogger; public override bool Execute() { @@ -366,12 +367,20 @@ namespace Uno.SourceGeneratorTasks { throw new InvalidOperationException($"Unable to find Uno.SourceGeneration.Host.dll (in {devPath} or {installedPath})"); } - } private void GenerateInProcess() { - new SourceGeneratorEngine(CreateBuildEnvironment(), null); + Log.LogMessage(MessageImportance.Low, $"Using in-process generation mode"); + + var generationInfo = CreateDomain(); + + _taskLogger = new TaskLoggerProvider() { TaskLog = Log }; + LogExtensionPoint.AmbientLoggerFactory.AddProvider(_taskLogger); + + var remotableLogger = new Logger.RemotableLogger2(_taskLogger.CreateLogger("Logger.RemotableLogger")); + + GenereratedFiles = generationInfo.Wrapper.Generate(remotableLogger, CreateBuildEnvironment()); } public bool IsMonoMSBuildCompatible => @@ -417,5 +426,49 @@ namespace Uno.SourceGeneratorTasks Path.IsPathRooted(targetPath) ? targetPath : Path.Combine(Path.GetDirectoryName(projectFile), targetPath); + + private (RemoteSourceGeneratorEngine Wrapper, AppDomain Domain) CreateDomain() + { + var generatorLocations = SourceGenerators.Select(Path.GetFullPath).Select(Path.GetDirectoryName).Distinct(); + var wrapperBasePath = Path.GetDirectoryName(new Uri(typeof(RemoteSourceGeneratorEngine).Assembly.CodeBase).LocalPath); + + // We can create an app domain per OwnerFile and all Analyzers files + // so that if those change, we can spin off another one, and still avoid + // locking these assemblies. + // + // If the domain exists, keep it and continue generating content with it. + + var setup = new AppDomainSetup(); + setup.ApplicationBase = wrapperBasePath; + setup.ShadowCopyFiles = "true"; + setup.ShadowCopyDirectories = string.Join(";", generatorLocations) + ";" + wrapperBasePath; + setup.PrivateBinPath = setup.ShadowCopyDirectories; + setup.ConfigurationFile = Path.Combine(wrapperBasePath, typeof(RemoteSourceGeneratorEngine).Assembly.GetName().Name + ".dll.config"); + + // Loader optimization must not use MultiDomainHost, otherwise MSBuild assemblies may + // be shared incorrectly when multiple versions are loaded in different domains. + // The loader must specify SingleDomain, otherwise in contexts where devenv.exe is the + // current process, the default optimization is "MultiDomain" and assemblies are + // incorrectly reused. + setup.LoaderOptimization = LoaderOptimization.SingleDomain; + + var domain = AppDomain.CreateDomain("Generators-" + Guid.NewGuid(), null, setup); + + Log.LogMessage($"[{Process.GetCurrentProcess().ProcessName}] Creating object {typeof(RemoteSourceGeneratorEngine).Assembly.CodeBase} with {typeof(RemoteSourceGeneratorEngine).FullName}. wrapperBasePath {wrapperBasePath} "); + + var newHost = domain.CreateInstanceFromAndUnwrap( + typeof(RemoteSourceGeneratorEngine).Assembly.CodeBase, + typeof(RemoteSourceGeneratorEngine).FullName + ) as RemoteSourceGeneratorEngine; + + var msbuildBasePath = Path.GetDirectoryName(new Uri(typeof(Microsoft.Build.Logging.ConsoleLogger).Assembly.CodeBase).LocalPath); + + newHost.MSBuildBasePath = msbuildBasePath; + newHost.AdditionalAssemblies = AdditionalAssemblies; + + newHost.Initialize(); + + return (newHost, domain); + } } }