|
2 | 2 | <Project DefaultTargets="All" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="Current"> |
3 | 3 | <PropertyGroup> |
4 | 4 | <!-- Increment the overall semantic version here. --> |
5 | | - <Version>9.2.0</Version> |
| 5 | + <Version>9.3.0</Version> |
6 | 6 | <SolutionName>Autofac</SolutionName> |
7 | 7 | <Configuration Condition="'$(Configuration)'==''">Release</Configuration> |
8 | 8 | <ArtifactDirectory>$([System.IO.Path]::Combine($(MSBuildProjectDirectory),"artifacts"))</ArtifactDirectory> |
|
70 | 70 | <MakeDir Directories="$(LogDirectory)" /> |
71 | 71 | <Exec Command="dotnet test "%(SolutionFile.FullPath)" -c $(Configuration) --results-directory "$(LogDirectory)" --logger:trx /p:Version=$(Version) --collect:"XPlat Code Coverage" --settings "$(CoverageRunSettings)"" /> |
72 | 72 | </Target> |
| 73 | + <!-- |
| 74 | + Native AOT verification. Publishes the AOT smoke-test app with PublishAot=true |
| 75 | + (which runs the ILC trim/AOT analyzer and would fail the build on any IL2104/ |
| 76 | + IL3053 warning, since the project treats warnings as errors) and then executes |
| 77 | + the produced native binary, asserting a zero exit code. This proves both that |
| 78 | + Autofac is statically AOT-clean AND that the AOT-safe resolve path works at |
| 79 | + runtime. The project is intentionally excluded from Autofac.sln so the normal |
| 80 | + Compile/Test targets do not require the native toolchain. |
| 81 | + --> |
| 82 | + <PropertyGroup> |
| 83 | + <AotProjectDirectory>$([System.IO.Path]::Combine($(MSBuildProjectDirectory),'test/Autofac.Test.Aot'))</AotProjectDirectory> |
| 84 | + <AotPublishDirectory>$([System.IO.Path]::Combine($(ArtifactDirectory),'aot'))</AotPublishDirectory> |
| 85 | + <AotExecutableName>Autofac.Test.Aot</AotExecutableName> |
| 86 | + <AotExecutableName Condition="'$(OS)' == 'Windows_NT'">Autofac.Test.Aot.exe</AotExecutableName> |
| 87 | + </PropertyGroup> |
| 88 | + <Target Name="VerifyAot" DependsOnTargets="VerifyAotWarnings"> |
| 89 | + <Message Text="****************************************" Importance="high" /> |
| 90 | + <Message Text="Verifying Native AOT compatibility" Importance="high" /> |
| 91 | + <Message Text="****************************************" Importance="high" /> |
| 92 | + <Exec Command="dotnet publish "$(AotProjectDirectory)" -c $(Configuration) --output "$(AotPublishDirectory)"" /> |
| 93 | + <Exec Command=""$([System.IO.Path]::Combine($(AotPublishDirectory),$(AotExecutableName)))"" /> |
| 94 | + </Target> |
| 95 | + <!-- |
| 96 | + AOT/trim warning verification. Builds the warning fixture (which calls the APIs |
| 97 | + annotated [RequiresDynamicCode] / [RequiresUnreferencedCode]) and asserts the |
| 98 | + expected analyzer diagnostics are emitted. This guards against silently LOSING an |
| 99 | + annotation: if an attribute is dropped, the warning stops firing and this target |
| 100 | + fails. Unlike VerifyAot proper, this needs no native toolchain - a plain build |
| 101 | + surfaces the analyzer diagnostics - so it is cheap to run anywhere. |
| 102 | +
|
| 103 | + The check is PER CALL SITE, not just per diagnostic code: each ExpectedAotWarning |
| 104 | + item names both the code (IL2026/IL3050) and a distinctive substring of the |
| 105 | + annotated member's signature as it appears in the warning text. Multiple call |
| 106 | + sites share a code (e.g. RegisterGeneric and RegisterGenericDecorator are both |
| 107 | + IL3050), so asserting only "IL3050 appears somewhere" would not catch losing the |
| 108 | + annotation on just one of them. Matching the member signature catches each one. |
| 109 | +
|
| 110 | + Keep the ExpectedAotWarning items in sync with the calls in |
| 111 | + test/Autofac.Test.AotWarnings/Program.cs - one item per annotated call. |
| 112 | + --> |
| 113 | + <PropertyGroup> |
| 114 | + <AotWarningsProjectDirectory>$([System.IO.Path]::Combine($(MSBuildProjectDirectory),'test/Autofac.Test.AotWarnings'))</AotWarningsProjectDirectory> |
| 115 | + </PropertyGroup> |
| 116 | + <ItemGroup> |
| 117 | + <!-- Identity = the IL code; Member = a substring uniquely identifying the API in the warning text. --> |
| 118 | + <ExpectedAotWarning Include="IL3050" Member="RegisterGeneric(ContainerBuilder, Type)" /> |
| 119 | + <ExpectedAotWarning Include="IL3050" Member="RegisterGenericDecorator(ContainerBuilder, Type, Type" /> |
| 120 | + <ExpectedAotWarning Include="IL2026" Member="RegisterAssemblyTypes(ContainerBuilder, params Assembly" /> |
| 121 | + <ExpectedAotWarning Include="IL2026" Member="RegisterAssemblyModules(ContainerBuilder, params Assembly" /> |
| 122 | + </ItemGroup> |
| 123 | + <Target Name="VerifyAotWarnings"> |
| 124 | + <Message Text="****************************************" Importance="high" /> |
| 125 | + <Message Text="Verifying AOT/trim warnings still fire" Importance="high" /> |
| 126 | + <Message Text="****************************************" Importance="high" /> |
| 127 | + <MakeDir Directories="$(LogDirectory)" /> |
| 128 | + <PropertyGroup> |
| 129 | + <AotWarningsLog>$([System.IO.Path]::Combine($(LogDirectory),'aot-warnings-build.log'))</AotWarningsLog> |
| 130 | + </PropertyGroup> |
| 131 | + <!-- |
| 132 | + Build the fixture (full recompile so analyzer diagnostics are always emitted) |
| 133 | + and redirect ALL output to a log file. This is deliberate: the fixture emits the |
| 134 | + IL2026/IL3050 warnings on purpose, and if they reached the CI job's stdout the |
| 135 | + .NET problem matcher would turn each one into a (misleading) PR annotation. By |
| 136 | + sending the build output only to a file and reading it back here, the warnings |
| 137 | + are verified without ever surfacing on the console. The log is written under the |
| 138 | + artifacts directory and inspected below. |
| 139 | + --> |
| 140 | + <Exec Command="dotnet build "$(AotWarningsProjectDirectory)" -c $(Configuration) --no-incremental > "$(AotWarningsLog)" 2>&1" |
| 141 | + IgnoreExitCode="true" /> |
| 142 | + <ReadLinesFromFile File="$(AotWarningsLog)"> |
| 143 | + <Output TaskParameter="Lines" ItemName="AotWarningsBuildOutput" /> |
| 144 | + </ReadLinesFromFile> |
| 145 | + <PropertyGroup> |
| 146 | + <AotWarningsBuildText>@(AotWarningsBuildOutput, '%0a')</AotWarningsBuildText> |
| 147 | + </PropertyGroup> |
| 148 | + <!-- Each expected warning must appear with BOTH its code and the specific member signature. --> |
| 149 | + <Error Condition="!($(AotWarningsBuildText.Contains('warning %(ExpectedAotWarning.Identity)')) and $(AotWarningsBuildText.Contains('%(ExpectedAotWarning.Member)')))" |
| 150 | + Text="Expected AOT/trim diagnostic %(ExpectedAotWarning.Identity) for '%(ExpectedAotWarning.Member)' was NOT emitted by Autofac.Test.AotWarnings. A [RequiresDynamicCode]/[RequiresUnreferencedCode] annotation may have been lost in core Autofac." /> |
| 151 | + <Message Text="All expected AOT/trim warnings were emitted (@(ExpectedAotWarning->'%(Identity): %(Member)', '; '))." Importance="high" /> |
| 152 | + </Target> |
73 | 153 | </Project> |
0 commit comments