Skip to content

Commit

Permalink
Port cswinmd tooling (#1190)
Browse files Browse the repository at this point in the history
* Port of cswinmd

* Scope down - remove xdc for now

* use dll crt

* fb

* >

* pr feedback

* >

* Move to .NET 6 and drop AnyCPU in global sln config

Co-authored-by: Manodasan Wignarajah <[email protected]>
  • Loading branch information
asklar and manodasanW authored Sep 10, 2022
1 parent f25f408 commit bbc6a9d
Show file tree
Hide file tree
Showing 18 changed files with 677 additions and 28 deletions.
34 changes: 34 additions & 0 deletions nuget/Microsoft.Windows.CsWinMD.nuspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?xml version="1.0"?>
<package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
<metadata minClientVersion="2.5">
<id>Microsoft.Windows.CsWinMD</id>
<version>$cswinmd_nuget_version$</version>
<title>C#/WinMD tooling</title>
<authors>Microsoft</authors>
<owners>Microsoft</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>C#/WinMD provides support for compiling WinRT API definitions written in C# to be implemented in C++.</description>
<releaseNotes>Release notes are available at https://github.com/microsoft/CsWinRT/releases</releaseNotes>
<tags>C++ C#/WinMD WinRT cswinmd WinMD xlang</tags>
<copyright>© Microsoft Corporation. All rights reserved.</copyright>
<license type="file">LICENSE</license>
<projectUrl>https://github.com/microsoft/cswinrt</projectUrl>
<dependencies>
<group targetFramework="native" />
</dependencies>
</metadata>
<files>
<file src="LICENSE"/>
<file src="NOTICE.txt"/>

<file src="$cswinmd_outpath$\CsWinMD.deps.json" target="tools\native"/>
<file src="$cswinmd_outpath$\cswinmd.dll" target="tools\native"/>
<file src="$cswinmd_outpath$\cswinmd.exe" target="tools\native"/>
<file src="$cswinmd_outpath$\CsWinMD.runtimeconfig.json" target="tools\native"/>
<file src="$cswinmd_outpath$\Microsoft.CodeAnalysis.CSharp.dll" target="tools\native"/>
<file src="$cswinmd_outpath$\Microsoft.CodeAnalysis.dll" target="tools\native"/>
<file src="$cswinmd_outpath$\WinRT.SourceGenerator.dll" target="tools\native"/>
<file src="Microsoft.Windows.CsWinMD.targets" target="build"/>

</files>
</package>
21 changes: 21 additions & 0 deletions nuget/Microsoft.Windows.CsWinMD.targets
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="CSWinMDProduceWinMDFromCSharpComponent" BeforeTargets="CSWinMDInsertComponentWinMD">
<PropertyGroup>
<CsWinMDPath Condition="'$(CsWinMDPath)'==''">$(MSBuildThisFileDirectory)..\tools\native\CsWinMD.exe</CsWinMDPath>
<CsWinMDOutputPath Condition="'$(CsWinMDOutputPath)'==''">$(OutDir)cswinmd-$(ProjectName)</CsWinMDOutputPath>
</PropertyGroup>
<Message Text="Producing winmd for %(CSWinMDComponent.Identity)" Importance="High" />
<Message Text="$(CsWinMDPath) -i %(CSWinMDComponent.FullPath) -o $(CsWinMDOutputPath) -a $(RootNamespace)" Importance="High" />
<MakeDir Directories="$(CSWinMDOutputPath)" />
<Exec Command="$(CsWinMDPath) -i %(CSWinMDComponent.FullPath) -o $(CsWinMDOutputPath) -a $(RootNamespace)" />
</Target>

<Target Name="CSWinMDInsertComponentWinMD" AfterTargets="GetCppWinRTMdMergeInputs" BeforeTargets="CppWinRTMakeComponentProjection;CppWinRTMergeProjectWinMDInputs">
<ItemGroup>
<CppWinRTMdMergeInputs Include="@(CSWinMDComponent->'$(CsWinMDOutputPath)\%(FileName).winmd')">
<IsWinMDFile>true</IsWinMDFile>
</CppWinRTMdMergeInputs>
</ItemGroup>
</Target>
</Project>
8 changes: 6 additions & 2 deletions src/Authoring/WinRT.SourceGenerator/Generator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,10 @@ public void Generate()
writer.FinalizeGeneration();

GenerateWinMD(metadataBuilder);
GenerateSources();
if (!context.ShouldGenerateWinMDOnly())
{
GenerateSources();
}
}
catch (Exception e)
{
Expand All @@ -188,8 +191,9 @@ public class SourceGenerator : ISourceGenerator
{
public void Execute(GeneratorExecutionContext context)
{
if (!context.IsCsWinRTComponent())
if (!context.IsCsWinRTComponent() && !context.ShouldGenerateWinMDOnly())
{
System.Diagnostics.Debug.WriteLine($"Skipping component {context.GetAssemblyName()}");
return;
}

Expand Down
57 changes: 36 additions & 21 deletions src/Authoring/WinRT.SourceGenerator/Helper.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis;
using System;
using System.Collections.Generic;
using System.IO;
using System.IO;
using System.Linq;

namespace Generator
Expand Down Expand Up @@ -32,23 +32,23 @@ public static Guid EncodeGuid(byte[] data)
}
return new Guid(data.Take(16).ToArray());
}
}

class AttributeDataComparer : IEqualityComparer<AttributeData>
{
public bool Equals(AttributeData x, AttributeData y)
{
return string.CompareOrdinal(x.ToString(), y.ToString()) == 0;
}

public int GetHashCode(AttributeData obj)
{
return obj.ToString().GetHashCode();
}
}

static class GeneratorExecutionContextHelper
{
class AttributeDataComparer : IEqualityComparer<AttributeData>
{
public bool Equals(AttributeData x, AttributeData y)
{
return string.CompareOrdinal(x.ToString(), y.ToString()) == 0;
}

public int GetHashCode(AttributeData obj)
{
return obj.ToString().GetHashCode();
}
}

static class GeneratorExecutionContextHelper
{
public static string GetAssemblyName(this GeneratorExecutionContext context)
{
context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.AssemblyName", out var assemblyName);
Expand Down Expand Up @@ -78,6 +78,16 @@ public static bool IsCsWinRTComponent(this GeneratorExecutionContext context)
return false;
}

public static bool ShouldGenerateWinMDOnly(this GeneratorExecutionContext context)
{
if (context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTGenerateWinMDOnly", out var CsWinRTGenerateWinMDOnlyStr))
{
return bool.TryParse(CsWinRTGenerateWinMDOnlyStr, out var CsWinRTGenerateWinMDOnly) && CsWinRTGenerateWinMDOnly;
}

return false;
}

public static string GetCsWinRTExe(this GeneratorExecutionContext context)
{
context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTExe", out var cswinrtExe);
Expand All @@ -100,11 +110,16 @@ public static string GetCsWinRTDependentMetadata(this GeneratorExecutionContext
{
context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTAuthoringInputs", out var winmds);
return winmds;
}

}

public static string GetWinmdOutputFile(this GeneratorExecutionContext context)
{
return Path.Combine(context.GetGeneratedFilesDir(), context.GetAssemblyName() + ".winmd");
}
var fileName = context.GetAssemblyName();
if (context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTWinMDOutputFile", out var ret))
{
fileName = ret!;
}
return Path.Combine(context.GetGeneratedFilesDir(), fileName + ".winmd");
}
}
}
10 changes: 9 additions & 1 deletion src/Authoring/WinRT.SourceGenerator/WinRTTypeWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1522,6 +1522,11 @@ private void EncodeFixedArguments(IList<object> primitiveArguments, FixedArgumen
{
encoder.SystemType(type);
}
else if (argument is INamedTypeSymbol namedTypeSymbol)
{
var typeEntity = GetTypeReference(namedTypeSymbol);
encoder.Builder.WriteReference(CodedIndex.TypeDefOrRef(typeEntity), false);
}
else
{
encoder.Constant(argument);
Expand Down Expand Up @@ -1713,7 +1718,9 @@ private void AddCustomAttributes(
Logger.Log("# constructor found: " + attributeType.Constructors.Length);
var matchingConstructor = attributeType.Constructors.Where(constructor =>
constructor.Parameters.Length == primitiveValues.Count &&
constructor.Parameters.Select(param => param.Type).SequenceEqual(primitiveTypes));
constructor.Parameters.Select(param => (param.Type is IErrorTypeSymbol) ?
Model.Compilation.GetTypeByMetadataName(param.Type.ToDisplayString()) : param.Type)
.SequenceEqual(primitiveTypes));

Logger.Log("# matching constructor found: " + matchingConstructor.Count());
Logger.Log("matching constructor found: " + matchingConstructor.First());
Expand Down Expand Up @@ -2584,6 +2591,7 @@ public void FinalizeGeneration()
var classTypeDeclarations = typeDefinitionMapping.Values
.Where(declaration => declaration.Node is INamedTypeSymbol symbol && symbol.TypeKind == TypeKind.Class)
.ToList();

foreach (var classTypeDeclaration in classTypeDeclarations)
{
INamedTypeSymbol classSymbol = classTypeDeclaration.Node as INamedTypeSymbol;
Expand Down
35 changes: 35 additions & 0 deletions src/Authoring/cswinmd/CsWinMD.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>net6.0</TargetFrameworks>
<RollForward>Major</RollForward>
<LangVersion>preview</LangVersion>
<Authors>Microsoft Corporation</Authors>
<Company>Microsoft Corporation</Company>
<Product>C#/WinRT</Product>
<PackageId>Microsoft.Windows.CsWinMD</PackageId>

<SatelliteResourceLanguages>en</SatelliteResourceLanguages>
<FileVersion>$(VersionNumber)</FileVersion>
<Version>$(VersionNumber)</Version>
<AssemblyVersion>$(VersionNumber)</AssemblyVersion>
<InformationalVersion>$(VersionNumber)</InformationalVersion>
<NeutralLanguage>en</NeutralLanguage>

<Description>C# to WinMD authoring tool Preview $(VersionString)</Description>
<AssemblyTitle>C# to WinMD authoring tool Preview v$(VersionString)</AssemblyTitle>
<Copyright>Copyright (c) Microsoft Corporation. All rights reserved.</Copyright>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.Common" Version="3.11.0" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.11.0" />
<PackageReference Include="Microsoft.Win32.Registry" Version="5.0.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\WinRT.SourceGenerator\WinRT.SourceGenerator.csproj" />
</ItemGroup>

</Project>
Loading

0 comments on commit bbc6a9d

Please sign in to comment.