From b8d91f491f7672c25842e24f69d12389d0ada65d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20M=C3=BCller?= Date: Thu, 16 Jan 2025 15:14:09 -0800 Subject: [PATCH] libbpf-cargo: Introduce dedicated link step to BpfObjBuilder MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Building a BPF object file already invokes the libbpf linker in order to strip DWARF debug information from the resulting file. In the future we would like to link multiple files instead of only a single one, so refactor the code in such a way that we have a dedicated link step in BpfObjBuilder::build(). Signed-off-by: Daniel Müller --- libbpf-cargo/src/build.rs | 49 ++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/libbpf-cargo/src/build.rs b/libbpf-cargo/src/build.rs index ef901bd9..59944cdd 100644 --- a/libbpf-cargo/src/build.rs +++ b/libbpf-cargo/src/build.rs @@ -153,19 +153,35 @@ impl BpfObjBuilder { /// Build a BPF object file. pub fn build(&mut self, src: &Path, dst: &Path) -> Result { + 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 output = Self::compile_single(src, dst, &self.compiler, 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) })?; - // Compilation with clang may contain DWARF information that references - // system specific and temporary paths. That can render our generated - // skeletons unstable, potentially rendering them unsuitable for inclusion - // in version control systems. So strip this information. - strip_dwarf_info(dst) - .with_context(|| format!("Failed to strip object file {}", dst.display()))?; + // The resulting object file may contain DWARF information + // that references system specific and temporary paths. That + // can render our generated skeletons unstable, potentially + // making them unsuitable for inclusion in version control + // systems. Linking has the side effect of stripping this + // information. + linker.link().context("failed to link object file")?; Ok(output) } @@ -230,25 +246,6 @@ fn extract_libbpf_headers_to_disk(_target_dir: &Path) -> Result> Ok(None) } -/// Strip DWARF information from the provided BPF object file. -/// -/// We rely on the `libbpf` linker here, which removes debug information as a -/// side-effect. -fn strip_dwarf_info(file: &Path) -> Result<()> { - let mut temp_file = file.as_os_str().to_os_string(); - temp_file.push(".tmp"); - - fs::rename(file, &temp_file).context("Failed to rename compiled BPF object file")?; - - let mut linker = - libbpf_rs::Linker::new(file).context("Failed to instantiate libbpf object file linker")?; - linker - .add_file(temp_file) - .context("Failed to add object file to BPF linker")?; - linker.link().context("Failed to link object file")?; - Ok(()) -} - /// Concatenate a command and its arguments into a single string. fn concat_command(command: C, args: A) -> OsString where