flowey_lib_hvlite/
run_split_debug_info.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Splits debug info from a binary into a separate file using `objcopy`
5
6use crate::run_cargo_build::common::CommonArch;
7use flowey::node::prelude::*;
8
9flowey_request! {
10    pub struct Request {
11        pub arch: CommonArch,
12        pub in_bin: ReadVar<PathBuf>,
13        pub out_bin: WriteVar<PathBuf>,
14        pub out_dbg_info: WriteVar<PathBuf>,
15    }
16}
17
18new_simple_flow_node!(struct Node);
19
20impl SimpleFlowNode for Node {
21    type Request = Request;
22
23    fn imports(ctx: &mut ImportCtx<'_>) {
24        ctx.import::<flowey_lib_common::install_dist_pkg::Node>();
25    }
26
27    fn process_request(request: Self::Request, ctx: &mut NodeCtx<'_>) -> anyhow::Result<()> {
28        let Request {
29            arch,
30            in_bin,
31            out_bin,
32            out_dbg_info,
33        } = request;
34
35        let host_arch = ctx.arch();
36        let platform = ctx.platform();
37        let (objcopy_pkg, objcopy_bin) = match arch {
38            CommonArch::X86_64 => match platform {
39                FlowPlatform::Linux(linux_distribution) => match linux_distribution {
40                    FlowPlatformLinuxDistro::Fedora => {
41                        ("binutils-x86_64-linux-gnu", "x86_64-linux-gnu-objcopy")
42                    }
43                    FlowPlatformLinuxDistro::Ubuntu => {
44                        ("binutils-x86-64-linux-gnu", "x86_64-linux-gnu-objcopy")
45                    }
46                    FlowPlatformLinuxDistro::Arch => {
47                        match_arch!(host_arch, FlowArch::X86_64, ("binutils", "objcopy"))
48                    }
49                    FlowPlatformLinuxDistro::Unknown => anyhow::bail!("Unknown Linux distribution"),
50                },
51                _ => anyhow::bail!("Unsupported platform"),
52            },
53            CommonArch::Aarch64 => {
54                let pkg = match platform {
55                    FlowPlatform::Linux(linux_distribution) => match linux_distribution {
56                        FlowPlatformLinuxDistro::Fedora | FlowPlatformLinuxDistro::Ubuntu => {
57                            "binutils-aarch64-linux-gnu"
58                        }
59                        FlowPlatformLinuxDistro::Arch => {
60                            match_arch!(host_arch, FlowArch::X86_64, "aarch64-linux-gnu-binutils")
61                        }
62                        FlowPlatformLinuxDistro::Unknown => {
63                            anyhow::bail!("Unknown Linux distribution")
64                        }
65                    },
66                    _ => anyhow::bail!("Unsupported platform"),
67                };
68                (pkg, "aarch64-linux-gnu-objcopy")
69            }
70        };
71
72        let installed_objcopy =
73            ctx.reqv(
74                |side_effect| flowey_lib_common::install_dist_pkg::Request::Install {
75                    package_names: vec![objcopy_pkg.into()],
76                    done: side_effect,
77                },
78            );
79
80        ctx.emit_rust_step("split debug symbols", |ctx| {
81            installed_objcopy.clone().claim(ctx);
82            let in_bin = in_bin.claim(ctx);
83            let out_bin = out_bin.claim(ctx);
84            let out_dbg_info = out_dbg_info.claim(ctx);
85            move |rt| {
86                let in_bin = rt.read(in_bin);
87
88                let sh = xshell::Shell::new()?;
89                let output = sh.current_dir().join(in_bin.file_name().unwrap());
90                xshell::cmd!(sh, "{objcopy_bin} --only-keep-debug {in_bin} {output}.dbg").run()?;
91                xshell::cmd!(
92                    sh,
93                    "{objcopy_bin} --strip-all --keep-section=.build_info --add-gnu-debuglink={output}.dbg {in_bin} {output}"
94                )
95                .run()?;
96
97                let output = output.absolute()?;
98
99                rt.write(out_bin, &output);
100                rt.write(out_dbg_info, &output.with_extension("dbg"));
101
102                Ok(())
103            }
104        });
105
106        Ok(())
107    }
108}