Fix xtask to work with backends

This commit is contained in:
Emil Fresk 2023-02-20 20:09:51 +01:00 committed by Henrik Tjäder
parent e8cebff69e
commit 9552790dcc

View file

@ -32,27 +32,44 @@ const ARMV7M: &str = "thumbv7m-none-eabi";
const ARMV8MBASE: &str = "thumbv8m.base-none-eabi"; const ARMV8MBASE: &str = "thumbv8m.base-none-eabi";
const ARMV8MMAIN: &str = "thumbv8m.main-none-eabi"; const ARMV8MMAIN: &str = "thumbv8m.main-none-eabi";
const DEFAULT_FEATURES: Option<&str> = Some("test-critical-section"); const DEFAULT_FEATURES: &str = "test-critical-section";
#[derive(clap::ValueEnum, Copy, Clone, Default, Debug)]
enum Backends {
Thumbv6,
#[default]
Thumbv7,
Thumbv8Base,
Thumbv8Main,
}
impl Backends {
fn to_target(&self) -> &str {
match self {
Backends::Thumbv6 => ARMV6M,
Backends::Thumbv7 => ARMV7M,
Backends::Thumbv8Base => ARMV8MBASE,
Backends::Thumbv8Main => ARMV8MMAIN,
}
}
fn to_rtic_feature(&self) -> &str {
match self {
Backends::Thumbv6 => "thumbv6",
Backends::Thumbv7 => "thumbv7",
Backends::Thumbv8Base => "thumbv8_base",
Backends::Thumbv8Main => "thumbv8_main",
}
}
}
#[derive(Parser)] #[derive(Parser)]
#[command(author, version, about, long_about = None)] #[command(author, version, about, long_about = None)]
/// RTIC xtask powered testing toolbox /// RTIC xtask powered testing toolbox
struct Cli { struct Cli {
/// For which target to build /// For which backend to build
/// #[arg(value_enum, short, long)]
/// Defaults to these targets if omitted: backend: Backends,
///
/// thumbv6m-none-eabi
/// thumbv7m-none-eabi
///
/// The valid targets are:
///
/// thumbv6m-none-eabi
/// thumbv7m-none-eabi
/// thumbv8m.base-none-eabi
/// thumbv8m.main-none-eabi
#[arg(short, long)]
target: Option<String>,
/// List of comma separated examples to include, all others are excluded /// List of comma separated examples to include, all others are excluded
/// ///
@ -215,8 +232,6 @@ fn main() -> anyhow::Result<()> {
bail!("xtasks can only be executed from the root of the `rtic` repository"); bail!("xtasks can only be executed from the root of the `rtic` repository");
} }
let mut targets: Vec<String> = [ARMV7M.to_owned(), ARMV6M.to_owned()].to_vec();
let examples: Vec<_> = std::fs::read_dir("./rtic/examples")? let examples: Vec<_> = std::fs::read_dir("./rtic/examples")?
.filter_map(|p| p.ok()) .filter_map(|p| p.ok())
.map(|p| p.path()) .map(|p| p.path())
@ -239,25 +254,7 @@ fn main() -> anyhow::Result<()> {
trace!("default logging level: {0}", cli.verbose); trace!("default logging level: {0}", cli.verbose);
let target = cli.target; let backend = cli.backend;
if let Some(target) = target {
let mut targets_extended = targets.clone();
targets_extended.push(ARMV8MBASE.to_owned());
targets_extended.push(ARMV8MMAIN.to_owned());
if targets_extended.contains(&target) {
debug!("\nTesting target: {target}");
// If we managed to filter, set the targets to test to only this one
targets = vec![target]
} else {
error!(
"\nThe target you specified is not available. Available targets are:\
\n{targets:#?}\n\
By default all targets are tested.",
);
process::exit(exitcode::USAGE);
}
}
let example = cli.example; let example = cli.example;
let exampleexclude = cli.exampleexclude; let exampleexclude = cli.exampleexclude;
@ -320,67 +317,60 @@ fn main() -> anyhow::Result<()> {
match cli.command { match cli.command {
Commands::Size(arguments) => { Commands::Size(arguments) => {
debug!("Measuring on target(s): {targets:?}");
// x86_64 target not valid // x86_64 target not valid
for t in &targets { info!("Measuring for backend: {backend:?}");
info!("Measuring for target: {t:?}"); build_and_check_size(
build_and_check_size(&cargoarg, t, &examples_to_run, &arguments.sizearguments)?; &cargoarg,
} backend,
&examples_to_run,
&arguments.sizearguments,
)?;
} }
Commands::Qemu(args) | Commands::Run(args) => { Commands::Qemu(args) | Commands::Run(args) => {
debug!("Running on target(s): {targets:?}");
// x86_64 target not valid // x86_64 target not valid
for t in &targets { info!("Testing for backend: {backend:?}");
info!("Testing for target: {t:?}"); run_test(
run_test(&cargoarg, t, &examples_to_run, args.overwrite_expected)?; &cargoarg,
} backend,
&examples_to_run,
args.overwrite_expected,
)?;
} }
Commands::ExampleBuild => { Commands::ExampleBuild => {
debug!("Building for target(s): {targets:?}"); info!("Building for backend: {backend:?}");
for t in &targets { example_build(&cargoarg, backend, &examples_to_run)?;
info!("Building for target: {t:?}");
example_build(&cargoarg, t, &examples_to_run)?;
}
} }
Commands::ExampleCheck => { Commands::ExampleCheck => {
debug!("Checking on target(s): {targets:?}"); info!("Checking on backend: {backend:?}");
for t in &targets { example_check(&cargoarg, backend, &examples_to_run)?;
info!("Checking on target: {t:?}");
example_check(&cargoarg, t, &examples_to_run)?;
}
} }
Commands::Build(args) => { Commands::Build(args) => {
debug!("Building for target(s): {targets:?}"); info!("Building for backend: {backend:?}");
for t in &targets { cargo_build(&cargoarg, &args, backend)?;
info!("Building for target: {t:?}");
cargo_build(&cargoarg, &args, t)?;
}
} }
Commands::Check(args) => { Commands::Check(args) => {
debug!("Checking on target(s): {targets:?}"); info!("Checking on backend: {backend:?}");
for t in &targets { cargo_check(&cargoarg, &args, backend)?;
info!("Checking on target: {t:?}");
cargo_check(&cargoarg, &args, t)?;
}
} }
Commands::Clippy(args) => { Commands::Clippy(args) => {
debug!("Clippy on target(s): {targets:?}"); info!("Running clippy on backend: {backend:?}");
for t in &targets { cargo_clippy(&cargoarg, &args, backend)?;
info!("Running clippy on target: {t:?}");
cargo_clippy(&cargoarg, &args, t)?;
}
} }
} }
Ok(()) Ok(())
} }
fn cargo_build(cargoarg: &Option<&str>, package: &Package, target: &str) -> anyhow::Result<()> { fn cargo_build(
cargoarg: &Option<&str>,
package: &Package,
backend: Backends,
) -> anyhow::Result<()> {
command_parser( command_parser(
&CargoCommand::Build { &CargoCommand::Build {
cargoarg, cargoarg,
package: package_filter(package), package: package_filter(package),
target, target: backend.to_target(),
features: None, features: None,
mode: BuildMode::Release, mode: BuildMode::Release,
}, },
@ -389,12 +379,16 @@ fn cargo_build(cargoarg: &Option<&str>, package: &Package, target: &str) -> anyh
Ok(()) Ok(())
} }
fn cargo_check(cargoarg: &Option<&str>, package: &Package, target: &str) -> anyhow::Result<()> { fn cargo_check(
cargoarg: &Option<&str>,
package: &Package,
backend: Backends,
) -> anyhow::Result<()> {
command_parser( command_parser(
&CargoCommand::Check { &CargoCommand::Check {
cargoarg, cargoarg,
package: package_filter(package), package: package_filter(package),
target, target: backend.to_target(),
features: None, features: None,
}, },
false, false,
@ -402,12 +396,16 @@ fn cargo_check(cargoarg: &Option<&str>, package: &Package, target: &str) -> anyh
Ok(()) Ok(())
} }
fn cargo_clippy(cargoarg: &Option<&str>, package: &Package, target: &str) -> anyhow::Result<()> { fn cargo_clippy(
cargoarg: &Option<&str>,
package: &Package,
backend: Backends,
) -> anyhow::Result<()> {
command_parser( command_parser(
&CargoCommand::Clippy { &CargoCommand::Clippy {
cargoarg, cargoarg,
package: package_filter(package), package: package_filter(package),
target, target: backend.to_target(),
features: None, features: None,
}, },
false, false,
@ -417,16 +415,19 @@ fn cargo_clippy(cargoarg: &Option<&str>, package: &Package, target: &str) -> any
fn run_test( fn run_test(
cargoarg: &Option<&str>, cargoarg: &Option<&str>,
target: &str, backend: Backends,
examples: &[String], examples: &[String],
overwrite: bool, overwrite: bool,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
let s = format!("{},{}", DEFAULT_FEATURES, backend.to_rtic_feature());
let features: Option<&str> = Some(&s);
examples.into_par_iter().for_each(|example| { examples.into_par_iter().for_each(|example| {
let cmd = CargoCommand::ExampleBuild { let cmd = CargoCommand::ExampleBuild {
cargoarg: &Some("--quiet"), cargoarg: &Some("--quiet"),
example, example,
target, target: backend.to_target(),
features: DEFAULT_FEATURES, features,
mode: BuildMode::Release, mode: BuildMode::Release,
}; };
if let Err(err) = command_parser(&cmd, false) { if let Err(err) = command_parser(&cmd, false) {
@ -436,8 +437,8 @@ fn run_test(
let cmd = CargoCommand::Qemu { let cmd = CargoCommand::Qemu {
cargoarg, cargoarg,
example, example,
target, target: backend.to_target(),
features: DEFAULT_FEATURES, features,
mode: BuildMode::Release, mode: BuildMode::Release,
}; };
@ -448,13 +449,20 @@ fn run_test(
Ok(()) Ok(())
} }
fn example_check(cargoarg: &Option<&str>, target: &str, examples: &[String]) -> anyhow::Result<()> { fn example_check(
cargoarg: &Option<&str>,
backend: Backends,
examples: &[String],
) -> anyhow::Result<()> {
let s = format!("{},{}", DEFAULT_FEATURES, backend.to_rtic_feature());
let features: Option<&str> = Some(&s);
examples.into_par_iter().for_each(|example| { examples.into_par_iter().for_each(|example| {
let cmd = CargoCommand::ExampleCheck { let cmd = CargoCommand::ExampleCheck {
cargoarg, cargoarg,
example, example,
target, target: backend.to_target(),
features: DEFAULT_FEATURES, features,
mode: BuildMode::Release, mode: BuildMode::Release,
}; };
@ -466,13 +474,20 @@ fn example_check(cargoarg: &Option<&str>, target: &str, examples: &[String]) ->
Ok(()) Ok(())
} }
fn example_build(cargoarg: &Option<&str>, target: &str, examples: &[String]) -> anyhow::Result<()> { fn example_build(
cargoarg: &Option<&str>,
backend: Backends,
examples: &[String],
) -> anyhow::Result<()> {
let s = format!("{},{}", DEFAULT_FEATURES, backend.to_rtic_feature());
let features: Option<&str> = Some(&s);
examples.into_par_iter().for_each(|example| { examples.into_par_iter().for_each(|example| {
let cmd = CargoCommand::ExampleBuild { let cmd = CargoCommand::ExampleBuild {
cargoarg, cargoarg,
example, example,
target, target: backend.to_target(),
features: DEFAULT_FEATURES, features,
mode: BuildMode::Release, mode: BuildMode::Release,
}; };
@ -486,17 +501,20 @@ fn example_build(cargoarg: &Option<&str>, target: &str, examples: &[String]) ->
fn build_and_check_size( fn build_and_check_size(
cargoarg: &Option<&str>, cargoarg: &Option<&str>,
target: &str, backend: Backends,
examples: &[String], examples: &[String],
size_arguments: &Option<Sizearguments>, size_arguments: &Option<Sizearguments>,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
let s = format!("{},{}", DEFAULT_FEATURES, backend.to_rtic_feature());
let features: Option<&str> = Some(&s);
examples.into_par_iter().for_each(|example| { examples.into_par_iter().for_each(|example| {
// Make sure the requested example(s) are built // Make sure the requested example(s) are built
let cmd = CargoCommand::ExampleBuild { let cmd = CargoCommand::ExampleBuild {
cargoarg: &Some("--quiet"), cargoarg: &Some("--quiet"),
example, example,
target, target: backend.to_target(),
features: DEFAULT_FEATURES, features,
mode: BuildMode::Release, mode: BuildMode::Release,
}; };
if let Err(err) = command_parser(&cmd, false) { if let Err(err) = command_parser(&cmd, false) {
@ -506,8 +524,8 @@ fn build_and_check_size(
let cmd = CargoCommand::ExampleSize { let cmd = CargoCommand::ExampleSize {
cargoarg, cargoarg,
example, example,
target, target: backend.to_target(),
features: DEFAULT_FEATURES, features,
mode: BuildMode::Release, mode: BuildMode::Release,
arguments: size_arguments.clone(), arguments: size_arguments.clone(),
}; };