Building for Linux
Checking out
Obtain the source code via git clone.
git clone https://chromium.googlesource.com/chromiumos/platform/crosvm
Setting up the development environment
Crosvm uses submodules to manage external dependencies. Initialize them via:
git submodule update --init
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):
git config submodule.recurse true
git config push.recurseSubmodules no
Crosvm development best works on Debian derivatives. First install rust via https://rustup.rs/. Then for the rest, we provide a script to install the necessary packages on Debian:
./tools/install-deps
For other systems, please see below for instructions on Using the development container.
Setting up for cross-compilation
Crosvm is built and tested on x86, aarch64 and armhf. Your host needs to be set up to allow installation of foreign architecture packages.
On Debian this is as easy as:
sudo dpkg --add-architecture arm64
sudo dpkg --add-architecture armhf
sudo apt update
On ubuntu this is a little harder and needs some manual modifications of APT sources.
For other systems (including gLinux), please see below for instructions on Using the development container.
With that enabled, the following scripts will install the needed packages:
./tools/install-aarch64-deps
./tools/install-armhf-deps
Using the development container
We provide a Debian container with the required packages installed. With Docker installed, it can be started with:
./tools/dev_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:
./tools/dev_container cargo build
Note: The container and build artifacts are preserved between calls to ./tools/dev_container. If
you wish to start fresh, use the --reset flag.
Building a binary
If you simply want to try crosvm, run cargo build. Then the binary is generated at
./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
Iterative development
You can use cargo as usual for crosvm development to cargo build and cargo test single crates
that you are working on.
If you are working on aarch64 specific code, you can use the set_test_target tool to instruct
cargo to build for aarch64 and run tests on a VM:
./tools/set_test_target vm:aarch64 && source .envrc
cd mycrate && cargo test
The script will start a VM for testing and write environment variables for cargo to .envrc. With
those cargo build will build for aarch64 and cargo test will run tests inside the VM.
The aarch64 VM can be managed with the ./tools/aarch64vm script.
Running all tests
Crosvm cannot use cargo test --workspace because of various restrictions of cargo. So we have our
own test runner:
./tools/run_tests
Which will run all tests locally. Since we have some architecture-dependent code, we also have the option of running tests within an aarch64 VM:
./tools/run_tests --target=vm:aarch64
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.
./tools/dev_container ./tools/run_tests --target=vm:aarch64
It is also possible to run tests on a remote machine via ssh. The target architecture is automatically detected:
./tools/run_tests --target=ssh:hostname
However, it is your responsibility to make sure the required libraries for crosvm are installed and
password-less authentication is set up. See ./tools/impl/testvm/cloud_init.yaml for hints on what
the VM has installed.
Presubmit checks
To verify changes before submitting, use the presubmit script:
./tools/presubmit
This will run clippy, formatters and runs all tests. The presubmits will use the dev container to build for other platforms if your host is not set up to do so.
To run checks faster, they can be run in parallel in multiple tmux panes:
./tools/presubmit --tmux
The --quick variant will skip some slower checks, like building for other platforms altogether:
./tools/presubmit --quick
Known issues
- By default, crosvm is running devices in sandboxed mode, which requires seccomp policy files to be
set up. For local testing it is often easier to
--disable-sandboxto run everything in a single process. - If your Linux header files are too old, you may find minijail rejecting seccomp filters for
containing unknown syscalls. You can try removing the offending lines from the filter file, or add
--seccomp-log-failuresto the crosvm command line to turn these into warnings. Note that this option will also stop minijail from killing processes that violate the seccomp rule, making the sandboxing much less aggressive. - Seccomp policy files have hardcoded absolute paths. You can either fix up the paths locally, or
set up an awesome hacky symlink:
sudo mkdir /usr/share/policy && sudo ln -s /path/to/crosvm/seccomp/x86_64 /usr/share/policy/crosvm. We'll eventually build the precompiled policies into the crosvm binary. - 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.