1*fae6e9adSlinfeng use std::{path::PathBuf, process::Command};
2*fae6e9adSlinfeng
3*fae6e9adSlinfeng use clap::Parser;
4*fae6e9adSlinfeng
5*fae6e9adSlinfeng #[derive(Debug, Copy, Clone)]
6*fae6e9adSlinfeng pub enum Architecture {
7*fae6e9adSlinfeng BpfEl,
8*fae6e9adSlinfeng BpfEb,
9*fae6e9adSlinfeng }
10*fae6e9adSlinfeng
11*fae6e9adSlinfeng impl std::str::FromStr for Architecture {
12*fae6e9adSlinfeng type Err = String;
13*fae6e9adSlinfeng
from_str(s: &str) -> Result<Self, Self::Err>14*fae6e9adSlinfeng fn from_str(s: &str) -> Result<Self, Self::Err> {
15*fae6e9adSlinfeng Ok(match s {
16*fae6e9adSlinfeng "bpfel-unknown-none" => Architecture::BpfEl,
17*fae6e9adSlinfeng "bpfeb-unknown-none" => Architecture::BpfEb,
18*fae6e9adSlinfeng _ => return Err("invalid target".to_owned()),
19*fae6e9adSlinfeng })
20*fae6e9adSlinfeng }
21*fae6e9adSlinfeng }
22*fae6e9adSlinfeng
23*fae6e9adSlinfeng impl std::fmt::Display for Architecture {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result24*fae6e9adSlinfeng fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
25*fae6e9adSlinfeng f.write_str(match self {
26*fae6e9adSlinfeng Architecture::BpfEl => "bpfel-unknown-none",
27*fae6e9adSlinfeng Architecture::BpfEb => "bpfeb-unknown-none",
28*fae6e9adSlinfeng })
29*fae6e9adSlinfeng }
30*fae6e9adSlinfeng }
31*fae6e9adSlinfeng
32*fae6e9adSlinfeng #[derive(Debug, Parser)]
33*fae6e9adSlinfeng pub struct Options {
34*fae6e9adSlinfeng /// Set the endianness of the BPF target
35*fae6e9adSlinfeng #[clap(default_value = "bpfel-unknown-none", long)]
36*fae6e9adSlinfeng pub target: Architecture,
37*fae6e9adSlinfeng /// Build the release target
38*fae6e9adSlinfeng #[clap(long)]
39*fae6e9adSlinfeng pub release: bool,
40*fae6e9adSlinfeng }
41*fae6e9adSlinfeng
build_ebpf(opts: Options) -> Result<(), anyhow::Error>42*fae6e9adSlinfeng pub fn build_ebpf(opts: Options) -> Result<(), anyhow::Error> {
43*fae6e9adSlinfeng let dir = PathBuf::from("syscall_ebpf-ebpf");
44*fae6e9adSlinfeng let target = format!("--target={}", opts.target);
45*fae6e9adSlinfeng let mut args = vec![
46*fae6e9adSlinfeng "build",
47*fae6e9adSlinfeng target.as_str(),
48*fae6e9adSlinfeng "-Z",
49*fae6e9adSlinfeng "build-std=core",
50*fae6e9adSlinfeng ];
51*fae6e9adSlinfeng if opts.release {
52*fae6e9adSlinfeng args.push("--release")
53*fae6e9adSlinfeng }
54*fae6e9adSlinfeng
55*fae6e9adSlinfeng // Command::new creates a child process which inherits all env variables. This means env
56*fae6e9adSlinfeng // vars set by the cargo xtask command are also inherited. RUSTUP_TOOLCHAIN is removed
57*fae6e9adSlinfeng // so the rust-toolchain.toml file in the -ebpf folder is honored.
58*fae6e9adSlinfeng
59*fae6e9adSlinfeng let status = Command::new("cargo")
60*fae6e9adSlinfeng .current_dir(dir)
61*fae6e9adSlinfeng .env_remove("RUSTUP_TOOLCHAIN")
62*fae6e9adSlinfeng .args(&args)
63*fae6e9adSlinfeng .status()
64*fae6e9adSlinfeng .expect("failed to build bpf program");
65*fae6e9adSlinfeng assert!(status.success());
66*fae6e9adSlinfeng Ok(())
67*fae6e9adSlinfeng }
68