Search code examples
c#projectsourcegenerators

Deploying a C# source generator project that includes references to other private projects


I want to release a source generator package, and I want to include a private project dependency on the source generator project.

For example, assume that my projects are A.SourceGenerator and A.CodeAnalysis.Core. I want A.SourceGenerator to depend on A.CodeAnalysis.Core, but use ProjectReference instead of PackageReference.

This means that I want the following line or something similar in my A.SourceGenerator.csproj file:

<None Include="$(OutputPath)\A.CodeAnalysis.Core.dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />

The issue is that this, or some similar variations, won't work and will produce a source generation error, under the CS8785 compiler warning, with the following error message:

Generator BenchmarkSourceGenerator failed to generate source. It will not contribute to the output and compilation errors may occur as a result.

Exception was of type FileNotFoundException with message:

Could not load file or assembly A.CodeAnalysis.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null or one of its dependencies. The system cannot find the file specified.

The above error is shown because the project's contents need to be locally copied on the directory that the source generator lies on. There is a trick for that when using PackageReference, as shown here, but it clearly does not apply for the case of ProjectReference.

I would prefer to avoid creating a brand new NuGet package that the source generator depends on, just to include the dependencies. The other solution is to not abstract that away and only have one source generator project including all source generators.


Solution

  • I don't have much knowledge about project files, but at least i can share some contents of my project file.
    I had to reference other projects like this:

    <ProjectReference Include="..\OtherProject.csproj" OutputItemType="Analyzer" />
    

    I don't remember where i found this, but i hope it helps.

    Update:

    I had someone explain this to me and I hope I'll get it right:

    Basically in order to not interfere with the rest of the Package, OutputItemType="Analyzer" causes C# Analyzers and SGs to be packed under analyzers/dotnet/cs.
    But there it won't be able to locate it's normal dependencies.

    So you add PackagePath="analyzers/dotnet/cs" to pack your package dependencies alongside your Analyzer/SG.
    And to get your project dependencies packed to the right path, you can add OutputItemType="Analyzer" even though they might not be analyzers.