- Build Requirements
- Getting Yourself Started
- Configurations and Subsets
- Full Instructions on Building and Testing the Runtime Repo
The repo can be built for the following platforms, using the provided setup and the following instructions. Before attempting to clone or build, please check the requirements that match your machine, and ensure you install and prepare all as necessary.
Chip | Windows | Linux | macOS | FreeBSD |
---|---|---|---|---|
x64 | ✔ | ✔ | ✔ | ✔ |
x86 | ✔ | |||
ARM | ✔ | ✔ | ||
ARM64 | ✔ | ✔ | ✔ | |
Requirements | Requirements | Requirements | Requirements |
Additionally, keep in mind that cloning the full history of this repo takes roughly 400-500 MB of network transfer, inflating to a repository that can consume somewhere between 1 to 1.5 GB. A build of the repo can take somewhere between 10 and 20 GB of space for a single OS and Platform configuration depending on the portions of the product built. This might increase over time, so consider this to be a minimum bar for working with this codebase.
The runtime repo can be built from a regular, non-administrator command prompt, from the root of the repo.
The repository currently consists of three different major parts:
- The Runtimes
- The Libraries
- The Installer
More info on this, as well as the different build configurations in the Configurations and Subsets section.
This was a concise introduction and now it's time to show the specifics of building specific subsets in any given supported platform, since most likely you will want to customize your builds according to what component(s) you're working on, as well as how you configured your build environment. We have links to instructions depending on your needs in this section.
- For instructions on how to edit code and make changes, see Editing and Debugging.
- For instructions on how to debug CoreCLR, see Debugging CoreCLR.
- For instructions on using GitHub Codespaces, see Codespaces.
You may need to build the tree in a combination of configurations. This section explains why.
A quick reminder of some concepts -- see the glossary for more on these:
- Debug Configuration -- Non-optimized code. Asserts are enabled.
- Checked Configuration -- Optimized code. Asserts are enabled. Only relevant to CoreCLR runtime.
- Release Configuration -- Optimized code. Asserts are disabled. Runs at the best speed, and suitable for performance profiling. This will impact the debugging experience due to compiler optimizations that make understanding what the debugging is showing difficult to reason about, relative to the source code.
When we talk about mixing configurations, we're discussing the following sub-components:
- Runtime is the execution engine for managed code and there are two different implementations available. Both are written in C/C++, therefore, easier to debug when built in a Debug configuration.
- CoreCLR is the comprehensive execution engine which, if built in Debug Configuration, executes managed code very slowly. For example, it will take a long time to run the managed code unit tests. The code lives under src/coreclr.
- Mono is a portable and also slimmer runtime and it's not that sensitive to Debug Configuration for running managed code. You will still need to build it without optimizations to have good runtime debugging experience though. The code lives under src/mono.
- CoreLib (also known as System.Private.CoreLib) is the lowest level managed library. It has a special relationship to the runtimes and therefore it must be built in the matching configuration, e.g., if the runtime you are using was built in a Debug configuration, this must be in a Debug configuration. The runtime agnostic code for this library can be found at src/libraries/System.Private.CoreLib/src.
- Libraries is the bulk of the dlls that are oblivious to the configuration that runtimes and CoreLib were built in. They are most debuggable when built in a Debug configuration, and happily, they still run sufficiently fast in that configuration that it's acceptable for development work. The code lives under src/libraries.
To build just one part of the repo, you add the -subset
flag with the subset you wish to build to the root build script (build.cmd/sh). You can specify more than one by linking them with the +
operator (e.g. -subset clr+libs
would build CoreCLR and the libraries). Note that if the subset is the first argument you pass to the script, you can omit the --subset
flag altogether.
At this point you probably know what you are planning to work on primarily: the runtimes or libraries. As general suggestions on how to proceed, here are some ideas:
- If you're working in runtimes, you may want to build everything in the Debug configuration, depending on how comfortable you are debugging optimized native code.
- If you're working in libraries, you will want to use debug libraries with a release version of runtime and CoreLib, because the tests will run faster.
- If you're working in CoreLib - you probably want to try to get the job done with release runtime and CoreLib, and fall back to debug if you need to. The Building Libraries document explains how you'll do this.
Now you know about configurations and how we use them, so now you will want to read how to build what you plan to work on. Each of these will have further specific instructions or links for whichever platform you are developing on.
After that, here's information about how to run tests:
And how to measure performance:
- Benchmarking workflow for dotnet/runtime repository
- Profiling workflow for dotnet/runtime repository
The repo build treats warnings as errors. Dealing with warnings when you're in the middle of making changes can be annoying (e.g. unused variable that you plan to use later). To disable treating warnings as errors, set the TreatWarningsAsErrors
environment variable to false
before building. This variable will be respected by both the build.sh
/build.cmd
root build scripts and builds done with dotnet build
or Visual Studio. Some people may prefer setting this environment variable globally in their machine settings.