Skip to content

Add draft of combined tool + library packages #337

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

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

baronfel
Copy link
Member

This adds a spec for an idea I've been discussing with @joelverhagen and @DamianEdwards now that we have a very lightweight tool-manifest package pattern with .NET 10's RID-specific tool packages.

The short form is that users should be able to author one package that can be used as a tool and a PackageReference, without

a) impacting the behavior of either mode,
b) incurring large download size increase costs, and
c) sacrificing simplicity of project files

<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.0" />
```

However, ideally none of the _entrypoint_ (or code only used by the entrypoint) of the application would be included in the library portion of the package. To achieve this, we can condition the removal of the Entrypoint-related code from the project:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it so bad to include Program.cs in the library? I guess it would lead some untrimmed code?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, exactly - it's not required per se, but I want to aim for the moon here in terms of not influencing the library code from the program if possible.

<!-- JsonSchemaValidator.csproj -->
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How does multi-targetting play in here? If I had <TargetFrameworks>net10.0;net9.0</TargetFrameworks> would this impact both the library and the tool assets?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good question! the answer depends on the kind of tool. framework-dependent, platform-agnostic tools would bundle the N TFM variants of the tool in the package. framework-dependent, platform-specific tools could make the N platform-specific tools, but our existing model actually doesn't handle TFM variants of platform-specific tools at this time. I don't actually know what would happen here. For self-contained tools, there is no need to have TFM-specific variants at all, and so we should strongly consider taking the 'newest' TFM and only making the platform-specific variants for that TFM.


Depending on the deployment model chosen for the tool package, the impact to library package size is variable.
* For packages that lean into the RID-specific deployment model, the library package size remains similar to existing library packages - it only adds a single small XML manifest file to locate the platform-specific tools.
* For packages that prefer the framework-dependent, platform-agnostic deployment model, the library package will be increased by the size of the tool's runtime assets.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this be mitigated with a single .any "RID specific" package?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes - that is a good call out and will light up starting in preview 7. I almost want to push us to this as a default, except that then older SDKs won't be able to use the .any RID-specific packages.

<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<PackAsTool>true</PackAsTool>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like there should be a way to opt in to the new experience. This .csproj looks just like an existing tool project, but now it's magically adding Dependency assets? Or am I missing something?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does look like a tool package - but the key signal here is the lack of OutputType Exe. This project is actually a library - that's our signal. "This library wants to be packed like a tool, too!"

We can of course have a signal, but I'm trying to angle towards as light of a touch as possible on the project file.

- Combined packages can be consumed as either tools or libraries by consumers unaware of the dual nature
- NuGet clients that don't understand combined packages treat them as either tools or libraries based on which assets they recognize

## Q & A
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does dotnet publish do on this project?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

publishes the project as a library, by default. This is because the project has no OutputType set, so the defaults it to a Library OutputType.

Co-authored-by: Joel Verhagen <joel.verhagen@gmail.com>
└── [package metadata files]
```

### Compatibility Considerations
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Many tools are going to be confused when they see a library that is executable with an entry point.

For example, NativeAOT compiler will choke when it sees multiple binaries with entrypoint on the command line here: https://github.com/dotnet/runtime/blob/1e860a4bd3915f35d51cc079cff212322a6991e7/src/coreclr/tools/aot/ILCompiler/Program.cs#L218 . I am pretty sure that diagnostic tools like debuggers will get confused in similar way. it would be a very long tail to find and fix all these.

You really want to have separate binary for the tool and for the library.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that's good confirmation - we do today, and will continue to have in this proposal, separate binaries for the tool usage and the library usage. This layout is intended to show this separation. The idea would be that the entrypoint would not be part of the library-use-case dlls in any way - only the tool-use-case dlls.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants