Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for AOT #714

Open
Basyras opened this issue Dec 8, 2024 · 5 comments
Open

Support for AOT #714

Basyras opened this issue Dec 8, 2024 · 5 comments

Comments

@Basyras
Copy link

Basyras commented Dec 8, 2024

Describe the bug
Using ReportGenerator.Core "top level classes" inside AOT app does not works

To Reproduce
Create new console app and compile with (or use dotnet build/publish cli options)

<IsAotCompatible>true</IsAotCompatible>
<PublishAot>true</PublishAot>

Call in main:
var exitCode = Palmmedia.ReportGenerator.Core.Program.Main(generatorArgs);

The app will crash since they are calls like Assembly.GetExecutingAsembly() etc.
Those call can be very often replaced with System.AppContext.BaseDirectory to achieve same behaivor.
They are few similar places that do some not AOT friendly stuff but can be easily avoided if methods/ctor would have extra parameter and user could decide if to use default => use what we have now, or provide => skip aot unfriendly stuff.

What i ended up with (in order to skip the AOT unfriendly bits):

    public enum ReportType
    {
        Cobertura,
        Html,
    }

            RiskHotspotAnalysisResult riskHotspotAnalysisResult = new RiskHotspotAnalysisResult([], false);
            CustomReportContext reportContext = new CustomReportContext(reportConfiguration, settings, riskHotspotAnalysisResult);
            var parserResult = new CoverageReportParser(
                    reportContext)
             .ParseFiles(reportConfiguration.ReportFiles);

            SummaryResult summaryResult = new SummaryResult(parserResult);
            if (reportTypes.Contains(ReportType.Html))
            {
                var builder = new HtmlInlineCssAndJavaScriptReportBuilder();
                builder.ReportContext = reportContext;
                builder.CreateSummaryReport(summaryResult);
            }

            if(reportTypes.Contains(ReportType.Cobertura))
            {
                var builder = new CoberturaReportBuilder();
                builder.ReportContext = reportContext;
                builder.CreateSummaryReport(summaryResult);
            }
@danielpalme
Copy link
Owner

Thanks for your code sample!
Will add support for your scenario in the next release (next 1-3 weeks).

danielpalme added a commit that referenced this issue Dec 21, 2024
@danielpalme
Copy link
Owner

I made some litte improvements in release 5.4.2.
After those changes var exitCode = Palmmedia.ReportGenerator.Core.Program.Main(generatorArgs); works fine in my scenario.

Could you please try again? Does it work for you?

@Basyras
Copy link
Author

Basyras commented Jan 12, 2025

Hey, sorry for waiting. Seems there is still something remaining.
Tested with <PackageReference Include="ReportGenerator.Core" Version="5.4.2" />

In my Directory.Build.props (i guess you can just put in csproj file) I have these rules that enforces all analyzers warnings to be solved in order to build.

    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
    <PreferredUILang>en</PreferredUILang>
    <EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
    <EnableNETAnalyzers>true</EnableNETAnalyzers>
    <AnalysisMode>All</AnalysisMode>
    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>
Command: Executing: C:\Program Files\dotnet\dotnet.exe publish "C:/Users/Honza/source/repos/BasyrasAzure/EasyPipelines/src/EasyPipelines.Pipelines/EasyPipelines.Pipelines.csproj" --configuration Release --nologo --verbosity quiet --output C:/Users/Honza/source/repos/BasyrasAzure/EasyPipelines/src/EasyPipelines.Pipelines/bin/Debug/net9.0/Temp/Providers/AzurePipelineProvider/provide-build --runtime win-x64 --property:PublishReadyToRun=true;PublishSingleFile=true;PublishTrimmed=true;PublishAot=true;DebugType=None;DebugSymbols=False;Deterministic=true;ContinuousIntegrationBuild=true

StdOutput:
/_/src/ReportGenerator.Core/Generator.cs(360): error IL3000: Palmmedia.ReportGenerator.Core.Generator.GetConfiguration(): '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'. [C:\Users\Honza\source\repos\BasyrasAzure\EasyPipelines\src\EasyPipelines.Pipelines\EasyPipelines.Pipelines.csproj]
/_/src/ReportGenerator.Core/Generator.cs(370): error IL3000: Palmmedia.ReportGenerator.Core.Generator.GetConfiguration(): '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'. [C:\Users\Honza\source\repos\BasyrasAzure\EasyPipelines\src\EasyPipelines.Pipelines\EasyPipelines.Pipelines.csproj]
/_/src/ReportGenerator.Core/Generator.cs(139): error IL3000: Palmmedia.ReportGenerator.Core.Generator.GenerateReport(IReportConfiguration,Settings,MinimumCoverageThresholds,RiskHotspotsAnalysisThresholds): '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'. [C:\Users\Honza\source\repos\BasyrasAzure\EasyPipelines\src\EasyPipelines.Pipelines\EasyPipelines.Pipelines.csproj]
/_/src/ReportGenerator.Core/Plugin/ReflectionPluginLoader.cs(130): error IL3000: Palmmedia.ReportGenerator.Core.Plugin.ReflectionPluginLoader.CreateAssemblyLoader(): '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'. [C:\Users\Honza\source\repos\BasyrasAzure\EasyPipelines\src\EasyPipelines.Pipelines\EasyPipelines.Pipelines.csproj]
C:\Users\Honza\.nuget\packages\reportgenerator.core\5.4.2\lib\net9.0\ReportGenerator.Core.dll : error IL2104: Assembly 'ReportGenerator.Core' produced trim warnings. For more information see https://aka.ms/il2104 [C:\Users\Honza\source\repos\BasyrasAzure\EasyPipelines\src\EasyPipelines.Pipelines\EasyPipelines.Pipelines.csproj]
C:\Users\Honza\.nuget\packages\microsoft.dotnet.ilcompiler\9.0.0\build\Microsoft.NETCore.Native.targets(317,5): error MSB3073: The command ""C:\Users\Honza\.nuget\packages\runtime.win-x64.microsoft.dotnet.ilcompiler\9.0.0\tools\\ilc" @"obj\Release\net9.0\win-x64\native\EasyPipelines.Pipelines.ilc.rsp"" exited with code -1. [C:\Users\Honza\source\repos\BasyrasAzure\EasyPipelines\src\EasyPipelines.Pipelines\EasyPipelines.Pipelines.csproj]

I think just replacing Assembly.Location everywhere with System.AppContext.BaseDirectory might just work?

@danielpalme
Copy link
Owner

Will have another look as soon as possible.

1 similar comment
@danielpalme
Copy link
Owner

Will have another look as soon as possible.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants