MSBuild.CompilerCache
is a NuGet package that provides machine-wide or distributed caching of C# and F# project compilation.
It extends the CoreCompile
targets from the .NET SDK with caching steps and uses custom MSBuild tasks that perform the actual caching.
Caching works in commandline builds as well as in the IDE.
- Before
Csc
orFsc
task is invoked, we calculate a hash of all the relevant compilation inputs. - If a cache entry exists with that hash, we simply copy the files and skip compilation.
- If the file does not exist, we run compilation and then populate the cache.
⚠️ The project is in an experimental phase. It is known to have issues, like limited debugging ability and potential incorrect cache hits. Please keep that in mind before using.
To use the cache, add the following to your project file (or Directory.Build.props
in your directory structure):
<PropertyGroup>
<CompilationCacheBaseDir>c:/machine-wide/compilation-cache/</CompilationCacheBaseDir>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="MSBuild.CompilerCache" Version="0.0.2" />
</ItemGroup>
The above code does two things:
- Adds the
MSBuild.CompilerCache
package, which provides custom Task definitions and ships .targets files. - Sets the
CompilationCacheBaseDir
used as a root directory for cache entries. This needs to be an accessible filesystem directory.
The location set in CompilationCacheBaseDir
can be either a local path or a network share - the caching logic behaves exactly the same.
This means that you could share the cache between multiple people. If you do, note that in many scenarios this is not secure enough, as it means that users can inject malicious dll files into a shared place, to be used by other users.
- Limited debugging ability - Dlls copied from the cache contain symbols with absolute paths to the source files from original compilation. This means that debugging the cached dlls will not work with source files in a different directory. This is a current limitation and should be fixed in upcoming versions.
- Currently only selected .NET SDKs are supported.
- Some of the less common compilation inputs are currently ignored. This is easy to fix, but can currently lead to incorrectly reusing cached results when one of those inputs changes.
- The cache mechanism is currently not safe for running multiple builds in parallel. If the same project is being built in two workspaces at the same time, there might be some undefined behaviour.
Below is the list of all supported .NET SDKs:
- 6.0.300
- 7.0.202
If your project is not using one of those versions, caching will be disabled.
Note that the SDK you use must match one of the supported ones precisely.
This is because the CoreCompile
targets are created by first copy-pasting the original targets from the SDK and then adding caching logic - so a new SDK requires a new copy.
The project is in a very early stage. You are free to try the tool, but it is expected to cause some issues in some cases. If you think you found an issue that isn't covered in the "Outstanding issues" list above, please raise it on GitHub.
You are most welcome to contribute to the project here on GitHub.
Please raise an issue if you would like to:
- share an idea
- report a bug
- ask a question
- make implementation changes