devlooped / nugetizer

A simple to understand packing model for authoring NuGet packages
https://clarius.org/nugetizer/
MIT License
256 stars 7 forks source link

Can't get a project to pack correctly (multi-project, with analyzer) #54

Closed Sergio0694 closed 3 years ago

Sergio0694 commented 3 years ago

Overview

Hello, I discovered this project yesterday and it looks super promising, so great work on this! πŸ˜„ I've been trying to use this in my own project, ComputeSharp, but so far I have not been able to figure out how to configure this correctly, and I'm wondering what I'm doing wrong. I looked at the docs and I couldn't find a solution there either.

I'm trying to build/pack this .csproj file in particular. The structure of my project is like this:

NuGet package structure (click to expand):
![image](https://user-images.githubusercontent.com/10199417/101916592-73aa3f80-3bc7-11eb-8b40-802c6862e551.png)

So essentially:

To do this, I did the following in the .csproj file:

  <ItemGroup>
    <ProjectReference Include="..\ComputeSharp.Core\ComputeSharp.Core.csproj" />
    <ProjectReference Include="..\ComputeSharp.Graphics\ComputeSharp.Graphics.csproj" />
    <ProjectReference Include="..\ComputeSharp.Shaders\ComputeSharp.Shaders.csproj" />
    <ProjectReference Include="..\ComputeSharp.SourceGenerators\ComputeSharp.SourceGenerators.csproj" PrivateAssets="All" PackagePath="analyzers\dotnet\cs" />
  </ItemGroup>

I have a few issues though:

Nugetize result (click to expand):
``` Project is not packable, rendering its contributed package contents. Dependencies: net5.0 Microsoft.Toolkit, 7.0.0-preview4 TerraFX.Interop.Windows, 10.0.19041-beta2-379749354 netstandard2.0 Microsoft.Toolkit, 7.0.0-preview4 Contents: /icon.png /runtimes/ win-x64/ native/ dxcompiler.dll dxil.dll /analyzers/ dotnet/ cs /lib/ net5.0/ ComputeSharp.Core.dll ComputeSharp.Core.pdb ComputeSharp.dll ComputeSharp.Graphics.dll ComputeSharp.Graphics.pdb ComputeSharp.pdb ComputeSharp.Shaders.dll ComputeSharp.Shaders.pdb netstandard2.0/ ComputeSharp.Core.dll ComputeSharp.Core.pdb ComputeSharp.SourceGenerators.dll ComputeSharp.SourceGenerators.pdb Microsoft.CodeAnalysis.CSharp.dll Microsoft.CodeAnalysis.dll System.Buffers.dll System.Collections.Immutable.dll System.Memory.dll System.Numerics.Vectors.dll System.Reflection.Metadata.dll System.Runtime.CompilerServices.Unsafe.dll System.Text.Encoding.CodePages.dll System.Threading.Tasks.Extensions.dll ```

EDIT: just noticed that adding the ProjectReference to the .csproj like that also causes the SG to break when used in the sample projects. Not sure if this is expected or if it's just a thing that happens when used locally and not through NuGet. Would love to have a way to make this work in both cases though, and I'm also not sure that ProjectReference for the SG in the main project is correct at all, since the SG is not actually a dependency of that project πŸ€”

I couldn't find any info on the docs/readme specifically regarding these "mixed" scenarios, with a single package containing both binaries to be used by consumers, as well as a SG that should also be added as an analyzer by consuming projects.

Steps to Reproduce

Expected Behavior

The package would be created with the referenced projects in the correct location. Of course, I'm very probably just missing something obvious here, but I can't figure out what πŸ˜…

Version Info

kzu commented 3 years ago

Here's a similar package that can serve as inspiration: https://github.com/moq/moq/blob/main/src/Moq.Package/Moq.Package.msbuildproj. I strongly recommend creating a packaging project separate from any of the libraries, so you have full control of where each project goes.

Finally, the project doesn't have a PackageId property, which is why it's not considered packable. The opposite (considering everything packable) is what the SDK pack does, and it's quite bad in almost all cases.

Please do let me know how it goes with those tips! And thanks a lot for the incredibly detailed report.

kzu commented 3 years ago

I'm closing for now, plz do reopen if you have further doubts or if the pointers I shared aren't sufficient.

I plan on documenting the packaging project support too. You can follow that progress on #55.

Sergio0694 commented 3 years ago

Hey @kzu, sorry for the delay! I hadn't replied yet as I was in the process of applying your suggestions there to my own project, and to document and update this issue once I had managed to figure it out! Right now I have another user that's helping me out (https://github.com/Sergio0694/ComputeSharp/pull/79), and so far we had to add both a package project, a .targets and a .props file (to make the whole thing work both locally and from NuGet, etc.), and we still haven't quite ironed out all the variuous quirks just yet πŸ˜… I really wish there was a more straightforward way to handle similar scenarios, or at least proper docs. Will update again once we (hopefully) managed to get that working properly πŸ˜„

kzu commented 3 years ago

Hm, I wouldn't worry for the "locally" scenario much. You should have unit tests for ensuring your generator works (checkout github.com/kzu/avatar, for example). Even for nugetizer itself, I just build a local nuget package which (thanks to nugetizer) is pruned from the local nuget cache, so you can test it out locally by just adding a package source pointing to the package output path directly (see https://github.com/kzu/avatar/blob/main/src/Acceptance/Directory.Build.props#L8-L11 for example).

Also, keep in mind that source generators must target NS2 or they won't work properly everywhere (spent countless hours going down that rabbit hole), so the collection of "runtime dependencies" is extremely brittle and tricky. You'll most likely need some targets that resolve dependencies depending on the current MSBuild runtime (MSBuildRuntimeType == Core vs MSBuildRuntimeType == Full) and based on that you can determine that you need to load desktop dependencies (Windows, the only one where Full runs) or portable ones. You might even need to inspect the platform. None of this is trivial but rest assured, it's not the main scenario for nuget authors :).

Keep me posted!