> ## Documentation Index
> Fetch the complete documentation index at: https://docs.reasonos.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Toolchains

> Manage external tools, runtimes, and compilers hermetically with the RBS toolchain system.

# Toolchain Management

RBS provides a **hermetic toolchain system** that automatically downloads, caches, and manages all external tools and runtimes your project needs. No manual installation required — RBS handles everything.

## Why Hermetic Toolchains?

* **Reproducibility**: Every developer and CI server uses the exact same tool versions.
* **No System Dependencies**: No need to install Java, Python, Node.js, or any other tool system-wide.
* **Version Isolation**: Different projects can use different versions of the same tool without conflict.
* **Automatic Caching**: Tools are downloaded once and cached for future use.

## How It Works

1. You declare toolchains in `WORKSPACE.rbs`.
2. RBS automatically downloads the correct version for your platform.
3. Tools are cached in `.rbs/toolchains/`.
4. Build rules use the managed toolchains — never system-installed tools.

```
.rbs/toolchains/
├── java/
│   └── jdk-17.0.11/          # Managed JDK
├── nodejs/
│   └── node-v20.11.0/        # Managed Node.js
├── python/
│   └── python-3.11.7/        # Managed Python
└── custom/
    └── protoc-25.1/           # Custom managed tool
```

## Declaring Toolchains

### Language Toolchains

RBS provides built-in toolchain rules for common languages:

```python filename="WORKSPACE.rbs" theme={null}
# Java/JVM Toolchain
load("@rbs//java/toolchain.rbs", "java_toolchain")
java_toolchain(name = "java", version = "17.0.11")

# Node.js Toolchain
load("@rbs//nodejs/toolchain.rbs", "nodejs_toolchain")
nodejs_toolchain(name = "nodejs", version = "20.11.0")

# Python Toolchain
load("@rbs//python/toolchain.rbs", "python_toolchain")
python_toolchain(name = "python", version = "3.11.7")

# Go Toolchain
load("@rbs//go/toolchain.rbs", "go_toolchain")
go_toolchain(name = "go", version = "1.21.5")

# Kotlin Toolchain
load("@rbs//kotlin/toolchain.rbs", "kotlin_toolchain")
kotlin_toolchain(name = "kotlin", version = "1.9.22")
```

### Custom Toolchains

For tools not covered by built-in rules, use the low-level primitives:

#### `native.http_file` — Download a Single File

```python filename="WORKSPACE.rbs" theme={null}
# Download a single executable
native.http_file(
    name = "protoc",
    url = select({
        "//platforms:darwin_arm64": "https://github.com/protocolbuffers/protobuf/releases/download/v25.1/protoc-25.1-osx-aarch_64.zip",
        "//platforms:linux_amd64": "https://github.com/protocolbuffers/protobuf/releases/download/v25.1/protoc-25.1-linux-x86_64.zip",
    }),
    sha256 = select({
        "//platforms:darwin_arm64": "abc123...",
        "//platforms:linux_amd64": "def456...",
    }),
    executable = True,
)
```

#### `native.http_archive` — Download and Extract an Archive

```python filename="WORKSPACE.rbs" theme={null}
# Download and extract a tar.gz or zip archive
native.http_archive(
    name = "terraform",
    url = select({
        "//platforms:darwin_arm64": "https://releases.hashicorp.com/terraform/1.7.0/terraform_1.7.0_darwin_arm64.zip",
        "//platforms:linux_amd64": "https://releases.hashicorp.com/terraform/1.7.0/terraform_1.7.0_linux_amd64.zip",
    }),
    sha256 = select({
        "//platforms:darwin_arm64": "abc...",
        "//platforms:linux_amd64": "def...",
    }),
    strip_prefix = "",           # Strip leading directory from archive
    build_file = None,           # Optional BUILD.rbs for the extracted contents
)
```

#### `native.tool_binary` — Declare a Tool from an Archive

```python filename="WORKSPACE.rbs" theme={null}
# Declare an executable within a downloaded archive
native.tool_binary(
    name = "terraform_bin",
    archive = "@terraform",           # Reference to http_archive
    binary_path = "terraform",        # Path to executable within the archive
    tool_type = "terraform",          # Tool type identifier
)
```

### `register_toolchain` — Register for Use in Rules

```python filename="WORKSPACE.rbs" theme={null}
# Register the toolchain so rules can reference it
register_toolchain(
    name = "terraform_toolchain",
    tool = "@terraform_bin",
    type = "terraform",
)
```

## Using Toolchains in Rules

### In Built-in Rules

Built-in rules automatically use the appropriate registered toolchain:

```python filename="BUILD.rbs" theme={null}
load("@rbs//java/rules.rbs", "java_binary")

# Automatically uses the java_toolchain declared in WORKSPACE.rbs
java_binary(
    name = "server",
    srcs = glob(["src/**/*.java"]),
    main = "com.example.Server",
)
```

### In Custom Rules

Access toolchains via `ctx.tools`:

```python theme={null}
def _my_rule_impl(ctx):
    dirs = ctx.bin.create_dirs()
    
    # Copy the Java toolchain into the target's output
    java_home = ctx.tools.copy(
        toolchain = "java",
        destination = dirs.toolchains + "/java",
    )
    
    # Use the toolchain binary
    ctx.actions.run(
        executable = java_home + "/bin/java",
        arguments = ["-jar", "app.jar"],
    )
```

## Platform-Aware Downloads

RBS automatically selects the correct download URL based on the current platform using `select()`:

```python theme={null}
NODEJS_URLS = select({
    "//platforms:darwin_arm64": "https://nodejs.org/dist/v20.11.0/node-v20.11.0-darwin-arm64.tar.gz",
    "//platforms:darwin_amd64": "https://nodejs.org/dist/v20.11.0/node-v20.11.0-darwin-x64.tar.gz",
    "//platforms:linux_arm64": "https://nodejs.org/dist/v20.11.0/node-v20.11.0-linux-arm64.tar.gz",
    "//platforms:linux_amd64": "https://nodejs.org/dist/v20.11.0/node-v20.11.0-linux-x64.tar.gz",
    "//platforms:windows_amd64": "https://nodejs.org/dist/v20.11.0/node-v20.11.0-win-x64.zip",
})
```

### Available Platform Labels

| Platform    | Label                       |
| ----------- | --------------------------- |
| macOS ARM64 | `//platforms:darwin_arm64`  |
| macOS x64   | `//platforms:darwin_amd64`  |
| Linux ARM64 | `//platforms:linux_arm64`   |
| Linux x64   | `//platforms:linux_amd64`   |
| Windows x64 | `//platforms:windows_amd64` |

## Toolchains vs External Dependencies

It's important to understand the difference between **toolchains** and **external dependencies**:

| Aspect           | Toolchains                                      | External Dependencies                                   |
| ---------------- | ----------------------------------------------- | ------------------------------------------------------- |
| **What**         | Build tools (compilers, runtimes, linters)      | Language packages (libraries, frameworks)               |
| **Examples**     | JDK, Node.js, Python, protoc                    | Spring Boot, Express, Django, React                     |
| **Defined with** | `java_toolchain`, `http_archive`, `tool_binary` | `java_repository`, `nodejs_repository`, `py_repository` |
| **Stored in**    | `.rbs/toolchains/`                              | `.rbs/external-deps/`                                   |
| **Used by**      | Build rules (compilation, execution)            | Application code (imports, runtime)                     |

### Example: Both Together

```python filename="WORKSPACE.rbs" theme={null}
# TOOLCHAIN: The Java runtime itself
load("@rbs//java/toolchain.rbs", "java_toolchain")
java_toolchain(name = "java", version = "17.0.11")

# EXTERNAL DEPENDENCIES: Java libraries your code uses
load("@rbs//java/dependencies.rbs", "java_repository")
java_repository(
    name = "spring_boot_web",
    artifact = "org.springframework.boot:spring-boot-starter-web",
    version = "3.2.0",
)
```

```python filename="BUILD.rbs" theme={null}
load("@rbs//java/rules.rbs", "java_binary")

java_binary(
    name = "server",
    srcs = glob(["src/**/*.java"]),
    main = "com.example.Server",
    # Uses the java_toolchain (JDK) to compile
    # Uses the spring_boot_web dependency at runtime
    deps = ["@external://spring_boot_web"],
)
```

## Caching and Offline Builds

### Cache Location

All toolchains are cached in `.rbs/toolchains/`:

```
.rbs/toolchains/
├── java/
│   └── jdk-17.0.11/
│       ├── bin/
│       ├── lib/
│       └── ...
├── nodejs/
│   └── node-v20.11.0/
│       ├── bin/
│       ├── lib/
│       └── ...
└── custom/
    └── protoc-25.1/
        └── bin/protoc
```

### Offline Mode

Once all toolchains are downloaded, RBS can run without network access:

```bash theme={null}
# First run: downloads toolchains (requires network)
rbs build //...

# Subsequent runs: fully offline
rbs build //...   # Uses cached toolchains
```

### Cache Management

```bash theme={null}
# View workspace info including toolchain status
rbs workspace

# Clean all caches (forces re-download)
rm -rf .rbs/toolchains/
```

## Integrity Verification

Use SHA256 checksums to verify downloaded toolchains:

```python theme={null}
native.http_archive(
    name = "terraform",
    url = "https://releases.hashicorp.com/terraform/1.7.0/terraform_1.7.0_darwin_arm64.zip",
    sha256 = "e4add092a54ff6febd3325d1e0c109c9e590dc6c38f8bb7f9632e4e6bcca99d4",
)
```

If the checksum doesn't match, RBS will refuse to use the download, protecting against tampered artifacts.
