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

AOT compile gives incorrect error about Roslyn source generator coming from a ProjectReference #37228

Open
jasonmalinowski opened this issue Nov 29, 2023 · 8 comments
Labels
Area-NativeAOT Native AOT compilation Area-NetSDK untriaged Request triage from a team member

Comments

@jasonmalinowski
Copy link
Member

It appears there's a bug in the SDK's enforcement around project references and AOT compile. If you're doing an AOT compile, all the dependencies are checked for being a valid TFM for AOT, which 100% makes sense. However if a user is consuming a Roslyn source generator from another project (which folks often do), that project is also being checked even though we enforce that Roslyn source generators must be compiled as netstandard2.0. Note the generator in this case is being ran not as a part of deployed app but as a part of the build, so AOT shouldn't be applying in the first place.

I'd say the bug in this case would be that a project reference that's marked as ReferenceOutputAssembly="false" or OutputItemType="Analyzer" shouldn't be getting considered for purposes of AOT. I'm not sure exactly where that condition check should go but I'd expect it to be somewhere.

Discussed in dotnet/roslyn#70900

Originally posted by rudiv November 20, 2023
We have a test project that references our source generator:

<ProjectReference Include="..\..\src\Reaper.SourceGenerator\Reaper.SourceGenerator.csproj" ReferenceOutputAssembly="false" OutputItemType="Analyzer" />

This works fine until we try to compile as AOT, it is trying to compile the source generator too which obviously fails due to the netstandard2.0 target.

1.148 /usr/share/dotnet/sdk/8.0.100/Sdks/Microsoft.NET.Sdk/targets/Microsoft.NET.Sdk.FrameworkReferenceResolution.targets(90,5): error NETSDK1207: Ahead-of-time compilation is not supported for the target framework. [/src/src/Reaper.SourceGenerator/Reaper.SourceGenerator.csproj]
------

The Source Generator is marked as a Roslyn Component and works in other scenarios for AOT (ie. referenced from NuGet).

What is the correct way to test this? Our generator is designed to produce code that makes the project AOT friendly, but we would obviously like the ability to test this.

The workaround we're using now is to compile the source generator first, get the nupkg and create a target that references this local package. However that seems cumbersome.

@dotnet-issue-labeler dotnet-issue-labeler bot added Area-NetSDK untriaged Request triage from a team member labels Nov 29, 2023
@baronfel baronfel added the Area-NativeAOT Native AOT compilation label Nov 29, 2023
@vitek-karas
Copy link
Member

We need to get clarity if this is caused by passing PublishAOT=true on the command line or not.

If it is passed on the command line, then this is very likely the same problem as described in dotnet/runtime#94406.

@hwoodiwiss
Copy link

I've run into the same issue in a project, and it's as you describe above, with the following in my csproj:

  <PropertyGroup Condition="$([MSBuild]::IsTargetFrameworkCompatible($(TargetFramework), 'net8.0'))">
    <IsAotCompatible>true</IsAotCompatible>
    <PublishAot>true</PublishAot>
  </PropertyGroup>

and using the command dotnet publish .\examples\ExampleMinimalApi\ExampleMinimalApi.csproj -r win-x64 -c Release --framework net8.0 with a netstandard2.0 project dependency, the build runs fine and outputs an AoT compiled exe.

With the command dotnet publish .\examples\ExampleMinimalApi\ExampleMinimalApi.csproj /p:PublishAot=true -r win-x64 -c Release --framework net8.0, I get the same error as above:

C:\Program Files\dotnet\sdk\8.0.100\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Sdk.FrameworkReferenceResolution.targe
ts(90,5): error NETSDK1207: Ahead-of-time compilation is not supported for the target framework. [R:\source\repos\Argum
entativeFilters\src\ArgumentativeFilters.Generator\ArgumentativeFilters.Generator.csproj]

C:\Program Files\dotnet\sdk\8.0.100\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Sdk.FrameworkReferenceResolution.targe
ts(90,5): error NETSDK1207: Ahead-of-time compilation is not supported for the target framework. [R:\source\repos\Argum
entativeFilters\src\ArgumentativeFilters\ArgumentativeFilters.csproj]

hwoodiwiss added a commit to hwoodiwiss/ArgumentativeFilters that referenced this issue Dec 23, 2023
@vitek-karas
Copy link
Member

With the command dotnet publish .\examples\ExampleMinimalApi\ExampleMinimalApi.csproj /p:PublishAot=true -r win-x64 -c Release --framework net8.0, I get the same error as above:

Unfortunately, as described above, this is an expected behavior right now. Passing the property on the command line "forces" the property on all projects, including dependent library projects.

@AshleighAdams
Copy link

@vitek-karas What's the recommended way to produce 2 builds, one AOT'd and one not, without resorting to modifying the csproj with shell commands?

@vitek-karas
Copy link
Member

You can introduce conditionals into the project:

<PublishAot Condition="'$(MyPublishWithoutAot)' != 'true'">true</PublishAot>

And then on command line:

This will produce the AOT build

dotnet publish

This will produce a non-AOT build

dotnet publish /p:MyPublishWithoutAot=true

@AshleighAdams
Copy link

Thanks @vitek-karas, tho I found mirroring the value to be more... canonical?

<PublishAot Condition="'$(ProjectPublishAot)' != ''">$(ProjectPublishAot)</PublishAot>

@vitek-karas
Copy link
Member

I intentionally made it to default to PublishAOT - because this property also enables analyzers during build/IDE, and if the app is supposed to be AOT ready then it should use the analyzers by default.

@AshleighAdams
Copy link

Ah, I slapped <IsAotCompatible Condition="'$(IsAotCompatible)'==''">true</IsAotCompatible> in my Directory.Build.props instead for that, so I can enable it for all projects in the solution, then selectively disable the ones that aren't AOT compatible

MIRIMIRIM added a commit to Nekomoekissaten-SUB/Mobsub that referenced this issue Sep 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-NativeAOT Native AOT compilation Area-NetSDK untriaged Request triage from a team member
Projects
None yet
Development

No branches or pull requests

5 participants