The following document includes documentation for the build scripts. Over time, this README is expected to just be a TOC as the instructions move into separate docs.
The scripts are supported on macOS and Linux. The scripts are based on Bash on macOS and Linux.
The source-build repository doesn't currently support Windows. See source-build#1190.
This repo uses submodules so remember on fresh clones or when updating/switching branches to run
git submodule update --init --recursive
./build.{cmd|sh}
Once the build is successful, the built SDK tarball is placed at:
artifacts/${ARCHITECTURE}/Release/dotnet-sdk-${SDK_VERSION}-${RUNTIME_ID}.tar.gz
${ARCHITECTURE}
is your platform architecture (probablyx64
)${SDK_VERSION}
is the SDK version you are building${RUNTIME_ID}
is your OS name and architecture (something likedebian.9-x64
orfedora.33-x64
)
For example, building a 3.1.105 SDK on an x64 (aka x86_64) platform running Fedora 32 will produce artifacts/x64/Release/dotnet-sdk-3.1.105-fedora.32-x64.tar.gz
.
If you are interested in "installing" this SDK system wide or making a Linux package out of the SDK, please see Packaging and Installation.
./build.{cmd|sh}
accepts a number of parameters to control the build.
-
/p:UseSystemLibraries=true
or/p:UseSystemLibraries=false
can be used to explicitly link against the system libraries.false
will make itdlopen
any required libraries at runtime. -
/p:UseSystemLibunwind=true
or/p:UseSystemLibunwind=false
can be used to use either the system libunwind or the version of libunwind included in the dotnet/runtime repository. Defaults to the value ofUseSystemLibraries
.
By default we build the cli and its dependencies but the default root repository to build can be passed in. For example, if you just want to build the .NET Core Runtime, you would just build the core-setup
repo and its dependencies:
./build.{cmd|sh} /p:RootRepo=core-setup
Sometimes you want to just iterate on a single repo build and not rebuild all dependencies that can be done passing another property.
./build.{cmd|sh} /p:RootRepo=core-setup /p:SkipRepoReferences=true
./clean.{cmd|sh} # Cleans root binary directory and fully git cleans and hard resets all submodules
./clean.{cmd|sh} -a # Does a full git clean on the root repo as well as fully git cleans and hard resets all submodules
You can build the .NET Core SDK and generate a source tarball in a specific directory. This script is bash-only and is intended to be run on Linux.
./build-source-tarball.sh <path-to-tarball-root>
tar -czf <tarball-destination> --directory <path-to-tarball-root> "."
After this completes, you can take the output tarball to another machine and build .NET Core again without an internet connection.
tar -xf <tarball-destination> -C <path-to-extraction-root>
cd <path-to-extraction-root>
./build.sh
You can also build a .NET Core Runtime with custom changes in order to test locally the produced runtime with the affected changes.
The .NET Core Runtime consists of 4 repos, core-setup at the top of the stack (which produces the runtime), standard, corefx (BCL repo), coreclr (Runtime repo).
This means that in order to get a runtime you'll need to build the source-build repo with the /p:RootRepo=core-setup
parameter, this will automatically build coreclr, standard and corefx. Source-Build is composed by git submodules, so the first thing you need to run before doing anything is:
git submodule update --init --recursive
This will initialize the submodules and clone the repos under the src folder if they haven't been initialized. Note that this will update every submodule to their tracking commit checked in to the source-build
repo . However you can go to each repo indivually, add custom remotes and checkout certain branches containing your changes.
Let's say that you want to produce a runtime that has a new API that it's implementation lives in coreclr and you want to create a .NET Core console app that uses it to test it without waiting for a new SDK or Runtime to be produced by official builds. Imagine we will add an API that just throws in Hashtable.
Hashtable implementation lives in coreclr and it's APIs are exposed in corefx in the System.Runtime.Extensions.cs contract. So in my local coreclr repo I will just add Hashtable.cs the following API:
public static void PNSE()
{
throw new PlatformNotSupportedException();
}
Then in my local corefx repo let's expose it in System.Runtime.Extensions.cs in the Hashtable class:
public static void PNSE() { }
Of course we need to commit this changes in our current repos. Once we've commited this locally, let's move to the source-build repo.
Once in the source-build in our commmand prompt or terminal, lets navigate to src/coreclr
. Once there, we will need to add a remote to the local coreclr repo, in example:
git remote add local C:\repos\coreclr
Then, let's fetch the changes from our repo, by running:
git fetch local
Once we've fetched the changes, we just need to checkout the branch where we made the changes:
git checkout branchWithChanges
Just repeat this steps under src/corefx
as well, to pull the corefx changes. Once we've done that, let's navigate to the source-build
root and run:
build.{cmd|sh} /p:RootRepo=core-setup
The build detects you've changed the coreclr and corefx commits and offers to move them back to the tracked commits. Press n
when you see the following message to decline and keep your changes:
WARNING: submodule src/corefx, currently at 831264e53e5b9333850baa659af8a2857a9cb9b7, has diverged from checked-in
version 5b7674e4ae5cc782e99f50b2919dfdeb29106a46
If you are changing a submodule branch or moving a submodule backwards, this is expected.
Should I checkout src/corefx to the expected commit 5b7674e4ae5cc782e99f50b2919dfdeb29106a46 [N]o / [y]es / [q]uit
To skip this check and avoid pressing
n
for each build, you can either:
- Set the environment variable
SOURCE_BUILD_SKIP_SUBMODULE_CHECK=1
.- Stage the submodule changes with
git add src/corefx
and/orgit add src/coreclr
.
Once the build is done, we will have a .NET Runtime containing the Hashtable.PNSE()
API that can be used with our local cli in .NET Core projects.
The produced runtime will be under artifacts/{architecture}/{configuration}/runtime
.
Now create a new .NET Core project:
dotnet new Console -o source-build-test
In your new project add a new NuGet.config to point to the Microsoft.NETCore.App and runtime packages.
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<!--
Use a fresh packages directory located in the working directory.
This helps avoid nuget cache collision problems.
-->
<config>
<add key="globalPackagesFolder" value="packages" />
</config>
<!-- Prefer the source-built packages over the ones from nuget.org. -->
<packageSources>
<clear/>
<add key="local feed" value="E:\repos\source-build\bin\x64\Release\runtime" />
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
</packageSources>
</configuration>
Then in your csproj we need to set the Runtime version:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.0</TargetFramework>
<RootNamespace>source_build_test</RootNamespace>
<RuntimeFrameworkVersion>3.0.0-preview1-26509-04</RuntimeFrameworkVersion>
<NETCoreAppMaximumVersion>3.0</NETCoreAppMaximumVersion>
</PropertyGroup>
</Project>
Note that the TargetFramework
value needs to be the minimum or later framework that the Runtime supports. Therefore if there is no cli produced yet or you don't have installed a dotnet cli that supports that TargetFramework
you need to add the property NETCoreAppMaximumVersion
to match the version framework you want to target.
If you don't set this property, you will see an error similar to this one:
C:\Program Files\dotnet\sdk\2.1.300\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.TargetFrameworkInference.targets(137,5): error : The current .NET SDK does not support targeting .NET Core 2.2. Either target .NET Core 2.1 or lower, or use a version of the .NET SDK that supports .NET Core 2.2.
Also, RuntimeFrameworkVersion
needs to match whatever version of the runtime was produced.
After that you're all set to use your new API and test it with a locally produced runtime.
using System;
using System.Collections;
namespace source_build_test
{
class Program
{
static void Main(string[] args)
{
Hashtable.PNSE();
}
}
}
In order to run the app you have two options:
- Publish the app:
- Run
dotnet publish -r RID
. You more information about publish and RID in this guide. - Run produced executable in publish directory.
- Run
- Use
dotnet run
:- In order to use
dotnet run
you will have to install the produced runtime before running the app. Note that installing the runtime, whenever a real runtime for the current produced version is released, if you forget to delete/uninstall the custom runtime, it could cause issues.
- In order to use