Skip to content
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

Add xtask to generate manpages #792

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
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 --"
25 changes: 25 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 @@ -14,4 +14,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.
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
26 changes: 26 additions & 0 deletions vhost-device-sound/src/args.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// SPDX-License-Identifier: Apache-2.0 or BSD-3-Clause
//! An arguments type for the binary interface of this library.

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: String,
/// 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 @@ -49,7 +50,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 @@ -190,16 +191,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 @@ -262,6 +253,14 @@ pub struct SoundConfig {
audio_backend: BackendType,
}

impl From<args::SoundArgs> for SoundConfig {
fn from(cmd_args: args::SoundArgs) -> Self {
let socket = cmd_args.socket.trim().to_string();

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

impl SoundConfig {
/// Create a new instance of the SoundConfig struct, containing the
/// parameters to be fed into the sound-backend server.
Expand Down
53 changes: 10 additions & 43 deletions vhost-device-sound/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,37 +1,14 @@
// Manos Pitsidianakis <[email protected]>
// Stefano Garzarella <[email protected]>
// SPDX-License-Identifier: Apache-2.0 or BSD-3-Clause
use std::convert::TryFrom;

use clap::Parser;
use vhost_device_sound::{start_backend_server, BackendType, Error, Result, SoundConfig};

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

impl TryFrom<SoundArgs> for SoundConfig {
type Error = Error;

fn try_from(cmd_args: SoundArgs) -> Result<Self> {
let socket = cmd_args.socket.trim().to_string();

Ok(SoundConfig::new(socket, false, cmd_args.backend))
}
}
use vhost_device_sound::{args::SoundArgs, start_backend_server, SoundConfig};

fn main() {
env_logger::init();

let config = SoundConfig::try_from(SoundArgs::parse()).unwrap();
let config = SoundConfig::from(SoundArgs::parse());

loop {
start_backend_server(config.clone());
Expand All @@ -40,19 +17,12 @@ fn main() {

#[cfg(test)]
mod tests {
use clap::Parser;
use rstest::*;
use vhost_device_sound::BackendType;

use super::*;

impl SoundArgs {
fn from_args(socket: &str) -> Self {
SoundArgs {
socket: socket.to_string(),
backend: BackendType::default(),
}
}
}

fn init_logger() {
std::env::set_var("RUST_LOG", "trace");
let _ = env_logger::builder().is_test(true).try_init();
Expand All @@ -61,12 +31,12 @@ mod tests {
#[test]
fn test_sound_config_setup() {
init_logger();
let args = SoundArgs::from_args("/tmp/vhost-sound.socket");
let args = SoundArgs {
socket: "/tmp/vhost-sound.socket".to_string(),
backend: BackendType::default(),
};
let config = SoundConfig::from(args);

let config = SoundConfig::try_from(args);
assert!(config.is_ok());

let config = config.unwrap();
assert_eq!(config.get_socket_path(), "/tmp/vhost-sound.socket");
}

Expand All @@ -89,10 +59,7 @@ mod tests {
backend_name,
]);

let config = SoundConfig::try_from(args);
assert!(config.is_ok());

let config = config.unwrap();
let config = SoundConfig::from(args);
assert_eq!(config.get_audio_backend(), backend);
}
}
28 changes: 28 additions & 0 deletions xtask/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
[package]
name = "xtask"
version = "0.1.0"
authors = ["Manos Pitsidianakis <[email protected]>"]
description = "A helper binary crate following the cargo-xtask workflow recommended in <https://github.com/matklad/cargo-xtask>"
repository = "https://github.com/rust-vmm/vhost-device"
readme = "README.md"
license = "EUPL-1.2 OR GPL-3.0-or-later"
edition = "2021"
publish = false

[dependencies]
clap = { version = "4.5", features = ["derive"], optional = true }
clap_mangen = { version = "0.2.24", optional = true }
toml = { version = "0.8.19", optional = true }

[build-dependencies]

[features]
default = ["vhost-device-sound", "vhost-device-scmi"]
vhost-device-scmi = []
vhost-device-sound = ["vhost-device-sound-alsa", "vhost-device-sound-pipewire"]
vhost-device-sound-alsa = ["mangen"]
vhost-device-sound-pipewire = ["mangen"]
mangen = ["dep:clap_mangen", "dep:clap", "dep:toml"]

[lints.rust]
unexpected_cfgs = { level = "allow", check-cfg = ['cfg(feature, values("alsa-backend", "pw-backend"))'] }
22 changes: 22 additions & 0 deletions xtask/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# `xtask` - Run tasks with `cargo`

This binary crate provides support for running useful tasks with `cargo xtask <..>`.

## `mangen`

The `mangen` task which is enabled by the `mangen` cargo feature, builds ROFF manual pages for binary crates in this repository. It uses the [`clap_mangen`](https://crates.io/crates/clap_mangen) crate to generate ROFF from the crate's argument types which implement the `clap::CommandFactory` trait, through the `clap::Parser` derive macro.

```session
$ cargo xtask mangen
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.04s
Running `target/debug/xtask mangen`
Generated the following manual pages:
/path/to/rust-vmm/vhost-device/target/dist/man/vhost-device-sound.1
/path/to/rust-vmm/vhost-device/target/dist/man/vhost-device-scmi.1
```

The following crates have manual pages built by default:

- [`vhost-device-sound`](../vhost-device-sound), enabled by the default feature `vhost-device-sound`.
- It can further be fine-tuned with the features `vhost-device-sound-pipewire` and `vhost-device-sound-alsa`.
- [`vhost-device-scmi`](../vhost-device-scmi), enabled by the default feature `vhost-device-scmi`.
Loading