diff --git a/.github/workflows/_build.yml b/.github/workflows/_build.yml index f1851b33..116051be 100644 --- a/.github/workflows/_build.yml +++ b/.github/workflows/_build.yml @@ -9,10 +9,19 @@ on: jobs: build: - name: Build packages + name: Build packages [${{ matrix.host.platform }}] if: inputs.enabled - runs-on: brioche-dev-builder-runner - timeout-minutes: 720 + strategy: + fail-fast: false + matrix: + host: + - platform: x86_64-linux + runs-on: brioche-dev-builder-runner + - platform: aarch64-linux + runs-on: brioche-dev-builder-runner-aarch64 + + runs-on: ${{ matrix.host.runs-on }} + timeout-minutes: 1440 steps: - name: Install system packages run: | @@ -24,9 +33,11 @@ jobs: - name: Install Brioche run: | mkdir -p ~/.local/bin - curl -L https://development-content.brioche.dev/github.com/brioche-dev/brioche/branches/main/x86_64-linux/brioche -o ~/.local/bin/brioche + curl -L https://development-content.brioche.dev/github.com/brioche-dev/brioche/branches/main/$PLATFORM/brioche -o ~/.local/bin/brioche chmod +x ~/.local/bin/brioche echo "$HOME/.local/bin" >> $GITHUB_PATH + env: + PLATFORM: ${{ matrix.host.platform }} - name: Build packages run: | @@ -36,11 +47,16 @@ jobs: for package in "${packages[@]}"; do label="$package ($n / ${#packages[@]})" ((n++)) - echo "::group::$label" - brioche build -p "$package" --sync --locked --display plain-reduced - echo "::endgroup::" + if grep -q "@brioche-packages skip-platform $PLATFORM" "$package/project.bri"; then + echo "$label: skipping (does not support $PLATFORM)" + else + echo "::group::$label" + brioche build -p "$package" --sync --locked --display plain-reduced + echo "::endgroup::" + fi done env: + PLATFORM: ${{ matrix.host.platform }} BRIOCHE_REGISTRY_PASSWORD: ${{ secrets.BRIOCHE_REGISTRY_PASSWORD }} BRIOCHE_CACHE_URL: ${{ vars.BRIOCHE_CACHE_URL }} AWS_ACCESS_KEY_ID: ${{ secrets.CACHE_AWS_ACCESS_KEY_ID }} @@ -60,9 +76,13 @@ jobs: ((n++)) if grep -q 'export.*test' "$package/project.bri"; then - echo "::group::$label" - brioche build -p "$package" -e test --sync --locked - echo "::endgroup::" + if grep -q "@brioche-packages skip-platform $PLATFORM" "$package/project.bri"; then + echo "$label: skipping (does not support $PLATFORM)" + else + echo "::group::$label" + brioche build -p "$package" -e test --sync --locked + echo "::endgroup::" + fi else echo "$label: no tests found" fi @@ -89,19 +109,30 @@ jobs: if: failure() run: | process_events=(~/.local/share/brioche/process-temp/*/events.bin.zst) - process_event="${process_events[0]}" - if [ -f "$process_event" ]; then + for process_event in "${process_events[@]}"; do + echo "::group::$process_event" + truncated_line_count="$(brioche jobs logs "$process_event" --limit 200 | wc -l)" - if [ "$truncated_line_count" -gt 190 ]; then - # Looks like the output might be long, so show the first 80 - # lines and the last 80 lines + if [ "$truncated_line_count" -gt 1200 ]; then + # Looks like the output might be long, so show the first 500 + # lines and the last 500 lines - brioche jobs logs "$process_event" --limit 80 | head -n80 + brioche jobs logs "$process_event" --limit 500 | head -n500 echo "..." - brioche jobs logs "$process_event" | tail -n80 + brioche jobs logs "$process_event" | tail -n500 else # Looks like the output might be short, so show the whole file brioche jobs logs "$process_event" fi - fi + + echo "::endgroup::" + done + + # Extra job that succeeds when all build jobs succeed (useful for PR requirements) + all-builds-passed: + name: All builds passed + needs: [build] + runs-on: ubuntu-24.04 + steps: + - run: ':' diff --git a/packages/bugstalker/project.bri b/packages/bugstalker/project.bri index 826024a4..d20ccdb3 100644 --- a/packages/bugstalker/project.bri +++ b/packages/bugstalker/project.bri @@ -2,6 +2,8 @@ import * as std from "std"; import libunwind from "libunwind"; import { cargoBuild } from "rust"; +// Currently, BugStalker only support x86-64 Linux +// @brioche-packages skip-platform aarch64-linux export const project = { name: "bugstalker", version: "0.3.1", @@ -14,6 +16,11 @@ const source = Brioche.gitCheckout({ }); export default function bugstalker(): std.Recipe { + std.assert( + std.CURRENT_PLATFORM === "x86_64-linux", + `BugStalker does not currently support the platform '${std.CURRENT_PLATFORM}'`, + ); + return cargoBuild({ source, runnable: "bin/bs", diff --git a/packages/gitui/project.bri b/packages/gitui/project.bri index e57955e9..99c05775 100644 --- a/packages/gitui/project.bri +++ b/packages/gitui/project.bri @@ -12,7 +12,11 @@ export const project = { const source = Brioche.gitCheckout({ repository: project.repository, ref: `v${project.version}`, -}); +}) + // Remove upstream's custom Cargo `config.toml`, which overrides the linker + // for various targets (for cross-compilation). This can interfere with + // our default working linker configuration. + .remove(".cargo/config.toml"); export default function gitui(): std.Recipe { return cargoBuild({ diff --git a/packages/go/brioche.lock b/packages/go/brioche.lock index 221ed535..572e6232 100644 --- a/packages/go/brioche.lock +++ b/packages/go/brioche.lock @@ -4,6 +4,10 @@ "https://go.dev/dl/go1.24.4.linux-amd64.tar.gz": { "type": "sha256", "value": "77e5da33bb72aeaef1ba4418b6fe511bc4d041873cbf82e5aa6318740df98717" + }, + "https://go.dev/dl/go1.24.4.linux-arm64.tar.gz": { + "type": "sha256", + "value": "d5501ee5aca0f258d5fe9bfaed401958445014495dc115f202d43d5210b45241" } } } diff --git a/packages/go/project.bri b/packages/go/project.bri index a9ea3702..cc3c0c2c 100644 --- a/packages/go/project.bri +++ b/packages/go/project.bri @@ -6,11 +6,26 @@ export const project = { version: "1.24.4", }; -const source = Brioche.download( - `https://go.dev/dl/go${project.version}.linux-amd64.tar.gz`, -) - .unarchive("tar", "gzip") - .peel(); +function goPrebuilt(): std.Recipe { + switch (std.CURRENT_PLATFORM) { + case "x86_64-linux": + return Brioche.download( + `https://go.dev/dl/go${project.version}.linux-amd64.tar.gz`, + ) + .unarchive("tar", "gzip") + .peel(); + case "aarch64-linux": + return Brioche.download( + `https://go.dev/dl/go${project.version}.linux-arm64.tar.gz`, + ) + .unarchive("tar", "gzip") + .peel(); + default: + throw new Error( + `The platform '${std.CURRENT_PLATFORM}' is currently not supported by this version of the go package`, + ); + } +} /** * The Go programming language. @@ -27,7 +42,7 @@ const source = Brioche.download( export default function go(): std.Recipe { return std .directory({ - go: source, + go: goPrebuilt(), bin: std.directory({ go: std.symlink({ target: "../go/bin/go" }), gofmt: std.symlink({ target: "../go/bin/gofmt" }), diff --git a/packages/linux/project.bri b/packages/linux/project.bri index 6a6f4f40..0126341d 100644 --- a/packages/linux/project.bri +++ b/packages/linux/project.bri @@ -1,6 +1,7 @@ import * as std from "std"; import kmod from "kmod"; import openssl from "openssl"; +import python from "python"; import nushell from "nushell"; export const project = { @@ -107,7 +108,14 @@ export default function linux( make modules_install ` .workDir(source) - .dependencies(...dependencies, openssl, kmod, ldWrapper, std.toolchain) + .dependencies( + ...dependencies, + kmod, + openssl, + python, + ldWrapper, + std.toolchain, + ) .env({ INSTALL_MOD_PATH: std.outputPath, diff --git a/packages/llvm/project.bri b/packages/llvm/project.bri index 7f5327ba..242e2caf 100644 --- a/packages/llvm/project.bri +++ b/packages/llvm/project.bri @@ -22,7 +22,11 @@ export default function llvm(): std.Recipe { CMAKE_BUILD_TYPE: "Release", }, env: { - CMAKE_BUILD_PARALLEL_LEVEL: "16", + // HACK: Building LLVM can use A LOT of memory, especially when building + // in parallel. These values are tuned based on the CI runners currently + // in use in the `brioche-packages` repo. + CMAKE_BUILD_PARALLEL_LEVEL: + std.CURRENT_PLATFORM === "x86_64-linux" ? "16" : "8", }, dependencies: [std.toolchain, python], }).pipe((recipe) => diff --git a/packages/nodejs/brioche.lock b/packages/nodejs/brioche.lock index ecc93772..da000d3c 100644 --- a/packages/nodejs/brioche.lock +++ b/packages/nodejs/brioche.lock @@ -1,6 +1,10 @@ { "dependencies": {}, "downloads": { + "https://nodejs.org/dist/v24.2.0/node-v24.2.0-linux-arm64.tar.xz": { + "type": "sha256", + "value": "cd4f25d2f05d0750159a209915267af6f9970ade4702a8810641120404bf54ee" + }, "https://nodejs.org/dist/v24.2.0/node-v24.2.0-linux-x64.tar.xz": { "type": "sha256", "value": "91a0794f4dbc94bc4a9296139ed9101de21234982bae2b325e37ebd3462273e5" diff --git a/packages/nodejs/project.bri b/packages/nodejs/project.bri index 43738ae2..75d97665 100644 --- a/packages/nodejs/project.bri +++ b/packages/nodejs/project.bri @@ -8,6 +8,27 @@ export const project = { version: "24.2.0", }; +function nodejsPrebuilt(): std.Recipe { + switch (std.CURRENT_PLATFORM) { + case "x86_64-linux": + return Brioche.download( + `https://nodejs.org/dist/v${project.version}/node-v${project.version}-linux-x64.tar.xz`, + ) + .unarchive("tar", "xz") + .peel(); + case "aarch64-linux": + return Brioche.download( + `https://nodejs.org/dist/v${project.version}/node-v${project.version}-linux-arm64.tar.xz`, + ) + .unarchive("tar", "xz") + .peel(); + default: + throw new Error( + `The platform '${std.CURRENT_PLATFORM}' is currently not supported by this version of the nodejs package`, + ); + } +} + /** * The main Node.js recipe. Returns a recipe containing the following: * @@ -15,17 +36,13 @@ export const project = { * - `bin/npm` */ export default function nodejs(): std.Recipe { - let node = Brioche.download( - `https://nodejs.org/dist/v${project.version}/node-v${project.version}-linux-x64.tar.xz`, - ) - .unarchive("tar", "xz") - .peel(); - - node = std.autopack(node, { - globs: ["bin/**"], - }); - - return std.withRunnableLink(node, "bin/node"); + return nodejsPrebuilt() + .pipe((node) => + std.autopack(node, { + globs: ["bin/**"], + }), + ) + .pipe((node) => std.withRunnableLink(node, "bin/node")); } export async function test(): Promise> { diff --git a/packages/proot/project.bri b/packages/proot/project.bri index 75bd900f..65b9e3bd 100644 --- a/packages/proot/project.bri +++ b/packages/proot/project.bri @@ -27,7 +27,19 @@ const source = std.recipe(() => { export default function proot(): std.Recipe { return std.runBash` - BRIOCHE_LD_AUTOPACK=false make -C src loader.elf loader-m32.elf build.h + case "$(uname -m)" in + x86_64) + BRIOCHE_LD_AUTOPACK=false make -C src loader.elf loader-m32.elf build.h + ;; + aarch64) + BRIOCHE_LD_AUTOPACK=false make -C src loader.elf build.h + ;; + *) + echo "Unhandled architecture for PRoot package" + exit 1 + ;; + esac + make -C src proot care make -C src install PREFIX="$BRIOCHE_OUTPUT" ` diff --git a/packages/rust/project.bri b/packages/rust/project.bri index e5737991..edd60386 100644 --- a/packages/rust/project.bri +++ b/packages/rust/project.bri @@ -57,7 +57,7 @@ export default async function rust(): Promise> { throw new Error(`Rustup package ${pkgName} not found`); } - const pkgTarget = pkg.target["x86_64-unknown-linux-gnu"]; + const pkgTarget = pkg.target[targetTriple()]; if (pkgTarget?.available !== true) { continue; } @@ -450,3 +450,16 @@ export function vendorCrate( return crate; } + +function targetTriple(): string { + switch (std.CURRENT_PLATFORM) { + case "x86_64-linux": + return "x86_64-unknown-linux-gnu"; + case "aarch64-linux": + return "aarch64-unknown-linux-gnu"; + default: + throw new Error( + `The platform '${std.CURRENT_PLATFORM}' is currently not supported by this version of the rust package`, + ); + } +} diff --git a/packages/std/brioche.lock b/packages/std/brioche.lock index a303b182..6fee5a09 100644 --- a/packages/std/brioche.lock +++ b/packages/std/brioche.lock @@ -5,26 +5,46 @@ "type": "sha256", "value": "f4a245b94124b377d8b49646bf421f9155d36aa7614b6ebf83705d3ffc76eaad" }, + "https://development-content.brioche.dev/github.com/brioche-dev/brioche-bootstrap/99ab9787d5ee27eb613227131e23d2c651de318a/aarch64-linux/brioche-bootstrap.tar.zstd": { + "type": "sha256", + "value": "dde2f006b119a8154dc6c22a63f064e67fd880bb42d74f64730be7325fde4fbb" + }, "https://development-content.brioche.dev/github.com/brioche-dev/brioche-bootstrap/99ab9787d5ee27eb613227131e23d2c651de318a/x86_64-linux/brioche-bootstrap.tar.zstd": { "type": "sha256", "value": "0cabcd0a074e08ac132281f711f884777b47def17fbeff2a82ba011836b83d11" }, - "https://development-content.brioche.dev/github.com/brioche-dev/brioche-runtime-utils/commits/bd8af11dcd61855df38cc12401f5ddc4ff5466e0/x86_64-linux/brioche-runtime-utils.tar.zstd": { + "https://development-content.brioche.dev/github.com/brioche-dev/brioche-runtime-utils/commits/fa9ce0565ea067c84216838073c22176bb4a6399/aarch64-linux/brioche-runtime-utils.tar.zstd": { "type": "sha256", - "value": "ca2bdc7d2bb6184036e5a3b247935a25979d7ec5381dd5b94058a0a50cc6b870" + "value": "3a5aef8493d087ff42bc178c5f56a77867d11e2429556dfe6768257248fd74b6" + }, + "https://development-content.brioche.dev/github.com/brioche-dev/brioche-runtime-utils/commits/fa9ce0565ea067c84216838073c22176bb4a6399/x86_64-linux/brioche-runtime-utils.tar.zstd": { + "type": "sha256", + "value": "1ea74d7c2ea1e806876bac4cc3c210f15197195f7c9a2943a2fced35d55a3c43" }, "https://development-content.brioche.dev/github.com/tangramdotdev/bootstrap/2022-10-31/busybox_amd64_linux.tar.xz": { "type": "sha256", "value": "e2e9ae181e115e155158cb9031687d943b0847d8058a4c28454194d835478be6" }, + "https://development-content.brioche.dev/github.com/tangramdotdev/bootstrap/2022-10-31/busybox_arm64_linux.tar.xz": { + "type": "sha256", + "value": "02308fd5aaea492d730f390b8122a0d518a13df7fbbeb46568497cc6ef93bc81" + }, "https://development-content.brioche.dev/github.com/tangramdotdev/bootstrap/2023-07-06/toolchain_amd64_linux.tar.zstd": { "type": "sha256", "value": "27416708f7ee8cd0c5d408010192705b40c914647fd0d80f00c2194795828cd6" }, + "https://development-content.brioche.dev/github.com/tangramdotdev/bootstrap/2023-07-06/toolchain_arm64_linux.tar.zstd": { + "type": "sha256", + "value": "823c4f9687aaee22f4115845063c84c62fccb75c081c2e50c0b78d459857b4fd" + }, "https://development-content.brioche.dev/github.com/tangramdotdev/bootstrap/2023-07-06/utils_amd64_linux.tar.zstd": { "type": "sha256", "value": "eb29ea059fcd9ca457841f5c79151721a74761a31610d694bce61a62f4de6d33" }, + "https://development-content.brioche.dev/github.com/tangramdotdev/bootstrap/2023-07-06/utils_arm64_linux.tar.zstd": { + "type": "sha256", + "value": "36c0dcfb02e61a07f4654e1ca6047cdefb17ce1f2e37fcb2ba5dc20695b3e273" + }, "https://development-content.brioche.dev/linuxfromscratch.org/v12.0/packages/Python-3.11.4.tar.xz": { "type": "sha256", "value": "2f0e409df2ab57aa9fc4cbddfb976af44e4e55bf6f619eee6bc5c2297264a7f6" diff --git a/packages/std/core/index.bri b/packages/std/core/index.bri index cbe43e06..486ea7ac 100644 --- a/packages/std/core/index.bri +++ b/packages/std/core/index.bri @@ -11,6 +11,7 @@ export { } from "./utils.bri"; export { BRIOCHE_VERSION, + CURRENT_PLATFORM, utf8Encode, utf8Decode, tickEncode, @@ -19,6 +20,7 @@ export { bstringToBytes, bstringToString, type BString, + type Platform, } from "./runtime.bri"; import "./console.bri"; diff --git a/packages/std/core/recipes/process.bri b/packages/std/core/recipes/process.bri index ad6b8473..a25a7a4b 100644 --- a/packages/std/core/recipes/process.bri +++ b/packages/std/core/recipes/process.bri @@ -193,7 +193,7 @@ export function process(options: ProcessOptions): Process { env: Object.fromEntries(envPairsSerialized), currentDir: currentDirSerialized ?? undefined, dependencies: dependenciesSerialized, - platform: "x86_64-linux", + platform: runtime.CURRENT_PLATFORM, workDir: workDirSerialized ?? { type: "create_directory", entries: {}, diff --git a/packages/std/core/runtime.bri b/packages/std/core/runtime.bri index 36f87bd5..624075f6 100644 --- a/packages/std/core/runtime.bri +++ b/packages/std/core/runtime.bri @@ -11,6 +11,18 @@ function getBriocheVersion(): string { export const BRIOCHE_VERSION = getBriocheVersion(); +function getCurrentPlatform(): Platform { + const { op_brioche_current_platform } = (globalThis as any).Deno.core.ops; + + if (op_brioche_current_platform === undefined) { + return "x86_64-linux"; + } + + return op_brioche_current_platform(); +} + +export const CURRENT_PLATFORM = getCurrentPlatform(); + export async function bakeAll(recipes: []): Promise<[]>; export async function bakeAll(recipes: [Recipe]): Promise<[Artifact]>; export async function bakeAll( diff --git a/packages/std/runtime_utils.bri b/packages/std/runtime_utils.bri index 729de89f..61fe6c7a 100644 --- a/packages/std/runtime_utils.bri +++ b/packages/std/runtime_utils.bri @@ -1,9 +1,25 @@ import * as std from "/core"; +const PLATFORM_RUNTIME_UTILS: Record< + std.Platform, + std.Recipe | undefined +> = { + "x86_64-linux": Brioche.download( + "https://development-content.brioche.dev/github.com/brioche-dev/brioche-runtime-utils/commits/fa9ce0565ea067c84216838073c22176bb4a6399/x86_64-linux/brioche-runtime-utils.tar.zstd", + ).unarchive("tar", "zstd"), + "aarch64-linux": Brioche.download( + "https://development-content.brioche.dev/github.com/brioche-dev/brioche-runtime-utils/commits/fa9ce0565ea067c84216838073c22176bb4a6399/aarch64-linux/brioche-runtime-utils.tar.zstd", + ).unarchive("tar", "zstd"), +}; + export function runtimeUtils(): std.Recipe { - return Brioche.download( - "https://development-content.brioche.dev/github.com/brioche-dev/brioche-runtime-utils/commits/bd8af11dcd61855df38cc12401f5ddc4ff5466e0/x86_64-linux/brioche-runtime-utils.tar.zstd", - ).unarchive("tar", "zstd"); + const platformRuntimeUtils = PLATFORM_RUNTIME_UTILS[std.CURRENT_PLATFORM]; + std.assert( + platformRuntimeUtils != null, + `The platform '${std.CURRENT_PLATFORM}' is not handled by this version of std`, + ); + + return platformRuntimeUtils; } interface RunnableData { diff --git a/packages/std/toolchain/native/binutils.bri b/packages/std/toolchain/native/binutils.bri index 68ba3e9e..0b6e8d12 100644 --- a/packages/std/toolchain/native/binutils.bri +++ b/packages/std/toolchain/native/binutils.bri @@ -1,10 +1,12 @@ import * as std from "/core"; -import stage2 from "/toolchain/stage2"; import { useBriocheLd } from "/toolchain/utils.bri"; +import { currentPlatformInfo } from "/toolchain/stage0"; +import stage2 from "/toolchain/stage2"; import flex from "./flex.bri"; import zlib from "./zlib.bri"; export default std.memo((): std.Recipe => { + const platformInfo = currentPlatformInfo(); const source = Brioche.download( "https://development-content.brioche.dev/linuxfromscratch.org/v12.0/packages/binutils-2.41.tar.xz", ) @@ -50,7 +52,7 @@ export default std.memo((): std.Recipe => { binutils = useBriocheLd(binutils, { ldPaths: ["bin/ld.bfd", "bin/ld.gold"], interpreterPaths: { - "lib64/ld-linux-x86-64.so.2": "lib64/ld-linux-x86-64.so.2", + [platformInfo.dynamicLinkerPath]: platformInfo.dynamicLinkerPath, }, }); diff --git a/packages/std/toolchain/native/gcc.bri b/packages/std/toolchain/native/gcc.bri index 898dfe23..449589ba 100644 --- a/packages/std/toolchain/native/gcc.bri +++ b/packages/std/toolchain/native/gcc.bri @@ -1,5 +1,6 @@ import * as std from "/core"; import { useBriocheCc } from "../utils.bri"; +import { currentPlatformInfo } from "../stage0"; import linuxHeaders from "./linux_headers.bri"; import stage2 from "/toolchain/stage2"; import glibc from "./glibc.bri"; @@ -11,6 +12,7 @@ import mpc from "./mpc.bri"; import libxcrypt from "./libxcrypt.bri"; export default std.memo((): std.Recipe => { + const platformInfo = currentPlatformInfo(); let source = Brioche.download( "https://development-content.brioche.dev/linuxfromscratch.org/v12.0/packages/gcc-13.2.0.tar.xz", ) @@ -92,7 +94,7 @@ export default std.memo((): std.Recipe => { ], env: { PATH: std.tpl`${buildSysroot}/bin:${stage2}/bin`, - CPPFLAGS: std.tpl`-I${zlib}/include -I${gmp}/include -I${mpfr}/include -I${mpc}/include -isystem ${stage2}/usr/lib/gcc/x86_64-lfs-linux-gnu/13.2.0/include -isystem ${buildSysroot}/include -isystem ${buildSysroot}/usr/include`, + CPPFLAGS: std.tpl`-I${zlib}/include -I${gmp}/include -I${mpfr}/include -I${mpc}/include -isystem ${stage2}/usr/lib/gcc/${platformInfo.arch}-lfs-linux-gnu/13.2.0/include -isystem ${buildSysroot}/include -isystem ${buildSysroot}/usr/include`, LDFLAGS: std.tpl`-L${zlib}/lib -L${gmp}/lib -L${mpfr}/lib -L${mpc}/lib -L${buildSysroot}/lib -L${buildSysroot}/lib64 -lm --sysroot=${buildSysroot}`, buildSysroot, gmp: gmp(), @@ -105,10 +107,10 @@ export default std.memo((): std.Recipe => { gcc = useBriocheCc(gcc, { ccPaths: [ - "bin/x86_64-pc-linux-gnu-c++", - "bin/x86_64-pc-linux-gnu-g++", - "bin/x86_64-pc-linux-gnu-gcc", - "bin/x86_64-pc-linux-gnu-gcc-13.2.0", + `bin/${toolchainTriple()}-c++`, + `bin/${toolchainTriple()}-g++`, + `bin/${toolchainTriple()}-gcc`, + `bin/${toolchainTriple()}-gcc-13.2.0`, "bin/c++", "bin/g++", "bin/gcc", @@ -118,3 +120,16 @@ export default std.memo((): std.Recipe => { return gcc; }); + +function toolchainTriple(): string { + switch (std.CURRENT_PLATFORM) { + case "x86_64-linux": + return "x86_64-pc-linux-gnu"; + case "aarch64-linux": + return "aarch64-unknown-linux-gnu"; + default: + throw new Error( + `The platform '${std.CURRENT_PLATFORM}' is not handled by this version of std`, + ); + } +} diff --git a/packages/std/toolchain/native/glibc.bri b/packages/std/toolchain/native/glibc.bri index 1d1a5ecc..75715a71 100644 --- a/packages/std/toolchain/native/glibc.bri +++ b/packages/std/toolchain/native/glibc.bri @@ -1,7 +1,9 @@ import * as std from "/core"; +import { currentPlatformInfo } from "/toolchain/stage0"; import stage2 from "/toolchain/stage2"; export default std.memo((): std.Recipe => { + const platformInfo = currentPlatformInfo(); let source = Brioche.download( "https://development-content.brioche.dev/linuxfromscratch.org/v12.0/packages/glibc-2.38.tar.xz", ) @@ -68,20 +70,22 @@ export default std.memo((): std.Recipe => { ], env: { PATH: std.tpl`${stage2}/bin`, - stage2: stage2(), + stage2, }, workDir: source, }) .toDirectory(); - glibc = glibc.insert( - "lib64", - std.directory({ - "ld-linux-x86-64.so.2": std.symlink({ - target: "../lib/ld-linux-x86-64.so.2", + if (platformInfo.arch === "x86_64") { + glibc = glibc.insert( + "lib64", + std.directory({ + "ld-linux-x86-64.so.2": std.symlink({ + target: "../lib/ld-linux-x86-64.so.2", + }), }), - }), - ); + ); + } return glibc; }); diff --git a/packages/std/toolchain/native/index.bri b/packages/std/toolchain/native/index.bri index 34110547..d2d27546 100644 --- a/packages/std/toolchain/native/index.bri +++ b/packages/std/toolchain/native/index.bri @@ -62,64 +62,64 @@ import patchelf from "./patchelf.bri"; export { bash }; const toolPackages = [ - zlib(), - bzip2(), - xz(), - zstd(), - file(), - bc(), - sed(), - grep(), - bash(), - coreutils(), - diffutils(), - gawk(), - findutils(), - gzip(), - make(), - patch(), - tar(), - which(), + zlib, + bzip2, + xz, + zstd, + file, + bc, + sed, + grep, + bash, + coreutils, + diffutils, + gawk, + findutils, + gzip, + make, + patch, + tar, + which, ]; const toolchainOnlyPackages = [ - linuxHeaders(), - glibc(), - readline(), - m4(), - flex(), - binutils(), - gmp(), - mpfr(), - mpc(), - attr(), - acl(), - libxcrypt(), - gcc(), - pkgconf(), - ncurses(), - psmisc(), - gettext(), - bison(), - libtool(), - gdbm(), - gperf(), - expat(), - inetutils(), - less(), - perl(), - perlXmlParser(), - intltool(), - autoconf(), - automake(), - libelf(), - groff(), - libpipeline(), - texinfo(), - manDb(), - procpsNg(), - utilLinux(), - patchelf(), + linuxHeaders, + glibc, + readline, + m4, + flex, + binutils, + gmp, + mpfr, + mpc, + attr, + acl, + libxcrypt, + gcc, + pkgconf, + ncurses, + psmisc, + gettext, + bison, + libtool, + gdbm, + gperf, + expat, + inetutils, + less, + perl, + perlXmlParser, + intltool, + autoconf, + automake, + libelf, + groff, + libpipeline, + texinfo, + manDb, + procpsNg, + utilLinux, + patchelf, ]; /** diff --git a/packages/std/toolchain/stage0/index.bri b/packages/std/toolchain/stage0/index.bri index cf7fd67e..770913cd 100644 --- a/packages/std/toolchain/stage0/index.bri +++ b/packages/std/toolchain/stage0/index.bri @@ -1,6 +1,77 @@ import * as std from "/core"; import { runtimeUtils } from "../utils.bri"; +interface PlatformInfo { + bootstrapToolchain: std.Recipe; + bootstrapToolchainTargetTriple: string; + bootstrapToolchainDynamicLinkerName: string; + bootstrapUtils: std.Recipe; + bootstrapRootfs: std.Recipe; + bootstrapRootfsSystemToolchainPath: string; + busybox: std.Recipe; + libDir: string; + dynamicLinkerPath: string; + arch: string; + os: string; +} + +export const PLATFORM_INFO: Record = { + "x86_64-linux": { + bootstrapToolchain: Brioche.download( + "https://development-content.brioche.dev/github.com/tangramdotdev/bootstrap/2023-07-06/toolchain_amd64_linux.tar.zstd", + ).unarchive("tar", "zstd"), + bootstrapToolchainTargetTriple: "x86_64-linux-musl", + bootstrapToolchainDynamicLinkerName: "ld-musl-x86_64.so.1", + bootstrapUtils: Brioche.download( + "https://development-content.brioche.dev/github.com/tangramdotdev/bootstrap/2023-07-06/utils_amd64_linux.tar.zstd", + ).unarchive("tar", "zstd"), + bootstrapRootfs: Brioche.download( + "https://development-content.brioche.dev/github.com/brioche-dev/brioche-bootstrap/99ab9787d5ee27eb613227131e23d2c651de318a/x86_64-linux/brioche-bootstrap.tar.zstd", + ).unarchive("tar", "zstd"), + bootstrapRootfsSystemToolchainPath: "/usr/lib/gcc/x86_64-linux-gnu/12", + busybox: Brioche.download( + "https://development-content.brioche.dev/github.com/tangramdotdev/bootstrap/2022-10-31/busybox_amd64_linux.tar.xz", + ).unarchive("tar", "xz"), + libDir: "lib64", + dynamicLinkerPath: "lib64/ld-linux-x86-64.so.2", + arch: "x86_64", + os: "linux", + }, + "aarch64-linux": { + bootstrapToolchain: Brioche.download( + "https://development-content.brioche.dev/github.com/tangramdotdev/bootstrap/2023-07-06/toolchain_arm64_linux.tar.zstd", + ).unarchive("tar", "zstd"), + bootstrapToolchainTargetTriple: "aarch64-linux-musl", + bootstrapToolchainDynamicLinkerName: "ld-musl-aarch64.so.1", + bootstrapUtils: Brioche.download( + "https://development-content.brioche.dev/github.com/tangramdotdev/bootstrap/2023-07-06/utils_arm64_linux.tar.zstd", + ).unarchive("tar", "zstd"), + bootstrapRootfs: Brioche.download( + "https://development-content.brioche.dev/github.com/brioche-dev/brioche-bootstrap/99ab9787d5ee27eb613227131e23d2c651de318a/aarch64-linux/brioche-bootstrap.tar.zstd", + ).unarchive("tar", "zstd"), + bootstrapRootfsSystemToolchainPath: "/usr/lib/gcc/aarch64-linux-gnu/12", + busybox: Brioche.download( + "https://development-content.brioche.dev/github.com/tangramdotdev/bootstrap/2022-10-31/busybox_arm64_linux.tar.xz", + ) + .unarchive("tar", "xz") + .peel(1), + libDir: "lib", + dynamicLinkerPath: "lib/ld-linux-aarch64.so.1", + arch: "aarch64", + os: "linux", + }, +}; + +export function currentPlatformInfo(): PlatformInfo { + const platformInfo = PLATFORM_INFO[std.CURRENT_PLATFORM]; + std.assert( + platformInfo != null, + `The platform '${std.CURRENT_PLATFORM}' is not handled by this version of std`, + ); + + return platformInfo; +} + interface BootstrapRunOptions { script: string; env?: Record; @@ -11,14 +82,7 @@ interface BootstrapRunOptions { export function bootstrapRun( options: BootstrapRunOptions, ): std.Recipe { - const bootstrapRootfs = Brioche.download( - "https://development-content.brioche.dev/github.com/brioche-dev/brioche-bootstrap/99ab9787d5ee27eb613227131e23d2c651de318a/x86_64-linux/brioche-bootstrap.tar.zstd", - ).unarchive("tar", "zstd"); - - const busybox = Brioche.download( - "https://development-content.brioche.dev/github.com/tangramdotdev/bootstrap/2022-10-31/busybox_amd64_linux.tar.xz", - ).unarchive("tar", "xz"); - + const platformInfo = currentPlatformInfo(); const briocheLd = runtimeUtils().get("bin/brioche-ld"); const briochePacked = runtimeUtils().get("bin/brioche-packed-exec"); @@ -50,13 +114,13 @@ export function bootstrapRun( "$BUSYBOX/bin/busybox" mount --rbind "$BRIOCHE_OUTPUT" "$(pwd)/rootfs/$BRIOCHE_OUTPUT" "$BUSYBOX/bin/busybox" mount --rbind "$BRIOCHE_RESOURCE_DIR" "$(pwd)/rootfs/$BRIOCHE_RESOURCE_DIR" - "$BUSYBOX/bin/busybox" mkdir -p "$HOME/.local/libexec/brioche-toolchain/bin" "$HOME/.local/libexec/brioche-toolchain/libexec/brioche-ld/lib64" + "$BUSYBOX/bin/busybox" mkdir -p "$HOME/.local/libexec/brioche-toolchain/bin" "$HOME/.local/libexec/brioche-toolchain/libexec/brioche-ld/$lib_dir" "$BUSYBOX/bin/busybox" cp "$BRIOCHE_LD" "$HOME/.local/libexec/brioche-toolchain/bin/ld" "$BUSYBOX/bin/busybox" cp "$BRIOCHE_PACKED" "$HOME/.local/libexec/brioche-toolchain/libexec/brioche-ld/brioche-packed" "$BUSYBOX/bin/busybox" chmod +x "$HOME/.local/libexec/brioche-toolchain/bin/ld" "$HOME/.local/libexec/brioche-toolchain/libexec/brioche-ld/brioche-packed" "$BUSYBOX/bin/busybox" ln -s "/usr/bin/ld" "$HOME/.local/libexec/brioche-toolchain/libexec/brioche-ld/ld" - "$BUSYBOX/bin/busybox" ln -s "/lib64/ld-linux-x86-64.so.2" "$HOME/.local/libexec/brioche-toolchain/libexec/brioche-ld/lib64/" - "$BUSYBOX/bin/busybox" ln -s "ld" "$HOME/.local/libexec/brioche-toolchain/bin/x86_64-linux-gnu-ld" + "$BUSYBOX/bin/busybox" ln -s "/$dynamic_linker_path" "$HOME/.local/libexec/brioche-toolchain/libexec/brioche-ld/$lib_dir/" + "$BUSYBOX/bin/busybox" ln -s "ld" "$HOME/.local/libexec/brioche-toolchain/bin/$ld_name" export PATH="$HOME/.local/libexec/brioche-toolchain/bin\${PATH:+:$PATH}" @@ -67,19 +131,26 @@ export function bootstrapRun( `) .withPermissions({ executable: true }); + const ldName = `${platformInfo.arch}-${platformInfo.os}-gnu-ld`; return std .process({ - command: std.tpl`${busybox}/bin/busybox`, + command: std.tpl`${platformInfo.busybox}/bin/busybox`, args: ["unshare", "-Umfr", enterBootstrapChrootScript], env: { - BUSYBOX: busybox, + BUSYBOX: platformInfo.busybox, BRIOCHE_LD: briocheLd, BRIOCHE_PACKED: briochePacked, - SYSTEM_TOOLCHAIN_PATH: "/usr/lib/gcc/x86_64-linux-gnu/12", + SYSTEM_TOOLCHAIN_PATH: platformInfo.bootstrapRootfsSystemToolchainPath, + dynamic_linker_path: platformInfo.dynamicLinkerPath, + lib_dir: platformInfo.libDir, + ld_name: ldName, ...options.env, }, workDir: std.directory({ - rootfs: bootstrapRootfs.insert("bootstrap.sh", bootstrapScript), + rootfs: platformInfo.bootstrapRootfs.insert( + "bootstrap.sh", + bootstrapScript, + ), work: options.workDir ?? std.directory(), }), outputScaffold: options.outputScaffold, @@ -88,19 +159,17 @@ export function bootstrapRun( } export default async (): Promise => { - const utils = Brioche.download( - "https://development-content.brioche.dev/github.com/tangramdotdev/bootstrap/2023-07-06/utils_amd64_linux.tar.zstd", - ).unarchive("tar", "zstd"); - - const toolchain = Brioche.download( - "https://development-content.brioche.dev/github.com/tangramdotdev/bootstrap/2023-07-06/toolchain_amd64_linux.tar.zstd", - ).unarchive("tar", "zstd"); + const platformInfo = PLATFORM_INFO[std.CURRENT_PLATFORM]; + std.assert( + platformInfo != null, + `The platform '${std.CURRENT_PLATFORM}' is not handled by this version of std`, + ); const briocheLd = runtimeUtils().get("bin/brioche-ld"); const briochePacked = runtimeUtils().get("bin/brioche-packed-exec"); const briochePack = std.directory({ - "x86_64-linux-musl": std.directory({ + [platformInfo.bootstrapToolchainTargetTriple]: std.directory({ bin: std.directory({ "brioche-ld": briocheLd, }), @@ -109,8 +178,8 @@ export default async (): Promise => { ld: std.symlink({ target: "../../bin/system-ld" }), "brioche-packed": briochePacked, lib: std.directory({ - "ld-musl-x86_64.so.1": std.symlink({ - target: "../../../../lib/ld-musl-x86_64.so.1", + [platformInfo.bootstrapToolchainDynamicLinkerName]: std.symlink({ + target: `../../../../lib/${platformInfo.bootstrapToolchainDynamicLinkerName}`, }), }), }), @@ -118,17 +187,28 @@ export default async (): Promise => { }), }); - let stage0 = std.merge(utils, toolchain, briochePack); + let stage0 = std.merge( + platformInfo.bootstrapUtils, + platformInfo.bootstrapToolchain, + briochePack, + ); - const systemLd = stage0.get("x86_64-linux-musl/bin/ld"); - stage0 = stage0.insert("x86_64-linux-musl/bin/system-ld", systemLd); + const systemLd = stage0.get( + `${platformInfo.bootstrapToolchainTargetTriple}/bin/ld`, + ); + stage0 = stage0.insert( + `${platformInfo.bootstrapToolchainTargetTriple}/bin/system-ld`, + systemLd, + ); stage0 = stage0.insert( - "x86_64-linux-musl/bin/ld", + `${platformInfo.bootstrapToolchainTargetTriple}/bin/ld`, std.symlink({ target: "brioche-ld" }), ); stage0 = stage0.insert( "bin/ld", - std.symlink({ target: "../x86_64-linux-musl/bin/ld" }), + std.symlink({ + target: `../${platformInfo.bootstrapToolchainTargetTriple}/bin/ld`, + }), ); return stage0; diff --git a/packages/std/toolchain/stage1/1_01_binutils.bri b/packages/std/toolchain/stage1/1_01_binutils.bri index 041b3664..2130057b 100644 --- a/packages/std/toolchain/stage1/1_01_binutils.bri +++ b/packages/std/toolchain/stage1/1_01_binutils.bri @@ -1,5 +1,5 @@ import * as std from "/core"; -import { bootstrapRun } from "/toolchain/stage0"; +import { bootstrapRun, currentPlatformInfo } from "/toolchain/stage0"; const source = Brioche.download( "https://development-content.brioche.dev/linuxfromscratch.org/v12.0/packages/binutils-2.41.tar.xz", @@ -26,7 +26,7 @@ export default std.memo(async (): Promise> => { `, env: { BRIOCHE_OUTPUT: std.outputPath, - TARGET: "x86_64-lfs-linux-gnu", + TARGET: `${currentPlatformInfo().arch}-lfs-linux-gnu`, }, workDir: source, }); diff --git a/packages/std/toolchain/stage1/1_02_gcc.bri b/packages/std/toolchain/stage1/1_02_gcc.bri index d04cb9e0..988d0629 100644 --- a/packages/std/toolchain/stage1/1_02_gcc.bri +++ b/packages/std/toolchain/stage1/1_02_gcc.bri @@ -1,5 +1,5 @@ import * as std from "/core"; -import { bootstrapRun } from "/toolchain/stage0"; +import { bootstrapRun, currentPlatformInfo } from "/toolchain/stage0"; import binutils from "./1_01_binutils.bri"; export default std.memo(async (): Promise> => { @@ -75,7 +75,7 @@ export default std.memo(async (): Promise> => { `, env: { BRIOCHE_OUTPUT: std.outputPath, - TARGET: "x86_64-lfs-linux-gnu", + TARGET: `${currentPlatformInfo().arch}-lfs-linux-gnu`, stage1, }, workDir: source, diff --git a/packages/std/toolchain/stage1/1_03_linux_headers.bri b/packages/std/toolchain/stage1/1_03_linux_headers.bri index ded0dfbf..21551352 100644 --- a/packages/std/toolchain/stage1/1_03_linux_headers.bri +++ b/packages/std/toolchain/stage1/1_03_linux_headers.bri @@ -1,5 +1,5 @@ import * as std from "/core"; -import { bootstrapRun } from "/toolchain/stage0"; +import { bootstrapRun, currentPlatformInfo } from "/toolchain/stage0"; export default std.memo(async (): Promise> => { const source = Brioche.download( @@ -22,7 +22,7 @@ export default std.memo(async (): Promise> => { `, env: { BRIOCHE_OUTPUT: std.outputPath, - TARGET: "x86_64-lfs-linux-gnu", + TARGET: `${currentPlatformInfo().arch}-lfs-linux-gnu`, }, workDir: source, }); diff --git a/packages/std/toolchain/stage1/1_04_glibc.bri b/packages/std/toolchain/stage1/1_04_glibc.bri index 472d9639..77775053 100644 --- a/packages/std/toolchain/stage1/1_04_glibc.bri +++ b/packages/std/toolchain/stage1/1_04_glibc.bri @@ -1,11 +1,12 @@ import * as std from "/core"; import { runtimeUtils } from "../utils.bri"; -import { bootstrapRun } from "/toolchain/stage0"; +import { bootstrapRun, currentPlatformInfo } from "/toolchain/stage0"; import binutils from "./1_01_binutils.bri"; import gcc from "./1_02_gcc.bri"; import linuxHeaders from "./1_03_linux_headers.bri"; export default std.memo((): std.Recipe => { + const platformInfo = currentPlatformInfo(); let source = Brioche.download( "https://development-content.brioche.dev/linuxfromscratch.org/v12.0/packages/glibc-2.38.tar.xz", ) @@ -68,8 +69,8 @@ export default std.memo((): std.Recipe => { `, env: { BRIOCHE_OUTPUT: std.outputPath, - TARGET: "x86_64-lfs-linux-gnu", - LD_LINUX: "/lib64/ld-linux-x86-64.so.2", + TARGET: `${platformInfo.arch}-lfs-linux-gnu`, + LD_LINUX: `/${platformInfo.dynamicLinkerPath}`, stage1, }, workDir: source, diff --git a/packages/std/toolchain/stage1/1_05_libstdcpp.bri b/packages/std/toolchain/stage1/1_05_libstdcpp.bri index 6fd6de4c..323024f1 100644 --- a/packages/std/toolchain/stage1/1_05_libstdcpp.bri +++ b/packages/std/toolchain/stage1/1_05_libstdcpp.bri @@ -1,5 +1,5 @@ import * as std from "/core"; -import { bootstrapRun } from "/toolchain/stage0"; +import { bootstrapRun, currentPlatformInfo } from "/toolchain/stage0"; import binutils from "./1_01_binutils.bri"; import gcc from "./1_02_gcc.bri"; import linuxHeaders from "./1_03_linux_headers.bri"; @@ -7,6 +7,7 @@ import glibc from "./1_04_glibc.bri"; import { wrapWithScript, useBriocheLd } from "../utils.bri"; export default std.memo(async (): Promise> => { + const platformInfo = currentPlatformInfo(); const source = Brioche.download( "https://development-content.brioche.dev/linuxfromscratch.org/v12.0/packages/gcc-13.2.0.tar.xz", ) @@ -16,7 +17,7 @@ export default std.memo(async (): Promise> => { let stage1 = std.merge(binutils(), gcc(), linuxHeaders(), glibc()); stage1 = wrapWithScript(stage1, { - paths: ["usr/bin/x86_64-lfs-linux-gnu-gcc"], + paths: [`usr/bin/${platformInfo.arch}-lfs-linux-gnu-gcc`], renameSuffix: "-orig", script: std .file(std.indoc` @@ -29,13 +30,13 @@ export default std.memo(async (): Promise> => { stage1 = useBriocheLd(stage1, { ldPaths: [ - "usr/bin/x86_64-lfs-linux-gnu-ld", - "usr/bin/x86_64-lfs-linux-gnu-ld.bfd", - "usr/x86_64-lfs-linux-gnu/bin/ld", - "usr/x86_64-lfs-linux-gnu/bin/ld.bfd", + `usr/bin/${platformInfo.arch}-lfs-linux-gnu-ld`, + `usr/bin/${platformInfo.arch}-lfs-linux-gnu-ld.bfd`, + `usr/${platformInfo.arch}-lfs-linux-gnu/bin/ld`, + `usr/${platformInfo.arch}-lfs-linux-gnu/bin/ld.bfd`, ], interpreterPaths: { - "lib64/ld-linux-x86-64.so.2": "lib64/ld-linux-x86-64.so.2", + [platformInfo.dynamicLinkerPath]: platformInfo.dynamicLinkerPath, }, }); @@ -66,7 +67,7 @@ export default std.memo(async (): Promise> => { `, env: { BRIOCHE_OUTPUT: std.outputPath, - TARGET: "x86_64-lfs-linux-gnu", + TARGET: `${platformInfo.arch}-lfs-linux-gnu`, stage1, }, workDir: source, diff --git a/packages/std/toolchain/stage1/index.bri b/packages/std/toolchain/stage1/index.bri index f2886912..b4e74700 100644 --- a/packages/std/toolchain/stage1/index.bri +++ b/packages/std/toolchain/stage1/index.bri @@ -4,6 +4,7 @@ import gcc from "./1_02_gcc.bri"; import linuxHeaders from "./1_03_linux_headers.bri"; import glibc from "./1_04_glibc.bri"; import libstdcpp from "./1_05_libstdcpp.bri"; +import { currentPlatformInfo } from "../stage0"; import { useBriocheLd, wrapWithScript } from "../utils.bri"; export { default as linuxHeaders } from "./1_03_linux_headers.bri"; @@ -11,32 +12,27 @@ export { default as glibc } from "./1_04_glibc.bri"; export { default as libstdcpp } from "./1_05_libstdcpp.bri"; export default std.memo(() => { - let stage1 = std.merge( - binutils(), - gcc(), - linuxHeaders(), - glibc(), - libstdcpp(), - ); + const platformInfo = currentPlatformInfo(); + let stage1 = std.merge(binutils, gcc, linuxHeaders, glibc, libstdcpp); stage1 = stage1.insert("bin", std.symlink({ target: "usr/bin" })); stage1 = useBriocheLd(stage1, { ldPaths: [ - "usr/bin/x86_64-lfs-linux-gnu-ld", - "usr/bin/x86_64-lfs-linux-gnu-ld.bfd", - "usr/x86_64-lfs-linux-gnu/bin/ld", - "usr/x86_64-lfs-linux-gnu/bin/ld.bfd", + `usr/bin/${platformInfo.arch}-lfs-linux-gnu-ld`, + `usr/bin/${platformInfo.arch}-lfs-linux-gnu-ld.bfd`, + `usr/${platformInfo.arch}-lfs-linux-gnu/bin/ld`, + `usr/${platformInfo.arch}-lfs-linux-gnu/bin/ld.bfd`, ], interpreterPaths: { - "lib64/ld-linux-x86-64.so.2": "lib/ld-linux-x86-64.so.2", + [platformInfo.dynamicLinkerPath]: platformInfo.dynamicLinkerPath, }, }); stage1 = wrapWithScript(stage1, { paths: [ - "usr/bin/x86_64-lfs-linux-gnu-g++", - "usr/bin/x86_64-lfs-linux-gnu-gcc", + `usr/bin/${platformInfo.arch}-lfs-linux-gnu-g++`, + `usr/bin/${platformInfo.arch}-lfs-linux-gnu-gcc`, ], renameSuffix: "-orig", script: std @@ -44,7 +40,7 @@ export default std.memo(() => { #!/usr/bin/env sh script_dir=$(cd "$(dirname -- "$0")" && pwd -P) sysroot=$(cd "$script_dir/../.." && pwd -P) - "$0-orig" --sysroot="$sysroot" -isystem "$sysroot/x86_64-lfs-linux-gnu/include/c++/13.2.0/x86_64-lfs-linux-gnu" -isystem "$sysroot/x86_64-lfs-linux-gnu/include/c++/13.2.0" -isystem "$sysroot/usr/include" "$@" + "$0-orig" --sysroot="$sysroot" -isystem "$sysroot/${platformInfo.arch}-lfs-linux-gnu/include/c++/13.2.0/${platformInfo.arch}-lfs-linux-gnu" -isystem "$sysroot/${platformInfo.arch}-lfs-linux-gnu/include/c++/13.2.0" -isystem "$sysroot/usr/include" "$@" `) .withPermissions({ executable: true }), }); diff --git a/packages/std/toolchain/stage2/2_01_m4.bri b/packages/std/toolchain/stage2/2_01_m4.bri index 11afc1d5..5783c5e2 100644 --- a/packages/std/toolchain/stage2/2_01_m4.bri +++ b/packages/std/toolchain/stage2/2_01_m4.bri @@ -1,5 +1,5 @@ import * as std from "/core"; -import { bootstrapRun } from "../stage0"; +import { bootstrapRun, currentPlatformInfo } from "../stage0"; import stage1 from "../stage1"; export default std.memo(async (): Promise> => { @@ -22,8 +22,8 @@ export default std.memo(async (): Promise> => { `, env: { BRIOCHE_OUTPUT: std.outputPath, - TARGET: "x86_64-lfs-linux-gnu", - stage1: stage1(), + TARGET: `${currentPlatformInfo().arch}-lfs-linux-gnu`, + stage1, }, workDir: source, }); diff --git a/packages/std/toolchain/stage2/2_02_ncurses.bri b/packages/std/toolchain/stage2/2_02_ncurses.bri index e83d73fc..bcfe05ee 100644 --- a/packages/std/toolchain/stage2/2_02_ncurses.bri +++ b/packages/std/toolchain/stage2/2_02_ncurses.bri @@ -1,5 +1,5 @@ import * as std from "/core"; -import { bootstrapRun } from "../stage0"; +import { bootstrapRun, currentPlatformInfo } from "../stage0"; import stage1 from "../stage1"; export default std.memo(async (): Promise> => { @@ -48,8 +48,8 @@ export default std.memo(async (): Promise> => { `, env: { BRIOCHE_OUTPUT: std.outputPath, - TARGET: "x86_64-lfs-linux-gnu", - stage1: stage1(), + TARGET: `${currentPlatformInfo().arch}-lfs-linux-gnu`, + stage1, }, workDir: source, }); diff --git a/packages/std/toolchain/stage2/2_03_bash.bri b/packages/std/toolchain/stage2/2_03_bash.bri index 97999c8e..05d69d1d 100644 --- a/packages/std/toolchain/stage2/2_03_bash.bri +++ b/packages/std/toolchain/stage2/2_03_bash.bri @@ -1,5 +1,5 @@ import * as std from "/core"; -import { bootstrapRun } from "../stage0"; +import { bootstrapRun, currentPlatformInfo } from "../stage0"; import stage1 from "../stage1"; export default std.memo(async (): Promise> => { @@ -25,8 +25,8 @@ export default std.memo(async (): Promise> => { `, env: { BRIOCHE_OUTPUT: std.outputPath, - TARGET: "x86_64-lfs-linux-gnu", - stage1: stage1(), + TARGET: `${currentPlatformInfo().arch}-lfs-linux-gnu`, + stage1, }, workDir: source, }); diff --git a/packages/std/toolchain/stage2/2_04_coreutils.bri b/packages/std/toolchain/stage2/2_04_coreutils.bri index 58865ad3..5d90798e 100644 --- a/packages/std/toolchain/stage2/2_04_coreutils.bri +++ b/packages/std/toolchain/stage2/2_04_coreutils.bri @@ -1,5 +1,5 @@ import * as std from "/core"; -import { bootstrapRun } from "../stage0"; +import { bootstrapRun, currentPlatformInfo } from "../stage0"; import stage1 from "../stage1"; export default std.memo(async (): Promise> => { @@ -31,8 +31,8 @@ export default std.memo(async (): Promise> => { `, env: { BRIOCHE_OUTPUT: std.outputPath, - TARGET: "x86_64-lfs-linux-gnu", - stage1: stage1(), + TARGET: `${currentPlatformInfo().arch}-lfs-linux-gnu`, + stage1, }, workDir: source, }); diff --git a/packages/std/toolchain/stage2/2_05_diffutils.bri b/packages/std/toolchain/stage2/2_05_diffutils.bri index 30591ba4..a43e6c10 100644 --- a/packages/std/toolchain/stage2/2_05_diffutils.bri +++ b/packages/std/toolchain/stage2/2_05_diffutils.bri @@ -1,5 +1,5 @@ import * as std from "/core"; -import { bootstrapRun } from "../stage0"; +import { bootstrapRun, currentPlatformInfo } from "../stage0"; import stage1 from "../stage1"; export default std.memo(async (): Promise> => { @@ -23,8 +23,8 @@ export default std.memo(async (): Promise> => { `, env: { BRIOCHE_OUTPUT: std.outputPath, - TARGET: "x86_64-lfs-linux-gnu", - stage1: stage1(), + TARGET: `${currentPlatformInfo().arch}-lfs-linux-gnu`, + stage1, }, workDir: source, }); diff --git a/packages/std/toolchain/stage2/2_06_file.bri b/packages/std/toolchain/stage2/2_06_file.bri index 388555a2..b3bf4377 100644 --- a/packages/std/toolchain/stage2/2_06_file.bri +++ b/packages/std/toolchain/stage2/2_06_file.bri @@ -1,5 +1,5 @@ import * as std from "/core"; -import { bootstrapRun } from "../stage0"; +import { bootstrapRun, currentPlatformInfo } from "../stage0"; import stage1 from "../stage1"; export default std.memo(async (): Promise> => { @@ -35,8 +35,8 @@ export default std.memo(async (): Promise> => { `, env: { BRIOCHE_OUTPUT: std.outputPath, - TARGET: "x86_64-lfs-linux-gnu", - stage1: stage1(), + TARGET: `${currentPlatformInfo().arch}-lfs-linux-gnu`, + stage1, }, workDir: source, }); diff --git a/packages/std/toolchain/stage2/2_07_findutils.bri b/packages/std/toolchain/stage2/2_07_findutils.bri index 8f1c20bb..55008ff8 100644 --- a/packages/std/toolchain/stage2/2_07_findutils.bri +++ b/packages/std/toolchain/stage2/2_07_findutils.bri @@ -1,5 +1,5 @@ import * as std from "/core"; -import { bootstrapRun } from "../stage0"; +import { bootstrapRun, currentPlatformInfo } from "../stage0"; import stage1 from "../stage1"; export default std.memo(async (): Promise> => { @@ -24,8 +24,8 @@ export default std.memo(async (): Promise> => { `, env: { BRIOCHE_OUTPUT: std.outputPath, - TARGET: "x86_64-lfs-linux-gnu", - stage1: stage1(), + TARGET: `${currentPlatformInfo().arch}-lfs-linux-gnu`, + stage1, }, workDir: source, }); diff --git a/packages/std/toolchain/stage2/2_08_gawk.bri b/packages/std/toolchain/stage2/2_08_gawk.bri index b9e1ff27..9a063540 100644 --- a/packages/std/toolchain/stage2/2_08_gawk.bri +++ b/packages/std/toolchain/stage2/2_08_gawk.bri @@ -1,5 +1,5 @@ import * as std from "/core"; -import { bootstrapRun } from "../stage0"; +import { bootstrapRun, currentPlatformInfo } from "../stage0"; import stage1 from "../stage1"; export default std.memo(async (): Promise> => { @@ -25,8 +25,8 @@ export default std.memo(async (): Promise> => { `, env: { BRIOCHE_OUTPUT: std.outputPath, - TARGET: "x86_64-lfs-linux-gnu", - stage1: stage1(), + TARGET: `${currentPlatformInfo().arch}-lfs-linux-gnu`, + stage1, }, workDir: source, }); diff --git a/packages/std/toolchain/stage2/2_09_grep.bri b/packages/std/toolchain/stage2/2_09_grep.bri index 209f727c..3a8cf0fd 100644 --- a/packages/std/toolchain/stage2/2_09_grep.bri +++ b/packages/std/toolchain/stage2/2_09_grep.bri @@ -1,5 +1,5 @@ import * as std from "/core"; -import { bootstrapRun } from "../stage0"; +import { bootstrapRun, currentPlatformInfo } from "../stage0"; import stage1 from "../stage1"; export default std.memo(async (): Promise> => { @@ -23,8 +23,8 @@ export default std.memo(async (): Promise> => { `, env: { BRIOCHE_OUTPUT: std.outputPath, - TARGET: "x86_64-lfs-linux-gnu", - stage1: stage1(), + TARGET: `${currentPlatformInfo().arch}-lfs-linux-gnu`, + stage1, }, workDir: source, }); diff --git a/packages/std/toolchain/stage2/2_10_gzip.bri b/packages/std/toolchain/stage2/2_10_gzip.bri index 440126e7..1ee2518d 100644 --- a/packages/std/toolchain/stage2/2_10_gzip.bri +++ b/packages/std/toolchain/stage2/2_10_gzip.bri @@ -1,5 +1,5 @@ import * as std from "/core"; -import { bootstrapRun } from "../stage0"; +import { bootstrapRun, currentPlatformInfo } from "../stage0"; import stage1 from "../stage1"; export default std.memo(async (): Promise> => { @@ -22,8 +22,8 @@ export default std.memo(async (): Promise> => { `, env: { BRIOCHE_OUTPUT: std.outputPath, - TARGET: "x86_64-lfs-linux-gnu", - stage1: stage1(), + TARGET: `${currentPlatformInfo().arch}-lfs-linux-gnu`, + stage1, }, workDir: source, }); diff --git a/packages/std/toolchain/stage2/2_11_make.bri b/packages/std/toolchain/stage2/2_11_make.bri index b0fc938e..e039a846 100644 --- a/packages/std/toolchain/stage2/2_11_make.bri +++ b/packages/std/toolchain/stage2/2_11_make.bri @@ -1,5 +1,5 @@ import * as std from "/core"; -import { bootstrapRun } from "../stage0"; +import { bootstrapRun, currentPlatformInfo } from "../stage0"; import stage1 from "../stage1"; export default std.memo(async (): Promise> => { @@ -24,8 +24,8 @@ export default std.memo(async (): Promise> => { `, env: { BRIOCHE_OUTPUT: std.outputPath, - TARGET: "x86_64-lfs-linux-gnu", - stage1: stage1(), + TARGET: `${currentPlatformInfo().arch}-lfs-linux-gnu`, + stage1, }, workDir: source, }); diff --git a/packages/std/toolchain/stage2/2_12_patch.bri b/packages/std/toolchain/stage2/2_12_patch.bri index 18203750..20c7d012 100644 --- a/packages/std/toolchain/stage2/2_12_patch.bri +++ b/packages/std/toolchain/stage2/2_12_patch.bri @@ -1,5 +1,5 @@ import * as std from "/core"; -import { bootstrapRun } from "../stage0"; +import { bootstrapRun, currentPlatformInfo } from "../stage0"; import stage1 from "../stage1"; export default std.memo(async (): Promise> => { @@ -23,8 +23,8 @@ export default std.memo(async (): Promise> => { `, env: { BRIOCHE_OUTPUT: std.outputPath, - TARGET: "x86_64-lfs-linux-gnu", - stage1: stage1(), + TARGET: `${currentPlatformInfo().arch}-lfs-linux-gnu`, + stage1, }, workDir: source, }); diff --git a/packages/std/toolchain/stage2/2_13_sed.bri b/packages/std/toolchain/stage2/2_13_sed.bri index c84c9a73..a3890f78 100644 --- a/packages/std/toolchain/stage2/2_13_sed.bri +++ b/packages/std/toolchain/stage2/2_13_sed.bri @@ -1,5 +1,5 @@ import * as std from "/core"; -import { bootstrapRun } from "../stage0"; +import { bootstrapRun, currentPlatformInfo } from "../stage0"; import stage1 from "../stage1"; export default std.memo(async (): Promise> => { @@ -23,8 +23,8 @@ export default std.memo(async (): Promise> => { `, env: { BRIOCHE_OUTPUT: std.outputPath, - TARGET: "x86_64-lfs-linux-gnu", - stage1: stage1(), + TARGET: `${currentPlatformInfo().arch}-lfs-linux-gnu`, + stage1, }, workDir: source, }); diff --git a/packages/std/toolchain/stage2/2_14_tar.bri b/packages/std/toolchain/stage2/2_14_tar.bri index 656eb0d4..fdb4d78c 100644 --- a/packages/std/toolchain/stage2/2_14_tar.bri +++ b/packages/std/toolchain/stage2/2_14_tar.bri @@ -1,5 +1,5 @@ import * as std from "/core"; -import { bootstrapRun } from "../stage0"; +import { bootstrapRun, currentPlatformInfo } from "../stage0"; import stage1 from "../stage1"; export default std.memo(async (): Promise> => { @@ -23,8 +23,8 @@ export default std.memo(async (): Promise> => { `, env: { BRIOCHE_OUTPUT: std.outputPath, - TARGET: "x86_64-lfs-linux-gnu", - stage1: stage1(), + TARGET: `${currentPlatformInfo().arch}-lfs-linux-gnu`, + stage1, }, workDir: source, }); diff --git a/packages/std/toolchain/stage2/2_15_xz.bri b/packages/std/toolchain/stage2/2_15_xz.bri index c7251f48..3b1ca8c3 100644 --- a/packages/std/toolchain/stage2/2_15_xz.bri +++ b/packages/std/toolchain/stage2/2_15_xz.bri @@ -1,5 +1,5 @@ import * as std from "/core"; -import { bootstrapRun } from "../stage0"; +import { bootstrapRun, currentPlatformInfo } from "../stage0"; import stage1 from "../stage1"; export default std.memo(async (): Promise> => { @@ -27,8 +27,8 @@ export default std.memo(async (): Promise> => { `, env: { BRIOCHE_OUTPUT: std.outputPath, - TARGET: "x86_64-lfs-linux-gnu", - stage1: stage1(), + TARGET: `${currentPlatformInfo().arch}-lfs-linux-gnu`, + stage1, }, workDir: source, }); diff --git a/packages/std/toolchain/stage2/2_16_binutils.bri b/packages/std/toolchain/stage2/2_16_binutils.bri index 1de7cc70..398c02bc 100644 --- a/packages/std/toolchain/stage2/2_16_binutils.bri +++ b/packages/std/toolchain/stage2/2_16_binutils.bri @@ -1,5 +1,5 @@ import * as std from "/core"; -import { bootstrapRun } from "../stage0"; +import { bootstrapRun, currentPlatformInfo } from "../stage0"; import stage1 from "../stage1"; export default std.memo(async (): Promise> => { @@ -41,8 +41,8 @@ export default std.memo(async (): Promise> => { `, env: { BRIOCHE_OUTPUT: std.outputPath, - TARGET: "x86_64-lfs-linux-gnu", - stage1: stage1(), + TARGET: `${currentPlatformInfo().arch}-lfs-linux-gnu`, + stage1, }, workDir: source, }); diff --git a/packages/std/toolchain/stage2/2_17_gcc.bri b/packages/std/toolchain/stage2/2_17_gcc.bri index 13aa2239..48556a86 100644 --- a/packages/std/toolchain/stage2/2_17_gcc.bri +++ b/packages/std/toolchain/stage2/2_17_gcc.bri @@ -1,6 +1,6 @@ import * as std from "/core"; import { useBriocheLd } from "../utils.bri"; -import { bootstrapRun } from "../stage0"; +import { bootstrapRun, currentPlatformInfo } from "../stage0"; import stage1 from "../stage1"; import m4 from "./2_01_m4.bri"; import ncurses from "./2_02_ncurses.bri"; @@ -20,6 +20,7 @@ import xz from "./2_15_xz.bri"; import binutils from "./2_16_binutils.bri"; export default std.memo(async (): Promise> => { + const platformInfo = currentPlatformInfo(); let source = Brioche.download( "https://development-content.brioche.dev/linuxfromscratch.org/v12.0/packages/gcc-13.2.0.tar.xz", ) @@ -59,34 +60,34 @@ export default std.memo(async (): Promise> => { }); let stage2 = std.merge( - stage1(), - m4(), - ncurses(), - bash(), - coreutils(), - diffutils(), - file(), - findutils(), - gawk(), - grep(), - gzip(), - make(), - patch(), - sed(), - tar(), - xz(), - binutils(), + stage1, + m4, + ncurses, + bash, + coreutils, + diffutils, + file, + findutils, + gawk, + grep, + gzip, + make, + patch, + sed, + tar, + xz, + binutils, ); stage2 = useBriocheLd(stage2, { ldPaths: [ "usr/bin/ld", "usr/bin/ld.bfd", - "usr/x86_64-lfs-linux-gnu/bin/ld", - "usr/x86_64-lfs-linux-gnu/bin/ld.bfd", + `usr/${platformInfo.arch}-lfs-linux-gnu/bin/ld`, + `usr/${platformInfo.arch}-lfs-linux-gnu/bin/ld.bfd`, ], interpreterPaths: { - "lib64/ld-linux-x86-64.so.2": "lib/ld-linux-x86-64.so.2", + [platformInfo.dynamicLinkerPath]: platformInfo.dynamicLinkerPath, }, }); @@ -94,7 +95,7 @@ export default std.memo(async (): Promise> => { for (const tool of prefixedTools) { stage2 = stage2.insert( `usr/bin/${tool}`, - std.symlink({ target: `x86_64-lfs-linux-gnu-${tool}` }), + std.symlink({ target: `${platformInfo.arch}-lfs-linux-gnu-${tool}` }), ); } @@ -138,7 +139,7 @@ export default std.memo(async (): Promise> => { `, env: { BRIOCHE_OUTPUT: std.outputPath, - TARGET: "x86_64-lfs-linux-gnu", + TARGET: `${platformInfo.arch}-lfs-linux-gnu`, stage2, }, workDir: source, diff --git a/packages/std/toolchain/stage2/2_18_toolchain.bri b/packages/std/toolchain/stage2/2_18_toolchain.bri index 38a20dac..1aa2af70 100644 --- a/packages/std/toolchain/stage2/2_18_toolchain.bri +++ b/packages/std/toolchain/stage2/2_18_toolchain.bri @@ -1,5 +1,6 @@ import * as std from "/core"; import { wrapWithScript, useBriocheLd } from "../utils.bri"; +import { currentPlatformInfo } from "../stage0"; import { linuxHeaders, glibc, libstdcpp } from "../stage1"; import m4 from "./2_01_m4.bri"; import ncurses from "./2_02_ncurses.bri"; @@ -20,6 +21,7 @@ import binutils from "./2_16_binutils.bri"; import gcc from "./2_17_gcc.bri"; export default std.memo(async (): Promise> => { + const platformInfo = currentPlatformInfo(); let toolchain = std.merge( linuxHeaders(), glibc(), @@ -49,20 +51,20 @@ export default std.memo(async (): Promise> => { ldPaths: [ "usr/bin/ld", "usr/bin/ld.bfd", - "usr/x86_64-lfs-linux-gnu/bin/ld", - "usr/x86_64-lfs-linux-gnu/bin/ld.bfd", + `usr/${platformInfo.arch}-lfs-linux-gnu/bin/ld`, + `usr/${platformInfo.arch}-lfs-linux-gnu/bin/ld.bfd`, ], interpreterPaths: { - "lib64/ld-linux-x86-64.so.2": "lib/ld-linux-x86-64.so.2", + [platformInfo.dynamicLinkerPath]: platformInfo.dynamicLinkerPath, }, }); toolchain = wrapWithScript(toolchain, { paths: [ - "usr/bin/x86_64-lfs-linux-gnu-c++", - "usr/bin/x86_64-lfs-linux-gnu-g++", - "usr/bin/x86_64-lfs-linux-gnu-gcc", - "usr/bin/x86_64-lfs-linux-gnu-gcc-13.2.0", + `usr/bin/${platformInfo.arch}-lfs-linux-gnu-c++`, + `usr/bin/${platformInfo.arch}-lfs-linux-gnu-g++`, + `usr/bin/${platformInfo.arch}-lfs-linux-gnu-gcc`, + `usr/bin/${platformInfo.arch}-lfs-linux-gnu-gcc-13.2.0`, "usr/bin/c++", "usr/bin/g++", "usr/bin/gcc", @@ -131,8 +133,8 @@ export default std.memo(async (): Promise> => { if [ "$include_system_headers" -eq 1 ]; then set -- \ - -isystem "$sysroot/x86_64-lfs-linux-gnu/include/c++/13.2.0/x86_64-lfs-linux-gnu" \ - -isystem "$sysroot/x86_64-lfs-linux-gnu/include/c++/13.2.0" \ + -isystem "$sysroot/${platformInfo.arch}-lfs-linux-gnu/include/c++/13.2.0/${platformInfo.arch}-lfs-linux-gnu" \ + -isystem "$sysroot/${platformInfo.arch}-lfs-linux-gnu/include/c++/13.2.0" \ -isystem "$sysroot/usr/include" \ "$@" fi @@ -147,7 +149,7 @@ export default std.memo(async (): Promise> => { for (const tool of prefixedTools) { toolchain = toolchain.insert( `usr/bin/${tool}`, - std.symlink({ target: `x86_64-lfs-linux-gnu-${tool}` }), + std.symlink({ target: `${platformInfo.arch}-lfs-linux-gnu-${tool}` }), ); } diff --git a/packages/std/toolchain/utils.bri b/packages/std/toolchain/utils.bri index b94e744d..577cd024 100644 --- a/packages/std/toolchain/utils.bri +++ b/packages/std/toolchain/utils.bri @@ -1,12 +1,28 @@ import * as std from "/core"; +const PLATFORM_RUNTIME_UTILS: Record< + std.Platform, + std.Recipe | undefined +> = { + "x86_64-linux": Brioche.download( + "https://development-content.brioche.dev/github.com/brioche-dev/brioche-runtime-utils/commits/fa9ce0565ea067c84216838073c22176bb4a6399/x86_64-linux/brioche-runtime-utils.tar.zstd", + ).unarchive("tar", "zstd"), + "aarch64-linux": Brioche.download( + "https://development-content.brioche.dev/github.com/brioche-dev/brioche-runtime-utils/commits/fa9ce0565ea067c84216838073c22176bb4a6399/aarch64-linux/brioche-runtime-utils.tar.zstd", + ).unarchive("tar", "zstd"), +}; + // NOTE: This download is just like the `runtimeUtils()` export, except // it's pinned to a specific version. It should only be updated if the // tools used for building the toolchain should be upgraded export function runtimeUtils(): std.Recipe { - return Brioche.download( - "https://development-content.brioche.dev/github.com/brioche-dev/brioche-runtime-utils/commits/bd8af11dcd61855df38cc12401f5ddc4ff5466e0/x86_64-linux/brioche-runtime-utils.tar.zstd", - ).unarchive("tar", "zstd"); + const platformRuntimeUtils = PLATFORM_RUNTIME_UTILS[std.CURRENT_PLATFORM]; + std.assert( + platformRuntimeUtils != null, + `The platform '${std.CURRENT_PLATFORM}' is not handled by this version of std`, + ); + + return platformRuntimeUtils; } interface UseBriocheLdOptions { diff --git a/packages/strace/project.bri b/packages/strace/project.bri index c8aba23b..cbe84ca5 100644 --- a/packages/strace/project.bri +++ b/packages/strace/project.bri @@ -14,7 +14,18 @@ const source = Brioche.download( export default function strace(): std.Recipe { return std.runBash` - ./configure --prefix=/ + case "$(uname -m)" in + aarch64) + # Disable multiple personality support for aarch64 for now + ./configure \\ + --prefix=/ \\ + --enable-mpers=no + ;; + *) + ./configure --prefix=/ + ;; + esac + make -j16 make install DESTDIR="$BRIOCHE_OUTPUT" ` diff --git a/packages/xplr/project.bri b/packages/xplr/project.bri index 9e381afa..32181f78 100644 --- a/packages/xplr/project.bri +++ b/packages/xplr/project.bri @@ -7,21 +7,22 @@ export const project = { repository: "https://github.com/sayanarijit/xplr.git", }; -const source = (() => { - let source = Brioche.gitCheckout({ - repository: project.repository, - ref: `v${project.version}`, - }); - +const source = Brioche.gitCheckout({ + repository: project.repository, + ref: `v${project.version}`, +}) + // Remove upstream's custom Cargo `config.toml`, which overrides the linker + // for various targets (for cross-compilation). This can interfere with + // our default working linker configuration. + .remove(".cargo/config.toml") // HACK: Workaround for https://github.com/LukeMathWalker/cargo-chef/issues/295#issuecomment-2619963413 - source = std.runBash` - sed -i "s|path = './benches/|path = 'benches/|g" "$BRIOCHE_OUTPUT/Cargo.toml" - ` - .outputScaffold(source) - .toDirectory(); - - return source; -})(); + .pipe((source) => + std.runBash` + sed -i "s|path = './benches/|path = 'benches/|g" "$BRIOCHE_OUTPUT/Cargo.toml" + ` + .outputScaffold(source) + .toDirectory(), + ); export default function xplr(): std.Recipe { return cargoBuild({