I've created a source generator which barring some issues mostly seems to work.
I tested it during development using a test project with a project reference to the generator.
I've now packaged it up into a nuget package and am trying to use it in a different project with that but I'm getting this not very helpful warning:
CSC : warning CS8032: An instance of analyzer SuperFluid.Internal.SourceGenerators.FluidApiSourceGenerator cannot be created from /home/james/.nuget/packages/superfluid/0.0.1/analyzers/dotnet/cs/SuperFluid.dll : Exception has been thrown by the target of an invocation.. [/home/james/repos/SuperFluid/src/DemoProject/DemoProject.csproj]
The (abridged) csproj for my source generator is:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<LangVersion>default</LangVersion>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<IncludeBuildOutput>false</IncludeBuildOutput>
<EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>
</PropertyGroup>
<ItemGroup>
<None Include="../../README.md" Pack="true" PackagePath="\" />
</ItemGroup>
<ItemGroup>
<InternalsVisibleTo Include="SuperFluid.Tests" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.4.0" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" PrivateAssets="all" />
<PackageReference Include="YamlDotNet" Version="13.1.0" PrivateAssets="all" GeneratePathProperty="true" />
</ItemGroup>
<!-- Gross hack to let source generator use nuget packages -->
<PropertyGroup>
<GetTargetPathDependsOn>$(GetTargetPathDependsOn);GetDependencyTargetPaths</GetTargetPathDependsOn>
</PropertyGroup>
<Target Name="GetDependencyTargetPaths" AfterTargets="ResolvePackageDependenciesForBuild">
<ItemGroup>
<TargetPathWithTargetPlatformMoniker Include="@(ResolvedCompileFileDefinitions)" IncludeRuntimeDependency="false" />
<None Include="@(ResolvedCompileFileDefinitions)" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />
</ItemGroup>
</Target>
<!-- End Hack -->
<ItemGroup>
<None Include="$(OutputPath)\$(AssemblyName).dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />
</ItemGroup>
</Project>
And my test project is:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<AdditionalFiles Include="DemoApiDefinition.fluid.yml" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="SuperFluid" Version="0.0.1" />
</ItemGroup>
</Project>
Does anyone know what might be causing this? If not, how can I get the details of this inner exception?
Edit: I've retargetted my Source Generator to use netstandard2.0 and that doesn't seem to have helped:
I've also noticed this warning that may or may not be relevant when I pack:
/usr/share/dotnet/sdk/7.0.105/Sdks/NuGet.Build.Tasks.Pack/build/NuGet.Build.Tasks.Pack.targets(221,5): warning NU5128: - Add lib or ref assemblies for the netstandard2.0 target framework
I have finally managed to get this working, although I'm not entirely sure why this works, so I'd defer to the other answer for that.
First, include the package as a private asset and set GeneratePathProperty="true"
:
<ItemGroup>
<PackageReference Include="YamlDotNet" Version="16.3.0" GeneratePathProperty="true" PrivateAssets="all" />
</ItemGroup>
Then add this magic snippet:
<PropertyGroup>
<GetTargetPathDependsOn>$(GetTargetPathDependsOn);GetDependencyTargetPaths</GetTargetPathDependsOn>
</PropertyGroup>
Then manually include your analyzer and your dependencies:
<Target Name="GetDependencyTargetPaths">
<ItemGroup>
<TargetPathWithTargetPlatformMoniker Include="$(PKGYamlDotNet)\lib\netstandard2.0\YamlDotNet.dll" IncludeRuntimeDependency="false" />
</ItemGroup>
</Target>
<ItemGroup>
<None Include="$(OutputPath)\$(AssemblyName).dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />
<None Include="$(PKGYamlDotNet)\lib\netstandard2.0\YamlDotNet.dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />
</ItemGroup>
I am not entirely sure why this works, but it does.