Skip to content

Commit

Permalink
Merge pull request #974 from DustinCampbell/sdk-resolver
Browse files Browse the repository at this point in the history
Use MSBuild SDK Resolvers
  • Loading branch information
DustinCampbell authored Oct 4, 2017
2 parents 23ae5f9 + 7904f81 commit 9a8afe7
Show file tree
Hide file tree
Showing 10 changed files with 183 additions and 115 deletions.
2 changes: 1 addition & 1 deletion NuGet.Config
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
<clear />
<add key="NuGet" value="https://api.nuget.org/v3/index.json" />
<add key="dotnet-core" value="https://dotnet.myget.org/F/dotnet-core/api/v3/index.json" />
<add key="cli-deps" value="https://dotnet.myget.org/F/cli-deps/api/v3/index.json" />
<add key="dotnet-cli" value="https://dotnet.myget.org/F/cli-deps/api/v3/index.json" />
</packageSources>
</configuration>
59 changes: 53 additions & 6 deletions build.cake
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,27 @@ Task("InstallMonoAssets")
Run("chmod", $"+x '{CombinePaths(env.Folders.Mono, "run")}'");
});

void CopyDotNetHostResolver(BuildEnvironment env, string os, string arch, string hostFileName, string targetFolderBase, bool copyToArchSpecificFolder)
{
var source = CombinePaths(
env.Folders.Tools,
$"runtime.{os}-{arch}.Microsoft.NETCore.DotNetHostResolver",
"runtimes",
$"{os}-{arch}",
"native",
hostFileName);

var targetFolder = targetFolderBase;

if (copyToArchSpecificFolder)
{
targetFolder = CombinePaths(targetFolderBase, arch);
DirectoryHelper.ForceCreate(targetFolder);
}

FileHelper.Copy(source, CombinePaths(targetFolder, hostFileName));
}

/// <summary>
/// Create '.msbuild' folder and copy content to it.
/// </summary>
Expand All @@ -227,17 +248,43 @@ Task("CreateMSBuildFolder")
{
DirectoryHelper.ForceCreate(env.Folders.MSBuild);
if (!Platform.Current.IsWindows)
string sdkResolverTFM;
if (Platform.Current.IsWindows)
{
Information("Copying Mono MSBuild runtime...");
DirectoryHelper.Copy(env.Folders.MonoMSBuildRuntime, env.Folders.MSBuild);
Information("Copying MSBuild runtime...");
var msbuildRuntimeFolder = CombinePaths(env.Folders.Tools, "Microsoft.Build.Runtime", "contentFiles", "any", "net46");
DirectoryHelper.Copy(msbuildRuntimeFolder, env.Folders.MSBuild);
sdkResolverTFM = "net46";
}
else
{
Information("Copying MSBuild runtime...");
Information("Copying Mono MSBuild runtime...");
DirectoryHelper.Copy(env.Folders.MonoMSBuildRuntime, env.Folders.MSBuild);
sdkResolverTFM = "netstandard1.5";
}
var msbuildRuntimeFolder = CombinePaths(env.Folders.Tools, "Microsoft.Build.Runtime", "contentFiles", "any", "net46");
DirectoryHelper.Copy(msbuildRuntimeFolder, env.Folders.MSBuild);
// Copy MSBuild SDK Resolver and DotNetHostResolver
Information("Coping MSBuild SDK resolver...");
var sdkResolverFolder = CombinePaths(env.Folders.Tools, "Microsoft.DotNet.MSBuildSdkResolver", "lib", sdkResolverTFM);
var msbuildSdkResolverFolder = CombinePaths(env.Folders.MSBuild, "SdkResolvers", "Microsoft.DotNet.MSBuildSdkResolver");
DirectoryHelper.ForceCreate(msbuildSdkResolverFolder);
FileHelper.Copy(
source: CombinePaths(sdkResolverFolder, "Microsoft.DotNet.MSBuildSdkResolver.dll"),
destination: CombinePaths(msbuildSdkResolverFolder, "Microsoft.DotNet.MSBuildSdkResolver.dll"));
if (Platform.Current.IsWindows)
{
CopyDotNetHostResolver(env, "win", "x86", "hostfxr.dll", msbuildSdkResolverFolder, copyToArchSpecificFolder: true);
CopyDotNetHostResolver(env, "win", "x64", "hostfxr.dll", msbuildSdkResolverFolder, copyToArchSpecificFolder: true);
}
else if (Platform.Current.IsMacOS)
{
CopyDotNetHostResolver(env, "osx", "x64", "libhostfxr.dylib", msbuildSdkResolverFolder, copyToArchSpecificFolder: false);
}
else if (Platform.Current.IsLinux)
{
CopyDotNetHostResolver(env, "linux", "x64", "libhostfxr.so", msbuildSdkResolverFolder, copyToArchSpecificFolder: false);
}
// Copy content of Microsoft.Net.Compilers
Expand Down
12 changes: 6 additions & 6 deletions build.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
"LegacyDotNetVersion": "1.0.0-preview2-1-003177",
"RequiredMonoVersion": "5.2.0.196",
"DownloadURL": "https://omnisharpdownload.blob.core.windows.net/ext",
"MonoRuntimeMacOS": "mono.osx-5.2.0.213.zip",
"MonoRuntimeLinux32": "mono.linux-x86-5.2.0.213.zip",
"MonoRuntimeLinux64": "mono.linux-x86_64-5.2.0.213.zip",
"MonoFramework": "framework-5.2.0.213.zip",
"MonoMSBuildRuntime": "Microsoft.Build.Runtime.Mono-alpha5.zip",
"MonoMSBuildLib": "Microsoft.Build.Lib.Mono-alpha5.zip",
"MonoRuntimeMacOS": "mono.osx-5.2.0.215.zip",
"MonoRuntimeLinux32": "mono.linux-x86-5.2.0.215.zip",
"MonoRuntimeLinux64": "mono.linux-x86_64-5.2.0.215.zip",
"MonoFramework": "framework-5.2.0.215.zip",
"MonoMSBuildRuntime": "Microsoft.Build.Runtime.Mono-alpha6.zip",
"MonoMSBuildLib": "Microsoft.Build.Lib.Mono-alpha6.zip",
"HostProjects": [
"OmniSharp.Stdio",
"OmniSharp.Http"
Expand Down
3 changes: 2 additions & 1 deletion src/OmniSharp.MSBuild/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Runtime.CompilerServices;

[assembly: InternalsVisibleTo("OmniSharp.MSBuild.Tests")]
[assembly: InternalsVisibleTo("OmniSharp.MSBuild.Tests")]
[assembly: InternalsVisibleTo("TestUtility")]
44 changes: 40 additions & 4 deletions src/OmniSharp.MSBuild/MSBuildEnvironment.cs
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,40 @@ public static void Initialize(ILogger logger)
return;
}

LogSummary(logger);
}

internal static void InitializeForTest(ILogger logger)
{
// For tests, we only initialize in standalone mode.

if (s_isInitialized)
{
throw new InvalidOperationException("MSBuild environment is already initialized.");
}

if (TryWithLocalMSBuild(allowMonoPaths: false))
{
s_kind = MSBuildEnvironmentKind.StandAlone;
s_isInitialized = true;
}
else
{
s_kind = MSBuildEnvironmentKind.Unknown;
logger.LogError("MSBuild environment could not be initialized.");
s_isInitialized = false;
}

if (!s_isInitialized)
{
return;
}

LogSummary(logger);
}

private static void LogSummary(ILogger logger)
{
var summary = new StringBuilder();
switch (s_kind)
{
Expand Down Expand Up @@ -295,7 +329,7 @@ private static bool TrySetRoslynTargetsPathAndCscTool()
return false;
}

private static bool TryWithLocalMSBuild()
private static bool TryWithLocalMSBuild(bool allowMonoPaths = true)
{
var msbuildDirectory = FindMSBuildDirectory();
if (msbuildDirectory == null)
Expand All @@ -312,12 +346,14 @@ private static bool TryWithLocalMSBuild()

SetMSBuildExePath(msbuildExePath);

if (!TrySetMSBuildExtensionsPathToXBuild())
s_msbuildExtensionsPath = msbuildDirectory;

if (allowMonoPaths)
{
s_msbuildExtensionsPath = msbuildDirectory;
TrySetMSBuildExtensionsPathToXBuild();
TrySetTargetFrameworkRootPathToXBuildFrameworks();
}

TrySetTargetFrameworkRootPathToXBuildFrameworks();
TrySetRoslynTargetsPathAndCscTool();

return true;
Expand Down
20 changes: 2 additions & 18 deletions src/OmniSharp.MSBuild/MSBuildProjectSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -306,22 +306,6 @@ private static string FindSolutionFilePath(string rootPath, ILogger logger)
return result.FilePath;
}

private string GetSdksPath(string projectFilePath)
{
var info = _dotNetCli.GetInfo(Path.GetDirectoryName(projectFilePath));

if (info.IsEmpty || string.IsNullOrWhiteSpace(info.BasePath))
{
return null;
}

var result = Path.Combine(info.BasePath, "Sdks");

return Directory.Exists(result)
? result
: null;
}

private ProjectFileInfo LoadProject(string projectFilePath)
{
_logger.LogInformation($"Loading project: {projectFilePath}");
Expand All @@ -331,7 +315,7 @@ private ProjectFileInfo LoadProject(string projectFilePath)

try
{
project = ProjectFileInfo.Create(projectFilePath, _environment.TargetDirectory, GetSdksPath(projectFilePath), _loggerFactory.CreateLogger<ProjectFileInfo>(), _options, diagnostics);
project = ProjectFileInfo.Create(projectFilePath, _environment.TargetDirectory, _loggerFactory.CreateLogger<ProjectFileInfo>(), _options, diagnostics);

if (project == null)
{
Expand All @@ -357,7 +341,7 @@ private void OnProjectChanged(string projectFilePath, bool allowAutoRestore)
if (_projects.TryGetValue(projectFilePath, out var oldProjectFileInfo))
{
var diagnostics = new List<MSBuildDiagnosticsMessage>();
var newProjectFileInfo = oldProjectFileInfo.Reload(_environment.TargetDirectory, GetSdksPath(projectFilePath), _loggerFactory.CreateLogger<ProjectFileInfo>(), _options, diagnostics);
var newProjectFileInfo = oldProjectFileInfo.Reload(_environment.TargetDirectory, _loggerFactory.CreateLogger<ProjectFileInfo>(), _options, diagnostics);

if (newProjectFileInfo != null)
{
Expand Down
94 changes: 37 additions & 57 deletions src/OmniSharp.MSBuild/ProjectFile/ProjectFileInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,15 +69,15 @@ private ProjectFileInfo(
}

public static ProjectFileInfo Create(
string filePath, string solutionDirectory, string sdksPath, ILogger logger,
string filePath, string solutionDirectory, ILogger logger,
MSBuildOptions options = null, ICollection<MSBuildDiagnosticsMessage> diagnostics = null)
{
if (!File.Exists(filePath))
{
return null;
}

var projectInstance = LoadProject(filePath, solutionDirectory, sdksPath, logger, options, diagnostics, out var targetFrameworks);
var projectInstance = LoadProject(filePath, solutionDirectory, logger, options, diagnostics, out var targetFrameworks);
if (projectInstance == null)
{
return null;
Expand All @@ -90,65 +90,51 @@ public static ProjectFileInfo Create(
}

private static ProjectInstance LoadProject(
string filePath, string solutionDirectory, string sdksPath, ILogger logger,
string filePath, string solutionDirectory, ILogger logger,
MSBuildOptions options, ICollection<MSBuildDiagnosticsMessage> diagnostics, out ImmutableArray<string> targetFrameworks)
{
options = options ?? new MSBuildOptions();

var globalProperties = GetGlobalProperties(options, solutionDirectory, sdksPath, logger);
var globalProperties = GetGlobalProperties(options, solutionDirectory, logger);

const string MSBuildSDKsPath = "MSBuildSDKsPath";
var oldSdksPathValue = Environment.GetEnvironmentVariable(MSBuildSDKsPath);
try
{
if (globalProperties.TryGetValue(MSBuildSDKsPath, out var sdksPathValue))
{
Environment.SetEnvironmentVariable(MSBuildSDKsPath, sdksPathValue);
}

var collection = new ProjectCollection(globalProperties);

var toolsVersion = options.ToolsVersion;
if (string.IsNullOrEmpty(toolsVersion) || Version.TryParse(toolsVersion, out _))
{
toolsVersion = collection.DefaultToolsVersion;
}

toolsVersion = GetLegalToolsetVersion(toolsVersion, collection.Toolsets);
var collection = new ProjectCollection(globalProperties);

// Evaluate the MSBuild project
var project = collection.LoadProject(filePath, toolsVersion);
var toolsVersion = options.ToolsVersion;
if (string.IsNullOrEmpty(toolsVersion) || Version.TryParse(toolsVersion, out _))
{
toolsVersion = collection.DefaultToolsVersion;
}

var targetFramework = project.GetPropertyValue(PropertyNames.TargetFramework);
targetFrameworks = PropertyConverter.SplitList(project.GetPropertyValue(PropertyNames.TargetFrameworks), ';');
toolsVersion = GetLegalToolsetVersion(toolsVersion, collection.Toolsets);

// If the project supports multiple target frameworks and specific framework isn't
// selected, we must pick one before execution. Otherwise, the ResolveReferences
// target might not be available to us.
if (string.IsNullOrWhiteSpace(targetFramework) && targetFrameworks.Length > 0)
{
// For now, we'll just pick the first target framework. Eventually, we'll need to
// do better and potentially allow OmniSharp hosts to select a target framework.
targetFramework = targetFrameworks[0];
project.SetProperty(PropertyNames.TargetFramework, targetFramework);
}
else if (!string.IsNullOrWhiteSpace(targetFramework) && targetFrameworks.Length == 0)
{
targetFrameworks = ImmutableArray.Create(targetFramework);
}
// Evaluate the MSBuild project
var project = collection.LoadProject(filePath, toolsVersion);

var projectInstance = project.CreateProjectInstance();
var buildResult = projectInstance.Build(TargetNames.Compile,
new[] { new MSBuildLogForwarder(logger, diagnostics) });
var targetFramework = project.GetPropertyValue(PropertyNames.TargetFramework);
targetFrameworks = PropertyConverter.SplitList(project.GetPropertyValue(PropertyNames.TargetFrameworks), ';');

return buildResult
? projectInstance
: null;
// If the project supports multiple target frameworks and specific framework isn't
// selected, we must pick one before execution. Otherwise, the ResolveReferences
// target might not be available to us.
if (string.IsNullOrWhiteSpace(targetFramework) && targetFrameworks.Length > 0)
{
// For now, we'll just pick the first target framework. Eventually, we'll need to
// do better and potentially allow OmniSharp hosts to select a target framework.
targetFramework = targetFrameworks[0];
project.SetProperty(PropertyNames.TargetFramework, targetFramework);
}
finally
else if (!string.IsNullOrWhiteSpace(targetFramework) && targetFrameworks.Length == 0)
{
Environment.SetEnvironmentVariable(MSBuildSDKsPath, oldSdksPathValue);
targetFrameworks = ImmutableArray.Create(targetFramework);
}

var projectInstance = project.CreateProjectInstance();
var buildResult = projectInstance.Build(TargetNames.Compile,
new[] { new MSBuildLogForwarder(logger, diagnostics) });

return buildResult
? projectInstance
: null;
}

private static string GetLegalToolsetVersion(string toolsVersion, ICollection<Toolset> toolsets)
Expand Down Expand Up @@ -232,10 +218,10 @@ private static ProjectData CreateProjectData(ProjectInstance projectInstance, Im
}

public ProjectFileInfo Reload(
string solutionDirectory, string sdksPath, ILogger logger,
string solutionDirectory, ILogger logger,
MSBuildOptions options = null, ICollection<MSBuildDiagnosticsMessage> diagnostics = null)
{
var projectInstance = LoadProject(FilePath, solutionDirectory, sdksPath, logger, options, diagnostics, out var targetFrameworks);
var projectInstance = LoadProject(FilePath, solutionDirectory, logger, options, diagnostics, out var targetFrameworks);
if (projectInstance == null)
{
return null;
Expand All @@ -257,7 +243,7 @@ public bool IsUnityProject()
});
}

private static Dictionary<string, string> GetGlobalProperties(MSBuildOptions options, string solutionDirectory, string sdksPath, ILogger logger)
private static Dictionary<string, string> GetGlobalProperties(MSBuildOptions options, string solutionDirectory, ILogger logger)
{
var globalProperties = new Dictionary<string, string>
{
Expand All @@ -278,12 +264,6 @@ private static Dictionary<string, string> GetGlobalProperties(MSBuildOptions opt
userOptionValue: options.MSBuildExtensionsPath,
environmentValue: MSBuildEnvironment.MSBuildExtensionsPath);

globalProperties.AddPropertyIfNeeded(
logger,
PropertyNames.MSBuildSDKsPath,
userOptionValue: options.MSBuildSDKsPath,
environmentValue: sdksPath);

globalProperties.AddPropertyIfNeeded(
logger,
PropertyNames.TargetFrameworkRootPath,
Expand Down
Loading

0 comments on commit 9a8afe7

Please sign in to comment.