cargo-buckal 0.1.3

Seamlessly build Cargo projects with Buck2.
# Multi-platform builds

`cargo buckal migrate` can generate BUCK files that work across Linux/macOS/Windows without regenerating on each host. The key idea is to preserve Cargo’s platform-conditional dependencies in the generated rules.

## What gets generated

- `os_deps`: OS-scoped dependencies (e.g., a Windows-only dep lands under `os_deps["windows"]`).
- `os_named_deps`: same as `os_deps`, but for renamed dependencies.
- `compatible_with`: applied to a small allowlist of known OS-only crates to prevent Buck2 from building them on the wrong OS.

The generated rules use canonical Buck prelude OS constraint labels: `prelude//os/constraints:{linux,macos,windows}`.

## Supported platforms

Platform-aware dependency mapping and bundled sample platforms currently target these Rust tier-1
host triples:

- Linux: `x86_64-unknown-linux-gnu`
- Windows: `x86_64-pc-windows-msvc`
- macOS: `aarch64-apple-darwin`

## How platform matching works

Cargo encodes target-specific dependencies in `cargo metadata` as platform predicates (for example, `cfg(target_os = "windows")`). During `migrate`, cargo-buckal maps those predicates to a set of OS keys (`linux`/`macos`/`windows`) by evaluating them against cached `rustc --print=cfg --target <triple>` snapshots for Rust Tier-1 host targets.

If a predicate can’t be mapped to `linux`/`macos`/`windows`, cargo-buckal treats the dependency as unconditional by default (to preserve build success).

## Using it

1. Generate BUCK files:

   For first-time setup (initializes Buck2 and generates BUCK files):

   ```bash
   cargo buckal migrate --init
   ```

   For incremental updates (when Buck2 is already initialized):

   ```bash
   cargo buckal migrate
   ```

   This regenerates BUCK files based on current `Cargo.toml`/`Cargo.lock` changes without reinitializing Buck2. Use this after adding/removing dependencies or updating `Cargo.lock`.

   To update the pinned Buckal bundles revision (the `buckal` cell), rerun with:

   ```bash
   cargo buckal migrate --fetch
   ```

2. Build with `cargo buckal build`:

   Without `--target-platforms`, builds for the host platform:

   ```bash
   cargo buckal build //...
   ```

   With `--target-platforms`, builds for a specific target platform:

   ```bash
   cargo buckal build //... --target-platforms //platforms:x86_64-pc-windows-msvc
   ```

   You can also use `buck2 build` directly:

   ```bash
   buck2 build //... --target-platforms //platforms:x86_64-pc-windows-msvc
   ```

   `cargo buckal migrate --init` configures a `buckal` cell (Buckal bundles). The bundles provide sample platforms under `//platforms:*`. You can also use your own platform definitions; any platform you use must include the appropriate OS constraint value (`prelude//os/constraints:windows` in the example above) so `select()` picks up the right `os_deps` branch.

   If you want to use the bundled toolchain config too, point the `toolchains` cell at it in `.buckconfig`:

   ```ini
   [cells]
     toolchains = buckal/toolchains
   ```

3. Validate multi-platform builds by building against multiple target platforms:

   Linux:

   ```bash
   cargo buckal build //... --target-platforms //platforms:x86_64-unknown-linux-gnu
   ```

   Windows:

   ```bash
   cargo buckal build //... --target-platforms //platforms:x86_64-pc-windows-msvc
   ```

   macOS (bundled sample platforms):

   ```bash
   cargo buckal build //... --target-platforms //platforms:aarch64-apple-darwin
   ```

### Skipping tests for cross-compilation

When cross-compiling or when the target binaries cannot run on the host, you can
skip `rust_test` targets by passing `-c cross.skip_test=true`. cargo-buckal
marks generated `rust_test` targets with a `target_compatible_with` constraint
that matches the `//platforms:cross` config setting when this config is set.

Examples:

```bash
cargo buckal test //... --target-platforms //platforms:x86_64-unknown-linux-gnu -c cross.skip_test=true
cargo buckal test //... --target-platforms //platforms:x86_64-pc-windows-msvc -c cross.skip_test=true
```

## Troubleshooting

- If you see warnings about `rustc --print=cfg --target ...` failing, install the missing Rust targets (or expect fewer platform predicates to be mapped).
- If OS-specific deps appear in the default `deps` list, the corresponding predicate likely couldn’t be mapped; rerun with more Rust targets installed.
- If Buck2 fails to parse generated BUCK files due to missing support for `os_deps`/`os_named_deps` (or missing symbols like `rust_test` in `wrapper.bzl`), update the Buckal bundles (try `cargo buckal migrate --fetch`) or pin a bundles revision that supports these attributes.