-
Notifications
You must be signed in to change notification settings - Fork 379
Configuration
Documentation for how to configure cross through config files and environment variables.
Table of Contents
- Config File
- Custom Images
- Environment Variables
- Cargo Configuration
- Environment Variable Passthrough
- Unstable Features
You can place a Cross.toml file in the root of your Cargo project or use a CROSS_CONFIG
environment variable to tweak cross's behavior. You can also use package.metadata.cross.KEY
in Cargo.toml
, and the priority of settings is environment variables override Cross.toml
options, which override Cargo.toml
options. An annotated examples of both Cross.toml and Cargo.toml are provided
For example, the [build]
table in Cross.toml
is identical to setting [package.metadata.cross.build]
in Cargo.toml
.
The cross
configuration in the Cross.toml
file, can contain the following elements:
The build
key allows you to set global variables, e.g.:
[build]
build-std = false # do not build the std library. has precedence over xargo
xargo = true # enable the use of xargo by default
zig = false # do not use zig cc for the builds
default-target = "x86_64-unknown-linux-gnu" # use this target if none is explicitly provided
pre-build = [ # additional commands to run prior to building the package
"dpkg --add-architecture $CROSS_DEB_ARCH",
"apt-get update && apt-get --assume-yes install libssl-dev:$CROSS_DEB_ARCH"
]
With the build.env
key you can globally set volumes that should be mounted
in the Docker container or environment variables that should be passed through.
For example:
[build.env]
volumes = ["VOL1_ARG", "VOL2_ARG=/path/to/volume"]
passthrough = ["VAR1_ARG", "VAR2_ARG=VALUE"]
Note how in the environment variable passthrough, we can provide a definition for the variable as well. VAR1_ARG
will be the value of the environment variable on the host, while VAR2_ARG
will be VALUE
. Likewise, the path to the volume for VOL1_ARG
will be the value of the environment variable on the host, while VOL2_ARG
will be /path/to/volume
.
The build.dockerfile
key lets you provide a custom Docker image for all targets, except those specified target.TARGET.dockerfile
. You probably do not mean to use this. The value can be provided as either a table or a string. If build.dockerfile
is set to a string, it's equivalent to setting build.dockerfile.file
to that value. For example, using only a string:
[build]
dockerfile = "./Dockerfile"
Or using a table:
[build.dockerfile]
file = "./Dockerfile" # the dockerfile to use relative to the `Cargo.toml`
context = "." # the context folder to build the script in. defaults to `.`
build-args = { ARG1 = "foo" } # https://docs.docker.com/engine/reference/builder/#arg
cross will provide the argument CROSS_BASE_IMAGE
which points to the image cross would use for the target. Example:
ARG CROSS_BASE_IMAGE
FROM $CROSS_BASE_IMAGE
RUN ...
The build.zig
key lets you use zig cc
as a cross-compiler, enabling cross-compilation to numerous architectures and glibc versions using a single Docker image. Note that zig cc
doesn't support all targets: only a subset of our Linux GNU targets, so it might be better to set these values in target.TARGET.zig
instead. The value can be provided as either a table, a bool, or a string. If build.zig
is set to a string, it's equivalent to setting build.zig.version
to that value and build.zig.enable
to true
:
[build]
zig = "2.17"
If build.zig
is set to a bool, it's equivalent to setting build.zig.enable
to that value:
[build]
zig = true
Or using a table:
[build.zig]
enable = true # enable or disable the use of zig cc
version = "2.17" # the glibc version to use
image = "myimage" # a custom image containing zig to use
The target
key allows you to specify parameters for specific compilation targets.
[target.aarch64-unknown-linux-gnu]
build-std = false # always build the std library. has precedence over xargo
xargo = false # disable the use of xargo
image = "test-image" # use a different image for the target
runner = "qemu-user" # wrapper to run the binary (must be `qemu-system`, `qemu-user`, or `native`).
The pre-build
field can also reference a file to copy and run. This file is relative to the container context, which would be the workspace root, or the current directory if --manifest-path
is used. For more involved scripts, consider using target.TARGET.dockerfile
instead to directly control the execution.
This script will be invoked as RUN ./pre-build-script $CROSS_TARGET
where $CROSS_TARGET
is the target triple.
[target.aarch64-unknown-linux-gnu]
pre-build = "./scripts/my-script.sh"
$ cat ./scripts/my-script.sh
#!/usr/bin/env bash
apt-get install libssl-dev -y
[target.aarch64-unknown-linux-gnu]
image = "my_image:latest"
The image
key can also take the toolchains/platforms supported by the image.
[target.aarch64-unknown-linux-gnu]
image.name = "alpine:edge"
image.toolchain = ["x86_64-unknown-linux-musl", "linux/arm64=aarch64-unknown-linux-musl"] # Defaults to `x86_64-unknown-linux-gnu`
The target
key allows you to specify environment variables that should be used for a specific compilation target.
This is similar to build.env, but allows you to be more specific per target.
[target.x86_64-unknown-linux-gnu.env]
volumes = ["VOL1_ARG", "VOL2_ARG=/path/to/volume"]
passthrough = ["VAR1_ARG", "VAR2_ARG=VALUE"]
The target.(...).dockerfile
key lets you provide a custom Docker image for the given target. The value can be provided as either a table or a string. If target.TARGET.dockerfile
is set to a string, it's equivalent to setting target.(...).dockerfile.file
to that value. For example, using only a string:
[target.aarch64-unknown-linux-gnu]
dockerfile = "./Dockerfile"
Or using a table:
[target.aarch64-unknown-linux-gnu.dockerfile]
file = "./Dockerfile" # the dockerfile to use relative to the `Cargo.toml`
context = "." # the context folder to build the script in. defaults to `.`
build-args = { ARG1 = "foo" } # https://docs.docker.com/engine/reference/builder/#arg
The target.TARGET.zig
key lets you use zig cc
as a cross-compiler, enabling cross-compilation to numerous architectures and glibc versions using a single Docker image. The value can be provided as either a table, a bool, or a string. If target.TARGET.zig
is set to a string, it's equivalent to setting target.TARGET.zig.version
to that value and target.TARGET.zig.enable
to true
:
[target.aarch64-unknown-linux-gnu]
zig = "2.17"
If target.TARGET.zig
is set to a bool, it's equivalent to setting target.TARGET.zig.enable
to that value:
[target.aarch64-unknown-linux-gnu]
zig = true
Or using a table:
[target.aarch64-unknown-linux-gnu.zig]
enable = true # enable or disable the use of zig cc
version = "2.17" # the glibc version to use
image = "myimage" # a custom image containing zig to use
Custom images generated from config dockerfile
or pre-build
keys will export CROSS_DEB_ARCH
, which allows you to install packages from Ubuntu/Debian repositories without having to specify the exact architecture. For example, to install OpenSSL
for the target, you can do:
[target.aarch64-unknown-linux-gnu]
pre-build = [
"dpkg --add-architecture $CROSS_DEB_ARCH",
"apt-get update && apt-get --assume-yes install libssl-dev:$CROSS_DEB_ARCH"
]
Here, CROSS_DEB_ARCH
will automatically evaluate to arm64
, without you having to explicitly provide it.
Cross can be further customized by setting certain environment variables. In-depth documentation with examples can be found here.
-
CROSS_CONTAINER_ENGINE
: The container engine to run cross in. Defaults todocker
thenpodman
, whichever is found first (example:docker
, see the FAQ). -
XARGO_HOME
: Home for xargo (example:~/.xargo
). -
NIX_STORE
: The directory for the Nix store (example:/nix/store
). -
CROSS_CONTAINER_UID
: Set the user identifier for the cross command (example:1000
). -
CROSS_CONTAINER_GID
: Set the group identifier for the cross command (example:1000
). -
CROSS_CONTAINER_IN_CONTAINER
: Inform cross that it is running inside a container (example:true
, see the FAQ). -
CROSS_CONTAINER_OPTS
: Additional arguments to provide to the container engine during$engine run
(example:--env MYVAR=1
whereengine=docker
). -
CROSS_CONFIG
: Specify the path to thecross
config file (see Config File). -
CROSS_BUILD_OPTS
: Space separated flags to add when building a custom image, i.e--network=host
-
CROSS_DEBUG
: Print debugging information for cross. -
CROSS_COMPATIBILITY_VERSION
: Use older cross behavior (example:0.2.1
). -
CROSS_CUSTOM_TOOLCHAIN
: Specify that rustup is using a custom toolchain, and therefore should not try to add targets/install components. Useful with cargo-bisect-rustc. -
CROSS_REMOTE
: Inform cross it is using a remote container engine, and use data volumes rather than local bind mounts. See Remote for more information using remote container engines. -
QEMU_STRACE
: Get a backtrace of of system calls from “foreign” (non x86_64) binaries when usingcross run
. -
CARGO_BUILD_TARGET
: Sets the default target, similar to specifying--target
. -
CROSS_ROOTLESS_CONTAINER_ENGINE
: Specify whether to container engine runs as root or is rootless. If set toauto
or not provided, it assumes docker runs as root and all other container engines are rootless. -
CROSS_CONTAINER_USER_NAMESPACE
: Custom the container user namespace. If set tonone
, user namespaces will be disabled. If not provided or set toauto
, it will use the default namespace. -
CROSS_CUSTOM_TOOLCHAIN_COMPAT
: A descriptive name for a custom toolchain socross
can convert it to a fully-qualified toolchain name. -
CROSS_CONTAINER_ENGINE_NO_BUILDKIT
: The container engine does not havebuildx
command (or BuildKit support) when building custom images.
All config file options can also be specified using environment variables. For example, setting CROSS_BUILD_XARGO=1
is identical to setting build.xargo = true
, and CROSS_TARGET_AARCH64_UNKNOWN_LINUX_GNU_XARGO=1
is identical to target.aarch64-unknown-linux-gnu.xargo = true
.
When cross-compiling, cargo
does not use environment variables such as RUSTFLAGS
, and must be provided using CARGO_TARGET_${TARGET}_${OPTION}
. Please note that some of these may be provided by the image themselves, such as runners, and should be provided with caution. A list of important flags includes:
-
CARGO_TARGET_${TARGET}_LINKER
: specify a custom linker passed to rustc. -
CARGO_TARGET_${TARGET}_RUNNER
: specify the wrapper to run executables. -
CARGO_TARGET_${TARGET}_RUSTFLAGS
: add additional flags passed torustc
.
Any of the following flags can be provided, and are converted to uppercase. For example, changing foo-bar
would be provided as CARGO_TARGET_${TARGET}_FOO_BAR
.
For example, to run binaries on i686-unknown-linux-gnu
with Qemu, first create a custom image containing Qemu, and run with the following command:
CARGO_TARGET_I686_UNKNOWN_LINUX_GNU_RUNNER=qemu-i386 cross run ...
By default, cross does not pass most environment variables into the build environment from the calling shell. This is chosen as a safe default as most use cases will not want the calling environment leaking into the inner execution environment. There are, however, some notable exceptions: most environment variables cross or cargo reads are passed through automatically to the build environment. The major exceptions are variables that are set by cross or conflict with our build environment, including:
CARGO_HOME
CARGO_TARGET_DIR
CARGO_BUILD_TARGET_DIR
CARGO_BUILD_RUSTC
CARGO_BUILD_RUSTC_WRAPPER
CARGO_BUILD_RUSTC_WORKSPACE_WRAPPER
CARGO_BUILD_RUSTDOC
CROSS_RUNNER
CROSS_RUSTC_MAJOR_VERSION
CROSS_RUSTC_MINOR_VERSION
CROSS_RUSTC_PATCH_VERSION
Otherwise, any environment variables that start with CARGO_
or CROSS_
, and a few others, will be available in the build environment. For example, RUSTFLAGS
and CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUSTFLAGS
will both be automatically available in the build environment.
Certain unstable features can enable additional functionality useful to cross-compiling. Note that these are unstable, and may be removed at any time (particularly if the feature is stabilized or removed), and will only be used on a nightly channel.
-
CROSS_UNSTABLE_ENABLE_DOCTESTS
: enable or disable running doctests (example:true
).