HamedFathi
HamedFathi

Reputation: 3979

How to pack a C# 9 source generator and upload it to the Nuget?

I made a C# 9 source code generator, you can find it here

When I use the whole project inside another solution and reference it as a project it works but when I upload it with current configs into the Nuget (here) it does not work.

How to config a C# 9 source generator correctly to work as a Nuget package? What is wrong with my project?

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
    <Version>0.0.2</Version>
    <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
    <PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
    <PackageLicenseExpression>MIT</PackageLicenseExpression>
    <PackageTags>dotnet</PackageTags>
    <PublishRepositoryUrl>true</PublishRepositoryUrl>
    <GenerateRepositoryUrlAttribute>true</GenerateRepositoryUrlAttribute>
    <PackBuildOutput>true</PackBuildOutput>
    <PackageId>MockableStaticGenerator</PackageId>
    <PackOnBuild>true</PackOnBuild>
    <PackFolder>analyzers\cs</PackFolder>
    <DebugType>embedded</DebugType>
    <DebugSymbols>true</DebugSymbols>
  </PropertyGroup>
  <PropertyGroup>
    <RestoreAdditionalProjectSources>https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet5/nuget/v3/index.json ;$(RestoreAdditionalProjectSources)</RestoreAdditionalProjectSources>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="3.8.0" PrivateAssets="all" />
    <PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.1">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>
  </ItemGroup>
</Project>

Upvotes: 14

Views: 6564

Answers (3)

CountZero
CountZero

Reputation: 6389

If you are using nuspec files to create your package then you'll need to update the file to use something like the following.

<files>
    <file src="bin\Release\netstandard2.0\publish\Camc.Common.SourceGenerators.RecordSourceGenerator.dll" target="analyzers\dotnet\cs" />
    <file src="bin\Release\netstandard2.0\publish\Camc.Common.SourceGenerators.RecordSourceGenerator.pdb" target="analyzers\dotnet\cs" />
    <file src="$nuget_icon_Path$\nuget_icon.png" target="\" />
</files>

Where the target is set to "analyzers\dotnet\cs".

Upvotes: 0

Drew Noakes
Drew Noakes

Reputation: 311245

Yair's answer covers this well. I wanted to add a debugging tip that is hopefully helpful.

If you're using an SDK-style project to specify your package, then after packing it you can find the generated .nuspec file in the obj folder. Reviewing the contents of that file can be very helpful when understanding what the consumer of your package will actually have available to them.

Upvotes: 3

Yair Halberstadt
Yair Halberstadt

Reputation: 6841

If you unzip the nuget package, you'll see that the package is stored in the lib directory. It has to be stored in the analyzers directory.

One way to do that is to add the following to your csproj:

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

If you're multitargeting it should be:

<ItemGroup>
  <None Include="$(OutputPath)\netstandard2.0\$(AssemblyName).dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />
</ItemGroup>

This will include your project as both a library and an analyzer.

To use it just as an analyzer, add the following:

<PropertyGroup>
  <IncludeBuildOutput>false</IncludeBuildOutput>
</PropertyGroup>

Upvotes: 30

Related Questions