From 937a39a6b1508c05f71cb6d596330d3080cae1e4 Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Thu, 5 Apr 2018 15:43:40 -0700 Subject: [PATCH 1/3] Update OmniSharp to latest MSBuild This change updates OmniSharp with the latest MSBuild binaries. Recent performance changes for MSBuild now require NuGet.Build.Tasks, which requires a set of NuGet binaries be included as well. Because the versions of these NuGet binaries might be different (actually, they *are* different) than the binaries that OmniSharp uses, there's a bit of duplication. --- build.cake | 69 +++++++++++++++++++++++++++++++++++-------- build.json | 4 +-- build/Packages.props | 8 ++--- tools/packages.config | 20 +++++++++---- 4 files changed, 77 insertions(+), 24 deletions(-) diff --git a/build.cake b/build.cake index 412337aa43..0623dfff6b 100644 --- a/build.cake +++ b/build.cake @@ -336,6 +336,40 @@ Task("CreateMSBuildFolder") CopyDotNetHostResolver(env, "linux", "x64", "libhostfxr.so", sdkResolverTargetFolder, copyToArchSpecificFolder: false); } + // Copy content of NuGet.Build.Tasks + var nugetBuildTasksFolder = CombinePaths(env.Folders.Tools, "NuGet.Build.Tasks"); + var nugetBuildTasksBinariesFolder = CombinePaths(nugetBuildTasksFolder, "lib", "net46"); + var nugetBuildTasksTargetsFolder = CombinePaths(nugetBuildTasksFolder, "runtimes", "any", "native"); + + FileHelper.Copy( + source: CombinePaths(nugetBuildTasksBinariesFolder, "NuGet.Build.Tasks.dll"), + destination: CombinePaths(msbuild15BinTargetFolder, "NuGet.Build.Tasks.dll")); + + FileHelper.Copy( + source: CombinePaths(nugetBuildTasksTargetsFolder, "NuGet.targets"), + destination: CombinePaths(msbuild15BinTargetFolder, "NuGet.targets")); + + // Copy dependencies of NuGet.Build.Tasks + var nugetPackages = new [] + { + "NuGet.Commands", + "NuGet.Common", + "NuGet.Configuration", + "NuGet.Frameworks", + "NuGet.ProjectModel", + "NuGet.Protocol", + "NuGet.Versioning" + }; + + foreach (var nugetPackage in nugetPackages) + { + var binaryName = nugetPackage + ".dll"; + + FileHelper.Copy( + source: CombinePaths(env.Folders.Tools, nugetPackage, "lib", "net46", binaryName), + destination: CombinePaths(msbuild15BinTargetFolder, binaryName)); + } + // Copy content of Microsoft.Net.Compilers Information("Copying Microsoft.Net.Compilers..."); var compilersSourceFolder = CombinePaths(env.Folders.Tools, "Microsoft.Net.Compilers", "tools"); @@ -632,8 +666,11 @@ Task("Test") else { // Copy the Mono-built Microsoft.Build.* binaries to the test folder. + // This is necessary to work around a Mono bug that is exasperated by xUnit. DirectoryHelper.Copy($"{env.Folders.MonoMSBuildLib}", instanceFolder); + DeleteUnnecessaryAssemblies(instanceFolder); + var runScript = CombinePaths(env.Folders.Mono, "run"); // By default, the run script launches OmniSharp. To launch our Mono runtime @@ -649,6 +686,25 @@ Task("Test") } }); +/// +/// Delete assemblies that are included in our Mono package. +/// +void DeleteUnnecessaryAssemblies(string folder) +{ + FileHelper.Delete(CombinePaths(folder, "System.AppContext.dll")); + FileHelper.Delete(CombinePaths(folder, "System.Numerics.Vectors.dll")); + FileHelper.Delete(CombinePaths(folder, "System.Runtime.InteropServices.RuntimeInformation.dll")); + FileHelper.Delete(CombinePaths(folder, "System.ComponentModel.Primitives.dll")); + FileHelper.Delete(CombinePaths(folder, "System.ComponentModel.TypeConverter.dll")); + FileHelper.Delete(CombinePaths(folder, "System.Console.dll")); + FileHelper.Delete(CombinePaths(folder, "System.IO.FileSystem.Primitives.dll")); + FileHelper.Delete(CombinePaths(folder, "System.IO.FileSystem.dll")); + FileHelper.Delete(CombinePaths(folder, "System.Security.Cryptography.Encoding.dll")); + FileHelper.Delete(CombinePaths(folder, "System.Security.Cryptography.Primitives.dll")); + FileHelper.Delete(CombinePaths(folder, "System.Security.Cryptography.X509Certificates.dll")); + FileHelper.Delete(CombinePaths(folder, "System.Threading.Thread.dll")); +} + void CopyMonoBuild(BuildEnvironment env, string sourceFolder, string outputFolder) { DirectoryHelper.Copy(sourceFolder, outputFolder, copySubDirectories: false); @@ -657,18 +713,7 @@ void CopyMonoBuild(BuildEnvironment env, string sourceFolder, string outputFolde DirectoryHelper.Copy($"{env.Folders.MSBuild}", CombinePaths(outputFolder, "msbuild")); // Included in Mono - FileHelper.Delete(CombinePaths(outputFolder, "System.AppContext.dll")); - FileHelper.Delete(CombinePaths(outputFolder, "System.Numerics.Vectors.dll")); - FileHelper.Delete(CombinePaths(outputFolder, "System.Runtime.InteropServices.RuntimeInformation.dll")); - FileHelper.Delete(CombinePaths(outputFolder, "System.ComponentModel.Primitives.dll")); - FileHelper.Delete(CombinePaths(outputFolder, "System.ComponentModel.TypeConverter.dll")); - FileHelper.Delete(CombinePaths(outputFolder, "System.Console.dll")); - FileHelper.Delete(CombinePaths(outputFolder, "System.IO.FileSystem.Primitives.dll")); - FileHelper.Delete(CombinePaths(outputFolder, "System.IO.FileSystem.dll")); - FileHelper.Delete(CombinePaths(outputFolder, "System.Security.Cryptography.Encoding.dll")); - FileHelper.Delete(CombinePaths(outputFolder, "System.Security.Cryptography.Primitives.dll")); - FileHelper.Delete(CombinePaths(outputFolder, "System.Security.Cryptography.X509Certificates.dll")); - FileHelper.Delete(CombinePaths(outputFolder, "System.Threading.Thread.dll")); + DeleteUnnecessaryAssemblies(outputFolder); } string PublishMonoBuild(string project, BuildEnvironment env, BuildPlan plan, string configuration) diff --git a/build.json b/build.json index 6c46a1920c..d5ec7b24df 100644 --- a/build.json +++ b/build.json @@ -12,8 +12,8 @@ "MonoRuntimeLinux32": "mono.linux-x86-5.10.1.20.zip", "MonoRuntimeLinux64": "mono.linux-x86_64-5.10.1.20.zip", "MonoFramework": "framework-5.10.1.20.zip", - "MonoMSBuildRuntime": "Microsoft.Build.Runtime.Mono-alpha6.zip", - "MonoMSBuildLib": "Microsoft.Build.Lib.Mono-alpha6.zip", + "MonoMSBuildRuntime": "Microsoft.Build.Runtime.Mono-mono-5.10.1.20.zip", + "MonoMSBuildLib": "Microsoft.Build.Lib.Mono-mono-5.10.1.20.zip", "HostProjects": [ "OmniSharp.Stdio", "OmniSharp.Http" diff --git a/build/Packages.props b/build/Packages.props index 31dfa036e8..d0376c7830 100644 --- a/build/Packages.props +++ b/build/Packages.props @@ -9,10 +9,10 @@ 1.1.0 1.1.0 1.1.0 - 15.3.409 - 15.3.409 - 15.3.409 - 15.3.409 + 15.6.82 + 15.6.82 + 15.6.82 + 15.6.82 2.7.0 2.7.0 2.7.0 diff --git a/tools/packages.config b/tools/packages.config index 2333d9e0d5..4f4744db46 100644 --- a/tools/packages.config +++ b/tools/packages.config @@ -1,13 +1,21 @@ - - - - - - + + + + + + + + + + + + + + From 357addb04a176ae508b4b7c50d5f7f45b8d303c1 Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Fri, 6 Apr 2018 08:18:22 -0700 Subject: [PATCH 2/3] Remove cli-deps from NuGet.config --- NuGet.Config | 1 - 1 file changed, 1 deletion(-) diff --git a/NuGet.Config b/NuGet.Config index 41c0ecd6d8..ab6af752a0 100644 --- a/NuGet.Config +++ b/NuGet.Config @@ -4,6 +4,5 @@ - From 11ab9d67907ac792ec8492d5dcbf5699fee5bbdb Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Fri, 6 Apr 2018 09:17:05 -0700 Subject: [PATCH 3/3] Set 'BypassFrameworkInstallChecks' MSBuild property when running on Mono 'BypassFrameworkInstallChecks' allows builds to skip a particularly hacky check in the GetReferenceAssemblyPaths task. This hack affects projects that target a .NET Framework version less than 4.0. Essentially, the hack tries to load a certain assembly from the GAC to "guarantee" that .NET Framework 3.5 SP1 is installed (an old case added specifically for WPF projects). However, we don't include that assembly in our Mono package. So, many Unity projects end up failing the check because they often target much early .NET Framework versions. We can fix that by just skipping the check, which isn't really necessary when we're running on Mono. --- .../Providers/StandAloneInstanceProvider.cs | 32 ++++++++++++------- .../ProjectFile/PropertyNames.cs | 1 + src/OmniSharp.MSBuild/ProjectLoader.cs | 5 +++ 3 files changed, 27 insertions(+), 11 deletions(-) diff --git a/src/OmniSharp.Host/MSBuild/Discovery/Providers/StandAloneInstanceProvider.cs b/src/OmniSharp.Host/MSBuild/Discovery/Providers/StandAloneInstanceProvider.cs index f0cb645681..e7cf7be033 100644 --- a/src/OmniSharp.Host/MSBuild/Discovery/Providers/StandAloneInstanceProvider.cs +++ b/src/OmniSharp.Host/MSBuild/Discovery/Providers/StandAloneInstanceProvider.cs @@ -30,19 +30,29 @@ public override ImmutableArray GetInstances() var propertyOverrides = ImmutableDictionary.CreateBuilder(StringComparer.OrdinalIgnoreCase); - // To better support older versions of Mono that don't include - // MSBuild 15, we attempt to set property overrides to the locations - // of Mono's 'xbuild' and 'xbuild-frameworks' paths. - if (_allowMonoPaths && PlatformHelper.IsMono) + if (PlatformHelper.IsMono) { - if (TryGetMonoXBuildPath(out var xbuildPath)) + // This disables a hack in the "GetReferenceAssemblyPaths" task which attempts + // guarantee that .NET Framework SP1 is installed when the target framework is + // .NET Framework, but the version is less than 4.0. The hack attempts to locate + // a particular assembly in the GAC as a "guarantee". However, we don't include that + // in our Mono package. So, we'll just bypass the check. + propertyOverrides.Add("BypassFrameworkInstallChecks", "true"); + + // To better support older versions of Mono that don't include + // MSBuild 15, we attempt to set property overrides to the locations + // of Mono's 'xbuild' and 'xbuild-frameworks' paths. + if (_allowMonoPaths) { - extensionsPath = xbuildPath; - } - - if (TryGetMonoXBuildFrameworksPath(out var xbuildFrameworksPath)) - { - propertyOverrides.Add("TargetFrameworkRootPath", xbuildFrameworksPath); + if (TryGetMonoXBuildPath(out var xbuildPath)) + { + extensionsPath = xbuildPath; + } + + if (TryGetMonoXBuildFrameworksPath(out var xbuildFrameworksPath)) + { + propertyOverrides.Add("TargetFrameworkRootPath", xbuildFrameworksPath); + } } } diff --git a/src/OmniSharp.MSBuild/ProjectFile/PropertyNames.cs b/src/OmniSharp.MSBuild/ProjectFile/PropertyNames.cs index 572036a5fd..2de1455018 100644 --- a/src/OmniSharp.MSBuild/ProjectFile/PropertyNames.cs +++ b/src/OmniSharp.MSBuild/ProjectFile/PropertyNames.cs @@ -7,6 +7,7 @@ internal static class PropertyNames public const string AssemblyOriginatorKeyFile = nameof(AssemblyOriginatorKeyFile); public const string BuildProjectReferences = nameof(BuildProjectReferences); public const string BuildingInsideVisualStudio = nameof(BuildingInsideVisualStudio); + public const string BypassFrameworkInstallChecks = nameof(BypassFrameworkInstallChecks); public const string Configuration = nameof(Configuration); public const string CscToolExe = nameof(CscToolExe); public const string CscToolPath = nameof(CscToolPath); diff --git a/src/OmniSharp.MSBuild/ProjectLoader.cs b/src/OmniSharp.MSBuild/ProjectLoader.cs index c494f9a5a3..dd16de599c 100644 --- a/src/OmniSharp.MSBuild/ProjectLoader.cs +++ b/src/OmniSharp.MSBuild/ProjectLoader.cs @@ -52,6 +52,11 @@ private static Dictionary CreateGlobalProperties( globalProperties.AddPropertyOverride(PropertyNames.Configuration, options.Configuration, propertyOverrides, logger); globalProperties.AddPropertyOverride(PropertyNames.Platform, options.Platform, propertyOverrides, logger); + if (propertyOverrides.TryGetValue(PropertyNames.BypassFrameworkInstallChecks, out var value)) + { + globalProperties.Add(PropertyNames.BypassFrameworkInstallChecks, value); + } + return globalProperties; }