Skip to content

Commit

Permalink
Merge pull request #8 from Thaumy/fix-build
Browse files Browse the repository at this point in the history
Support build on Linux 3.12+
  • Loading branch information
OptimatistOpenSource authored Jan 25, 2024
2 parents da64e72 + 0e1b477 commit 79c27db
Show file tree
Hide file tree
Showing 44 changed files with 586 additions and 248 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/build-dev-auto-feature.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,8 @@ jobs:
fail-fast: false
matrix:
target:
# TODO: Build in ubuntu-20.04 from GitHub Actions fails due to missing some definitions in `linux/version.h`
#- { os: ubuntu-20.04, triple: x86_64-unknown-linux-gnu , alias: amd64-gnu-ubuntu-20.04 }
#- { os: ubuntu-20.04, triple: x86_64-unknown-linux-musl, alias: amd64-musl-ubuntu-20.04 }
- { os: ubuntu-20.04, triple: x86_64-unknown-linux-gnu , alias: amd64-gnu-ubuntu-20.04 }
- { os: ubuntu-20.04, triple: x86_64-unknown-linux-musl, alias: amd64-musl-ubuntu-20.04 }
- { os: ubuntu-22.04, triple: x86_64-unknown-linux-gnu , alias: amd64-gnu-ubuntu-22.04 }
- { os: ubuntu-22.04, triple: x86_64-unknown-linux-musl, alias: amd64-musl-ubuntu-22.04 }

Expand All @@ -48,6 +47,7 @@ jobs:
cargo fmt -- -V
rustc -V
uname -a
cat /usr/include/linux/version.h
- name: Setup Rust cache
uses: Swatinem/rust-cache@v2
Expand Down
19 changes: 17 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ license = "MIT"
repository = "https://github.com/OptimatistOpenSource/perf-event-rs.git"
keywords = ["binding", "event", "perf"]
categories = ["api-bindings"]
build = "build.rs"
build = "build/main.rs"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

Expand All @@ -22,7 +22,22 @@ build = "build.rs"
"linux-5.8" = ["linux-5.7"]
"linux-5.7" = ["linux-5.5"]
"linux-5.5" = ["linux-5.4"]
"linux-5.4" = []
"linux-5.4" = ["linux-5.1"]
"linux-5.1" = ["linux-4.17"]
"linux-4.17" = ["linux-4.16"]
"linux-4.16" = ["linux-4.14"]
"linux-4.14" = ["linux-4.12"]
"linux-4.12" = ["linux-4.8"]
"linux-4.8" = ["linux-4.7"]
"linux-4.7" = ["linux-4.4"]
"linux-4.4" = ["linux-4.3"]
"linux-4.3" = ["linux-4.2"]
"linux-4.2" = ["linux-4.1"]
"linux-4.1" = ["linux-3.19"]
"linux-3.19" = ["linux-3.16"]
"linux-3.16" = ["linux-3.13"]
"linux-3.13" = ["linux-3.12"]
"linux-3.12" = []

[build-dependencies]
bindgen = "0.68.1"
Expand Down
145 changes: 0 additions & 145 deletions build.rs

This file was deleted.

40 changes: 40 additions & 0 deletions build/consts.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// [(major, patch_level, is_selected)]
#[rustfmt::skip]
pub const LINUX_FEATURE_VERSIONS: [(usize, usize, bool); 26] = [
(6, 3, cfg!(feature = "linux-6.3" )),
(6, 0, cfg!(feature = "linux-6.0" )),
(5,16, cfg!(feature = "linux-5.16")),
(5,13, cfg!(feature = "linux-5.13")),
(5,12, cfg!(feature = "linux-5.12")),
(5,11, cfg!(feature = "linux-5.11")),
(5, 9, cfg!(feature = "linux-5.9" )),
(5, 8, cfg!(feature = "linux-5.8" )),
(5, 7, cfg!(feature = "linux-5.7" )),
(5, 5, cfg!(feature = "linux-5.5" )),
(5, 4, cfg!(feature = "linux-5.4" )),
(5, 1, cfg!(feature = "linux-5.1" )),
(4,17, cfg!(feature = "linux-4.17")),
(4,16, cfg!(feature = "linux-4.16")),
(4,14, cfg!(feature = "linux-4.14")),
(4,12, cfg!(feature = "linux-4.12")),
(4, 8, cfg!(feature = "linux-4.8" )),
(4, 7, cfg!(feature = "linux-4.7" )),
(4, 4, cfg!(feature = "linux-4.4" )),
(4, 3, cfg!(feature = "linux-4.3" )),
(4, 2, cfg!(feature = "linux-4.2" )),
(4, 1, cfg!(feature = "linux-4.1" )),
(3,19, cfg!(feature = "linux-3.19")),
(3,16, cfg!(feature = "linux-3.16")),
(3,13, cfg!(feature = "linux-3.13")),
(3,12, cfg!(feature = "linux-3.12")),
];

// [(major, patch_level, enum_entry)]
#[rustfmt::skip]
pub const IOCTLS: [(usize, usize, &str); 5] = [
(3,12, "PERF_EVENT_IOCTL_ID = PERF_EVENT_IOC_ID," ),
(4, 1, "PERF_EVENT_IOCTL_SET_BPF = PERF_EVENT_IOC_SET_BPF," ),
(4, 7, "PERF_EVENT_IOCTL_PAUSE_OUTPUT = PERF_EVENT_IOC_PAUSE_OUTPUT," ),
(4,16, "PERF_EVENT_IOCTL_QUERY_BPF = PERF_EVENT_IOC_QUERY_BPF," ),
(4,17, "PERF_EVENT_IOCTL_MODIFY_ATTRIBUTES = PERF_EVENT_IOC_MODIFY_ATTRIBUTES,"),
];
90 changes: 90 additions & 0 deletions build/helpers.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
use crate::consts::IOCTLS;
use std::fs;

/// Parse `LINUX_VERSION_CODE` of `linux/version.h` to (major, patch_level, sub_level)
pub fn parse_linux_version_h(path: &str) -> (usize, usize, usize) {
let first_line = fs::read_to_string(path)
.unwrap_or_else(|_| panic!("Failed to read {}", path))
.lines()
.next()
.unwrap_or_else(|| panic!("No lines in {}", path))
.to_string();
let linux_version_code = first_line
.split(' ')
.nth(2)
.unwrap_or_else(|| panic!("Invalid line {}", first_line))
.to_string();
let linux_version_code = linux_version_code.parse::<usize>().unwrap_or_else(|e| {
panic!(
"Invalid LINUX_VERSION_CODE `{}` ({})",
linux_version_code, e
)
});

let major = linux_version_code >> 16;
let patch_lv = (linux_version_code & 65535) >> 8;
let sub_lv = linux_version_code & 255;
(major, patch_lv, sub_lv)
}

pub fn bindgen(linux_headers_path: &str, enabled_feature_versions: &[(usize, usize)]) {
let bindings_output_path = "src/syscall/bindings/bindgen.rs";
// Try delete `bindgen.rs` for every build
let _ = fs::remove_file(bindings_output_path);

let header_contents = {
let include_linux_bpf_h = if enabled_feature_versions.contains(&(5, 1)) {
"#include <linux/bpf.h>"
} else {
""
};
let enum_entries = enabled_feature_versions
.iter()
.fold(String::new(), |mut acc, it| {
IOCTLS.iter().try_for_each(|(m, p, str)| {
if *it == (*m, *p) {
acc.push_str(str);
None
} else {
Some(())
}
});
acc
});
format!(
"
#include <asm/unistd.h>
#include <linux/hw_breakpoint.h>
#include <linux/perf_event.h>
{}
enum perf_event_ioctls {{
PERF_EVENT_IOCTL_ENABLE = PERF_EVENT_IOC_ENABLE,
PERF_EVENT_IOCTL_DISABLE = PERF_EVENT_IOC_DISABLE,
PERF_EVENT_IOCTL_REFRESH = PERF_EVENT_IOC_REFRESH,
PERF_EVENT_IOCTL_RESET = PERF_EVENT_IOC_RESET,
PERF_EVENT_IOCTL_PERIOD = PERF_EVENT_IOC_PERIOD,
PERF_EVENT_IOCTL_SET_OUTPUT = PERF_EVENT_IOC_SET_OUTPUT,
PERF_EVENT_IOCTL_SET_FILTER = PERF_EVENT_IOC_SET_FILTER,
{}
}};",
include_linux_bpf_h, enum_entries,
)
};

let builder = bindgen::Builder::default()
.derive_default(true)
.generate_comments(false)
.prepend_enum_name(false)
.header_contents("wrapper.h", &header_contents);

if linux_headers_path != "/usr/include" {
builder.clang_arg(format!("-I{}", linux_headers_path))
} else {
builder
}
.generate()
.unwrap_or_else(|e| panic!("Failed to generate bindings: {}", e))
.write_to_file(bindings_output_path)
.unwrap_or_else(|e| panic!("Failed to write {}: {}", bindings_output_path, e));
}
Loading

0 comments on commit 79c27db

Please sign in to comment.