commandlineparser / commandline

The best C# command line parser that brings standardized *nix getopt style, for .NET. Includes F# support
MIT License
4.52k stars 477 forks source link

.NET 7 (RC1) trimming results in error #848

Open KoalaBear84 opened 1 year ago

KoalaBear84 commented 1 year ago

I've just upgraded my project to .NET 7 and seen that it results in an error (when running):

Error setting value to option 'u, url': Check if Option or Value attribute values are set properly for the given type.
Error setting value to option 't, threads': Check if Option or Value attribute values are set properly for the given type.
etc..

https://github.com/KoalaBear84/OpenDirectoryDownloader/

If I build it with the following it fails (when running):

dotnet publish OpenDirectoryDownloader --configuration Release --framework net7.0 --runtime win-x64 -p:PublishTrimmed=true

If I remove the -p:PublishTrimmed=true it works. This tells me it could be because of the trimming that will trim something that is important for this library.

Also tried with -p:TrimMode=Link and -p:TrimMode=CopyUsed, but it doesn't make a difference, but found out that -p:TrimMode=partial (Only worked with a lowercase p here) does, as it restores the behaviour of .NET 6.

https://learn.microsoft.com/en-us/dotnet/core/deploying/trimming/trimming-options?pivots=dotnet-7-0#trimming-granularity

Maybe this can be resolved at the library side, but I don't have experience with that. https://learn.microsoft.com/en-us/dotnet/core/deploying/trimming/prepare-libraries-for-trimming

It would be nice if it can be solved, as more users will try/upgrade to .NET 7. Until then this issue will be helpful for everyone looking for a quick workaround.

dusrdev commented 1 year ago

Especially important if you want to use PublishAot to produce native code. Because -p:PublishAot=true implies PublishTrimmed and produces the same error.

But while @KoalaBear84 was able to solve the issue by configuring -p:TrimMode=partial, it will not work with PublishAot.

mdemler commented 1 year ago

I see a different error with trimming fully enabled when building with .NET 7:

Type appears to be immutable, but no constructor found to accept values.

The type is clearly not immutable and worked just fine when building with .NET 6 and trimming enabled. I too was able to work around the issue by setting TrimMode to partial. Even with that, CommandLineParser produces some trim warnings.

edokan commented 1 year ago

I see a different error with trimming fully enabled when building with .NET 7:

Type appears to be immutable, but no constructor found to accept values.

The type is clearly not immutable and worked just fine when building with .NET 6 and trimming enabled. I too was able to work around the issue by setting TrimMode to partial. Even with that, CommandLineParser produces some trim warnings.

I tried to add and empty constructor, and one with the single argument, it still throws same exception. I also tried to mark the class with DynamicallyAccessedMembers attribute with no success.

I'm using .net SDK 7.0.102

dusrdev commented 1 year ago

I see a different error with trimming fully enabled when building with .NET 7:

Type appears to be immutable, but no constructor found to accept values.

The type is clearly not immutable and worked just fine when building with .NET 6 and trimming enabled. I too was able to work around the issue by setting TrimMode to partial. Even with that, CommandLineParser produces some trim warnings.

I tried to add and empty constructor, and one with the single argument, it still throws same exception. I also tried to mark the class with DynamicallyAccessedMembers attribute with no success.

I'm using .net SDK 7.0.102

This is because CommandLineParser uses reflection and it gets trimmed.

ericnewton76 commented 1 year ago

Can somebody work up a DotNetFiddle for this? fork from https://dotnetfiddle.net/mh9CjX

dermoench42 commented 1 year ago

Tell the code-analyser to create all members of the options by an attribute (CliOptions is my options class):

[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(CliOptions))] public static int Main( string[] args){ ....

would fix that. Could that be set up somewhere inside commandLineParser?

quinterojose commented 9 months ago

This is also occurring on .NET 8 and PublishTrimmed=true

kyurkchyan commented 7 months ago

Is there a fix for this issue?

micahlt commented 2 months ago

Can confirm that this issue happens up to .NET 8.0.301 as well.

MaxHayman commented 2 months ago

I am also having this issue