-
Notifications
You must be signed in to change notification settings - Fork 514
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[tools] Add helper tool to create launch.json for dotnet-linker. (#18294
) This tool takes a binlog as input, and creates a launch.json for dotnet-linker that will execute the linker as was done in the binlog. This is very useful for debugging custom linker steps, since they can be debugged in VSCode now.
- Loading branch information
1 parent
cdbf30c
commit 464cf69
Showing
4 changed files
with
185 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
using System.IO; | ||
using System.Text; | ||
|
||
using Microsoft.Build.Framework; | ||
using Microsoft.Build.Logging; | ||
using Microsoft.Build.Logging.StructuredLogger; | ||
|
||
using Mono.Options; | ||
|
||
class Program { | ||
static int Main (string [] args) | ||
{ | ||
var printHelp = false; | ||
var binlog = string.Empty; | ||
var rootDirectory = string.Empty; | ||
var skippedLinkerCommands = 0; | ||
var options = new OptionSet { | ||
{ "h|?|help", "Print this help message", (v) => printHelp = true }, | ||
{ "r|root=", "The root directory", (v) => rootDirectory = v }, | ||
{ "bl|binlog=", "The binlog", (v) => binlog = v }, | ||
{ "s|skip", "Task invocations to skip", (v) => skippedLinkerCommands++ }, | ||
}; | ||
|
||
if (printHelp) { | ||
options.WriteOptionDescriptions (Console.Out); | ||
return 0; | ||
} | ||
|
||
var others = options.Parse (args); | ||
if (others.Any ()) { | ||
Console.WriteLine ("Unexpected arguments:"); | ||
foreach (var arg in others) | ||
Console.WriteLine ("\t{0}", arg); | ||
Console.WriteLine ("Expected arguments are:"); | ||
options.WriteOptionDescriptions (Console.Out); | ||
return 1; | ||
} | ||
|
||
if (string.IsNullOrEmpty (binlog)) { | ||
Console.Error.WriteLine ("A binlog is required"); | ||
Console.WriteLine ("Expected arguments are:"); | ||
options.WriteOptionDescriptions (Console.Out); | ||
return 1; | ||
} | ||
|
||
var path = Path.GetFullPath (binlog); | ||
|
||
if (string.IsNullOrEmpty (rootDirectory)) | ||
rootDirectory = Path.GetDirectoryName (path)!; | ||
|
||
Console.WriteLine ($"Processing {path} with root directory {rootDirectory}..."); | ||
|
||
|
||
var reader = new BinLogReader (); | ||
var records = reader.ReadRecords (path).ToArray (); | ||
foreach (var record in records) { | ||
if (record is null) | ||
continue; | ||
|
||
if (record.Args is null) | ||
continue; | ||
|
||
if (record.Args is TaskStartedEventArgs tsea && tsea.TaskName == "ILLink") { | ||
if (skippedLinkerCommands > 0) { | ||
Console.WriteLine ($"Skipped an ILLink task invocation, {skippedLinkerCommands} left to skip..."); | ||
skippedLinkerCommands--; | ||
continue; | ||
} | ||
|
||
|
||
var relevantRecords = records.Where (v => v?.Args?.BuildEventContext?.TaskId == tsea.BuildEventContext.TaskId).Select (v => v.Args).ToArray (); | ||
var cla = relevantRecords.Where (v => v is BuildMessageEventArgs).Cast<BuildMessageEventArgs> ().Where (v => v?.ToString ()?.Contains ("CommandLineArguments") == true).ToArray (); | ||
foreach (var rr in relevantRecords) { | ||
if (rr is TaskCommandLineEventArgs tclea) { | ||
if (!Xamarin.Utils.StringUtils.TryParseArguments (tclea.CommandLine.Replace ('\n', ' '), out var arguments, out var ex)) { | ||
Console.WriteLine ($"Failed to parse command line arguments: {ex.Message}"); | ||
return 1; | ||
} | ||
|
||
WriteLaunchJson (CreateLaunchJson (rootDirectory, arguments)); | ||
return 0; | ||
} | ||
} | ||
} | ||
} | ||
|
||
Console.Error.WriteLine ($"Unable to find command line arguments for ILLink in {path}"); | ||
return 1; | ||
} | ||
|
||
static void WriteLaunchJson (string contents) | ||
{ | ||
var dir = Environment.CurrentDirectory!; | ||
while (!Directory.Exists (Path.Combine (dir, "tools", "dotnet-linker"))) | ||
dir = Path.GetDirectoryName (dir)!; | ||
var path = Path.Combine (dir, "tools", "dotnet-linker", ".vscode", "launch.json"); | ||
File.WriteAllText (path, contents); | ||
Console.WriteLine ($"Created {path}"); | ||
} | ||
|
||
static string CreateLaunchJson (string workingDirectory, string [] arguments) | ||
{ | ||
var dotnet = arguments [0]; | ||
var sb = new StringBuilder (); | ||
sb.AppendLine ("{"); | ||
sb.AppendLine (" // Use IntelliSense to learn about possible attributes."); | ||
sb.AppendLine (" // Hover to view descriptions of existing attributes."); | ||
sb.AppendLine (" // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387"); | ||
sb.AppendLine (" \"version\": \"0.2.0\","); | ||
sb.AppendLine (" \"configurations\": ["); | ||
sb.AppendLine (" {"); | ||
sb.AppendLine (" \"justMyCode\": false,"); | ||
sb.AppendLine (" \"preLaunchTask\": \"make\","); | ||
sb.AppendLine (" \"name\": \".NET Core Launch (console)\","); | ||
sb.AppendLine (" \"type\": \"coreclr\","); | ||
sb.AppendLine (" \"request\": \"launch\","); | ||
sb.AppendLine ($" \"program\": \"{dotnet}\","); | ||
sb.AppendLine (" \"args\": ["); | ||
for (var i = 1; i < arguments.Length; i++) { | ||
sb.AppendLine ($" \"{arguments [i]}\"{(i < arguments.Length - 1 ? "," : "")}"); | ||
} | ||
sb.AppendLine (" ],"); | ||
sb.AppendLine ($" \"cwd\": \"{Path.GetFullPath (workingDirectory)}\","); | ||
sb.AppendLine (" \"console\": \"internalConsole\","); | ||
sb.AppendLine (" \"stopAtEntry\": false"); | ||
sb.AppendLine (" },"); | ||
sb.AppendLine (" {"); | ||
sb.AppendLine (" \"name\": \".NET Core Attach\","); | ||
sb.AppendLine (" \"type\": \"coreclr\","); | ||
sb.AppendLine (" \"request\": \"attach\""); | ||
sb.AppendLine (" }"); | ||
sb.AppendLine (" ]"); | ||
sb.AppendLine ("}"); | ||
return sb.ToString (); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
This tool takes a binlog that executes dotnet-linker, and creates a | ||
launch.json file for the dotnet-linker directory so that the steps can be | ||
debugged in VSCode. |
21 changes: 21 additions & 0 deletions
21
tools/create-dotnet-linker-launch-json/create-dotnet-linker-launch-json.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<OutputType>Exe</OutputType> | ||
<TargetFramework>net7.0</TargetFramework> | ||
<RootNamespace>create_dotnet_linker_launch_json</RootNamespace> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="MSBuild.StructuredLogger" Version="2.1.758" /> | ||
<PackageReference Include="Mono.Options" Version="6.12.0.148" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<Compile Include="..\common\StringUtils.cs"> | ||
<Link>StringUtils.cs</Link> | ||
</Compile> | ||
</ItemGroup> | ||
</Project> |
25 changes: 25 additions & 0 deletions
25
tools/create-dotnet-linker-launch-json/create-dotnet-linker-launch-json.sln
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
|
||
Microsoft Visual Studio Solution File, Format Version 12.00 | ||
# Visual Studio Version 16 | ||
VisualStudioVersion = 25.0.1706.0 | ||
MinimumVisualStudioVersion = 10.0.40219.1 | ||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "create-dotnet-linker-launch-json", "create-dotnet-linker-launch-json.csproj", "{9D626D84-80BA-43E8-ADDF-EAE8944F73D8}" | ||
EndProject | ||
Global | ||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||
Debug|Any CPU = Debug|Any CPU | ||
Release|Any CPU = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||
{9D626D84-80BA-43E8-ADDF-EAE8944F73D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{9D626D84-80BA-43E8-ADDF-EAE8944F73D8}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{9D626D84-80BA-43E8-ADDF-EAE8944F73D8}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{9D626D84-80BA-43E8-ADDF-EAE8944F73D8}.Release|Any CPU.Build.0 = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(SolutionProperties) = preSolution | ||
HideSolutionNode = FALSE | ||
EndGlobalSection | ||
GlobalSection(ExtensibilityGlobals) = postSolution | ||
SolutionGuid = {B197B398-E8C7-444F-B2E2-1F479AE20CA2} | ||
EndGlobalSection | ||
EndGlobal |
This comment was marked as outdated.
Sorry, something went wrong.
This comment was marked as outdated.
Sorry, something went wrong.
This comment was marked as outdated.
Sorry, something went wrong.
This comment was marked as outdated.
Sorry, something went wrong.
This comment was marked as outdated.
Sorry, something went wrong.