Skip to content

Commit

Permalink
Detailed guidelines end-to-end for source-build (#3193)
Browse files Browse the repository at this point in the history
* Detailed guidelines end-to-end for source-build

* Fix markdown syntax issues

* System requirements updates to make the document easier to scan for pertinent info

* Fix linter violations

* Addressing the suggestions/comments on PR

* Updated section Building for New OS (Unsupported) and addressed all comments

* WIP adding instructions

* Add a couple more examples and make the weird cases clearer.

* Address last few review comments.

* Updates to make Readme easier to skim

* Update system requirements

* Cleanup bootstrap guideline wording

* Address review comments.

* Fix link.

* minor tweaks

* Addressed minor comments

* Update Documentation/system-requirements.md

Co-authored-by: Omair Majid <omajid@redhat.com>

* Address review comments.

* Simplification edits.

* fix wording

---------

Co-authored-by: Michael Simons <msimons@microsoft.com>
Co-authored-by: Chris Rummel <crummel@microsoft.com>
Co-authored-by: Omair Majid <omajid@redhat.com>
  • Loading branch information
4 people authored Mar 17, 2023
1 parent 7870499 commit 86da5e1
Show file tree
Hide file tree
Showing 3 changed files with 172 additions and 3 deletions.
112 changes: 112 additions & 0 deletions Documentation/bootstrapping-guidelines.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
# Bootstrapping Guidelines to Build .NET from Source

.NET utilizes itself to build therefore in order to build .NET from source, you first need to acquire or build a bootstrapping .NET SDK. This document provides guidance around acquiring and building this bootstrapping .NET SDK.

The version of the SDK used to source build .NET is referred to as "N-1" (e.g. 7.0.100). The version of the SDK produced by source build is referred to as "N" (e.g. 7.0.101). The previous SDK (e.g. N-1) supplies the tools required to build.

For new major versions or new platforms, you need to acquire or build the bootstrapping SDK as you cannot use a previous source-built SDK. This is to say you cannot use a 6.0 version of the SDK to build a 7.0 SDK.

Refer to the [build instructions](https://github.com/dotnet/installer/blob/main/README.md#build-net-from-source-source-build) to review how to build the .NET SDK from source.

## Scenarios

There are three major scenarios for bootstrapping:

1. [Building on a supported platform (Using RID known to .NET)](#building-on-a-supported-platform-using-rid-known-to-net)
1. [Building for New OS (Using a RID unknown to .NET)](#building-for-new-os-using-a-rid-unknown-to-net)
1. [Building for New Architecture (Using a RID unknown to .NET)](#building-for-new-architecture-using-a-rid-unknown-to-net)

## Building on a supported platform (Using RID known to .NET)

To find out if your platform is supported you must first determine its [RID](https://learn.microsoft.com/en-us/dotnet/core/rid-catalog). You can then check if it's supported by looking at the RID graph in the [runtime.json](https://github.com/dotnet/runtime/blob/main/src/libraries/Microsoft.NETCore.Platforms/src/runtime.json).

Building .NET for the first time is a two stage process:

**Stage 1:** Build bootstrapping .NET SDK for the targeted platform.

1. Download a platform-native portable Microsoft-built version of the dotnet SDK for bootstrapping as well as the previously-source-built package archive.

``` bash
./prep.sh
```

1. Build the source built .NET SDK.

``` bash
./build.sh
```

**Stage 2:** Use the source built .NET SDK created in stage 1 to build .NET SDK from source. There is no need to run `prep.sh` in this stage.

1. Extract your freshly-built stage 1 SDK to a convenient location.

``` bash
tar -ozxf /<stage1-path>/artifacts/<arch>/Release/dotnet-sdk-<version>-<rid>-tar.gz -C <extracted-stage1-sdk-path>
```

1. Build the source built .NET SDK.

``` bash
./build.sh --with-sdk <extracted-stage1-sdk-path> --with-packages /<stage1-path>/obj/bin/<arch>/blob-feed/packages
```

## Building for New OS (Using a RID unknown to .NET)

Building for an OS that Microsoft does not currently build the SDK for is possible but requires more work. If [Microsoft produces](https://dotnet.microsoft.com/en-us/download/dotnet) a portable SDK for your platform (e.g. amd64 and arm64), you can follow the two-step process below.

**RIDs:**

The RID graph or runtime fallback graph is a list of RIDs that are compatible with each other. You can see the list of supported RIDs and the RID graph in the [runtime.json](https://github.com/dotnet/runtime/blob/main/src/libraries/Microsoft.NETCore.Platforms/src/runtime.json). Learn more about RID catalog [here](https://learn.microsoft.com/en-us/dotnet/core/rid-catalog#linux-rids).

If a compatible RID is found, you can use a compatible supported OS as host to build. Choose a host with same processor architecture as that of the new targeted platform. If you choose this option, the RID of the resulting SDK will be that of the host. If this is acceptable follow the instructions in [Building on a supported platform (Using RID known to .NET)](#building-on-a-supported-platform-using-rid-known-to-net) using a compatible host OS.

If no compatible RID is found or you want a RID specific SDK use the folloring the steps (works for .NET 6, but requires validation for .NET 7):

**Stage 0:**

1. Get Microsoft portable SDK.
1. Update the RID graph (runtime.json) in the Microsoft-built portable SDK with the same changes you will make below to add your new RID to the RID graph. This should include a fallback to the portable RID (linux-x64 or similar).

**Stage 1:**

1. Update the RID graph in source with the same changes made in Stage 0. For an example, see <https://github.com/dotnet/runtime/pull/74372>.
1. Build with Stage 0 SDK using `--with-sdk` with your modified portable SDK. See the Stage 1 instructions in [Building on a supported platform (Using RID known to .NET)](#building-on-a-supported-platform-using-rid-known-to-net).

**Stage 2:**

1. Now you have a RID-specific SDK that knows about your new RID, build with Stage 1 SDK as done in [Building on a supported platform (Using RID known to .NET)](#building-on-a-supported-platform-using-rid-known-to-net).

## Building for New Architecture (Using a RID unknown to .NET)

Building for an architecture that Microsoft does not currently build the SDK for is possible but requires more work.

**RIDs:**

The RID graph or runtime fallback graph is a list of RIDs that are compatible with each other. You can see the list of supported RIDs and the RID graph in the [runtime.json](https://github.com/dotnet/runtime/blob/main/src/libraries/Microsoft.NETCore.Platforms/src/runtime.json). Learn more about RID catalog in [here](https://learn.microsoft.com/en-us/dotnet/core/rid-catalog#linux-rids).

You will need to update the RID graph to include your new platform and runtime IDs. See <https://github.com/dotnet/runtime/pull/82382> or <https://github.com/dotnet/runtime/pull/75396> for examples.

Building for unsupported architectures require cross-compilaton on the supported platform. Determine the compatible host to build which provides cross-compilation toolchain. [IBM has published](https://community.ibm.com/community/user/powerdeveloper/blogs/sapana-khemkar/2023/01/13/cross-build-dotnet7-on-x86-ibm-power?CommunityKey=8cc2a1f0-6307-48cb-9178-ace50920244e) a detailed description of how they successfully built .NET 7 for IBM Power.

While this is a more complicated scenario that may differ from platform to platform, the steps will be roughly:

**Stage 0:**

1. Cross compile an SDK (using prebuilts) on x64 for target platform (this process may be quite long and involved and include setting up a rootfs for your architecture).
2. Cross compile the runtime repo (on x64 for target platform, generally done as part of previous step) and save the nuget packages, use these to augment the Microsoft-built previously-source-built archive.

**Stage 1:**

1. Use the cross-compiled SDK and augmented previously-source-built-archive to build a stage 1 SDK. See the Stage 1 instructions in [Building on a supported platform (Using RID known to .NET)](#building-on-a-supported-platform-using-rid-known-to-net).

**Stage 2:**

1. Use your stage 1 SDK to build a stage 2 SDK, pointing it to the SDK and previously-source-built archives from stage 1. See the Stage 2 instructions in [Building on a supported platform (Using RID known to .NET)](#building-on-a-supported-platform-using-rid-known-to-net).

## Building a Servicing Release of .NET

Building a subsequent or servicing version of .NET requires that you have source built the previous version of .NET available as descibed in one of the [building scenarios](#scenarios). Once you have a previous verion of the .NET SDK available, all you have to do is run the following build command.

``` bash
./build.sh --with-sdk <extracted-previously-source-built-sdk-path> --with-packages <extracted-previously-source-built-packages-path>
```
53 changes: 53 additions & 0 deletions Documentation/system-requirements.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# System Requirements to Source-Build

This document provides the system requirements to source build the .NET SDK for a targeted platform.

## Operating System

### Linux

* [Toolchain Setup](https://github.com/dotnet/runtime/blob/main/docs/workflow/requirements/linux-requirements.md#toolchain-setup)
* [Preconfigured Container Images](https://github.com/dotnet/dotnet-buildtools-prereqs-docker) - These images are used by [CI](https://github.com/dotnet/installer/blob/release/7.0.1xx/src/SourceBuild/Arcade/eng/common/templates/job/source-build-run-tarball-build.yml#L12-L16) to build and test source-build.
* [Distros Source Building .NET](https://github.com/dotnet/source-build#net-in-linux-distributions)

### MacOS

MacOS is not currently supported: [Tracking Issue](https://github.com/dotnet/source-build/issues/2909). However, community users have created a [Homebrew project](https://github.com/Homebrew/homebrew-core/blob/master/Formula/dotnet.rb) to build .NET for OSX. Please feel free to open new issues in individual repos or in source-build for OSX issues.

### Windows

Windows is not currently supported. [Tracking Issue](https://github.com/dotnet/source-build/issues/2910)

## Hardware

### Disk Space

80 GB of space is required for a typical build. You can reduced this down to ~30 GB if you build with the `clean-while-building` option. This might increase over time, so consider this to be a minimum bar.

### Memory

A minimum of 8 GB of memory is recommended.

### Architectures

#### Officially Supported

* ARM64
* x64

#### Community Supported

* ARM32
* s390x
* ppc64le

## Network

The following assets will need to be downloaded in order to build.

* Source: 525 MB
* SDK: 230 MB
* Artifacts
* .NET 8.0: 1 GB
* .NET 7.0: 1.2 GB
* .NET 6.0: 4 GB
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ This repo is the starting point for building .NET from source. It contains docum

## Prerequisites

The dependencies for building .NET from source can be found [here](https://github.com/dotnet/runtime/blob/main/docs/workflow/requirements/linux-requirements.md). It may also be helpful to reference the Dockerfiles in [dotnet-buildtools-prereqs-docker](https://github.com/dotnet/dotnet-buildtools-prereqs-docker). We use these images to build and test source-build CI [here](https://github.com/dotnet/installer/blob/release/7.0.1xx/src/SourceBuild/Arcade/eng/common/templates/job/source-build-run-tarball-build.yml#L12-L16).
* [Build system requirements](Documentation/system-requirements.md)

## Building .NET 8.0

Expand All @@ -21,7 +21,6 @@ Clone the dotnet/installer repo and check out the tag for the desired release.
Then, follow the instructions in [dotnet/installer's README](https://github.com/dotnet/installer/blob/main/README.md#build-net-from-source-source-build) to build .NET from source.
Please see the [support](#support) section below to see which feature branches are currently supported.


> The source-build repository doesn't currently support Windows. See [source-build#1190](https://github.com/dotnet/source-build/issues/1190).
## Source-build goals
Expand All @@ -39,7 +38,13 @@ Source-build solves common challenges that most developers encounter when trying
* By default, most .NET repositories download prebuilt binary dependencies from online sources. These are forbidden by typical Linux distribution rules, and interfere with build output flow.
* Nearly all .NET repositories require the .NET SDK to build. This is a circular dependency, which presents a bootstrapping problem.

## Comprehensive Guidelines

* [Bootstrapping new distro and architecture guidelines](Documentation/bootstrapping-guidelines.md)
* [Distribution packaging guidelines](https://learn.microsoft.com/dotnet/core/distribution-packaging)

## .NET in Linux Distributions

| Distro | Package Feed | Maintainer |
|---|---|---|
| Alpine | [Community](https://pkgs.alpinelinux.org/packages?name=dotnet*&branch=v3.16&repo=&arch=&maintainer=) | [@ayakael](https://github.com/ayakael) |
Expand All @@ -50,7 +55,6 @@ Source-build solves common challenges that most developers encounter when trying
| [Red Hat Enterprise Linux](https://developers.redhat.com/products/dotnet/overview) | [Default](https://access.redhat.com/documentation/en-us/net/6.0) | [@omajid](https://github.com/omajid) |
| [Ubuntu](https://canonical.com/blog/install-dotnet-on-ubuntu) | [Default](https://packages.ubuntu.com/search?suite=default&section=all&arch=any&keywords=dotnet&searchon=names)<br>[Personal Package Archives](https://launchpad.net/ubuntu/+ppas?name_filter=dotnet) | [@mirespace](https://github.com/mirespace) |


## Support

.NET Source-Build is supported on the oldest available .NET SDK feature update for each major release, and on Linux only.
Expand Down

0 comments on commit 86da5e1

Please sign in to comment.