- Introduction
- Create a sample self-contained application
- Update CoreCLR and System.Private.CoreLib.dll with your build
- Confirm that the app used your new runtime (Optional)
- Troubleshooting
This guide will walk you through using your own build from the runtime repo for testing, running apps, and so on. This doc assumes you've already built at least the clr subset of the repo, and have the binaries under artifacts/bin/coreclr/<OS>.<arch>.<configuration>
. If this is not your case, the CoreCLR building docs have detailed instructions on how to get these artifacts.
To run a .NET app with the runtime you've built, you will need a host program that will load the runtime, as well as all the other .NET libraries that your application might need. There are three main ways to go about this:
- Use your machine's installed .NET SDK and replace the necessary binaries in a self-contained app.
- Use your build's Dev Shipping Packages to run your app.
- Use the CoreRun host generated as part of your build's artifacts.
This guide focuses on the first of the bullet points described above. For the other two, we have docs dedicated to them:
NOTE: It's unlikely, but it's possible that the officially released version of dotnet
may not be compatible with the live repository. If this happens to you, then unfortunately, you will be limited to either installing a nightly build on your machine (not that recommended), or use another of the methods described above to test your build. This is because this method requires a self-contained app, and the portable builds do not support this at the present time.
The sdk repo has downloads to all nightly builds for all the currently supported platforms. Find the one that matches your machine and download it.
To setup the nightly SDK, you can either install it to your machine or use a portable build. If you downloaded the installer, then just follow the usual installation instructions, and you're done.
To use a portable build (check the note above though), first extract somewhere the zip/tar.gz you downloaded at the beginning of this section. Then, you can either add the path where you extracted it to your PATH
environment variable, or always fully qualify the path to the dotnet
you extracted (e.g. /path/to/nightly/build/dotnet
).
After setting up dotnet you can verify you are using the newer version by issuing the dotnet --version
command on it. At the time of writing, the version must be equal or greater than 9.0.100-*
.
For another small walkthrough see Dogfooding .NET SDK.
First things first. We need a sample app to test our runtime build on. Let's create a quick 'Hello World' app for this example.
mkdir HelloWorld
cd HelloWorld
dotnet new console
In order to run with your local changes, the application needs to be self-contained, as opposed to running on the installed shared framework. In order to do that, you will need a RuntimeIdentifier
for your project. You can specify it directly in the command-line later on, or you can write it in your app's .csproj
file:
<PropertyGroup>
...
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
</PropertyGroup>
We are using Windows x64 for this example. Make sure you set it to the platform and configuration you have your build in. The codenames for the most common OS's are:
- Windows:
win
- macOS:
osx
- Linux:
linux
For example, if we were testing a macOS ARM64 build, our RuntimeIdentifier
would be osx-arm64
.
Now is the time to build and publish. This step will trigger restore and build.
dotnet publish --self-contained
NOTE: If publish fails to restore runtime packages, then you'll need to configure custom NuGet feeds. This is a side-effect of using a dogfood .NET SDK: Its dependencies are not yet on the regular NuGet feed. To configure this, you have to:
- Run the command
dotnet new nugetconfig
- Go to the newly created
NuGet.Config
file and replace the content with the following template:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<!--To inherit the global NuGet package sources remove the <clear/> line below -->
<clear />
<add key="nuget" value="https://api.nuget.org/v3/index.json" />
<add key="dotnet9" value="https://dnceng.pkgs.visualstudio.com/public/_packaging/dotnet9/nuget/v3/index.json" />
</packageSources>
</configuration>
After you publish successfully, you will find all the binaries needed to run your application under bin\Debug\net10.0\win-x64\publish
.
But we are not done yet, you need to replace the published runtime files with the files from your local build!
The publishing step described above creates a directory that has all the files necessary to run your app, including the CoreCLR runtime and the required libraries. Out of all these binaries, there are three notable ones that will contain any changes you make to the runtime:
coreclr.dll (windows)/libcoreclr.dylib (macos)/libcoreclr.so (linux)
: Most modifications (with the exception of the JIT compiler and tools) that are C++ code update this binary.System.Private.CoreLib.dll
: If you modified managed C# code, it will end up here.clrjit.dll
: The JIT compiler. It is also required you copy this one to your published app.
Now, here comes the main deal to test your build. Once you have your self-contained app published, and CoreCLR built, you will replace the binaries listed above with the generated artifacts. Copy them from artifacts/bin/coreclr/<OS>.<arch>.<configuration>/
to your app's publication directory, which by default is your-app-folder/bin/<configuration>/net10.0/<os-code>-<arch>/publish
.
In our previous example this would be:
- From:
artifacts/bin/coreclr/windows.x64.Debug/
- To:
HelloWorld/bin/Debug/net10.0/win-x64/publish/
Congratulations, you have successfully used your newly built runtime.
If you want to further ensure this is indeed the case before delving into more complex experiments and testing, you can run the following piece of code in your app:
using System.Diagnostics;
var coreAssemblyInfo = FileVersionInfo.GetVersionInfo(typeof(object).Assembly.Location);
Console.WriteLine($"Core Runtime Info: {coreAssemblyInfo.ProductVersion}");
Console.WriteLine($"System.Private.CoreLib.dll is located at: {typeof(object).Assembly.Location}");
That should tell you the version, and which user and machine built the assembly, as well as the commit hash of the code at the time of building:
Core Runtime Info: 10.0.0-dev
System.Private.CoreLib.dll is located at: /path/to/your/app/bin/Debug/net10.0/win-x64/publish/System.Private.CoreLib.dll
What you are looking for here is that the core runtime used is labelled as -dev
. This means it is indeed using the one you built in the runtime repo. Also, ensure that the picked System.Private.CoreLib.dll is indeed the one in your publish
folder.
Here are a few very common errors you might encounter, and how to fix them.
Make sure you are running the executable directly.
.\bin\Debug\net10.0\win-x64\publish\HelloWorld.exe
If you use dotnet run
it will overwrite your custom binaries before executing the app.
This failure happens when you only copy coreclr
, but not System.Private.Corelib.dll
as well.
Assert failure(PID 13452 [0x0000348c], Thread: 10784 [0x2a20]): Consistency check failed: AV in clr at this callstack:
If you forget to also copy clrjit.dll
, you will get the following error message:
Fatal error. Failed to load JIT compiler.