dotnet/ClangSharp

ClangSharpPInvokeGenerator as a dotnet global tool?

mjsabby opened this issue · 12 comments

Given the improvements in correctness and usability, maybe time to consider making this a dotnet global tool?

I think that this is a good goal and it is probably usable, as is, for a good number of scenarios.

However, it's worth noting there is still quite a bit of work needed overall as the current logic can't successfully parse all of the headers in the Windows SDK (which is what I'm currently trying to get working).

The things that aren't handled well today are:

  • Nested declarations
  • Functions with method bodies
  • C++ style declarations
  • Global variables
  • Areas libclang doesn't directly expose (these generally involve getting and checking tokens directly, like finding out the type of an operator).

The first entry is really the big blocker for most scenarios, since having nested structs (generally a struct with a nested anonymous union) is fairly common.

Adding some tests, in the form of some in memory header files that are parsed and checked against an output, would also be useful (and is on my list of things to add).

The code now handles nested declarations and with #55, it will support excluding any named declaration and remapping any name, which gives it quite a bit more flexibility for generating bindings how you want.

It should also be able to more readily process arbitrary header files now without falling over on itself and with the testing framework in place, we can validate that things are emitting code correctly and more readily respond to bugs now.

Any long term plans extend this to C++?

The latest code should handle some basic C++ scenarios and create valid bindings for both virtual and non-virtual instance methods.

It does not correctly handle virtual methods when multiple-inheritance exists (and therefore more than one vtbl can exist).

I hope to have the global tool package published within the next few days. I'm mostly just going over some remaining Win32 header files to ensure it is handling the various scenarios correctly first.

FWIW, there's a version of ClangSharpPInvokeGenerator available on NuGet, but it fails to install because it has references to other NuGet packages:

error NU1212: Invalid project-package combination for ClangSharpPInvokeGenerator 8.0.0-beta. DotnetToolReference project style can only contain references of the DotnetTool type
The tool package could not be restored.
Tool 'clangsharppinvokegenerator' failed to install. This failure may have been caused by:

* You are attempting to install a preview release and did not use the --version option to specify the version.
* A package by this name was found, but it was not a .NET Core tool.
* The required NuGet feed cannot be accessed, perhaps because of an Internet connection problem.
* You mistyped the name of the tool.

For more reasons, including package naming enforcement, visit https://aka.ms/failure-installing-tool

You'll likely need to mark those references as PrivateAssets=all, and include the required assemblies in the lib\ folder of the global tool NuGet package.

The error message is due to it not being marked as a .NET Core tool. This was resolved back in #101 and validated locally that installing and using the tool works.

include the required assemblies in the lib\ folder of the global tool NuGet package.

This is the problematic part of shipping ClangSharpPInvokeGenerator as a global tool.

Currently, there is no way to ship RID specific versions of a global tool and packaging the native assets for all 10 supported runtime ids is going to be a non starter.

The next "best" alternative is to require users to manually copy the dependency over one time with instructions on first run that they should ensure libClang and libClangSharp are somewhere on the path and how to get them from NuGet.

Cool, thanks!

I guess you could consider packaging libClang and libClangSharp for, say, win-x64 and osx-x64 as they have a fairly stable ABI, but that would be a fairly arbitrary subset of packages.

Unfortunately it isn't due to ABI stability, its just due to the sheer size of the libclang binaries even when compressed.

If we just include support for win-x64, osx-x64, and ubuntu.18.04-x64 we are looking at a 70MB NuGet package.

If we look at adding win-x86 and ubuntu-14.04, 16.04, and 19.04 we grow to 170MB.
If we add in sles-x64 and freebsd.11-x64, x86 we grow to 250MB.
Adding in the remaining support for linux-arm and linux-arm64 brings it up to 300MB.

A beta package has been uploaded and can be installed via dotnet tool install ClangSharpPInvokeGenerator --global --version 9.0.0-beta.
As specified above, users will currently need to copy over the correct libClang and libClangSharp binaries to the tool folder for things to work as expected.

Can you specify what exactly needs to be copied where? For the global install PInvokeGenerator this is my current tools dir. I can call ClangSharpPInvokeGenerator but it fails and says it's missing libclang. Clang is currently symlinked in to the xcode install (and is also on the PATH).
Screen Shot 2022-07-04 at 7 41 26 PM