cross-rs/cross
“Zero setup” cross compilation and “cross testing” of Rust crates
Healthy across the board
weakest axisPermissive license, no critical CVEs, actively maintained — safe to depend on.
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit 2w ago
- ✓27+ active contributors
- ✓Apache-2.0 licensed
Show all 6 evidence items →Show less
- ✓CI configured
- ✓Tests present
- ⚠Concentrated ownership — top contributor handles 50% of recent commits
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Healthy" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/cross-rs/cross)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/cross-rs/cross on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: cross-rs/cross
Generated by RepoPilot · 2026-05-09 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/cross-rs/cross shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
GO — Healthy across the board
- Last commit 2w ago
- 27+ active contributors
- Apache-2.0 licensed
- CI configured
- Tests present
- ⚠ Concentrated ownership — top contributor handles 50% of recent commits
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live cross-rs/cross
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/cross-rs/cross.
What it runs against: a local clone of cross-rs/cross — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in cross-rs/cross | Confirms the artifact applies here, not a fork |
| 2 | License is still Apache-2.0 | Catches relicense before you depend on it |
| 3 | Default branch main exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 45 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of cross-rs/cross. If you don't
# have one yet, run these first:
#
# git clone https://github.com/cross-rs/cross.git
# cd cross
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of cross-rs/cross and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "cross-rs/cross(\\.git)?\\b" \\
&& ok "origin remote is cross-rs/cross" \\
|| miss "origin remote is not cross-rs/cross (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(Apache-2\\.0)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"Apache-2\\.0\"" package.json 2>/dev/null) \\
&& ok "license is Apache-2.0" \\
|| miss "license drift — was Apache-2.0 at generation time"
# 3. Default branch
git rev-parse --verify main >/dev/null 2>&1 \\
&& ok "default branch main exists" \\
|| miss "default branch main no longer exists"
# 4. Critical files exist
test -f "src/main.rs" \\
&& ok "src/main.rs" \\
|| miss "missing critical file: src/main.rs"
test -f "src/build.rs" \\
&& ok "src/build.rs" \\
|| miss "missing critical file: src/build.rs"
test -f "Cargo.toml" \\
&& ok "Cargo.toml" \\
|| miss "missing critical file: Cargo.toml"
test -f ".cargo/config.toml" \\
&& ok ".cargo/config.toml" \\
|| miss "missing critical file: .cargo/config.toml"
test -f ".changes" \\
&& ok ".changes" \\
|| miss "missing critical file: .changes"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 45 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~15d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/cross-rs/cross"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
cross is a Rust tool that enables zero-setup cross-compilation and cross-testing of Rust crates across different target architectures using Docker or Podman containers. It abstracts away the complexity of setting up cross-compilation toolchains by providing pre-configured container images with all necessary compilers, libraries, and tools, allowing developers to run cross build --target aarch64-unknown-linux-gnu with the same ease as native compilation. Single-crate Rust binary with a workspace member (xtask/) for build automation. The main src/ contains the CLI argument parsing (via clap), container orchestration logic, and cross-compilation target definitions. Build scripts (src/build.rs) generate embedded assets. Shell scripts and Dockerfiles (108KB across the repo) define container images for each target architecture. The .changes/ directory tracks changelog entries per PR for semantic versioning.
👥Who it's for
Rust developers and library maintainers who need to compile and test crates for non-native architectures (ARM, MIPS, PowerPC, etc.) without manually configuring toolchains. Systems programmers, embedded Rust developers, and CI/CD engineers who want to verify their crates work across multiple target platforms with minimal setup.
🌱Maturity & risk
Actively developed and production-ready. The project is maintained by the cross-rs team (successor to the Rust Embedded Working Group), has a robust CI pipeline, uses semantic versioning (currently v0.2.5), and includes comprehensive changelog tracking via .changes/ directory with 50+ tracked PRs. Recent commits and active issue management indicate healthy ongoing development.
Low risk for core use cases, but moderate infrastructure dependency: the tool relies entirely on Docker/Podman being available and properly configured, creating a hard external dependency. Container image maintenance is critical—if images become stale or unavailable, the tool fails silently. The relatively small maintainer team and reliance on container registry availability are potential vulnerability points, though community engagement via Matrix is active.
Active areas of work
The project is actively addressing cross-compilation edge cases and container image updates. Recent changes tracked in .changes/ (up to PR #1483) suggest work on compiler version compatibility, target architecture support expansion, and containerization improvements. The 0.2.5 release cycle is active with pre-release automation configured in Cargo.toml metadata.
🚀Get running
git clone https://github.com/cross-rs/cross.git
cd cross
cargo install --path .
# Requires: Docker (v20.10+) or Podman (v3.4.0+) and rustup
sudo systemctl start docker # on Linux
cross build --target aarch64-unknown-linux-gnu
Daily commands:
# Development build
cargo build
# Run tests
cargo test
# Run with a test target
./target/debug/cross build --target aarch64-unknown-linux-gnu
# For xtask changelog generation
cargo xtask changelog build
🗺️Map of the codebase
src/main.rs— Entry point for the cross CLI tool; defines command structure and routing for all subcommands (build, test, run)src/build.rs— Build script that handles compilation metadata and version info; critical for reproducible buildsCargo.toml— Project manifest with all dependencies (clap, color-eyre, thiserror); defines MSRV 1.85.0 and workspace structure.cargo/config.toml— Cargo configuration for workspace-level settings and build behavior defaults.changes— Changelog directory tracking all feature changes and bug fixes; essential for understanding project evolution
🧩Components & responsibilities
- CLI Parser (clap) (clap 4.1.4 with derive macros) — Validates user input, maps arguments to handler functions, enforces required flags
- Failure mode: Invalid target triple or missing required args → error message and help text
- Build Orchestrator (Rust std::process, Docker API) — Coordinates Cargo invocation, container setup, and compilation flow
- Failure mode: Cargo compilation failure → propagate compiler error; container unavailable → fallback or fail
- Error Formatter (color-eyre, thiserror) — Converts Rust errors to user-friendly messages with colors and context
- Failure mode: Panic during error formatting → raw backtrace (fallback)
- Target Registry (TOML config parsing) — Maps target triples to container images and toolchain configurations
- Failure mode: Unknown target triple → error with list of supported targets
🔀Data flow
Developer CLI input→clap argument parser— Command line arguments (cross build --target x86_64-unknown-linux-musl) are parsed and validatedclap parser→Build orchestrator— Parsed args routed to appropriate handler function (e.g., build, test, run)Build orchestrator→Cargo.toml / target registry— Maps target triple to container image, cross-compiler flags, and environment setupOrchestrator→Docker/Container runtime— Spawns container with cross-compiler toolchain and mounts project sourceContainer→Cargo (inside container)— Runs cargo build/test with target-specific flags and toolchainCargo output→Error formatter (color-eyre)— Compiler diagnostics and build failures formatted for terminal displayFormatted errors/artifacts→Developer terminal— Colored output and build artifacts returned to user
🛠️How to make changes
Add a new cross-compilation target
- Define target architecture in a new configuration file under a target-specific module (
src/main.rs) - Add target metadata (triple, toolchain requirements) to a targets registry (
src/main.rs) - Register new target in CLI argument parser using clap derive macros (
src/main.rs)
Add a new CLI subcommand
- Define new subcommand struct with clap attributes in main.rs (
src/main.rs) - Add handler function that processes the subcommand arguments (
src/main.rs) - Wire subcommand into main match statement for execution (
src/main.rs)
Document a breaking change or feature
- Create new JSON file in .changes/ directory with issue number and description (
.changes/template/940.json) - Follow template structure (kind, body, references) for changelog generation (
.changes/template) - Regenerate CHANGELOG.md using changelog tooling before release (
.changes/README.md)
Update project dependencies
- Modify dependency versions in [dependencies] section (
Cargo.toml) - Verify MSRV compatibility (currently 1.85.0) with new transitive dependencies (
Cargo.toml) - Run full test suite to ensure compatibility (
src/main.rs)
🔧Why these technologies
- Clap 4.1.4 (derive macros) — Declarative CLI parsing with minimal boilerplate; strong type safety for arguments and subcommands
- Color-eyre + thiserror — Consistent error formatting with colors and context; ergonomic error type definitions with Display impl
- Docker/OCI containers — Provides isolated, reproducible cross-compilation environments without modifying host system
- TOML for configuration — Human-readable config format for targets and toolchains; matches Rust ecosystem conventions (Cargo.toml)
- Rust 1.85.0 MSRV — Ensures portability across older stable Rust versions; balances latest features with broad compatibility
⚖️Trade-offs already made
-
Zero-setup via containerization vs. native toolchain installation
- Why: Eliminates need for manual toolchain setup while maintaining reproducibility
- Consequence: Requires Docker/container runtime; slower initial cross-target builds but faster subsequent invocations
-
CLI-only interface (no library API)
- Why: Simpler project scope; clear separation of concerns as a tool rather than library
- Consequence: Limited reusability in Rust scripts; users must shell out or parse CLI output
-
Support for multiple target architectures vs. single-target focus
- Why: Addresses embedded, ARM, RISC-V ecosystems with one tool
- Consequence: Higher maintenance burden; more container images to maintain and test
🚫Non-goals (don't propose these)
- Does not replace or wrap Cargo entirely; only supplements cross-compilation features
- Not a package manager; assumes Cargo.toml and dependencies are already configured
- Does not handle target-specific code generation at Rust source level (preprocessor-like features)
- Not a CI/CD system; focuses on local development workflow, not multi-platform release pipelines
⚠️Anti-patterns to avoid
- Large monolithic main.rs (Medium) —
src/main.rs: All CLI logic, subcommand handling, and build orchestration likely concentrated in a single file; no visible module organization from file list - Hardcoded container image references (Medium) —
src/main.rs (inferred): Container images for targets may be hardcoded rather than externalized to config; complicates target additions - Generic error types without context (Low) —
Cargo.toml (thiserror usage): If thiserror is underutilized, errors may lose context during propagation through the build pipeline
🔥Performance hotspots
Docker image pull and startup(I/O latency) — Cold-start latency when cross-compiler image not cached; can be 30+ seconds for first invocation per targetCargo dependency resolution + compilation(Computational latency) — For large projects with many dependencies, compilation inside container may exceed local native compilation timeBuild artifact extraction from(undefined) — undefined
🪤Traps & gotchas
- Container engine must be running: cross silently fails if Docker daemon isn't started; no fallback to native compilation. 2. binfmt_misc requirement for testing: cross test only works on Linux kernels with binfmt_misc support—fails on macOS/Windows even with Docker. 3. MSRV is strict: rust-version = "1.85.0" is a hard floor; dev machines must have at least that rustup toolchain. 4. Container image pull on first run: First invocation per target downloads a large image; network and registry availability are implicit dependencies. 5. Mount path assumptions: cross assumes standard /tmp and home directory structure; custom Docker daemon configs may break mount points.
🏗️Architecture
💡Concepts to learn
- binfmt_misc (binary format miscellaneous) — cross test requires kernel support for binfmt_misc to execute foreign architecture binaries; this Linux-kernel-only feature is why cross testing is unavailable on macOS/Windows despite Docker support.
- Cross-compilation toolchains (sysroot + linker + stdlib) — cross abstracts away the complexity of setting up target-specific toolchains; understanding what's in a toolchain (gcc, binutils, libc for the target arch) helps debug linking failures.
- Container image layering and build caching — cross ships pre-built Docker images per target; understanding Dockerfile layer caching and registry pulling helps optimize CI pipeline speed and diagnose stale-image bugs.
- Rustup target triple (target-os-arch-abi) — cross uses Rust's target triple syntax (e.g., aarch64-unknown-linux-gnu) to map to specific container images and rustc configurations; mismatches between target triples cause subtle incompatibilities.
- Container volume mounting and bind mounts — cross mounts the host's source code and Cargo cache into containers; understanding mount points and permission mapping is critical for debugging file access errors in containerized builds.
- QEMU user-mode emulation — cross test uses QEMU to emulate non-native architectures when binfmt_misc + QEMU are configured; understanding QEMU's performance limitations explains why cross test is slow for some targets.
- Semantic versioning and changelog fragments — cross uses a fragment-based changelog system (.changes/{pr}.json) to auto-generate release notes; contributors must follow this pattern to ensure proper version bumping and documentation.
🔗Related repos
rust-lang/rustup— Required dependency for toolchain management; cross builds on top of rustup's target installation systemmoby/moby— Docker engine that powers cross's containerization; understanding Docker volumes and networking is essential for debugging mount issuesrust-embedded/cargo-binutils— Companion tool for embedded Rust; users of cross often also use cargo-binutils for inspecting cross-compiled binariescontainers/podman— Alternative container runtime that cross supports as a Docker replacement; shares same API surface but different daemon behaviorrust-lang/cargo— Core dependency and design inspiration; cross mirrors Cargo's CLI interface exactly to feel native to Rust developers
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Consolidate changelog entries into CHANGELOG.md automation
The .changes/ directory contains 50+ individual JSON changelog fragments (e.g., 1006.json, 1018.json, etc.). Currently, the release process has a pre-release hook that runs cargo xtask changelog build to consolidate these. However, there's no validation that these fragments conform to a schema, no pre-commit hook to catch malformed entries, and no GitHub Action to automatically validate changelog entries on PRs. This prevents contributor mistakes and ensures release automation doesn't fail.
- [ ] Create a JSON schema file (e.g.,
schemas/changelog-entry.json) that defines required fields for.changes/*.jsonentries - [ ] Add a validation script in
xtask/src/main.rsto validate all.changes/*.jsonfiles against this schema - [ ] Create a GitHub Action workflow (
.github/workflows/changelog-validate.yml) that runs this validation on every PR - [ ] Update CONTRIBUTING.md to document the changelog entry format and validation process
Add integration tests for cross-compilation targets
The repo targets multiple architectures (aarch64, armv7, x86_64, etc.) but the dev-dependencies only include basic testing utilities (regex, once_cell, ignore). There are no visible integration tests validating that cross build and cross test actually work for specific targets. Adding target-specific integration tests (even if they only run on CI with docker/qemu available) would catch regressions early and document expected behavior.
- [ ] Create
tests/integration/directory with a module per target architecture (e.g.,aarch64.rs,armv7.rs) - [ ] Add a simple test crate in
tests/fixtures/that can be compiled for multiple targets - [ ] Write integration tests that invoke
cross build --target <target>and validate output - [ ] Add a CI matrix in
.github/workflows/ci.ymlto run these tests for at least 3-5 different target triples
Add Windows-specific cross-compilation tests and documentation
The codebase has platform-specific dependencies for Windows (winapi, dunce) but there's no dedicated Windows CI or documentation explaining which cross-compilation targets are supported on Windows. The README's feature showcase image shows Linux testing only. This creates uncertainty for Windows users about what works.
- [ ] Add a
WINDOWS_SUPPORT.mdfile documenting which targets are testable/compilable on Windows and any known limitations - [ ] Add a Windows-specific GitHub Action job (
.github/workflows/ci.yml) that runscross buildfor at least 2-3 targets onwindows-latest - [ ] Add platform-specific unit tests in
src/that validate Windows-only code paths (e.g.,duncepath handling) with#[cfg(windows)]tests - [ ] Update
.cargo/config.tomldocumentation comments to explain Windows-specific settings if any exist
🌿Good first issues
- Add integration tests for the aarch64-unknown-linux-gnu target in tests/ directory to verify the full cross build → cross test → binary execution pipeline; currently only unit tests exist for config parsing.
- Write docs/target-matrix.md documenting officially supported target architectures, their corresponding Dockerfile locations, and any platform-specific quirks (e.g., which targets support cross test vs. cross build only).
- Implement --dry-run flag in CLI (src/main.rs) to print the exact Docker/Podman command that would be invoked without actually running containers; helpful for debugging and CI integration.
⭐Top contributors
Click to expand
Top contributors
- @Emilgardis — 50 commits
- @neuschaefer — 8 commits
- @garasubo — 4 commits
- @danieleades — 3 commits
- @reneleonhardt — 3 commits
📝Recent commits
Click to expand
Recent commits
65fe72b— Define cargo aliases as a strings instead of lists (#1772) (Emilgardis)5fa6464— Define cargo aliases as a strings instead of lists (legeana)f86fd03— fix: lower MSRV to 1.85 (#1762) (Emilgardis)fa944e6— fix(clippy): needless_lifetimes (xtqqczze)9274943— fix: lower MSRV to 1.85 (xtqqczze)588b3c9— Fix again FreeBSD image build (#1752) (Emilgardis)ca70711— Fix again FreeBSD image build (ydirson)19bc73f— improve /ci try (#1748) (Emilgardis)81608e1— make it possible to pass CROSS_DEBUG=true (Emilgardis)8ce6a3b— add reason for failure in output (Emilgardis)
🔒Security observations
The cross-rs project demonstrates a reasonably secure dependency profile with generally well-maintained crates. The main areas of concern are: (1) potential for shell injection through shell execution helpers if user input is not properly validated, (2) lack of exact version pinning for some dependencies which could introduce unexpected updates, and (3) the importance of regular security audits given the tool's role in compilation workflows where arbitrary code execution is inherent. The project uses reputable security-focused libraries (color-eyre, thiserror, signal-hook) which is positive. No obvious hardcoded credentials, secrets, or SQL/XSS injection risks were identified in the provided materials. Overall security posture is good with minor improvements recommended.
- Medium · Outdated Rust Version Requirement —
Cargo.toml - rust-version field. The project specifies rust-version = '1.85.0' which may contain known vulnerabilities. While this is not critical, it's important to regularly update to the latest stable Rust version to receive security patches. Fix: Regularly review and update the minimum Rust version to ensure security patches are included. Monitor Rust security advisories at https://rustsec.org/ - Low · Multiple Dependency Versions Not Pinned —
Cargo.toml - [dependencies] section. Several dependencies use loose version specifications (e.g., 'which = "8.0"', 'home = "0.5.4"') which can introduce minor/patch updates with potential breaking changes or vulnerabilities. While semantic versioning should prevent major breaking changes, pinning to exact versions provides more control. Fix: Consider using exact version pinning (e.g., '=0.5.4') for critical dependencies or enable auditing with 'cargo audit' to detect known vulnerabilities. - Low · Signal Handler Library Usage —
Cargo.toml - signal-hook dependency. The dependency 'signal-hook = "0.4"' is used without version pinning. Signal handling can be security-sensitive when dealing with process termination and cleanup. Fix: Pin the exact version and regularly audit this dependency for security updates. Ensure signal handlers properly cleanup resources and don't introduce race conditions. - Low · Shell Execution Dependencies —
Cargo.toml - shell-escape and shell-words dependencies. The project uses 'shell-escape = "0.1.5"' and 'shell-words = "1.1.0"' for shell command construction. While these are safety-oriented libraries, shell execution always carries risk of injection if not properly validated. Fix: Validate all user inputs before passing to shell execution. Use the shell-escape and shell-words libraries correctly to prevent shell injection attacks. Prefer native APIs over shell invocation when possible. - Low · Unrestricted Walk Directory Operations —
Cargo.toml - walkdir optional dependency. The 'walkdir' dependency is included as optional but could be used for recursive directory traversal without clear safeguards visible in dependency list. Fix: Ensure walkdir usage includes proper symlink handling (use 'follow_links(false)' by default) to prevent directory traversal attacks. Validate user-provided paths.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.