Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
45 changes: 45 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,51 @@
"stopAtEntry": false,
"console": "internalConsole"
},
{
"name": "Launch Microsoft.Build.Tasks.CodeAnalysis.dll via MSBuild.exe (netfx)",
"type": "clr",
"request": "launch",
"preLaunchTask": "build toolset",
"program": "C:/Program Files/Microsoft Visual Studio/2022/Preview/MSBuild/Current/Bin/amd64/MSBuild.exe",
"args": [
"-restore",
"-p:RoslynTargetsPath=${workspaceFolder}/artifacts/bin/Microsoft.Net.Compilers.Toolset.Package/Debug/tasks/net472",
],
// A simple project that can be used to debug the build tasks against.
"cwd": "${workspaceFolder}/src/Tools/Source/CompilerGeneratorTools/Source/BoundTreeGenerator",
"stopAtEntry": false,
"console": "internalConsole"
},
{
"name": "Launch Microsoft.Build.Tasks.CodeAnalysis.dll via MSBuild.exe (netcore)",
"type": "clr",
"request": "launch",
"preLaunchTask": "build toolset",
"program": "C:/Program Files/Microsoft Visual Studio/2022/Preview/MSBuild/Current/Bin/amd64/MSBuild.exe",
"args": [
"-restore",
"-p:RoslynTargetsPath=${workspaceFolder}/artifacts/bin/Microsoft.Net.Compilers.Toolset.Package/Debug/tasks/netcore",
],
// A simple project that can be used to debug the build tasks against.
"cwd": "${workspaceFolder}/src/Tools/Source/CompilerGeneratorTools/Source/BoundTreeGenerator",
"stopAtEntry": false,
"console": "internalConsole"
},
{
"name": "Launch Microsoft.Build.Tasks.CodeAnalysis.dll via dotnet build",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build toolset",
"program": "dotnet",
"args": [
"build",
"-p:RoslynTargetsPath=${workspaceFolder}/artifacts/bin/Microsoft.Net.Compilers.Toolset.Package/Debug/tasks/netcore",
],
// A simple project that can be used to debug the build tasks against.
"cwd": "${workspaceFolder}/src/Tools/Source/CompilerGeneratorTools/Source/BoundTreeGenerator",
"stopAtEntry": false,
"console": "internalConsole"
},
{
"name": ".NET Core Launch (console)",
"type": "coreclr",
Expand Down
12 changes: 12 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,18 @@
"problemMatcher": "$msCompile",
"group": "build"
},
{
"label": "build toolset",
"type": "shell",
"command": "dotnet",
"args": [
"build",
"-p:GenerateFullPaths=true",
"${workspaceFolder}/src/NuGet/Microsoft.Net.Compilers.Toolset/AnyCpu/Microsoft.Net.Compilers.Toolset.Package.csproj"
],
"problemMatcher": "$msCompile",
"group": "build"
},
{
"label": "msbuild current project",
"type": "shell",
Expand Down
4 changes: 4 additions & 0 deletions src/Compilers/Core/CommandLine/NativeMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

using System;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;

namespace Microsoft.CodeAnalysis.CommandLine
Expand Down Expand Up @@ -43,6 +44,9 @@ internal struct PROCESS_INFORMATION
/// <summary>
/// Interop methods.
/// </summary>
#if NET
[SupportedOSPlatform("windows")]
#endif
internal static class NativeMethods
{
#region Constants
Expand Down
2 changes: 1 addition & 1 deletion src/Compilers/Core/MSBuildTask/InteractiveCompiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
namespace Microsoft.CodeAnalysis.BuildTasks
{
/// <summary>
/// This class defines all of the common stuff that is shared between the Vbc and Csc tasks.
/// This class defines all of the common stuff that is shared between the Vbi and Csi tasks.
/// This class is not instantiatable as a Task just by itself.
/// </summary>
public abstract class InteractiveCompiler : ManagedToolTask
Expand Down
28 changes: 28 additions & 0 deletions src/Compilers/Core/MSBuildTask/ManagedCompiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,27 @@ public bool ReportIVTs
get { return _store.GetOrDefault(nameof(ReportIVTs), false); }
}

public string? CompilerType
{
set { _store[nameof(CompilerType)] = value; }
get { return (string?)_store[nameof(CompilerType)]; }
}

protected override RoslynCompilerType GetCompilerType()
{
if (string.IsNullOrWhiteSpace(CompilerType))
{
return DefaultCompilerType;
}

if (Enum.TryParse<RoslynCompilerType>(CompilerType, ignoreCase: true, out var compilerType))
{
return compilerType;
}

throw new ArgumentException($"Invalid {nameof(CompilerType)} '{CompilerType}' specified. Valid values are {string.Join(", ", Enum.GetNames(typeof(RoslynCompilerType)))}.");
}

#endregion

/// <summary>
Expand Down Expand Up @@ -1226,4 +1247,11 @@ internal string? GetWin32ManifestSwitch
return win32Manifest;
}
}

public enum RoslynCompilerType
{
Core,
Framework,
FrameworkPackage,
}
}
15 changes: 14 additions & 1 deletion src/Compilers/Core/MSBuildTask/ManagedToolTask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,20 @@ public abstract class ManagedToolTask : ToolTask
/// </remarks>
protected bool IsManagedTool => string.IsNullOrEmpty(ToolPath) && ToolExe == ToolName;

internal string PathToManagedTool => Utilities.GenerateFullPathToTool(ToolName);
/// <summary>
/// Used to determine the directory where the tools (like csc) are located.
/// See <see cref="Utilities.GenerateFullPathToTool"/>.
/// </summary>
protected virtual RoslynCompilerType GetCompilerType() => DefaultCompilerType;

protected const RoslynCompilerType DefaultCompilerType
#if NET
= RoslynCompilerType.Core;
#else
= RoslynCompilerType.Framework;
#endif

internal string PathToManagedTool => Utilities.GenerateFullPathToTool(ToolName, GetCompilerType());

private string PathToManagedToolWithoutExtension
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@
ChecksumAlgorithm="$(ChecksumAlgorithm)"
CodeAnalysisRuleSet="$(ResolvedCodeAnalysisRuleSet)"
CodePage="$(CodePage)"
CompilerType="$(RoslynCompilerType)"
DebugType="$(DebugType)"
DefineConstants="$(DefineConstants)"
DelaySign="$(DelaySign)"
Expand Down
11 changes: 8 additions & 3 deletions src/Compilers/Core/MSBuildTask/Microsoft.Managed.Core.targets
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Licensed to the .NET Foundation under one or more agreements. The .NET Foundation licenses this file to you under the MIT license. See the LICENSE file in the project root for more information. -->
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<_BuildTasksDirectory>$(MSBuildThisFileDirectory)</_BuildTasksDirectory>
<_BuildTasksDirectory Condition="Exists('$(RoslynTargetsPath)')">$(RoslynTargetsPath)\</_BuildTasksDirectory>
</PropertyGroup>

<!--
Common targets for managed compilers.
-->
<UsingTask TaskName="Microsoft.CodeAnalysis.BuildTasks.MapSourceRoots" AssemblyFile="$(MSBuildThisFileDirectory)Microsoft.Build.Tasks.CodeAnalysis.dll" />
<UsingTask TaskName="Microsoft.CodeAnalysis.BuildTasks.MapSourceRoots" AssemblyFile="$(_BuildTasksDirectory)Microsoft.Build.Tasks.CodeAnalysis.dll" />

<Import Project="Microsoft.Managed.Core.CurrentVersions.targets" />

Expand Down Expand Up @@ -58,7 +63,7 @@
========================
-->
<UsingTask TaskName="Microsoft.CodeAnalysis.BuildTasks.ShowMessageForImplicitlySkipAnalyzers" AssemblyFile="$(MSBuildThisFileDirectory)Microsoft.Build.Tasks.CodeAnalysis.dll" />
<UsingTask TaskName="Microsoft.CodeAnalysis.BuildTasks.ShowMessageForImplicitlySkipAnalyzers" AssemblyFile="$(_BuildTasksDirectory)Microsoft.Build.Tasks.CodeAnalysis.dll" />

<Target Name="_ComputeSkipAnalyzers" BeforeTargets="CoreCompile">
<!-- First, force clear non-user facing properties '_SkipAnalyzers' and '_ImplicitlySkipAnalyzers'. -->
Expand Down Expand Up @@ -151,7 +156,7 @@
<CompilerVisibleProperty Include="PropertyNameToEval" />
<CompilerVisibleItemMetadata Include="ItemType" MetadataName="MetadataToRetrieve" />
-->
<UsingTask TaskName="Microsoft.CodeAnalysis.BuildTasks.GenerateMSBuildEditorConfig" AssemblyFile="$(MSBuildThisFileDirectory)Microsoft.Build.Tasks.CodeAnalysis.dll" />
<UsingTask TaskName="Microsoft.CodeAnalysis.BuildTasks.GenerateMSBuildEditorConfig" AssemblyFile="$(_BuildTasksDirectory)Microsoft.Build.Tasks.CodeAnalysis.dll" />

<Target Name="GenerateMSBuildEditorConfigFile"
BeforeTargets="BeforeCompile;CoreCompile"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
ChecksumAlgorithm="$(ChecksumAlgorithm)"
CodeAnalysisRuleSet="$(ResolvedCodeAnalysisRuleSet)"
CodePage="$(CodePage)"
CompilerType="$(RoslynCompilerType)"
DebugType="$(DebugType)"
DefineConstants="$(FinalDefineConstants)"
DelaySign="$(DelaySign)"
Expand Down
8 changes: 2 additions & 6 deletions src/Compilers/Core/MSBuildTask/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ This MSBuild tasks contains the core tasks and targets for compiling C# and VB p

## Debugging

> [!NOTE] In VSCode, you can use one of the `Microsoft.Build.Tasks.CodeAnalysis.dll` launch targets.

Debugging this code requires a bit of setup because it's not an independent component. It relies on having other parts of the toolset deployed in the same directory. Additionally the project being debugged needs to be modified to ensure this DLL is built instead of the one that ships along side MSBuild.

Set the startup project to Toolset. This project properly deploys all of the necessary components and hence provides a simple F5 experience.
Expand All @@ -26,9 +28,3 @@ The target project itself needs to be modified so that it will load the freshly
Replace `e:\dd\roslyn` with the path to your Roslyn enlistment.

Once that is all done you should be able to F5 the Toolset project and debug the MSBuild task directly.






4 changes: 2 additions & 2 deletions src/Compilers/Core/MSBuildTask/Utilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -171,14 +171,14 @@ internal static Exception GetLocalizedArgumentException(string errorString,
/// <summary>
/// Generate the full path to the tool that is deployed with our build tasks.
/// </summary>
internal static string GenerateFullPathToTool(string toolFileName)
internal static string GenerateFullPathToTool(string toolFileName, RoslynCompilerType compilerType)
{
var buildTask = typeof(Utilities).GetTypeInfo().Assembly;
var assemblyPath = buildTask.Location;
var assemblyDirectory = Path.GetDirectoryName(assemblyPath)!;

return RuntimeHostInfo.IsDesktopRuntime
? Path.Combine(assemblyDirectory, toolFileName)
? Path.Combine(assemblyDirectory, compilerType is RoslynCompilerType.Core ? "../bincore" : "", toolFileName)
: Path.Combine(assemblyDirectory, "bincore", toolFileName);
}
}
Expand Down
11 changes: 3 additions & 8 deletions src/Compilers/Core/MSBuildTaskTests/MiscTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,10 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Linq;
using Microsoft.Build.Framework;
using Microsoft.CodeAnalysis.BuildTasks;
using Xunit;
using Moq;
using Roslyn.Test.Utilities;
using Microsoft.CodeAnalysis.CSharp;
using System.Collections.Immutable;
using Microsoft.CodeAnalysis.CSharp;
using Roslyn.Test.Utilities;
using Xunit;

namespace Microsoft.CodeAnalysis.BuildTasks.UnitTests
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,9 +130,10 @@ public async Task IncorrectServerHashReturnsIncorrectHashResponse()
public void QuotePipeName_Desktop()
{
var serverInfo = BuildServerConnection.GetServerProcessInfo(@"q:\tools", "name with space");
Assert.Equal(@"q:\tools\VBCSCompiler.exe", serverInfo.processFilePath);
Assert.Equal(@"q:\tools\VBCSCompiler.exe", serverInfo.toolFilePath);
Assert.Equal(@"""-pipename:name with space""", serverInfo.commandLineArguments);
// Because q:\tools\VBCSCompiler.exe does not exist, the fallback 'dotnet exec VBCSCompiler.dll' is returned.
Assert.EndsWith(@"\dotnet.exe", serverInfo.processFilePath);
Assert.Equal(@"q:\tools\VBCSCompiler.dll", serverInfo.toolFilePath);
Assert.Equal(@"exec ""q:\tools\VBCSCompiler.dll"" ""-pipename:name with space""", serverInfo.commandLineArguments);
}

[ConditionalFact(typeof(CoreClrOnly))]
Expand Down
2 changes: 2 additions & 0 deletions src/Compilers/Shared/BuildClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,8 @@ private static bool AreNamedPipesSupported()
/// </summary>
private static IEnumerable<string> GetCommandLineWindows(IEnumerable<string> args)
{
Debug.Assert(PlatformInformation.IsWindows);

IntPtr ptr = NativeMethods.GetCommandLine();
if (ptr == IntPtr.Zero)
{
Expand Down
2 changes: 0 additions & 2 deletions src/Compilers/Shared/BuildServerConnection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -543,11 +543,9 @@ internal static string GetPipeName(string clientDirectory)
bool isAdmin = false;
if (PlatformInformation.IsWindows)
{
#pragma warning disable CA1416 // Validate platform compatibility
var currentIdentity = WindowsIdentity.GetCurrent();
var principal = new WindowsPrincipal(currentIdentity);
isAdmin = principal.IsInRole(WindowsBuiltInRole.Administrator);
#pragma warning restore CA1416
}

var userName = Environment.UserName;
Expand Down
2 changes: 0 additions & 2 deletions src/Compilers/Shared/NamedPipeUtil.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ internal static bool CheckClientElevationMatches(NamedPipeServerStream pipeStrea
{
if (PlatformInformation.IsWindows)
{
#pragma warning disable CA1416 // Validate platform compatibility
var serverIdentity = getIdentity();

(string name, bool admin) clientIdentity = default;
Expand All @@ -72,7 +71,6 @@ internal static bool CheckClientElevationMatches(NamedPipeServerStream pipeStrea
var elevatedToAdmin = currentPrincipal.IsInRole(WindowsBuiltInRole.Administrator);
return (currentIdentity.Name, elevatedToAdmin);
}
#pragma warning restore CA1416 // Validate platform compatibility
}

return true;
Expand Down
30 changes: 14 additions & 16 deletions src/Compilers/Shared/RuntimeHostInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ internal static class RuntimeHostInfo
/// </summary>
internal static (string processFilePath, string commandLineArguments, string toolFilePath) GetProcessInfo(string toolFilePathWithoutExtension, string commandLineArguments)
{
#if NET
// First check for an app host file and return that if it's available.
var appHostSuffix = PlatformInformation.IsWindows ? ".exe" : "";
var appFilePath = $"{toolFilePathWithoutExtension}{appHostSuffix}";
Expand All @@ -39,17 +38,17 @@ internal static (string processFilePath, string commandLineArguments, string too
var dotnetFilePath = GetDotNetPathOrDefault();
commandLineArguments = $@"exec ""{toolFilePath}"" {commandLineArguments}";
return (dotnetFilePath, commandLineArguments, toolFilePath);
#else
var toolFilePath = $"{toolFilePathWithoutExtension}.exe";
return (toolFilePath, commandLineArguments, toolFilePath);
#endif
}

internal static bool IsCoreClrRuntime =>
#if NET

internal static bool IsCoreClrRuntime => true;
true;
#else
false;
#endif

private const string DotNetHostPathEnvironmentName = "DOTNET_HOST_PATH";
private const string DotNetExperimentalHostPathEnvironmentName = "DOTNET_EXPERIMENTAL_HOST_PATH";

/// <summary>
/// Get the path to the dotnet executable. In the case the .NET SDK did not provide this information
Expand All @@ -58,14 +57,19 @@ internal static (string processFilePath, string commandLineArguments, string too
/// </summary>
internal static string GetDotNetPathOrDefault()
{
if (Environment.GetEnvironmentVariable(DotNetHostPathEnvironmentName) is string pathToDotNet)
if (Environment.GetEnvironmentVariable(DotNetHostPathEnvironmentName) is { Length: > 0 } pathToDotNet)
{
return pathToDotNet;
}

if (Environment.GetEnvironmentVariable(DotNetExperimentalHostPathEnvironmentName) is { Length: > 0 } pathToDotNetExperimental)
{
return pathToDotNetExperimental;
}

var (fileName, sep) = PlatformInformation.IsWindows
? ("dotnet.exe", ';')
: ("dotnet", ':');
? ("dotnet.exe", new char[] { ';' })
: ("dotnet", new char[] { ':' });

var path = Environment.GetEnvironmentVariable("PATH") ?? "";
foreach (var item in path.Split(sep, StringSplitOptions.RemoveEmptyEntries))
Expand All @@ -86,11 +90,5 @@ internal static string GetDotNetPathOrDefault()

return fileName;
}

#else

internal static bool IsCoreClrRuntime => false;

#endif
}
}
Loading