build: decouple Cargo.toml: split crate and workspace definitions

TL;DR: cargo clippy|check|... now runs on whole workspace by default.

## Steps

- add new workspace member `cloud-hypervisor`
- move `./src` to new workspace member
- move `./tests` to new workspace member
- move relevant parts from Cargo.toml to new workspace member
- kept necessary parts in main Cargo.toml, such as profile
  configurations

## About

The main Cargo.toml historically mixes workspace and crate definitions
for cloud-hypervisor and ch-remote. This makes it hard to read and
requires `--workspace` to run cargo clippy or cargo test on all
workspace members, which is counter-intuitive.

This patch separates the workspace from the crate definition in the main
Cargo.toml file. After this, cargo clippy, cargo test, etc., work on the
whole workspace naturally, giving a smoother developer experience. The
Cargo.toml without a package definition is also called a virtual
workspace or virtual manifest by Cargo [0].

Backporting is not a concern: CHV no longer backports, but the affected
files are rarely modified anyway.

[0] https://doc.rust-lang.org/cargo/reference/workspaces.html#virtual-workspace

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
This commit is contained in:
Philipp Schuster
2025-11-27 19:38:11 +01:00
committed by Rob Bradford
parent f104bcdb6b
commit 3d049765bd
9 changed files with 75 additions and 69 deletions

View File

@@ -0,0 +1,69 @@
[package]
authors = ["The Cloud Hypervisor Authors"]
build = "build.rs"
default-run = "cloud-hypervisor"
description = "Open source Virtual Machine Monitor (VMM) that runs on top of KVM & MSHV"
edition = "2024"
homepage = "https://github.com/cloud-hypervisor/cloud-hypervisor"
license = "Apache-2.0 AND BSD-3-Clause"
name = "cloud-hypervisor"
version = "49.0.0"
# Minimum buildable version:
# Keep in sync with version in .github/workflows/build.yaml
# Policy on MSRV (see #4318):
# Can only be bumped if satisfying any of the following:
# a.) A dependency requires it,
# b.) If we want to use a new feature and that MSRV is at least 6 months old,
# c.) There is a security issue that is addressed by the toolchain update.
rust-version = "1.89.0"
[dependencies]
anyhow = { workspace = true }
api_client = { path = "../api_client" }
clap = { workspace = true, features = ["string"] }
dhat = { workspace = true, optional = true }
env_logger = { workspace = true }
epoll = { workspace = true }
event_monitor = { path = "../event_monitor" }
hypervisor = { path = "../hypervisor" }
libc = { workspace = true }
log = { workspace = true, features = ["std"] }
option_parser = { path = "../option_parser" }
seccompiler = { workspace = true }
serde_json = { workspace = true }
signal-hook = { workspace = true }
thiserror = { workspace = true }
tpm = { path = "../tpm" }
tracer = { path = "../tracer" }
vm-memory = { workspace = true }
vmm = { path = "../vmm" }
vmm-sys-util = { workspace = true }
zbus = { version = "5.7.1", optional = true }
[dev-dependencies]
dirs = { workspace = true }
net_util = { path = "../net_util" }
serde_json = { workspace = true }
test_infra = { path = "../test_infra" }
wait-timeout = { workspace = true }
# Please adjust `vmm::feature_list()` accordingly when changing the
# feature list below
[features]
dbus_api = ["vmm/dbus_api", "zbus"]
default = ["io_uring", "kvm"]
dhat-heap = ["dhat", "vmm/dhat-heap"] # For heap profiling
fw_cfg = ["vmm/fw_cfg"]
guest_debug = ["vmm/guest_debug"]
igvm = ["mshv", "vmm/igvm"]
io_uring = ["vmm/io_uring"]
ivshmem = ["vmm/ivshmem"]
kvm = ["vmm/kvm"]
mshv = ["vmm/mshv"]
pvmemcontrol = ["vmm/pvmemcontrol"]
sev_snp = ["igvm", "mshv", "vmm/sev_snp"]
tdx = ["vmm/tdx"]
tracing = ["tracer/tracing", "vmm/tracing"]
[lints]
workspace = true

32
cloud-hypervisor/build.rs Normal file
View File

@@ -0,0 +1,32 @@
// Copyright © 2020 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
use std::env;
use std::process::Command;
fn main() {
let mut version = "v".to_owned() + env!("CARGO_PKG_VERSION");
if let Ok(git_out) = Command::new("git").args(["describe", "--dirty"]).output()
&& git_out.status.success()
&& let Ok(git_out_str) = String::from_utf8(git_out.stdout)
{
version = git_out_str;
// Pop the trailing newline.
version.pop();
}
// Append CH_EXTRA_VERSION to version if it is set.
if let Ok(extra_version) = env::var("CH_EXTRA_VERSION") {
println!("cargo:rerun-if-env-changed=CH_EXTRA_VERSION");
version.push_str(&format!("-{extra_version}"));
}
// This println!() has a special behavior, as it will set the environment
// variable BUILD_VERSION, so that it can be reused from the binary.
// Particularly, this is used from src/main.rs to display the exact
// version.
println!("cargo:rustc-env=BUILD_VERSION={version}");
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,46 @@
// Copyright © 2025 Cyberus Technology GmbH
//
// SPDX-License-Identifier: Apache-2.0
use std::error::Error;
use log::error;
/// Prints a chain of errors to the user in a consistent manner.
/// The user will see a clear chain of errors, followed by debug output
/// for opening issues.
pub fn cli_print_error_chain<'a>(
top_error: &'a (dyn Error + 'static),
component: &str,
// Function optionally returning the display representation of an error.
display_modifier: impl Fn(
/* level */ usize,
/*indention */ usize,
&'a (dyn Error + 'static),
) -> Option<String>,
) {
// Debug info.
error!("Fatal error: {top_error:?}");
eprint!("Error: {component} exited with the following ");
if top_error.source().is_none() {
eprintln!("error:");
eprintln!(" {top_error}");
} else {
eprintln!("chain of errors:");
std::iter::successors(Some(top_error), |sub_error| {
// Dereference necessary to mitigate rustc compiler bug.
// See <https://github.com/rust-lang/rust/issues/141673>
(*sub_error).source()
})
.enumerate()
.for_each(|(level, error)| {
// Special case: handling of HTTP Server responses in ch-remote
if let Some(message) = display_modifier(level, 2, error) {
eprintln!("{message}");
} else {
eprintln!(" {level}: {error}");
}
});
}
}

2018
cloud-hypervisor/src/main.rs Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,24 @@
// Copyright © 2025 Cyberus Technology GmbH
//
// SPDX-License-Identifier: Apache-2.0
//
//! Test utilities.
use std::cmp::Ordering;
use clap::Arg;
/// Ensures that all [`Arg`]s are sorted alphabetically.
pub fn assert_args_sorted<'a, F: Fn() -> R, R: Iterator<Item = &'a Arg>>(get_base_iter: F) {
let iter = get_base_iter().zip(get_base_iter().skip(1));
for (arg, next) in iter {
assert_ne!(
arg.get_id().cmp(next.get_id()),
Ordering::Greater,
"args not alphabetically sorted: arg={}, next={}",
arg.get_id(),
next.get_id()
);
}
}

File diff suppressed because it is too large Load Diff