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
38        let (objcopy_pkg, objcopy_bin): (Option<&str>, &str) = match arch {
39            CommonArch::X86_64 => match platform {
40                FlowPlatform::Linux(linux_distribution) => match linux_distribution {
41                    FlowPlatformLinuxDistro::Fedora => (
42                        Some("binutils-x86_64-linux-gnu"),
43                        "x86_64-linux-gnu-objcopy",
44                    ),
45                    FlowPlatformLinuxDistro::Ubuntu => (
46                        Some("binutils-x86-64-linux-gnu"),
47                        "x86_64-linux-gnu-objcopy",
48                    ),
49                    FlowPlatformLinuxDistro::AzureLinux => {
50                        match_arch!(host_arch, FlowArch::X86_64, (Some("binutils"), "objcopy"))
51                    }
52                    FlowPlatformLinuxDistro::Arch => {
53                        match_arch!(host_arch, FlowArch::X86_64, (Some("binutils"), "objcopy"))
54                    }
55                    FlowPlatformLinuxDistro::Nix => (None, "x86_64-linux-gnu-objcopy"),
56                    FlowPlatformLinuxDistro::Unknown => anyhow::bail!("Unknown Linux distribution"),
57                },
58                _ => anyhow::bail!("Unsupported platform"),
59            },
60            CommonArch::Aarch64 => match platform {
61                FlowPlatform::Linux(linux_distribution) => match linux_distribution {
62                    FlowPlatformLinuxDistro::Fedora | FlowPlatformLinuxDistro::Ubuntu => (
63                        Some("binutils-aarch64-linux-gnu"),
64                        "aarch64-linux-gnu-objcopy",
65                    ),
66                    FlowPlatformLinuxDistro::AzureLinux => match host_arch {
67                        FlowArch::Aarch64 => (Some("binutils"), "objcopy"),
68                        FlowArch::X86_64 => (
69                            Some("binutils-aarch64-linux-gnu"),
70                            "aarch64-linux-gnu-objcopy",
71                        ),
72                        _ => anyhow::bail!("unsupported host arch {host_arch:?}"),
73                    },
74                    FlowPlatformLinuxDistro::Arch => {
75                        match_arch!(
76                            host_arch,
77                            FlowArch::X86_64,
78                            (
79                                Some("aarch64-linux-gnu-binutils"),
80                                "aarch64-linux-gnu-objcopy"
81                            )
82                        )
83                    }
84                    FlowPlatformLinuxDistro::Nix => (None, "aarch64-linux-gnu-objcopy"),
85                    FlowPlatformLinuxDistro::Unknown => {
86                        anyhow::bail!("Unknown Linux distribution")
87                    }
88                },
89                _ => anyhow::bail!("Unsupported platform"),
90            },
91        };
92
93        let installed_objcopy = objcopy_pkg.map(|objcopy_pkg| {
94            ctx.reqv(
95                |side_effect| flowey_lib_common::install_dist_pkg::Request::Install {
96                    package_names: vec![objcopy_pkg.into()],
97                    done: side_effect,
98                },
99            )
100        });
101
102        ctx.emit_rust_step("split debug symbols", |ctx| {
103            installed_objcopy.claim(ctx);
104            let in_bin = in_bin.claim(ctx);
105            let out_bin = out_bin.claim(ctx);
106            let out_dbg_info = out_dbg_info.claim(ctx);
107            move |rt| {
108                let in_bin = rt.read(in_bin);
109
110                let output = rt.sh.current_dir().join(in_bin.file_name().unwrap());
111                flowey::shell_cmd!(rt, "{objcopy_bin} --only-keep-debug {in_bin} {output}.dbg").run()?;
112                flowey::shell_cmd!(
113                    rt,
114                    "{objcopy_bin} --strip-all --keep-section=.build_info --add-gnu-debuglink={output}.dbg {in_bin} {output}"
115                )
116                .run()?;
117
118                let output = output.absolute()?;
119
120                rt.write(out_bin, &output);
121                rt.write(out_dbg_info, &output.with_extension("dbg"));
122
123                Ok(())
124            }
125        });
126
127        Ok(())
128    }
129}