Building Crosvm on Linux
This page describes how to build and develop crosvm on linux. If you are targeting ChromeOS, please see Integration
Checking out
Obtain the source code via git clone.
Setting up the development environment
Crosvm uses submodules to manage external dependencies. Initialize them via:
It is recommended to enable automatic recursive operations to keep the submodules in sync with the main repository (but do not push them, as that can conflict with repo):
Crosvm development best works on Debian derivatives. We provide a script to install the necessary packages on Debian, Ubuntu or gLinux:
For other systems, please see below for instructions on Using the development container.
Using the development container
We provide a Debian container with the required packages installed. With Podman or Docker installed, it can be started with:
NOTE: to use podman, you will need to install passt.
KVM access on Linux systems is typically managed via supplemental user groups. To access KVM from inside the development container on such systems podman has to use 'crun' runtime. This runtime supports preserving user's supplemental groups when starting a container.
The container image is big and may take a while to download when first used. Once started, you can follow all instructions in this document within the container shell.
Instead of using the interactive shell, commands to execute can be provided directly:
Note: The container and build artifacts are preserved between calls to ./tools/dev_container. If you wish to start fresh, use the --clean flag.
Building a binary
If you simply want to try crosvm, run cargo build. Then the executable is generated at ./target/debug/crosvm. In case you are using development container, the executable will be inside the dev container at /scratch/cargo_target/debug/crosvm.
Now you can move to Example Usage.
If you want to enable additional features, use the --features flag. (e.g. cargo build --features=gdb)
Development
Running all tests
Crosvm's integration tests have special requirements for execution (see Testing), so we use a special test runner. By default it will only execute unit tests:
To execute integration tests as well, you need to specify a device-under-test (DUT). The most reliable option is to use the built-in VM for testing:
However, you can also use your local host directly. Your mileage may vary depending on your host kernel version and permissions.
Since we have some architecture-dependent code, we also have the option of running unit tests for aarch64, riscv64, and windows (mingw64). These will use an emulator to execute (QEMU or wine):
When working on a machine that does not support cross-compilation (e.g. gLinux), you can use the dev container to build and run the tests.
Presubmit checks
To verify changes before submitting, use the presubmit script. To ensure the toolchains for all platforms are available, it is recommended to run it inside the dev container.
This will run clippy, formatters and runs all tests for all platforms. The same checks will also be run by our CI system before changes are merged into main.
See tools/presumit -h for details on various options for selecting which checks should be run to trade off speed and accuracy.
Cross-compilation
Crosvm is built and tested on x86, aarch64, and riscv64. Your system needs some setup work to be able to cross-compile for other architectures, hence it is recommended to use the development container, which will have everything configured.
Note: Cross-compilation is not supported on gLinux. Please use the development container.
Enable foreign architectures
Your host needs to be set up to allow installation of foreign architecture packages.
On Debian this is as easy as:
On ubuntu this is a little harder and needs some manual modifications of APT sources.
With that enabled, the following scripts will install the needed packages:
Configuring wine and mingw64
Crosvm is also compiled and tested on windows. Some limited testing can be done with mingw64 and wine on linux machines. Use the provided setup script to install the needed dependencies.
Configure cargo for cross-compilation
Cargo requries additional configuration to support cross-compilation. You can copy the provided example config to your cargo configuration:
Note
In case of cross-compilation, crosvm executable would be at ./target/debug/<target>/crosvm. If cross-compiling inside development container, the executable would be inside dev container at /scratch/cargo_target/<target>/debug/crosvm.
e.g For aarch64, target will be aarch64-unknown-linux-gnu and you can build using
Known issues
Devices can't be jailed if
/var/emptydoesn't exist.sudo mkdir -p /var/emptyto work around this for now.You need read/write permissions for
/dev/kvmto run tests or other crosvm instances. Usually it's owned by thekvmgroup, sosudo usermod -a -G kvm $USERand then log out and back in again to fix this.Some other features (networking) require
CAP_NET_ADMINso those usually need to be run as root.