cross

repository·main·Indexed 27 days ago

https://github.com/cross-rs/cross

A tool for 'zero setup' cross-compilation and cross-testing of Rust crates using container engines like Docker or Podman. It leverages the same CLI as cargo to provide environments and toolchains for different architectures without modifying the system installation. Supports a wide range of targets, including Android and embedded systems, and allows for detailed configuration via Cargo.toml, Cross.toml, or environment variables.

Tokens
13.8K
Snippets
37
Records
87
Agent score
94%

What's inside cross

  1. Use Android build system utilities

    main
    The android package provides utilities for interacting with the Android project build system. It is specifically designed to facilitate modifications to both Soong and Make build files. A primary use case is removing unittests from the build configuration to increase build speeds and minimize the total number of dependencies required during the build process.
  2. Configure `cross` via config files or environment variables

    main
    You can configure cross using either a configuration file or environment variables. For detailed information on the configuration file schema, refer to the config_file.md documentation. For a complete list of supported environment variables, refer to the environment_variables.md documentation.
  3. Run cross inside a container (Docker in Docker)

    main

    To run cross from within a container, you must mount the host's Docker daemon socket and set the CROSS_CONTAINER_IN_CONTAINER environment variable to true. The container running cross must have Rust development tools installed.

    Example usage:

    docker run -v /var/run/docker.sock:/var/run/docker.sock -v .:/project \
      -w /project my/development-image:tag cross build --target mips64-unknown-linux-gnuabi64

    Dockerfile snippet:

    FROM rust:1
    
    # Inform cross it is running inside a container
    ENV CROSS_CONTAINER_IN_CONTAINER=true
    
    RUN cargo install cross

    Limitation: Finding the mount point for the container's root directory is currently only available for the overlayfs2 storage driver.

  4. Use persistent data volumes for remote builds

    main

    Copying the entire toolchain to a remote host can be slow. To optimize performance, you can create a persistent data volume for the current toolchain. cross will detect if a persistent volume is present and prefer it over single-use volumes. The persistent volume contains project files and synchronizes changes from the local project on every build.

    cross-util volumes crate
  5. Use a pre-built custom image for a specific target

    main

    If you have a pre-built Docker image available for a target, you can instruct cross to use it via the target.{{TARGET}}.image field in Cross.toml.

    cross follows standard Docker image resolution logic:

    • It first looks for a local image named my/image:tag.
    • If not found locally, it looks in Docker Hub.
    • If only image:tag is specified, it will not look in Docker Hub.
    • If the tag is omitted, Docker defaults to the latest tag.
    [target.aarch64-unknown-linux-gnu]
    image = "my/image:tag"
  6. Configure cross dependencies and requirements

    main

    Before using cross, ensure the following dependencies are met:

    • rustup: Required for Rust toolchain management.
    • Linux kernel: Requires binfmt_misc support for cross testing.
    • Container Engine: Either Docker (version 20.10 / API 1.40 or later) or Podman (version 3.4.0 or later). If both are installed, cross defaults to docker.

    Note for Linux users: If using Docker, non-sudo users must be in the docker group or use rootless Docker. You must also ensure the Docker daemon is running (e.g., sudo systemctl start docker or sudo service docker start on WSL2/SysVinit).

  7. Use vendored OpenSSL in Rust

    main

    To use the vendored version of OpenSSL instead of relying on system libraries, add the openssl crate to your Cargo.toml with the vendored feature enabled.

    openssl = { version = "0.10", features = ["vendored"] }
  8. Support private dependencies in remote builds

    main

    When using private dependencies (e.g., via SSH), you must copy the cargo registry because these dependencies are downloaded locally on the host. Without this, the remote container will not have access to the necessary credentials or the downloaded crates.

    Note: This approach may only support single-use volumes and has not been extensively tested.

    CROSS_REMOTE_COPY_REGISTRY=1 CROSS_REMOTE=1 cross build --target arm-unknown-linux-gnueabihf
  9. Install Cross

    main

    Once cargo is installed via rustup, you can install cross using cargo install. If you have cargo-binstall installed, you can use it to install via a pre-built binary instead.

    cargo install cross
    # Optionally, if you have cargo-binstall, you can install via pre-built binary
    cargo binstall cross
  10. Use a remote container engine with cross

    main

    To use a remote container engine (like a remote Docker daemon or Podman) instead of local bind mounts, set the CROSS_REMOTE=1 environment variable. In this mode, cross copies data from the local filesystem into data volumes on the remote host and symlinks them to ensure paths match the host's structure.

    Docker Remote

    If using Docker, you can specify the DOCKER_HOST. If you use Docker contexts, you do not need to provide DOCKER_HOST manually.

    Podman Remote

    This works with podman and podman-remote. For podman-remote, ensure the connection is added to podman. If using an authenticated connection, set it to the default identity to avoid password prompts.

    cross automatically detects if podman or podman-remote is being used and adds the --remote flag to the engine command if necessary.

    # Example using Docker remote
    CROSS_REMOTE=1 DOCKER_HOST=tcp://docker:2375/ cross build --target arm-unknown-linux-gnueabihf
    
    # Example using Podman remote
    podman system connection add cross tcp://localhost:8080 --default=true
    CROSS_REMOTE=1 CROSS_CONTAINER_ENGINE=podman cross build --target arm-unknown-linux-gnueabihf
  11. Integrate C++ build systems (vcpkg, Meson, Conan) with Rust

    main
    For complex C++ dependencies, use meson-rs or cmake-rs within your Rust project to trigger builds. This allows you to leverage Cross-compatible Docker images that have Meson, Conan, or vcpkg pre-installed, which automatically handle cross-compilation via pre-build hooks.
  12. Enable unstable features via environment variables

    main

    Certain unstable features in cross can enable additional functionality, such as running doctests. These features are experimental, may be removed at any time, and will only be used when running on a nightly Rust channel.

    To use an unstable feature, set the corresponding environment variable before running your cross command.