瀏覽代碼

integration-test: compile C probes using build.rs

- Add libbpf as a submodule. This prevents having to plumb its location
  around (which can't be passed to Cargo build scripts) and also
  controls the version against which codegen has run.
- Move bpf written in C to the integration-test crate and define
  constants for each probe.
- Remove magic; each C source file must be directly enumerated in the
  build script and in lib.rs.
Tamir Duberstein 1 年之前
父節點
當前提交
8c61fc9ea6

+ 1 - 6
.github/workflows/gen.yml

@@ -9,11 +9,6 @@ jobs:
     steps:
       - uses: actions/checkout@v3
 
-      - uses: actions/checkout@v3
-        with:
-          repository: libbpf/libbpf
-          path: libbpf
-
       - name: libbpf-version
         working-directory: libbpf
         run: echo "LIBBPF_SHA=$(git rev-parse HEAD)" >> $GITHUB_ENV
@@ -32,7 +27,7 @@ jobs:
 
       - name: Run codegen
         run: |
-          cargo xtask codegen --libbpf-dir ./libbpf
+          cargo xtask codegen
 
       - name: Check for changes
         run: |

+ 2 - 4
.github/workflows/integration-tests.yml

@@ -17,11 +17,9 @@ jobs:
     runs-on: macos-latest
 
     steps:
-      - uses: actions/checkout@v3
       - uses: actions/checkout@v3
         with:
-          repository: libbpf/libbpf
-          path: libbpf
+          submodules: recursive
 
       - name: Install Pre-requisites
         run: |
@@ -40,4 +38,4 @@ jobs:
           key: tmp-files-${{ hashFiles('test/run.sh') }}
 
       - name: Run integration tests
-        run: test/run.sh ./libbpf
+        run: test/run.sh

+ 0 - 1
.gitignore

@@ -1,6 +1,5 @@
 Cargo.lock
 target/
-libbpf/
 .vscode/
 !.vscode/settings.json
 site/

+ 3 - 0
.gitmodules

@@ -0,0 +1,3 @@
+[submodule "libbpf"]
+	path = libbpf
+	url = https://github.com/libbpf/libbpf

+ 1 - 1
aya/src/util.rs

@@ -299,7 +299,7 @@ macro_rules! include_bytes_aligned {
             pub bytes: Bytes,
         }
 
-        static ALIGNED: &Aligned<[u8]> = &Aligned {
+        const ALIGNED: &Aligned<[u8]> = &Aligned {
             _align: [],
             bytes: *include_bytes!($path),
         };

+ 1 - 0
libbpf

@@ -0,0 +1 @@
+Subproject commit a2258003f21d9d52afd48aa64787b65ef80bd355

+ 5 - 5
test/README.md

@@ -30,13 +30,13 @@ From the root of this repository:
 ### Native
 
 ```
-cargo xtask integration-test --libbpf-dir /path/to/libbpf
+cargo xtask integration-test
 ```
 
 ### Virtualized
 
 ```
-./test/run.sh /path/to/libbpf
+./test/run.sh
 ```
 
 ### Writing an integration test
@@ -45,9 +45,9 @@ Tests should follow these guidelines:
 
 - Rust eBPF code should live in `integration-ebpf/${NAME}.rs` and included in
   `integration-ebpf/Cargo.toml`.
-- C eBPF code should live in `integration-ebpf/src/bpf/${NAME}.bpf.c`. It's automatically compiled
-  and made available as `${OUT_DIR}/${NAME}.bpf.o`.
-- Any bytecode should be included in the integration test binary using `include_bytes_aligned!`.
+- C eBPF code should live in `integration-test/bpf/${NAME}.bpf.c`. It should be
+  added to the list of files in `integration-test/build.rs` and the list of
+  constants in `integration-test/src/lib.rs` using `include_bytes_aligned!`.
 - Tests should be added to `integration-test/tests`.
 - You may add a new module, or use an existing one.
 - Test functions should not return `anyhow::Result<()>` since this produces errors without stack

+ 0 - 0
test/integration-ebpf/src/bpf/ext.bpf.c → test/integration-test/bpf/ext.bpf.c


+ 0 - 0
test/integration-ebpf/src/bpf/main.bpf.c → test/integration-test/bpf/main.bpf.c


+ 0 - 0
test/integration-ebpf/src/bpf/multimap-btf.bpf.c → test/integration-test/bpf/multimap-btf.bpf.c


+ 0 - 0
test/integration-ebpf/src/bpf/text_64_64_reloc.c → test/integration-test/bpf/text_64_64_reloc.c


+ 88 - 0
test/integration-test/build.rs

@@ -0,0 +1,88 @@
+use std::{env, ffi::OsString, path::PathBuf, process::Command};
+
+fn main() {
+    let manifest_dir = env::var_os("CARGO_MANIFEST_DIR").unwrap();
+    let manifest_dir = PathBuf::from(manifest_dir);
+    let out_dir = env::var_os("OUT_DIR").unwrap();
+    let out_dir = PathBuf::from(out_dir);
+
+    let libbpf_dir = manifest_dir
+        .parent()
+        .unwrap()
+        .parent()
+        .unwrap()
+        .join("libbpf");
+
+    let libbpf_headers_dir = out_dir.join("libbpf_headers");
+
+    let mut includedir = OsString::new();
+    includedir.push("INCLUDEDIR=");
+    includedir.push(&libbpf_headers_dir);
+
+    let mut cmd = Command::new("make");
+    cmd.arg("-C")
+        .arg(libbpf_dir.join("src"))
+        .arg(includedir)
+        .arg("install_headers");
+    let status = cmd
+        .status()
+        .unwrap_or_else(|err| panic!("failed to run {cmd:?}: {err}"));
+    match status.code() {
+        Some(code) => match code {
+            0 => {}
+            code => panic!("{cmd:?} exited with code {code}"),
+        },
+        None => panic!("{cmd:?} terminated by signal"),
+    }
+
+    let bpf_dir = manifest_dir.join("bpf");
+
+    let endian = env::var_os("CARGO_CFG_TARGET_ENDIAN").unwrap();
+    let target = if endian == "big" {
+        "bpfeb"
+    } else if endian == "little" {
+        "bpfel"
+    } else {
+        panic!("unsupported endian={:?}", endian)
+    };
+
+    let mut target_arch = OsString::new();
+    target_arch.push("-D__TARGET_ARCH_");
+
+    let arch = env::var_os("CARGO_CFG_TARGET_ARCH").unwrap();
+    if arch == "x86_64" {
+        target_arch.push("x86");
+    } else if arch == "aarch64" {
+        target_arch.push("arm64");
+    } else {
+        target_arch.push(arch);
+    };
+
+    for (src, dst) in [
+        ("ext.bpf.c", "ext.bpf.o"),
+        ("main.bpf.c", "main.bpf.o"),
+        ("multimap-btf.bpf.c", "multimap-btf.bpf.o"),
+        ("text_64_64_reloc.c", "text_64_64_reloc.o"),
+    ] {
+        let src = bpf_dir.join(src);
+        let out = out_dir.join(dst);
+        let mut cmd = Command::new("clang");
+        cmd.arg("-I")
+            .arg(&libbpf_headers_dir)
+            .args(["-g", "-O2", "-target", target, "-c"])
+            .arg(&target_arch)
+            .arg(src)
+            .arg("-o")
+            .arg(out);
+        let status = cmd
+            .status()
+            .unwrap_or_else(|err| panic!("failed to run {cmd:?}: {err}"));
+        match status.code() {
+            Some(code) => match code {
+                0 => {}
+                code => panic!("{cmd:?} exited with code {code}"),
+            },
+            None => panic!("{cmd:?} terminated by signal"),
+        }
+    }
+}

+ 7 - 0
test/integration-test/src/lib.rs

@@ -1 +1,8 @@
+use aya::include_bytes_aligned;
 
+pub const EXT: &[u8] = include_bytes_aligned!(concat!(env!("OUT_DIR"), "/ext.bpf.o"));
+pub const MAIN: &[u8] = include_bytes_aligned!(concat!(env!("OUT_DIR"), "/main.bpf.o"));
+pub const MULTIMAP_BTF: &[u8] =
+    include_bytes_aligned!(concat!(env!("OUT_DIR"), "/multimap-btf.bpf.o"));
+pub const TEXT_64_64_RELOC: &[u8] =
+    include_bytes_aligned!(concat!(env!("OUT_DIR"), "/text_64_64_reloc.o"));

+ 1 - 3
test/integration-test/tests/load.rs

@@ -33,9 +33,7 @@ fn long_name() {
 
 #[test]
 fn multiple_btf_maps() {
-    let bytes =
-        include_bytes_aligned!("../../../target/bpfel-unknown-none/release/multimap-btf.bpf.o");
-    let mut bpf = Bpf::load(bytes).unwrap();
+    let mut bpf = Bpf::load(integration_test::MULTIMAP_BTF).unwrap();
 
     let map_1: Array<_, u64> = bpf.take_map("map_1").unwrap().try_into().unwrap();
     let map_2: Array<_, u64> = bpf.take_map("map_2").unwrap().try_into().unwrap();

+ 1 - 3
test/integration-test/tests/rbpf.rs

@@ -34,9 +34,7 @@ static mut MULTIMAP_MAPS: [*mut Vec<u64>; 2] = [null_mut(), null_mut()];
 
 #[test]
 fn use_map_with_rbpf() {
-    let bytes =
-        include_bytes_aligned!("../../../target/bpfel-unknown-none/release/multimap-btf.bpf.o");
-    let mut object = Object::parse(bytes).unwrap();
+    let mut object = Object::parse(integration_test::MULTIMAP_BTF).unwrap();
 
     assert_eq!(object.programs.len(), 1);
     matches::assert_matches!(

+ 1 - 4
test/integration-test/tests/relocations.rs

@@ -20,10 +20,7 @@ fn relocations() {
 
 #[test]
 fn text_64_64_reloc() {
-    let mut bpf = load_and_attach(
-        "test_text_64_64_reloc",
-        include_bytes_aligned!("../../../target/bpfel-unknown-none/release/text_64_64_reloc.o"),
-    );
+    let mut bpf = load_and_attach("test_text_64_64_reloc", integration_test::TEXT_64_64_RELOC);
 
     let mut m = aya::maps::Array::<_, u64>::try_from(bpf.map_mut("RESULTS").unwrap()).unwrap();
     m.set(0, 1, 0).unwrap();

+ 5 - 5
test/integration-test/tests/smoke.rs

@@ -27,15 +27,15 @@ fn extension() {
         eprintln!("skipping test on kernel {kernel_version:?}, XDP uses netlink");
         return;
     }
-    let main_bytes =
-        include_bytes_aligned!("../../../target/bpfel-unknown-none/release/main.bpf.o");
-    let mut bpf = Bpf::load(main_bytes).unwrap();
+    let mut bpf = Bpf::load(integration_test::MAIN).unwrap();
     let pass: &mut Xdp = bpf.program_mut("pass").unwrap().try_into().unwrap();
     pass.load().unwrap();
     pass.attach("lo", XdpFlags::default()).unwrap();
 
-    let ext_bytes = include_bytes_aligned!("../../../target/bpfel-unknown-none/release/ext.bpf.o");
-    let mut bpf = BpfLoader::new().extension("drop").load(ext_bytes).unwrap();
+    let mut bpf = BpfLoader::new()
+        .extension("drop")
+        .load(integration_test::EXT)
+        .unwrap();
     let drop_: &mut Extension = bpf.program_mut("drop").unwrap().try_into().unwrap();
     drop_.load(pass.fd().unwrap(), "xdp_pass").unwrap();
 }

+ 5 - 12
test/run.sh

@@ -7,7 +7,6 @@ if [ "$(uname -s)" = "Darwin" ]; then
 fi
 
 AYA_SOURCE_DIR="$(realpath $(dirname $0)/..)"
-LIBBPF_DIR=$1
 
 # Temporary directory for tests to use.
 AYA_TMPDIR="${AYA_SOURCE_DIR}/.tmp"
@@ -236,25 +235,19 @@ cleanup_vm() {
     fi
 }
 
-if [ -z "$LIBBPF_DIR" ]; then
-    echo "path to libbpf required"
-    exit 1
-fi
-
 start_vm
 trap cleanup_vm EXIT
 
-# make sure we always use fresh aya and libbpf (also see comment at the end)
-exec_vm "rm -rf aya/* libbpf"
+# make sure we always use fresh sources (also see comment at the end)
+exec_vm "rm -rf aya/*"
 rsync_vm "--exclude=target --exclude=.tmp $AYA_SOURCE_DIR"
-rsync_vm "$LIBBPF_DIR"
 
 # need to build or linting will fail trying to include object files; don't run the tests though.
-exec_vm "cd aya; cargo xtask integration-test --libbpf-dir ~/libbpf -- filter-that-matches-nothing"
+exec_vm "cd aya; cargo xtask integration-test -- filter-that-matches-nothing"
 exec_vm "cd aya; cargo clippy --all-targets -p integration-test -- --deny warnings"
-exec_vm "cd aya; cargo xtask integration-test --libbpf-dir ~/libbpf"
+exec_vm "cd aya; cargo xtask integration-test"
 
 # we rm and sync but it doesn't seem to work reliably - I guess we could sleep a
 # few seconds after but ain't nobody got time for that. Instead we also rm
 # before rsyncing.
-exec_vm "rm -rf aya/* libbpf; sync"
+exec_vm "rm -rf aya/*; sync"

+ 2 - 84
xtask/src/build_ebpf.rs

@@ -1,11 +1,4 @@
-use std::{
-    borrow::Cow,
-    env,
-    ffi::{OsStr, OsString},
-    fs,
-    path::{Path, PathBuf},
-    process::Command,
-};
+use std::{path::PathBuf, process::Command};
 
 use anyhow::Result;
 use clap::Parser;
@@ -44,21 +37,10 @@ pub struct BuildEbpfOptions {
     /// Set the endianness of the BPF target
     #[clap(default_value = "bpfel-unknown-none", long)]
     pub target: Architecture,
-    /// Libbpf dir, required for compiling C code
-    #[clap(long, action)]
-    pub libbpf_dir: PathBuf,
 }
 
 pub fn build_ebpf(opts: BuildEbpfOptions) -> Result<()> {
-    build_rust_ebpf(&opts)?;
-    build_c_ebpf(&opts)
-}
-
-fn build_rust_ebpf(opts: &BuildEbpfOptions) -> Result<()> {
-    let BuildEbpfOptions {
-        target,
-        libbpf_dir: _,
-    } = opts;
+    let BuildEbpfOptions { target } = opts;
 
     let mut dir = PathBuf::from(workspace_root());
     dir.push("test/integration-ebpf");
@@ -72,67 +54,3 @@ fn build_rust_ebpf(opts: &BuildEbpfOptions) -> Result<()> {
             .current_dir(&dir),
     )
 }
-
-fn get_libbpf_headers(libbpf_dir: &Path, include_path: &Path) -> Result<()> {
-    fs::create_dir_all(include_path)?;
-    let mut includedir = OsString::new();
-    includedir.push("INCLUDEDIR=");
-    includedir.push(include_path);
-    exec(
-        Command::new("make")
-            .current_dir(libbpf_dir.join("src"))
-            .arg(includedir)
-            .arg("install_headers"),
-    )
-}
-
-fn build_c_ebpf(opts: &BuildEbpfOptions) -> Result<()> {
-    let BuildEbpfOptions { target, libbpf_dir } = opts;
-
-    let mut src = PathBuf::from(workspace_root());
-    src.push("test/integration-ebpf/src/bpf");
-
-    let mut out_path = PathBuf::from(workspace_root());
-    out_path.push("target");
-    out_path.push(target.to_string());
-    out_path.push("release");
-
-    let include_path = out_path.join("include");
-    get_libbpf_headers(libbpf_dir, &include_path)?;
-    let files = fs::read_dir(&src).unwrap();
-    for file in files {
-        let p = file.unwrap().path();
-        if let Some(ext) = p.extension() {
-            if ext == "c" {
-                let mut out = PathBuf::from(&out_path);
-                out.push(p.file_name().unwrap());
-                out.set_extension("o");
-                compile_with_clang(&p, &out, &include_path)?;
-            }
-        }
-    }
-    Ok(())
-}
-
-/// Build eBPF programs with clang and libbpf headers.
-fn compile_with_clang(src: &Path, out: &Path, include_path: &Path) -> Result<()> {
-    let clang: Cow<'_, _> = match env::var_os("CLANG") {
-        Some(val) => val.into(),
-        None => OsStr::new("/usr/bin/clang").into(),
-    };
-    let arch = match env::consts::ARCH {
-        "x86_64" => "x86",
-        "aarch64" => "arm64",
-        arch => arch,
-    };
-    exec(
-        Command::new(clang)
-            .arg("-I")
-            .arg(include_path)
-            .args(["-g", "-O2", "-target", "bpf", "-c"])
-            .arg(format!("-D__TARGET_ARCH_{arch}"))
-            .arg(src)
-            .arg("-o")
-            .arg(out),
-    )
-}

+ 23 - 21
xtask/src/codegen/aya.rs

@@ -3,20 +3,22 @@ use std::path::PathBuf;
 
 use aya_tool::{bindgen, write_to_file};
 
-use crate::codegen::{Architecture, Options};
+use crate::codegen::{Architecture, SysrootOptions};
 
-pub fn codegen(opts: &Options) -> Result<(), anyhow::Error> {
-    codegen_internal_btf_bindings(opts)?;
+pub fn codegen(opts: &SysrootOptions) -> Result<(), anyhow::Error> {
+    codegen_internal_btf_bindings()?;
     codegen_bindings(opts)
 }
 
-fn codegen_internal_btf_bindings(opts: &Options) -> Result<(), anyhow::Error> {
+fn codegen_internal_btf_bindings() -> Result<(), anyhow::Error> {
     let dir = PathBuf::from("aya-obj");
     let generated = dir.join("src/generated");
+    let libbpf_dir = PathBuf::from("libbpf");
+
     let mut bindgen = bindgen::user_builder()
         .clang_arg(format!(
             "-I{}",
-            opts.libbpf_dir
+            libbpf_dir
                 .join("include/uapi")
                 .canonicalize()
                 .unwrap()
@@ -24,17 +26,13 @@ fn codegen_internal_btf_bindings(opts: &Options) -> Result<(), anyhow::Error> {
         ))
         .clang_arg(format!(
             "-I{}",
-            opts.libbpf_dir
+            libbpf_dir
                 .join("include")
                 .canonicalize()
                 .unwrap()
                 .to_string_lossy()
         ))
-        .header(
-            opts.libbpf_dir
-                .join("src/libbpf_internal.h")
-                .to_string_lossy(),
-        )
+        .header(libbpf_dir.join("src/libbpf_internal.h").to_string_lossy())
         .constified_enum_module("bpf_core_relo_kind");
 
     let types = ["bpf_core_relo", "btf_ext_header"];
@@ -54,7 +52,13 @@ fn codegen_internal_btf_bindings(opts: &Options) -> Result<(), anyhow::Error> {
     Ok(())
 }
 
-fn codegen_bindings(opts: &Options) -> Result<(), anyhow::Error> {
+fn codegen_bindings(opts: &SysrootOptions) -> Result<(), anyhow::Error> {
+    let SysrootOptions {
+        x86_64_sysroot,
+        aarch64_sysroot,
+        armv7_sysroot,
+        riscv64_sysroot,
+    } = opts;
     let types = [
         // BPF
         "BPF_TYPES",
@@ -158,15 +162,13 @@ fn codegen_bindings(opts: &Options) -> Result<(), anyhow::Error> {
 
     let dir = PathBuf::from("aya-obj");
     let generated = dir.join("src/generated");
+    let libbpf_dir = PathBuf::from("libbpf");
 
     let builder = || {
         bindgen::user_builder()
             .header(dir.join("include/linux_wrapper.h").to_string_lossy())
-            .clang_args(&[
-                "-I",
-                &*opts.libbpf_dir.join("include/uapi").to_string_lossy(),
-            ])
-            .clang_args(&["-I", &*opts.libbpf_dir.join("include").to_string_lossy()])
+            .clang_args(&["-I", &*libbpf_dir.join("include/uapi").to_string_lossy()])
+            .clang_args(&["-I", &*libbpf_dir.join("include").to_string_lossy()])
     };
 
     for arch in Architecture::supported() {
@@ -185,10 +187,10 @@ fn codegen_bindings(opts: &Options) -> Result<(), anyhow::Error> {
         // Set the sysroot. This is needed to ensure that the correct arch
         // specific headers are imported.
         let sysroot = match arch {
-            Architecture::X86_64 => &opts.x86_64_sysroot,
-            Architecture::ARMv7 => &opts.armv7_sysroot,
-            Architecture::AArch64 => &opts.aarch64_sysroot,
-            Architecture::RISCV64 => &opts.riscv64_sysroot,
+            Architecture::X86_64 => x86_64_sysroot,
+            Architecture::ARMv7 => armv7_sysroot,
+            Architecture::AArch64 => aarch64_sysroot,
+            Architecture::RISCV64 => riscv64_sysroot,
         };
         bindgen = bindgen.clang_args(&["-I", &*sysroot.to_string_lossy()]);
 

+ 17 - 12
xtask/src/codegen/aya_bpf_bindings.rs

@@ -8,11 +8,19 @@ use syn::{parse_str, Item};
 
 use crate::codegen::{
     helpers::{expand_helpers, extract_helpers},
-    Architecture, Options,
+    Architecture, SysrootOptions,
 };
 
-pub fn codegen(opts: &Options) -> Result<(), anyhow::Error> {
+pub fn codegen(opts: &SysrootOptions) -> Result<(), anyhow::Error> {
+    let SysrootOptions {
+        x86_64_sysroot,
+        aarch64_sysroot,
+        armv7_sysroot,
+        riscv64_sysroot,
+    } = opts;
+
     let dir = PathBuf::from("bpf/aya-bpf-bindings");
+    let libbpf_dir = PathBuf::from("libbpf");
 
     let builder = || {
         let mut bindgen = bindgen::bpf_builder()
@@ -20,12 +28,9 @@ pub fn codegen(opts: &Options) -> Result<(), anyhow::Error> {
             // aya-tool uses aya_bpf::cty. We can't use that here since aya-bpf
             // depends on aya-bpf-bindings so it would create a circular dep.
             .ctypes_prefix("::aya_bpf_cty")
-            .clang_args(&[
-                "-I",
-                &*opts.libbpf_dir.join("include/uapi").to_string_lossy(),
-            ])
-            .clang_args(&["-I", &*opts.libbpf_dir.join("include").to_string_lossy()])
-            .clang_args(&["-I", &*opts.libbpf_dir.join("src").to_string_lossy()])
+            .clang_args(&["-I", &*libbpf_dir.join("include/uapi").to_string_lossy()])
+            .clang_args(&["-I", &*libbpf_dir.join("include").to_string_lossy()])
+            .clang_args(&["-I", &*libbpf_dir.join("src").to_string_lossy()])
             // open aya-bpf-bindings/.../bindings.rs and look for mod
             // _bindgen, those are anonymous enums
             .constified_enum("BPF_F_.*")
@@ -82,10 +87,10 @@ pub fn codegen(opts: &Options) -> Result<(), anyhow::Error> {
         // Set the sysroot. This is needed to ensure that the correct arch
         // specific headers are imported.
         let sysroot = match arch {
-            Architecture::X86_64 => &opts.x86_64_sysroot,
-            Architecture::ARMv7 => &opts.armv7_sysroot,
-            Architecture::AArch64 => &opts.aarch64_sysroot,
-            Architecture::RISCV64 => &opts.riscv64_sysroot,
+            Architecture::X86_64 => x86_64_sysroot,
+            Architecture::ARMv7 => armv7_sysroot,
+            Architecture::AArch64 => aarch64_sysroot,
+            Architecture::RISCV64 => riscv64_sysroot,
         };
         bindgen = bindgen.clang_args(&["-I", &*sysroot.to_string_lossy()]);
 

+ 20 - 12
xtask/src/codegen/mod.rs

@@ -52,13 +52,10 @@ impl std::fmt::Display for Architecture {
     }
 }
 
+// sysroot options. Default to ubuntu headers installed by the
+// libc6-dev-{arm64,armel}-cross packages.
 #[derive(Parser)]
-pub struct Options {
-    #[arg(long, action)]
-    libbpf_dir: PathBuf,
-
-    // sysroot options. Default to ubuntu headers installed by the
-    // libc6-dev-{arm64,armel}-cross packages.
+pub struct SysrootOptions {
     #[arg(long, default_value = "/usr/include/x86_64-linux-gnu", action)]
     x86_64_sysroot: PathBuf,
 
@@ -70,6 +67,12 @@ pub struct Options {
 
     #[arg(long, default_value = "/usr/riscv64-linux-gnu/include", action)]
     riscv64_sysroot: PathBuf,
+}
+
+#[derive(Parser)]
+pub struct Options {
+    #[command(flatten)]
+    sysroot_options: SysrootOptions,
 
     #[command(subcommand)]
     command: Option<Command>,
@@ -84,13 +87,18 @@ enum Command {
 }
 
 pub fn codegen(opts: Options) -> Result<(), anyhow::Error> {
-    use Command::*;
-    match opts.command {
-        Some(Aya) => aya::codegen(&opts),
-        Some(AyaBpfBindings) => aya_bpf_bindings::codegen(&opts),
+    let Options {
+        sysroot_options,
+        command,
+    } = opts;
+    match command {
+        Some(command) => match command {
+            Command::Aya => aya::codegen(&sysroot_options),
+            Command::AyaBpfBindings => aya_bpf_bindings::codegen(&sysroot_options),
+        },
         None => {
-            aya::codegen(&opts)?;
-            aya_bpf_bindings::codegen(&opts)
+            aya::codegen(&sysroot_options)?;
+            aya_bpf_bindings::codegen(&sysroot_options)
         }
     }
 }

+ 1 - 9
xtask/src/run.rs

@@ -22,9 +22,6 @@ pub struct Options {
     /// The command used to wrap your application
     #[clap(short, long, default_value = "sudo -E")]
     pub runner: String,
-    /// libbpf directory
-    #[clap(long, action)]
-    pub libbpf_dir: PathBuf,
     /// Arguments to pass to your application
     #[clap(name = "args", last = true)]
     pub run_args: Vec<String>,
@@ -90,16 +87,11 @@ pub fn run(opts: Options) -> Result<()> {
         bpf_target,
         release,
         runner,
-        libbpf_dir,
         run_args,
     } = opts;
 
     // build our ebpf program followed by our application
-    build_ebpf(BuildOptions {
-        target: bpf_target,
-        libbpf_dir,
-    })
-    .context("error while building eBPF program")?;
+    build_ebpf(BuildOptions { target: bpf_target }).context("error while building eBPF program")?;
 
     let binaries = build(release).context("error while building userspace application")?;
     let mut args = runner.trim().split_terminator(' ');