From 320e191ce0338b08df38ed4a4d9d942dc8a2c98a Mon Sep 17 00:00:00 2001
From: wanjunlei <wanjunlei@kubesphere.io>
Date: Fri, 26 Apr 2024 10:19:04 +0800
Subject: [PATCH] add a build command

---
 README.md          |  6 ++++++
 xtask/src/build.rs | 42 ++++++++++++++++++++++++++++++++++++++++++
 xtask/src/main.rs  |  3 +++
 xtask/src/run.rs   | 27 ++++++---------------------
 4 files changed, 57 insertions(+), 21 deletions(-)
 create mode 100644 xtask/src/build.rs

diff --git a/README.md b/README.md
index fdc5c59..bee17f6 100644
--- a/README.md
+++ b/README.md
@@ -19,6 +19,12 @@ You may also change the target architecture with the `--target` flag.
 cargo build
 ```
 
+## Build eBPF and Userspace
+
+```bash
+cargo xtask build
+```
+
 ## Run
 
 ```bash
diff --git a/xtask/src/build.rs b/xtask/src/build.rs
new file mode 100644
index 0000000..ddeee44
--- /dev/null
+++ b/xtask/src/build.rs
@@ -0,0 +1,42 @@
+use std::process::Command;
+
+use anyhow::Context as _;
+use clap::Parser;
+
+use crate::build_ebpf::{build_ebpf, Architecture, Options as BuildOptions};
+
+#[derive(Debug, Parser)]
+pub struct Options {
+    /// Set the endianness of the BPF target
+    #[clap(default_value = "bpfel-unknown-none", long)]
+    pub bpf_target: Architecture,
+    /// Build and run the release target
+    #[clap(long)]
+    pub release: bool,
+}
+
+/// Build the project
+fn build_project(opts: &Options) -> Result<(), anyhow::Error> {
+    let mut args = vec!["build"];
+    if opts.release {
+        args.push("--release")
+    }
+    let status = Command::new("cargo")
+        .args(&args)
+        .status()
+        .expect("failed to build userspace");
+    assert!(status.success());
+    Ok(())
+}
+
+/// Build our ebpf program and the project
+pub fn build(opts: Options) -> Result<(), anyhow::Error> {
+    // build our ebpf program followed by our application
+    build_ebpf(BuildOptions {
+        target: opts.bpf_target,
+        release: opts.release,
+    })
+    .context("Error while building eBPF program")?;
+    build_project(&opts).context("Error while building userspace application")?;
+    Ok(())
+}
\ No newline at end of file
diff --git a/xtask/src/main.rs b/xtask/src/main.rs
index c1c594e..5079458 100644
--- a/xtask/src/main.rs
+++ b/xtask/src/main.rs
@@ -1,4 +1,5 @@
 mod build_ebpf;
+mod build;
 mod run;
 
 use std::process::exit;
@@ -14,6 +15,7 @@ pub struct Options {
 #[derive(Debug, Parser)]
 enum Command {
     BuildEbpf(build_ebpf::Options),
+    Build(build::Options),
     Run(run::Options),
 }
 
@@ -24,6 +26,7 @@ fn main() {
     let ret = match opts.command {
         BuildEbpf(opts) => build_ebpf::build_ebpf(opts),
         Run(opts) => run::run(opts),
+        Build(opts) => build::build(opts),
     };
 
     if let Err(e) = ret {
diff --git a/xtask/src/run.rs b/xtask/src/run.rs
index 109515e..d0610a6 100644
--- a/xtask/src/run.rs
+++ b/xtask/src/run.rs
@@ -3,7 +3,7 @@ use std::process::Command;
 use anyhow::Context as _;
 use clap::Parser;
 
-use crate::build_ebpf::{build_ebpf, Architecture, Options as BuildOptions};
+use crate::{build::{build, Options as BuildOptions}, build_ebpf::Architecture};
 
 #[derive(Debug, Parser)]
 pub struct Options {
@@ -21,30 +21,15 @@ pub struct Options {
     pub run_args: Vec<String>,
 }
 
-/// Build the project
-fn build(opts: &Options) -> Result<(), anyhow::Error> {
-    let mut args = vec!["build"];
-    if opts.release {
-        args.push("--release")
-    }
-    let status = Command::new("cargo")
-        .args(&args)
-        .status()
-        .expect("failed to build userspace");
-    assert!(status.success());
-    Ok(())
-}
 
 /// Build and run the project
 pub fn run(opts: Options) -> Result<(), anyhow::Error> {
-    // build our ebpf program followed by our application
-    build_ebpf(BuildOptions {
-        target: opts.bpf_target,
+     // Build our ebpf program and the project
+     build(BuildOptions{
+        bpf_target: opts.bpf_target,
         release: opts.release,
-    })
-    .context("Error while building eBPF program")?;
-    build(&opts).context("Error while building userspace application")?;
-
+    }).context("Error while building project")?;
+    
     // profile we are building (release or debug)
     let profile = if opts.release { "release" } else { "debug" };
     let bin_path = format!("target/{profile}/{{project-name}}");