spectreconsole / spectre.console

A .NET library that makes it easier to create beautiful console applications.
https://spectreconsole.net
MIT License
9.17k stars 472 forks source link

AOT Support #1332

Open lukewis opened 11 months ago

lukewis commented 11 months ago

Is your feature request related to a problem? Please describe. This library actually works in the context of native code generation (AOT), but it produces a compiler warning (which makes me suspect there are some features in this library that would not work from an AOT perspective.

Describe the solution you'd like Would love to see this library run cleanly in an AOT build (AOT seems like a primary candidate for a library like this to create multi-platform commandline tools that do not rely on the dotnet framework being installed.

Describe alternatives you've considered None

Additional context

.nuget\packages\spectre.console\0.47.0\lib\net7.0\Spectre.Console.dll : warning IL2104: Assembly
'Spectre.Console' produced trim warnings. For more information see https://aka.ms/dotnet-illink/libraries [C:\src\alpsdev\alpsc
li.csproj]

Please upvote :+1: this issue if you are interested in it.

borrrden commented 9 months ago

FYI I used the following to get this project to work with AOT:

Create some file (e.g. MyRoots.xml) with the following content (substitute MyAssembly with your assembly name):

<linker>
    <assembly fullname="MyAssembly" />
    <assembly fullname="Spectre.Console.Cli">
        <type fullname="Spectre.Console.Cli.ExplainCommand" />
        <type fullname="Spectre.Console.Cli.XmlDocCommand" />
        <type fullname="Spectre.Console.Cli.VersionCommand" />
    </assembly>
</linker>

This makes sure that all the reflected commands needed don't get trimmed out. Then make use of it in your csproj:

<ItemGroup>
  <TrimmerRootDescriptor Include="MyRoots.xml" />
</ItemGroup>
lukewis commented 9 months ago

Hmm.... things seemed to be working for me. I was just interested in cleaning up the warnings, but your answer now makes me wonder if some things are broken that i didn't catch. I'll have to take another look

borrrden commented 9 months ago

The project I am working on is here on GitHub so if you are interested in seeing if you see what I see then I can push what I discovered up into the repo (https://github.com/borrrden/Spectre.Net). Coincidentally the project started as a port of a separate unrelated project also called Spectre and then I remembered that this repo existed and thought it was poetic.

borrrden commented 9 months ago

There are still a few more issues I am having with AOT:

andwi commented 9 months ago

An alternative to the xml file mentioned by @borrrden that worked for me is to use the DynamicDependency attribute in your code. For example I have a command called DiffCommand and my entrypoint looks like this

[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(DiffCommand))]
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(DiffCommandSettings))]
[DynamicDependency(DynamicallyAccessedMemberTypes.All, "Spectre.Console.Cli.ExplainCommand", "Spectre.Console.Cli")]
[DynamicDependency(DynamicallyAccessedMemberTypes.All, "Spectre.Console.Cli.VersionCommand", "Spectre.Console.Cli")]
[DynamicDependency(DynamicallyAccessedMemberTypes.All, "Spectre.Console.Cli.XmlDocCommand", "Spectre.Console.Cli")]
private static int Main(string[] args)
{
}
borrrden commented 9 months ago

@andwi Would you happen to know anything about my enum situation? 😄

andwi commented 9 months ago

@andwi Would you happen to know anything about my enum situation? 😄

Sorry no, my application has not used any enum values so I have not encountered that

Mischala commented 6 months ago

I use CommandApp and AppSettings in my application. I can publish with:

<OutputType>Exe</OutputType>
<PublishAot>true</PublishAot>

and it seems to work just fine, however, I get the following warnings. Would be nice to mark any Dynamic access in the library.

ILC : Trim analysis warning IL2092: Libbyget.Infrastructure.TypeRegistrar.Register(Type,Type): 'DynamicallyAccessedMemb
erTypes' in 'DynamicallyAccessedMembersAttribute' on the parameter 'implementation' of method 'Libbyget.Infrastructure.
TypeRegistrar.Register(Type,Type)' don't match overridden parameter 'implementation' of method 'Spectre.Console.Cli.ITy
peRegistrar.Register(Type,Type)'. All overridden members must have the same 'DynamicallyAccessedMembersAttribute' usage
. [redacted
C:\Users\\.nuget\packages\spectre.console.cli\0.48.0\lib\net8.0\Spectre.Console.Cli.dll : warning IL2104: Assembly
 'Spectre.Console.Cli' produced trim warnings. For more information see https://aka.ms/dotnet-illink/libraries [C:\User
s\\Dev\LibbyGet\Libbyget\LibbyGet.csproj]
C:\Users\.nuget\packages\spectre.console.cli\0.48.0\lib\net8.0\Spectre.Console.Cli.dll : warning IL3053: Assembly
 'Spectre.Console.Cli' produced AOT analysis warnings. [redacted
/_/src/Spectre.Console.Cli/Internal/Modelling/CommandModel.cs(48): warning IL3000: Spectre.Console.Cli.CommandModel.Get
ApplicationFile(): 'System.Reflection.Assembly.Location.get' always returns an empty string for assemblies embedded in
a single-file app. If the path to the app directory is needed, consider calling 'System.AppContext.BaseDirectory'. [redacted]
C:\Users\\.nuget\packages\spectre.console\0.48.0\lib\net8.0\Spectre.Console.dll : warning IL2104: Assembly 'Spectr
e.Console' produced trim warnings. For more information see https://aka.ms/dotnet-illink/libraries [redacted]