Skip to content
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: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ axaddrspace = "0.1.1"
axhvc = {git = "https://github.com/arceos-hypervisor/axhvc.git"}
axruntime = {path = "modules/axruntime"}
axvcpu = "0.1"
axvm = {git = "https://github.com/arceos-hypervisor/axvm.git", branch = "next", ref = "0393f27"}
axvm = {git = "https://github.com/arceos-hypervisor/axvm.git", branch = "next"}

# System independent crates provided by ArceOS, these crates could be imported by remote url.
axerrno = "0.1.0"
Expand Down
2 changes: 2 additions & 0 deletions xtask/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,5 @@ toml.workspace = true
zerocopy = "=0.8.28"
# adapt nightly-2025-05-20
axvmconfig = {workspace = true, features = ["std"]}
tar = "0.4"
flate2 = "1.0"
2 changes: 1 addition & 1 deletion xtask/src/cargo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ impl Context {
PathBuf::from(format!(".qemu-{arch:?}.toml").to_lowercase())
};

// 如果配置文件不存在,从默认位置复制
// If the configuration file does not exist, copy from the default location
if !config_path.exists() {
fs::copy(
PathBuf::from("scripts")
Expand Down
63 changes: 30 additions & 33 deletions xtask/src/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
//!! ```
//! // List available images
//! xtask image ls
//! // Download a specific image and automatically extract it
//! // Download a specific image and automatically extract it (default behavior)
//! xtask image download evm3588_arceos --output-dir ./images
//! // Download a specific image without extracting
//! xtask image download evm3588_arceos --output-dir ./images --no-extract
Expand All @@ -21,12 +21,13 @@

use anyhow::{Result, anyhow};
use clap::{Parser, Subcommand};
use flate2::read::GzDecoder;
use sha2::{Digest, Sha256};
use std::env;
use std::fs;
use std::io::Read;
use std::path::Path;
use std::process::Command;
use tar::Archive;
use tokio::io::{AsyncWriteExt, BufWriter};

/// Base URL for downloading images
Expand All @@ -43,23 +44,28 @@ pub struct ImageArgs {
/// Image management commands
#[derive(Subcommand)]
pub enum ImageCommands {
/// List all available image
/// List all available images
Ls,

/// Download the specified image and automatically extract it
#[command(alias = "pull")]
Download {
/// Name of the image to download
image_name: String,

/// Output directory for the downloaded image
#[arg(short, long)]
output_dir: Option<String>,
#[arg(
short,
long,
help = "Automatically extract after download (default: true)"
)]
extract: Option<bool>,

/// Do not extract after download
#[arg(long, help = "Do not extract after download")]
no_extract: bool,
},

/// Remove the specified image from temp directory
Rm { image_name: String },
Rm {
/// Name of the image to remove
image_name: String
},
}

/// Representation of a guest image
Expand Down Expand Up @@ -315,8 +321,6 @@ fn image_list() -> Result<()> {
/// ```
/// // Download the evm3588_arceos image to the ./images directory and automatically extract it
/// xtask image download evm3588_arceos --output-dir ./images
/// // Or use the pull alias
/// xtask image pull evm3588_arceos --output-dir ./images
/// ```
async fn image_download(image_name: &str, output_dir: Option<String>, extract: bool) -> Result<()> {
let image = Image::find_by_name(image_name).ok_or_else(|| {
Expand Down Expand Up @@ -421,8 +425,6 @@ async fn image_download(image_name: &str, output_dir: Option<String>, extract: b
.await
.map_err(|e| anyhow!("Error flushing file: {e}"))?;

println!("\nDownload completed");

// Verify downloaded file
match image_verify_sha256(&output_path, image.sha256) {
Ok(true) => {
Expand All @@ -431,12 +433,12 @@ async fn image_download(image_name: &str, output_dir: Option<String>, extract: b
Ok(false) => {
// Remove the invalid downloaded file
let _ = fs::remove_file(&output_path);
return Err(anyhow!("Downloaded file SHA256 verification failed"));
return Err(anyhow!("Download completed but file SHA256 verification failed"));
}
Err(e) => {
// Remove the potentially corrupted downloaded file
let _ = fs::remove_file(&output_path);
return Err(anyhow!("Error verifying downloaded file: {e}"));
return Err(anyhow!("Download completed but error verifying downloaded file: {e}"));
}
}

Expand All @@ -453,18 +455,13 @@ async fn image_download(image_name: &str, output_dir: Option<String>, extract: b
// Ensure extraction directory exists
fs::create_dir_all(&extract_dir)?;

// Use tar command to extract file
let mut child = Command::new("tar")
.arg("-xzf")
.arg(&output_path)
.arg("-C")
.arg(&extract_dir)
.spawn()?;

let status = child.wait()?;
if !status.success() {
return Err(anyhow!("Extraction failed, tar exit code: {status}"));
}
// Open the compressed tar file
let tar_gz = fs::File::open(&output_path)?;
let decoder = GzDecoder::new(tar_gz);
let mut archive = Archive::new(decoder);

// Extract the archive
archive.unpack(&extract_dir)?;

println!("Image extracted to: {}", extract_dir.display());
}
Expand Down Expand Up @@ -529,8 +526,6 @@ fn image_remove(image_name: &str) -> Result<()> {
/// // Run image management commands
/// xtask image ls
/// xtask image download evm3588_arceos --output-dir ./images
/// // Or use the pull alias
/// xtask image pull evm3588_arceos --output-dir ./images
/// xtask image rm evm3588_arceos
/// ```
pub async fn run_image(args: ImageArgs) -> Result<()> {
Expand All @@ -541,9 +536,11 @@ pub async fn run_image(args: ImageArgs) -> Result<()> {
ImageCommands::Download {
image_name,
output_dir,
extract,
no_extract,
} => {
image_download(&image_name, output_dir, extract.unwrap_or(true)).await?;
// Determine if extraction should be performed
let should_extract = !no_extract;
image_download(&image_name, output_dir, should_extract).await?;
}
ImageCommands::Rm { image_name } => {
image_remove(&image_name)?;
Expand Down
25 changes: 24 additions & 1 deletion xtask/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,20 @@ struct Cli {
enum Commands {
/// Set default build configuration from board configs
Defconfig {
/// Board configuration name (e.g., qemu-aarch64, orangepi-5-plus)
/// Board configuration name (e.g., qemu-aarch64, orangepi-5-plus, phytiumpi)
board_name: String,
},
/// Build the ArceOS project with current configuration
Build,
/// Run clippy checks across all targets and feature combinations
Clippy(ClippyArgs),
/// Run ArceOS in QEMU emulation environment
Qemu(QemuArgs),
/// Run ArceOS with U-Boot bootloader
Uboot(UbootArgs),
/// Generate VM configuration schema
Vmconfig,
/// Interactive menu-based configuration editor
Menuconfig,
/// Guest Image management
Image(image::ImageArgs),
Expand All @@ -47,10 +52,15 @@ enum Commands {

#[derive(Parser)]
struct QemuArgs {
/// Path to custom build configuration file (TOML format)
#[arg(long)]
build_config: Option<PathBuf>,

/// Path to custom QEMU configuration file
#[arg(long)]
qemu_config: Option<PathBuf>,

/// Comma-separated list of VM configuration files
#[arg(long)]
vmconfigs: Vec<String>,
}
Expand All @@ -60,29 +70,39 @@ struct ClippyArgs {
/// Only check specific packages (comma separated)
#[arg(long)]
packages: Option<String>,

/// Only check specific targets (comma separated)
#[arg(long)]
targets: Option<String>,

/// Continue on error instead of exiting immediately
#[arg(long)]
continue_on_error: bool,

/// Dry run - show what would be checked without running clippy
#[arg(long)]
dry_run: bool,

/// Automatically fix clippy warnings where possible
#[arg(long)]
fix: bool,

/// Allow fixing when the working directory is dirty (has uncommitted changes)
#[arg(long)]
allow_dirty: bool,
}

#[derive(Parser)]
struct UbootArgs {
/// Path to custom build configuration file (TOML format)
#[arg(long)]
build_config: Option<PathBuf>,

/// Path to custom U-Boot configuration file
#[arg(long)]
uboot_config: Option<PathBuf>,

/// Comma-separated list of VM configuration files
#[arg(long)]
vmconfigs: Vec<String>,
}
Expand All @@ -95,7 +115,10 @@ struct DevspaceArgs {

#[derive(Subcommand)]
enum DevspaceCommand {
/// Start the development workspace
Start,

/// Stop the development workspace
Stop,
}

Expand Down
6 changes: 3 additions & 3 deletions xtask/src/menuconfig.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ use std::sync::Arc; // HashMap is unused
impl Context {
/// Main menuconfig runner function
pub async fn run_menuconfig(&mut self) -> anyhow::Result<()> {
println!("配置运行参数");
println!("Configure runtime parameters");
let config_path = self.ctx.workspace_folder.join(".build.toml");
if config_path.exists() {
println!("\n当前 .build.toml 配置文件: {}", config_path.display());
println!("\nCurrent .build.toml configuration file: {}", config_path.display());
} else {
println!("\n未找到 .build.toml 配置文件,将使用默认配置");
println!("\nNo .build.toml configuration file found, will use default configuration");
}

let Some(_c): Option<Config> =
Expand Down