scx_rustland_core/
rustland_builder.rs

1// Copyright (c) Andrea Righi <andrea.righi@linux.dev>
2
3// This software may be used and distributed according to the terms of the
4// GNU General Public License version 2.
5
6use anyhow::Result;
7
8use scx_utils::BpfBuilder;
9use std::fs;
10use std::fs::File;
11use std::io::Write;
12use std::path::Path;
13
14pub struct RustLandBuilder {
15    inner_builder: BpfBuilder,
16}
17
18impl RustLandBuilder {
19    pub fn new() -> Result<Self> {
20        Ok(Self {
21            inner_builder: BpfBuilder::new()?,
22        })
23    }
24
25    fn create_file(&self, file_name: &str, content: &[u8]) {
26        let path = Path::new(file_name);
27
28        // Limit file writing to when file contents differ (for caching)
29        if fs::read(path).map_or(false, |b| b == content) {
30            return;
31        }
32
33        let mut file = File::create(path).expect("Unable to create file");
34        file.write_all(content).expect("Unable to write to file");
35    }
36
37    pub fn build(&mut self) -> Result<()> {
38        // Embed the BPF source files.
39        let intf = include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/assets/bpf/intf.h"));
40        let skel = include_bytes!(concat!(
41            env!("CARGO_MANIFEST_DIR"),
42            "/assets/bpf/main.bpf.c"
43        ));
44        let bpf = include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/assets/bpf.rs"));
45
46        // Generate BPF backend code (C).
47        self.create_file("intf.h", intf);
48        self.create_file("main.bpf.c", skel);
49
50        self.inner_builder.enable_intf("intf.h", "bpf_intf.rs");
51        self.inner_builder.enable_skel("main.bpf.c", "bpf");
52
53        // Generate user-space BPF connector code (Rust).
54        self.create_file("src/bpf.rs", bpf);
55
56        // Build the scheduler.
57        self.inner_builder.build()
58    }
59}