src/ci/docker/README.md
This folder contains a bunch of docker images used by the continuous integration
(CI) of Rust. A script is accompanied (run.sh) with these images to actually
execute them.
Note that a single Docker image can be used by multiple CI jobs, so the job name
is the important thing that you should know. You can examine the existing CI jobs in
the jobs.yml file.
To run a specific CI job locally, you can use the citool Rust crate:
cargo run --manifest-path src/ci/citool/Cargo.toml run-local <job-name>
For example, to run the x86_64-gnu-llvm-21-1 job:
cargo run --manifest-path src/ci/citool/Cargo.toml run-local x86_64-gnu-llvm-21-1
The job will output artifacts in an obj/<image-name> dir at the root of a repository. Note
that the script will overwrite the contents of this directory. <image-name> is set based on the
Docker image executed in the given CI job.
NOTE: In CI, the script outputs the artifacts to the obj directory,
while locally, to the obj/<image-name> directory. This is primarily to prevent
strange linker errors when using multiple Docker images.
For some Linux workflows (for example x86_64-gnu-llvm-21-N), the process is more involved. You will need to see which script is executed for the given workflow inside the jobs.yml file and pass it through the DOCKER_SCRIPT environment variable. For example, to reproduce the x86_64-gnu-llvm-21-3 workflow, you can run the following script:
DOCKER_SCRIPT=x86_64-gnu-llvm3.sh ./src/ci/docker/run.sh x86_64-gnu-llvm-21
Refer to the dev guide for more information on testing locally.
host-{arch} directory, and those
directories contain a subdirectory for each Docker image (plus the disabled
subdirectory).host-{arch}/disabled contains images that are not built on CI.scripts contains files shared by multiple Docker images.For Windows before Windows 10, the docker images can be run on Windows via Docker Toolbox. There are several preparations that need to be made before running a Docker image.
Stop the virtual machine from the terminal with docker-machine stop
If your Rust source is placed outside of C:\Users\**, e.g. if you place the
repository in the E:\rust folder, please add a shared folder from
VirtualBox by:
Select the "default" virtual machine inside VirtualBox, then click "Settings"
Go to "Shared Folders", click "Add shared folder" (the folder icon with a plus sign), fill in the following information, then click "OK":
E:\ruste/rustVirtualBox might not support creating symbolic links inside a shared folder
by default. You can enable it manually by running these from cmd.exe:
cd "C:\Program Files\Oracle\VirtualBox"
VBoxManage setextradata default VBoxInternal2/SharedFoldersEnableSymlinksCreate/e/rust 1
:: ^~~~~~
:: folder name
Restart the virtual machine from terminal with docker-machine start.
To run the image,
./src/ci/docker/run.sh $image_name as explained at the beginning.A number of these images take quite a long time to compile as they're building
whole gcc toolchains to do cross builds with. Much of this is relatively
self-explanatory but some images use crosstool-ng which isn't quite as self
explanatory. Below is a description of where these *.defconfig files come from,
how to generate them, and how the existing ones were generated.
.defconfig fileNOTE: Existing Dockerfiles can also be a good guide for the process and order of script execution.
If you have a linux-cross image lying around you can use that and skip the
next two steps.
# Note: We use ubuntu:22.04 because that's the "base" of linux-cross Docker
# image, or simply run ./src/ci/docker/run.sh once, which will download the correct
# one and you can check it out with `docker images`
$ docker run -it ubuntu:22.04 bash
# in another terminal:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cfbec05ed730 ubuntu:22.04 "bash" 16 seconds ago Up 15 seconds drunk_murdock
$ docker cp src/ci/docker/scripts drunk_murdock:/tmp/
$ cd /tmp/scripts
# Download packages necessary for building
$ bash ./cross-apt-packages.sh
# Download and build crosstool-ng
$ bash ./crosstool-ng.sh
crosstool-ng will automatically load ./.config if
present. Otherwise one can use the TUI to load any config-file.$ docker cp arm-linux-gnueabi.defconfig drunk_murdock:/tmp/.config
$ cd /tmp/
$ ct-ng olddefconfig
$ ct-ng menuconfig
$ ct-ng savedefconfig
defconfig file from the container and give it a
meaningful name. This is done outside the container.$ docker cp drunk_murdock:/tmp/defconfig arm-linux-gnueabi.defconfig
.defconfig file.Changes on top of the default toolchain configuration used to generate the
.defconfig files in this directory. The changes are formatted as follows:
$category > $option = $value -- $comment
arm-linux-gnueabi.defconfigFor targets: arm-unknown-linux-gnueabi
arm-linux-gnueabihf.defconfigFor targets: arm-unknown-linux-gnueabihf
armv7-linux-gnueabihf.defconfigFor targets: armv7-unknown-linux-gnueabihf
(*) These options have been selected to match the configuration of the arm toolchains shipped with Ubuntu 15.10 (+) These options have been selected to match the gcc flags we use to compile C libraries like jemalloc. See the mk/cfg/arm(v7)-unknown-linux-gnueabi{,hf}.mk file in Rust's source code.
i586-linux-gnu.defconfigFor targets: i586-unknown-linux-gnu, i586-unknown-linux-musl and i686-unknown-linux-musl
(*) Compressed debug is enabled by default for gas (assembly) on Linux/x86 targets,
but that makes our compiler_builtins incompatible with binutils < 2.32.
loongarch64-unknown-linux-gnu.defconfigFor targets: loongarch64-unknown-linux-gnu
loongarch64-unknown-linux-musl.defconfigFor targets: loongarch64-unknown-linux-musl
mips-linux-gnu.defconfigFor targets: mips-unknown-linux-gnu
mipsel-linux-gnu.defconfigFor targets: mipsel-unknown-linux-gnu
mips64-linux-gnu.defconfigFor targets: mips64-unknown-linux-gnuabi64
mips64el-linux-gnu.defconfigFor targets: mips64el-unknown-linux-gnuabi64
powerpc-linux-gnu.defconfigFor targets: powerpc-unknown-linux-gnu
powerpc64-linux-gnu.defconfigFor targets: powerpc64-unknown-linux-gnu
(+) These CPU options match the configuration of the toolchains in RHEL6.
powerpc64-unknown-linux-musl.defconfigFor targets: powerpc64-unknown-linux-musl
powerpc64le-unknown-linux-gnu.defconfigFor targets: powerpc64le-unknown-linux-gnu
powerpc64le-unknown-linux-musl.defconfigFor targets: powerpc64le-unknown-linux-musl
riscv64-unknown-linux-gnu.defconfigFor targets: riscv64-unknown-linux-gnu
riscv64-unknown-linux-musl.defconfigFor targets: riscv64-unknown-linux-musl
s390x-linux-gnu.defconfigFor targets: s390x-unknown-linux-gnu