Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 26 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ The following warnings are generated by this package:
| Id | Description |
|--------|-------------|
| RT0000 | Enable documentation generation for accuracy of used references detection |
| RT0001 | Unnecessary reference |
| RT0001 | Unnecessary reference |
| RT0002 | Unnecessary project reference |
| RT0003 | Unnecessary package reference |

## How to use
Add a package reference to the [ReferenceTrimmer](https://www.nuget.org/packages/ReferenceTrimmer) package in your projects, or as a common package reference in the repo's [`Directory.Packages.props`](./Directory.Build.props).
Add a package reference to the [ReferenceTrimmer](https://www.nuget.org/packages/ReferenceTrimmer) package in your projects, or as a common package reference in the repo's `Directory.Packages.props`.

If you're using [Central Package Management](https://learn.microsoft.com/en-us/nuget/consume-packages/Central-Package-Management), you can use it as a `GlobalPackageReference` in your `Directory.Packages.props` to apply it to the entire repo.

Expand Down Expand Up @@ -54,15 +54,27 @@ You can turn off specific docxml related warnings and errors while defaulting Re

Note: To get better results, enable the [`IDE0005`](https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0005) unnecessary `using` rule. This avoids the C# compiler seeing a false positive assembly usage from unneeded `using` directives causing it to miss a removable dependency. See also the note for why IDE0005 code analysis rule requires `<GenerateDocumentationFile>` property to be enabled. Documentation generation is also required for accuracy of used references detection (based on https://github.com/dotnet/roslyn/issues/66188).

Packages are prevented from being trimmed if they contain build files, as there's no reliable way to determine whether it's safe to do so. You can explicitly ignore specific packages' build files and cause them to be solely judged based on whther the libraries are used by adding the package to the `ReferenceTrimmerIgnorePackageBuildFiles` item on a project level, or in `Directory.Build.props`.
#### What makes a reference non-trimmable?

ReferenceTrimmer automatically skips certain references that cannot be reliably evaluated. These are not reported as unused even if the compiler does not directly use them:

- **Implicitly defined (SDK-provided) references** - References added by the SDK (e.g. `System.Runtime`) are not under your control and are skipped.
- **Target framework assemblies** - Assemblies that are part of the target framework itself (e.g. from `FrameworkList.xml`) are skipped, since they may have been substituted in during package conflict resolution and may not be directly removable.
- **References originating from NuGet package build logic** - If a `Reference` item resolves to a path under the NuGet package root, it was likely injected by a package's `.props` or `.targets` file rather than declared by you directly, so it is skipped.
- **Transitive project references** - Project references that are indirect (transitive) dependencies, determined by NuGet restore, are skipped because you don't have direct control over them.
- **Packages with build files** - NuGet packages that ship `.props` or `.targets` files in their `build/` folder can influence the build in ways that go beyond providing compile-time assemblies. For example, they might define custom MSBuild properties, targets, items, or code generators. Because there is no reliable way to determine whether these build-time contributions are still needed, ReferenceTrimmer skips these packages by default.

#### `ReferenceTrimmerIgnorePackageBuildFiles`

Many commonly used packages ship build files that are inconsequential - they don't materially affect the build and only prevent the package from being evaluated for trimming. You can tell ReferenceTrimmer to ignore a package's build files and evaluate it solely based on whether its compile-time assemblies are used. Add the package to the `ReferenceTrimmerIgnorePackageBuildFiles` item in your project file or `Directory.Build.props`:

Example:
```xml
<ItemGroup>
<ReferenceTrimmerIgnorePackageBuildFiles Include="Microsoft.Extensions.Logging.Abstractions" />
</ItemGroup>
```
A default set of `ReferenceTrimmerIgnorePackageBuildFiles` items is already included for well-known package, notably various `Microsoft.Extensions.*` packages.

A default set of `ReferenceTrimmerIgnorePackageBuildFiles` items is already included for well-known packages, notably various `Microsoft.Extensions.*` packages. See the full list in the [ReferenceTrimmer.props](./src/Package/build/ReferenceTrimmer.props) file.

### C++ (.vcxproj projects)
ReferenceTrimmer for C++ is an MSBuild [distributed logger](https://learn.microsoft.com/en-us/visualstudio/msbuild/logging-in-a-multi-processor-environment?view=vs-2022). It writes guidance to the MSBuild stdout stream (not to the MSBuild internal logger at this time) and writes `ReferenceTrimmerUnusedMSVCLibraries.json.log` to the build working directory.
Expand Down Expand Up @@ -115,17 +127,25 @@ If you find an unused .lib that is created by a .vcxproj in your repo, you shoul
If you find an unused .lib that is from a package, remove the reference to that .lib from your project to speed up linking.

## Disabling a rule on a reference
To turn off a rule on a specific project or package reference, add the relevant RTxxxx code to a NoWarn metadata attribute. For example:
To turn off a rule on a specific project or package reference, add the relevant RTxxxx code to a `NoWarn` metadata attribute. For example:

```xml
<ProjectReference Include="../Other/Project.csproj" NoWarn="RT0002" />
```

Alternatively, you can add `TreatAsUsed` metadata to suppress all ReferenceTrimmer warnings for that reference:

```xml
<PackageReference Include="SomePackage" TreatAsUsed="true" />
```

## Configuration
`$(EnableReferenceTrimmer)` - Controls whether the build logic should run for a given project. Defaults to `true`.

`$(ReferenceTrimmerEnableVcxproj)` - Controls whether MSVC link flags are set up to print out unused libraries and delay-load DLLs. Defaults to `true`.

`$(EnableReferenceTrimmerDiagnostics)` - When set to `true`, writes used and unused reference lists to the intermediate output directory for debugging. Defaults to `false`.

## How does it work?

### C#
Expand Down