|
| 1 | +# Cross-Building |
| 2 | + |
| 3 | +Cross-building is the process of building .NET on a host machine for a target |
| 4 | +OS and/or CPU architecture that differs from the host. .NET supports many |
| 5 | +cross-build scenarios across different platforms — for example, building |
| 6 | +`windows-arm64` on a `windows-x64` host, `browser-wasm` on Linux or Windows, |
| 7 | +`android-arm64` on Linux, or `osx-arm64` on `osx-x64`. Each scenario has its |
| 8 | +own toolchain requirements. |
| 9 | + |
| 10 | +## ROOTFS_DIR-Based Cross-Builds |
| 11 | + |
| 12 | +For certain Linux and Unix targets (e.g. `linux-arm64`, `freebsd-x64`, `haiku-x64`), |
| 13 | +.NET uses a **sysroot** — a self-contained root filesystem for the target platform |
| 14 | +that contains the headers and libraries needed to compile and link code for that |
| 15 | +target. The path to the sysroot is provided via the `ROOTFS_DIR` environment |
| 16 | +variable. |
| 17 | + |
| 18 | +Cross-build container images provided by the .NET team |
| 19 | +(see [dotnet-buildtools-prereqs-docker](https://github.com/dotnet/dotnet-buildtools-prereqs-docker)) |
| 20 | +include a pre-configured sysroot and set `ROOTFS_DIR` to its location. |
| 21 | + |
| 22 | +For these ROOTFS_DIR-based cross builds, `/p:CrossBuild=true` is part of the build model. It is |
| 23 | +**automatically inferred** when the host and target OS/architecture differ (e.g. building |
| 24 | +`linux-arm64` or `freebsd-x64` on a `linux-x64` host), but must be provided explicitly |
| 25 | +when they are the same and a foreign sysroot is used. |
| 26 | + |
| 27 | +## Supported Cross-Build Scenarios |
| 28 | + |
| 29 | +The following table summarizes common .NET cross-build scenarios and whether they |
| 30 | +use a `ROOTFS_DIR`-based approach and whether `CrossBuild=true` needs to be |
| 31 | +explicitly provided: |
| 32 | + |
| 33 | +| Host → Target | ROOTFS_DIR-based? | CrossBuild inferred automatically? | |
| 34 | +|---|---|---| |
| 35 | +| linux-x64 → android-arm64 | No | N/A | |
| 36 | +| linux-x64 → browser-wasm | No | N/A | |
| 37 | +| windows-x64 → browser-wasm | No | N/A | |
| 38 | +| windows-x64 → windows-arm64 | No | N/A | |
| 39 | +| osx-x64 → osx-arm64 | No | N/A | |
| 40 | +| osx-arm64 → osx-x64 | No | N/A | |
| 41 | +| osx-arm64 → ios-arm64 | No | N/A | |
| 42 | +| osx-arm64 → tvos-arm64 | No | N/A | |
| 43 | +| android-x64 → android-arm64 | No | N/A | |
| 44 | +| linux-x64 → freebsd-x64 | Yes | Yes | |
| 45 | +| linux-x64 → freebsd-arm64 | Yes | Yes | |
| 46 | +| linux-x64 → linux-arm64 | Yes | Yes | |
| 47 | +| linux-x64 → haiku-x64 | Yes | Yes | |
| 48 | +| linux-arm64 → haiku-arm64 | Yes | Yes | |
| 49 | +| linux-x64 → linux-x64 (foreign ROOTFS) | Yes | **No** | |
| 50 | +| linux-arm64 → linux-arm64 (foreign ROOTFS) | Yes | **No** | |
| 51 | + |
| 52 | +## Explicitly Providing `/p:CrossBuild=true` |
| 53 | + |
| 54 | +The only case where `/p:CrossBuild=true` must be explicitly passed is when the |
| 55 | +host and target OS/architecture are the **same**, but you are still performing a |
| 56 | +ROOTFS_DIR-based build using a foreign sysroot. This happens when using a |
| 57 | +cross-build container image to target a specific Linux distribution with a |
| 58 | +dedicated sysroot (e.g. building `linux-x64` inside an |
| 59 | +`azurelinux-3.0-net10.0-cross-amd64` container with `ROOTFS_DIR=/crossrootfs/x64`). |
| 60 | + |
| 61 | +Without `/p:CrossBuild=true` in this scenario, the build will not use the sysroot |
| 62 | +when searching for native dependencies such as OpenSSL and will fail. |
| 63 | + |
| 64 | +### Example |
| 65 | + |
| 66 | +```bash |
| 67 | +docker run \ |
| 68 | + --rm \ |
| 69 | + --volume /path/to/dotnet:/dotnet \ |
| 70 | + --workdir /dotnet \ |
| 71 | + --env ROOTFS_DIR=/crossrootfs/x64 \ |
| 72 | + mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-net10.0-cross-amd64 \ |
| 73 | + ./build.sh \ |
| 74 | + --clean-while-building \ |
| 75 | + --source-only \ |
| 76 | + --arch x64 \ |
| 77 | + --os linux \ |
| 78 | + /p:CrossBuild=true |
| 79 | +``` |
0 commit comments