Skip to content

Add xtask to generate manpages #792

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Apr 15, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
[target.aarch64-unknown-linux-musl]
rustflags = [ "-C", "target-feature=+crt-static", "-C", "link-arg=-lgcc" ]

[alias]
xtask = "run --package xtask --"
41 changes: 41 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@ members = [
"vhost-device-spi",
"vhost-device-template",
"vhost-device-vsock",
"xtask",
]
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,3 +115,11 @@ Supporting Xen requires special handling while mapping the guest memory. The

It was decided by the `rust-vmm` maintainers to keep the interface simple and
build the crate for either standard Unix memory mapping or Xen, and not both.

## Packaging and distribution

The [`xtask`](./xtask/) workspace crate provides support for generating ROFF manual pages.

If the binary you're interested in packaging does not have a manual page
generated you are encouraged to file a bug or even contribute the necessary
changes by filing a pull request.
2 changes: 1 addition & 1 deletion coverage_config_x86_64.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"coverage_score": 86.60,
"exclude_path": "",
"exclude_path": "xtask",
"crate_features": ""
}
23 changes: 11 additions & 12 deletions vhost-device-scmi/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,22 +40,21 @@ messages on the standard error output.

The daemon should be started first:

::

host# vhost-device-scmi --socket-path=scmi.sock --device fake,name=foo
```shell
host# vhost-device-scmi --socket-path=scmi.sock --device fake,name=foo
```

The QEMU invocation needs to create a chardev socket the device can
use to communicate as well as share the guests memory over a memfd:

::

host# qemu-system \
-chardev socket,path=scmi.sock,id=scmi \
-device vhost-user-scmi-pci,chardev=vscmi,id=scmi \
-machine YOUR-MACHINE-OPTIONS,memory-backend=mem \
-m 4096 \
-object memory-backend-file,id=mem,size=4G,mem-path=/dev/shm,share=on \
...
```shell
host# qemu-system \
-chardev socket,path=scmi.sock,id=scmi \
-device vhost-user-scmi-pci,chardev=vscmi,id=scmi \
-machine YOUR-MACHINE-OPTIONS,memory-backend=mem \
-m 4096 \
-object memory-backend-file,id=mem,size=4G,mem-path=/dev/shm,share=on \
```

## Supported SCMI protocols

Expand Down
32 changes: 32 additions & 0 deletions vhost-device-scmi/src/args.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// SPDX-FileCopyrightText: Red Hat, Inc.
// SPDX-License-Identifier: Apache-2.0
// Based on implementation of other devices here, Copyright by Linaro Ltd.
//! An arguments type for the binary interface of this library.

use std::path::PathBuf;

use clap::Parser;

#[derive(Parser)]
#[command(author, version, about, long_about = None)]
pub struct ScmiArgs {
// Location of vhost-user Unix domain socket.
// Required, unless one of the --help options is used.
#[clap(
short,
long,
default_value_if(
"help_devices",
clap::builder::ArgPredicate::IsPresent,
"PathBuf::new()"
),
help = "vhost-user socket to use"
)]
pub socket_path: PathBuf,
// Specification of SCMI devices to create.
#[clap(short, long, help = "Devices to expose")]
#[arg(num_args(1..))]
pub device: Vec<String>,
#[clap(long, exclusive = true, help = "Print help on available devices")]
pub help_devices: bool,
}
35 changes: 6 additions & 29 deletions vhost-device-scmi/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
//! --device iio,path=/sys/bus/iio/devices/iio:device0,channel=in_accel
//! ```

pub mod args;
mod devices;
mod scmi;
mod vhu_scmi;
Expand All @@ -54,39 +55,15 @@ use vm_memory::{GuestMemoryAtomic, GuestMemoryMmap};

type Result<T> = std::result::Result<T, String>;

#[derive(Parser)]
#[command(author, version, about, long_about = None)]
struct ScmiArgs {
// Location of vhost-user Unix domain socket.
// Required, unless one of the --help options is used.
#[clap(
short,
long,
default_value_if(
"help_devices",
clap::builder::ArgPredicate::IsPresent,
"PathBuf::new()"
),
help = "vhost-user socket to use"
)]
socket_path: PathBuf,
// Specification of SCMI devices to create.
#[clap(short, long, help = "Devices to expose")]
#[arg(num_args(1..))]
device: Vec<String>,
#[clap(long, exclusive = true, help = "Print help on available devices")]
help_devices: bool,
}

pub struct VuScmiConfig {
socket_path: PathBuf,
devices: DeviceDescription,
}

impl TryFrom<ScmiArgs> for VuScmiConfig {
impl TryFrom<args::ScmiArgs> for VuScmiConfig {
type Error = String;

fn try_from(cmd_args: ScmiArgs) -> Result<Self> {
fn try_from(cmd_args: args::ScmiArgs) -> Result<Self> {
let socket_path = cmd_args.socket_path;
let mut devices: DeviceDescription = vec![];
let device_iterator = cmd_args.device.iter();
Expand Down Expand Up @@ -140,13 +117,13 @@ fn start_backend(config: VuScmiConfig) -> Result<()> {

fn print_help(message: &String) {
println!("{message}\n");
let mut command = ScmiArgs::command();
let mut command = args::ScmiArgs::command();
command.print_help().unwrap();
}

fn main() {
env_logger::init();
let args = ScmiArgs::parse();
let args = args::ScmiArgs::parse();
if args.help_devices {
println!("{}", devices_help());
return;
Expand Down Expand Up @@ -179,7 +156,7 @@ mod tests {
-d fake,name=bar"
);
let params: Vec<&str> = params_string.split_whitespace().collect();
let args: ScmiArgs = Parser::parse_from(params);
let args: args::ScmiArgs = Parser::parse_from(params);
let config = VuScmiConfig::try_from(args).unwrap();
assert_eq!(&config.socket_path, Path::new(&path));
let devices = vec![
Expand Down
28 changes: 28 additions & 0 deletions vhost-device-sound/src/args.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// SPDX-License-Identifier: Apache-2.0 or BSD-3-Clause
//! An arguments type for the binary interface of this library.

use std::path::PathBuf;

use clap::{Parser, ValueEnum};

#[derive(Parser, Debug)]
#[clap(version, about, long_about = None)]
pub struct SoundArgs {
/// vhost-user Unix domain socket path.
#[clap(long)]
pub socket: PathBuf,
/// audio backend to be used
#[clap(long)]
#[clap(value_enum)]
pub backend: BackendType,
}

#[derive(ValueEnum, Clone, Copy, Default, Debug, Eq, PartialEq)]
pub enum BackendType {
#[default]
Null,
#[cfg(all(feature = "pw-backend", target_env = "gnu"))]
Pipewire,
#[cfg(all(feature = "alsa-backend", target_env = "gnu"))]
Alsa,
}
21 changes: 10 additions & 11 deletions vhost-device-sound/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ pub fn init_logger() {
let _ = env_logger::builder().is_test(true).try_init();
}

pub mod args;
pub mod audio_backends;
pub mod device;
pub mod stream;
Expand All @@ -50,7 +51,7 @@ use std::{
sync::Arc,
};

use clap::ValueEnum;
pub use args::BackendType;
pub use stream::Stream;
use thiserror::Error as ThisError;
use vhost_user_backend::{VhostUserDaemon, VringRwLock, VringT};
Expand Down Expand Up @@ -191,16 +192,6 @@ impl From<stream::Error> for Error {
}
}

#[derive(ValueEnum, Clone, Copy, Default, Debug, Eq, PartialEq)]
pub enum BackendType {
#[default]
Null,
#[cfg(all(feature = "pw-backend", target_env = "gnu"))]
Pipewire,
#[cfg(all(feature = "alsa-backend", target_env = "gnu"))]
Alsa,
}

#[derive(Debug, PartialEq, Eq)]
pub struct InvalidControlMessage(u32);

Expand Down Expand Up @@ -263,6 +254,14 @@ pub struct SoundConfig {
audio_backend: BackendType,
}

impl From<args::SoundArgs> for SoundConfig {
fn from(cmd_args: args::SoundArgs) -> Self {
let args::SoundArgs { socket, backend } = cmd_args;

Self::new(socket, false, backend)
}
}

impl SoundConfig {
/// Create a new instance of the SoundConfig struct, containing the
/// parameters to be fed into the sound-backend server.
Expand Down
Loading