Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update to MSBuild project model and fix for cross-targeting projects #707

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 24 additions & 5 deletions build.cake
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ Task("AcquirePackages")
CreateDirectory(msbuildNet46Folder);
CreateDirectory(msbuildNetCoreAppFolder);

// Copy MSBuild and SDKs to appropriate locations
// Copy MSBuild runtime to appropriate locations
var msbuildInstallFolder = System.IO.Path.Combine(packagesFolder, "Microsoft.Build.Runtime", "contentFiles", "any");
var msbuildNet46InstallFolder = System.IO.Path.Combine(msbuildInstallFolder, "net46");
var msbuildNetCoreAppInstallFolder = System.IO.Path.Combine(msbuildInstallFolder, "netcoreapp1.0");
Expand Down Expand Up @@ -203,12 +203,25 @@ Task("AcquirePackages")
DeleteFiles(System.IO.Path.Combine(netCoreAppSdkTargetFolder, "*.nupkg"));
}

// Copy NuGet.targets from NuGet.Build.Tasks
var nugetTargetsName = "NuGet.targets";
var nugetTargetsPath = System.IO.Path.Combine(packagesFolder, "NuGet.Build.Tasks", "runtimes", "any", "native", nugetTargetsName);

CopyFile(nugetTargetsPath, System.IO.Path.Combine(msbuildNet46Folder, nugetTargetsName));
CopyFile(nugetTargetsPath, System.IO.Path.Combine(msbuildNetCoreAppFolder, nugetTargetsName));

// Finally, copy Microsoft.CSharp.Core.targets from Microsoft.Net.Compilers
var targetsName = "Microsoft.CSharp.Core.targets";
var csharpTargetsPath = System.IO.Path.Combine(packagesFolder, "Microsoft.Net.Compilers", "tools", targetsName);
var csharpTargetsName = "Microsoft.CSharp.Core.targets";
var csharpTargetsPath = System.IO.Path.Combine(packagesFolder, "Microsoft.Net.Compilers", "tools", csharpTargetsName);

var csharpTargetsNet46Folder = System.IO.Path.Combine(msbuildNet46Folder, "Roslyn");
var csharpTargetsNetCoreAppFolder = System.IO.Path.Combine(msbuildNetCoreAppFolder, "Roslyn");

CopyFile(csharpTargetsPath, System.IO.Path.Combine(msbuildNet46Folder, targetsName));
CopyFile(csharpTargetsPath, System.IO.Path.Combine(msbuildNetCoreAppFolder, targetsName));
CreateDirectory(csharpTargetsNet46Folder);
CreateDirectory(csharpTargetsNetCoreAppFolder);

CopyFile(csharpTargetsPath, System.IO.Path.Combine(csharpTargetsNet46Folder, csharpTargetsName));
CopyFile(csharpTargetsPath, System.IO.Path.Combine(csharpTargetsNetCoreAppFolder,csharpTargetsName));
});

/// <summary>
Expand Down Expand Up @@ -430,6 +443,9 @@ Task("Test")
}
else
{
// Copy the Mono-built Microsoft.Build.* binaries to the test folder.
CopyDirectory($"{msbuildLibForMonoInstallFolder}", instanceFolder);

Run("mono", $"\"{xunitInstancePath}\" {arguments}", instanceFolder)
.ExceptionOnError($"Test {project} failed for {framework}");
}
Expand Down Expand Up @@ -488,6 +504,9 @@ Task("OnlyPublish")
// Copy MSBuild and SDKs to output
CopyDirectory($"{msbuildBaseFolder}-{framework}", System.IO.Path.Combine(outputFolder, "msbuild"));

// Delete NuGet.targets from output
DeleteFile(System.IO.Path.Combine(outputFolder, "NuGet.targets"));

// For OSX/Linux net46 builds, copy the MSBuild libraries built for Mono.
if (!IsRunningOnWindows() && framework == "net46")
{
Expand Down
3 changes: 2 additions & 1 deletion build.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
"PackagesFolder": "packages",
"TestProjects": {
"OmniSharp.MSBuild.Tests": [
"netcoreapp1.0"
"netcoreapp1.0",
"net46"
],
"OmniSharp.Roslyn.CSharp.Tests": [
"netcoreapp1.0"
Expand Down
3 changes: 2 additions & 1 deletion packages/packages.config
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Build.Runtime" version="15.1.0-preview-000458-02" />
<package id="Microsoft.Build.Runtime" version="15.1.0-preview-000467-06" />
<package id="NuGet.Build.Tasks" version="4.0.0-rc2" />
<package id="NuGet.Build.Tasks.Pack" version="4.0.0-rc2" />
<package id="Microsoft.NET.Sdk" version="1.0.0-alpha-20161203-1" />
<package id="Microsoft.NET.Sdk.Web" version="1.0.0-alpha-20161205-1-154" />
Expand Down
126 changes: 126 additions & 0 deletions src/OmniSharp.MSBuild/MSBuildEnvironment.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
using System;
using System.IO;
using Microsoft.Extensions.Logging;

namespace OmniSharp.MSBuild
{
public static class MSBuildEnvironment
{
private static bool s_isInitialized;
private static string s_msbuildFolder;

public static bool IsInitialized => s_isInitialized;

public static string MSBuildFolder
{
get
{
EnsureInitialized();
return s_msbuildFolder;
}
}

public static void Initialize(ILogger logger)
{
if (s_isInitialized)
{
throw new InvalidOperationException("MSBuildEnvironment is already initialized");
}

// If OmniSharp is running normally, MSBuild is located in an 'msbuild' folder beneath OmniSharp.exe.
var msbuildFolder = Path.Combine(AppContext.BaseDirectory, "msbuild");

if (!Directory.Exists(msbuildFolder))
{
// If the 'msbuild' folder does not exist beneath OmniSharp.exe, this is likely a development scenario,
// such as debugging or running unit tests. In that case, we use one of the .msbuild-* folders at the
// solution level.
msbuildFolder = FindMSBuildFolderFromSolution();
}

if (msbuildFolder == null || !Directory.Exists(msbuildFolder))
{
logger.LogError("Could not locate MSBuild path. MSBuildProjectSystem will not function properly.");
return;
}

// Set the MSBuildExtensionsPath environment variable to the msbuild folder.
Environment.SetEnvironmentVariable("MSBuildExtensionsPath", msbuildFolder);
logger.LogInformation($"MSBuildExtensionsPath environment variable set to {msbuildFolder}");

// Set the MSBUILD_EXE_PATH environment variable to the location of MSBuild.exe or MSBuild.dll.
var msbuildExePath = Path.Combine(msbuildFolder, "MSBuild.exe");
if (!File.Exists(msbuildExePath))
{
msbuildExePath = Path.Combine(msbuildFolder, "MSBuild.dll");
}

if (!File.Exists(msbuildExePath))
{
logger.LogError("Could not locate MSBuild to set MSBUILD_EXE_PATH");
return;
}

if (File.Exists(msbuildExePath))
{
Environment.SetEnvironmentVariable("MSBUILD_EXE_PATH", msbuildExePath);
logger.LogInformation($"MSBUILD_EXE_PATH environment variable set to {msbuildExePath}");
}
else
{
logger.LogError("Could not locate MSBuild to set MSBUILD_EXE_PATH"); ;
}

// Set the MSBuildSDKsPath environment variable to the location of the SDKs.
var msbuildSdksFolder = Path.Combine(msbuildFolder, "Sdks");
if (Directory.Exists(msbuildSdksFolder))
{
Environment.SetEnvironmentVariable("MSBuildSDKsPath", msbuildSdksFolder);
logger.LogInformation($"MSBuildSDKsPath environment variable set to {msbuildSdksFolder}");
}
else
{
logger.LogError("Could not locate MSBuild Sdks path to set MSBuildSDKsPath");
}

s_msbuildFolder = msbuildFolder;
s_isInitialized = true;
}

private static void EnsureInitialized()
{
if (!s_isInitialized)
{
throw new InvalidOperationException("MSBuildEnvironment is not initialized");
}
}

private static string FindMSBuildFolderFromSolution()
{
// Try to locate the appropriate build-time msbuild folder by searching for
// the OmniSharp solution relative to the current folder.

var current = Directory.GetCurrentDirectory();
while (!File.Exists(Path.Combine(current, "OmniSharp.sln")))
{
current = Path.GetDirectoryName(current);
if (Path.GetPathRoot(current) == current)
{
break;
}
}

#if NET46
var folderName = ".msbuild-net46";
#else
var folderName = ".msbuild-netcoreapp1.0";
#endif

var result = Path.Combine(current, folderName);

return Directory.Exists(result)
? result
: null;
}
}
}
87 changes: 2 additions & 85 deletions src/OmniSharp.MSBuild/MSBuildProjectSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,95 +68,12 @@ public MSBuildProjectSystem(
_logger = loggerFactory.CreateLogger("OmniSharp#MSBuild");
}

private static string FindMSBuildFolder()
{
// Try to locate the appropriate build-time msbuild folder by searching for
// the OmniSharp solution relative to the current folder.

var current = Directory.GetCurrentDirectory();
while (!File.Exists(Path.Combine(current, "OmniSharp.sln")))
{
current = Path.GetDirectoryName(current);
if (Path.GetPathRoot(current) == current)
{
break;
}
}

#if NET46
var folderName = ".msbuild-net46";
#else
var folderName = ".msbuild-netcoreapp1.0";
#endif

var result = Path.Combine(current, folderName);

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

public static void SetUpMSBuildEnvironment(ILogger logger)
{
var msbuildFolder = Path.Combine(AppContext.BaseDirectory, "msbuild");

if (!Directory.Exists(msbuildFolder))
{
msbuildFolder = FindMSBuildFolder();
}

if (msbuildFolder == null || !Directory.Exists(msbuildFolder))
{
logger.LogError("Could not locate MSBuild path. MSBuildProjectSystem will not function properly.");
return;
}

// Set the MSBuildExtensionsPath environment variable to the msbuild folder.
Environment.SetEnvironmentVariable("MSBuildExtensionsPath", msbuildFolder);
logger.LogInformation($"MSBuildExtensionsPath environment variable set to {msbuildFolder}");

// Set the MSBUILD_EXE_PATH environment variable to the location of MSBuild.exe or MSBuild.dll.
var msbuildExePath = Path.Combine(msbuildFolder, "MSBuild.exe");
if (!File.Exists(msbuildExePath))
{
msbuildExePath = Path.Combine(msbuildFolder, "MSBuild.dll");
}

if (!File.Exists(msbuildExePath))
{
logger.LogError("Could not locate MSBuild to set MSBUILD_EXE_PATH");
return;
}

if (File.Exists(msbuildExePath))
{
Environment.SetEnvironmentVariable("MSBUILD_EXE_PATH", msbuildExePath);
logger.LogInformation($"MSBUILD_EXE_PATH environment variable set to {msbuildExePath}");
}
else
{
logger.LogError("Could not locate MSBuild to set MSBUILD_EXE_PATH"); ;
}

// Set the MSBuildSDKsPath environment variable to the location of the SDKs.
var msbuildSdksFolder = Path.Combine(msbuildFolder, "Sdks");
if (Directory.Exists(msbuildSdksFolder))
{
Environment.SetEnvironmentVariable("MSBuildSDKsPath", msbuildSdksFolder);
logger.LogInformation($"MSBuildSDKsPath environment variable set to {msbuildSdksFolder}");
}
else
{
logger.LogError("Could not locate MSBuild Sdks path to set MSBuildSDKsPath");
}
}

public void Initalize(IConfiguration configuration)
{
_options = new MSBuildOptions();
ConfigurationBinder.Bind(configuration, _options);

SetUpMSBuildEnvironment(_logger);
MSBuildEnvironment.Initialize(_logger);

if (_options.WaitForDebugger)
{
Expand Down Expand Up @@ -597,7 +514,7 @@ Task<object> IProjectSystem.GetProjectModelAsync(string filePath)
}

return Task.FromResult<object>(
new MSBuildProject(projectFileInfo));
new MSBuildProjectInformation(projectFileInfo));
}
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
using System;
using System.Collections.Generic;
using NuGet.Frameworks;
using OmniSharp.MSBuild.ProjectFile;

namespace OmniSharp.Models
{
public class MSBuildProject
public class MSBuildProjectInformation
{
public Guid ProjectGuid { get; set; }
public string Path { get; set; }
Expand All @@ -13,15 +14,34 @@ public class MSBuildProject
public string TargetFramework { get; set; }
public IList<string> SourceFiles { get; set; }
public IList<TargetFramework> TargetFrameworks { get; set; }
public string OutputPath { get; set; }

public MSBuildProject(ProjectFileInfo projectFileInfo)
public MSBuildProjectInformation(ProjectFileInfo projectFileInfo)
{
AssemblyName = projectFileInfo.AssemblyName;
Path = projectFileInfo.ProjectFilePath;
TargetPath = projectFileInfo.TargetPath;
ProjectGuid = projectFileInfo.ProjectGuid;
TargetFramework = projectFileInfo.TargetFramework.ToString();
SourceFiles = projectFileInfo.SourceFiles;

var targetFrameworks = new List<TargetFramework>();
foreach (var targetFramework in projectFileInfo.TargetFrameworks)
{
try
{
var framework = NuGetFramework.Parse(targetFramework);
targetFrameworks.Add(new TargetFramework(framework));
}
catch
{
// If the value can't be parsed, ignore it.
}
}

TargetFrameworks = targetFrameworks;

OutputPath = projectFileInfo.OutputPath;
}
}
}
4 changes: 2 additions & 2 deletions src/OmniSharp.MSBuild/Models/MsBuildWorkspaceInformation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public MsBuildWorkspaceInformation(string solutionFilePath, IEnumerable<ProjectF
Projects = projects
.OrderBy(x => x.AssemblyName)
.Select(p => {
var project = new MSBuildProject(p);
var project = new MSBuildProjectInformation(p);
if (excludeSourceFiles)
{
project.SourceFiles = null;
Expand All @@ -24,6 +24,6 @@ public MsBuildWorkspaceInformation(string solutionFilePath, IEnumerable<ProjectF
}

public string SolutionPath { get; }
public IEnumerable<MSBuildProject> Projects { get; }
public IEnumerable<MSBuildProjectInformation> Projects { get; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ private static class PropertyNames
public const string OutputType = nameof(OutputType);
public const string MSBuildExtensionsPath = nameof(MSBuildExtensionsPath);
public const string NoWarn = nameof(NoWarn);
public const string OutputPath = nameof(OutputPath);
public const string ProjectGuid = nameof(ProjectGuid);
public const string ProjectName = nameof(ProjectName);
public const string _ResolveReferenceDependencies = nameof(_ResolveReferenceDependencies);
Expand Down
Loading