From 1e01814ab847e2d3e5b580101a41f5f4fa1a4880 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20M=C3=BCller?= Date: Thu, 16 Jan 2025 15:00:40 -0800 Subject: [PATCH] libbpf-cargo: Support linking multiple files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support for building a BPF object file from multiple input files, by first compiling each separately and the linking everything together. Signed-off-by: Daniel Müller --- libbpf-cargo/src/build.rs | 52 ++++++++++++++++++++++++++------------- 1 file changed, 35 insertions(+), 17 deletions(-) diff --git a/libbpf-cargo/src/build.rs b/libbpf-cargo/src/build.rs index 59944cdd..7be9f3aa 100644 --- a/libbpf-cargo/src/build.rs +++ b/libbpf-cargo/src/build.rs @@ -151,28 +151,36 @@ impl BpfObjBuilder { f(&compiler_args) } - /// Build a BPF object file. - pub fn build(&mut self, src: &Path, dst: &Path) -> Result { + /// Build a BPF object file from a set of input files. + pub fn build_many(&mut self, srcs: S, dst: &Path) -> Result> + where + S: IntoIterator, + P: AsRef, + { let obj_dir = tempdir().context("failed to create temporary directory")?; let mut linker = libbpf_rs::Linker::new(dst) .context("failed to instantiate libbpf object file linker")?; let output = self.with_compiler_args(|compiler_args| { - let tmp_dst = obj_dir.path().join(src.file_name().with_context(|| { - format!( - "input path `{}` does not have a proper file name", - src.display() - ) - })?); - - let output = Self::compile_single(src, &tmp_dst, &self.compiler, compiler_args) - .with_context(|| format!("failed to compile `{}`", src.display()))?; - - linker - .add_file(tmp_dst) - .context("failed to add object file to BPF linker")?; - - Ok(output) + srcs.into_iter() + .map(|src| { + let src = src.as_ref(); + let tmp_dst = obj_dir.path().join(src.file_name().with_context(|| { + format!( + "input path `{}` does not have a proper file name", + src.display() + ) + })?); + + let output = Self::compile_single(src, &tmp_dst, &self.compiler, compiler_args) + .with_context(|| format!("failed to compile `{}`", src.display()))?; + + linker + .add_file(tmp_dst) + .context("failed to add object file to BPF linker")?; + Ok(output) + }) + .collect::>() })?; // The resulting object file may contain DWARF information @@ -185,6 +193,16 @@ impl BpfObjBuilder { Ok(output) } + + /// Build a BPF object file. + pub fn build(&mut self, src: &Path, dst: &Path) -> Result { + self.build_many([src], dst).map(|vec| { + // SANITY: We pass in a single file we `build_many` is + // guaranteed to produce as many outputs as input + // files; so there must be one. + vec.into_iter().next().unwrap() + }) + } } impl Default for BpfObjBuilder {