Skip to content

Commit

Permalink
Add example build script that finds the latest RefTrim package to avo…
Browse files Browse the repository at this point in the history
…id chicken-and-egg problem finding the package. Dogfood the public package in this repo's builds.
  • Loading branch information
erikmav committed Oct 3, 2023
1 parent 9c82a00 commit b8fc1ea
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 11 deletions.
6 changes: 6 additions & 0 deletions Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<Project>

<!-- Dogfooding - add the latest ReferenceTrimmer package to this repo's build.
Condition is used in src\Package\ReferenceTrimmer.Package.csproj to avoid a cycle. -->
<ItemGroup Condition=" '$(DisableRefTrimPackageRef)' != 'true' ">
<PackageReference Include="ReferenceTrimmer" Version="3.*" PrivateAssets="All" />
</ItemGroup>

<PropertyGroup>
<RepoRoot>$(MSBuildThisFileDirectory.TrimEnd('\\'))</RepoRoot>
<Nullable>Enable</Nullable>
Expand Down
14 changes: 3 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ The following warnings are generated by this package:
| RT0003 | Unnecessary package reference |

## How to use
Add a package reference to the [ReferenceTrimmer](https://www.nuget.org/packages/ReferenceTrimmer) package in your projects.
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).

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

Expand All @@ -25,8 +25,6 @@ If you're using [Central Package Management](https://learn.microsoft.com/en-us/n
</ItemGroup>
```

Alternately, you can add a `PackageReference` to your `Directory.Build.props` or `Directory.Build.targets` to apply to the entire repo.

### C#
You'll need to enable C# documentation XML generation to ensure good analysis results. If your repo is not already using docxml globally, this can introduce a large number of errors and warnings specific to docxml. Additionally, turning on docxml adds additional output I/O that can slow down large repos.

Expand Down Expand Up @@ -59,15 +57,9 @@ Note: To get better results, enable the [`IDE0005`](https://learn.microsoft.com/
### 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.

The distributed logger requires configuration in your repo's `Directory.Build.rsp` file. Add the following to your `Directory.Build.rsp` file, adjusting for the NuGet package path and version for ReferenceTrimmer:

```shell
# NOTE: The version string appears twice in the following line, both need to be updated to the current ReferenceTrimmer version.
# NOTE: Use %NUGET_PACKAGES% instead of %USERPROFILE%\.nuget\packages if your repo environment uses that environment variable.
-distributedlogger:CentralLogger,%USERPROFILE%\.nuget\packages\ReferenceTrimmer\3.1.25\build\ReferenceTrimmer.Loggers.dll*ForwardingLogger,%USERPROFILE%\.nuget\packages\ReferenceTrimmer\3.1.25\build\ReferenceTrimmer.Loggers.dll
```
The distributed logger requires configuration at the MSBuild command line using the `-distributedlogger` parameter. See the [BuildWithReferenceTrimmer example script](./examples/BuildWithReferenceTrimmer.cmd) for how to orchestrate pulling and using the package's loggers.

Use `msbuild -restore` or `msbuild /t:Restore` instead of `dotnet restore` to ensure .vcxproj restore will work to add the ReferenceTrimmer props and targets to your build. NOTE: If you are seeing a `Sequence contains no elements` exception from MSBuild, see https://github.com/dotnet/NuGet.BuildTasks/issues/154 for a workaround or status on a fix.
Use `msbuild -restore` or `msbuild /t:Restore` instead of `dotnet restore` to ensure .vcxproj restore will work to add the ReferenceTrimmer props and targets to your build. *NOTE*: If you are seeing a `Sequence contains no elements` exception from MSBuild, see https://github.com/dotnet/NuGet.BuildTasks/issues/154 for a workaround or status on a fix.

The current implementation turns on MSVC `link.exe` flags `/VERBOSE:UNUSEDLIBS` and `/VERBOSE:UNUSEDDELAYLOAD`. These flags tell the linker to print out unused .lib files and delay-load DLLs to stdout. This will include .lib files containing code bundles as well as import libraries for DLLs. Removing these libraries reduces I/O and memory usage by the linker. Here's an example of the linker output:

Expand Down
23 changes: 23 additions & 0 deletions examples/BuildWithReferenceTrimmer.cmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
@echo off
@rem Builds with ReferenceTrimmer C# and C++ modes
@rem Assumes RefTrim is wired into Directory.Build.props or Directory.Packages.props as a global package reference.
@rem Usage: BuildWithReferenceTrimmer [msbuild args]
setlocal EnableDelayedExpansion

@rem Explicitly turn on in case the repo is defaulting to false.
set EnableReferenceTrimmer=true

@echo Restoring with ReferenceTrimmer enabled
call msbuild /t:Restore

@rem Find the RefTrim latest package in the package store.
set NuGetPkgBase=%NUGET_PACKAGES%
if "%NuGetPkgBase%"=="" set NuGetPkgBase=%USERPROFILE%\.nuget\packages
set RefTrimPkgBase=%NuGetPkgBase%\ReferenceTrimmer
for /d %%d in (%RefTrimPkgBase%\*) do set RefTrimPkg=%%d
set MSBuildLoggerParam=-distributedlogger:CentralLogger,%RefTrimPkg%\build\ReferenceTrimmer.Loggers.dll*ForwardingLogger,%RefTrimPkg%\build\ReferenceTrimmer.Loggers.dll

@echo Building with ReferenceTrimmer C# and C++ logger.
set cmd=msbuild %MSBuildLoggerParam% %*
echo %cmd%
call %cmd%
3 changes: 3 additions & 0 deletions src/Package/ReferenceTrimmer.Package.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
<IncludeSymbols>false</IncludeSymbols>
<PackageOutputPath>$(RepoRoot)\artifacts</PackageOutputPath>
<PackageReadmeFile>README.md</PackageReadmeFile>

<!-- Avoid cycle when dogfooding the published package. -->
<DisableRefTrimPackageRef>true</DisableRefTrimPackageRef>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Analyzer\ReferenceTrimmer.Analyzer.csproj"
Expand Down

0 comments on commit b8fc1ea

Please sign in to comment.