CsWinRT icon indicating copy to clipboard operation
CsWinRT copied to clipboard

Port cswinmd tooling

Open asklar opened this issue 2 years ago • 2 comments

This is the first PR to bring cswinmd over into this repo.

Description

CSWinMD is a tool to generate WinMD files from C#/WinRT .cs files (technically not valid C#, but C#-ish). This can be used as a replacement to MIDL for producing WinMD files; instead of writing .idl, you'd write this C# syntax in your C++ project, reference the cswinmd nuget, and it would run cswinmd to generate the winmd from your C# files, and then pass the winmd to cppwinrt for it to generate component headers/sources.

Usage

  <Import Project="..\packages\CsWinMD.0.0.2-prerelease\build\cswinmd.targets" 
          Condition="Exists('..\packages\CsWinMD.0.0.2-prerelease\build\cswinmd.targets')" />
  <!-- ... -->
  <ItemGroup>
    <CSWinMDComponent Include="CSWinMDComponent.cs" />
  </ItemGroup>

Current state and future work

This is not yet a complete implementation (it suffers from the same expressivity limitations that C#/WinRT currently has, like no support for unsealed classes, etc.) however it starts laying the groundwork for a more complete solution. Included in this:

  • CsWinMD generator
  • targets file which will used in a new CsWinMD NuGet package
  • Test component project that exercises the flow.

For more context (internal to msft only) see my talk https://aka.ms/cswinmd/talk_2021

asklar avatar May 11 '22 06:05 asklar

This sounds like a great idea! IDL for authoring components is not the greatest development experience (both in terms of IDE and tooling support), so hopefully this can make it easier for C++/WinRT devs.

One thing that's probably worth exploring for a future revision is mixing with IDL, since some concepts aren't representable in C#, and to allow progressive migration to cswinmd.

Apparently, currently everything runs before cppwinrt, so it should allow IDL to use types from cswinmd, but not cswinmd to use types from IDL. If we run cswinmd after, then the reverse applies (cswinmd can consume types from IDL, but IDL can't consume types from cswinmd). So maybe an option to determine when in the build order a C# file gets compiled would be nice. Even better would be going for a two-pass build , so that both worlds can consume from each other. But that's much harder to implement, most likely.

sylveon avatar May 11 '22 07:05 sylveon

For others: I was confused to see a C++ focused PR writeup for C# projections, so I asked Alexander for additional details to double-check my understanding.

The gist is that developers prefer idiomatic experiences, especially when it comes to component authoring and metadata generation. That is, rather than write awkward IDL and pass it to MIDL(RT), you can write classes in C#, Rust, etc. and a ECMA-335 compliant blob pops out the other end.

It is his belief that the C# authoring experience trumps the C++ IDL experience and provides a sample above. Shameless plug: Developers interested in a Rust idiomatic experience can also follow similar development here.

riverar avatar May 12 '22 21:05 riverar