mirror of
https://github.com/sched-ext/scx.git
synced 2024-11-28 05:30:24 +00:00
Use per-arch vmlinux.h
vmlinux.h is not compatible across archs. Handle this compatibility issue by * Add arch info into vmlinux.h real file name * Link vmlinux.h to the target-arch real file at build time * Use target-arch real file for scx_utils bindgen. Also refactored clang related logic into a new clang_info mod, which is shared by bpf_builder.rs and builder.rs. Signed-off-by: Ming Yang <minos.future@gmail.com>
This commit is contained in:
parent
03f078ac74
commit
a23f3566e3
@ -37,6 +37,12 @@ bindgen = ">=0.68, <0.70"
|
||||
tar = "0.4"
|
||||
vergen = { version = "8.0.0", features = ["cargo", "git", "gitcl"] }
|
||||
walkdir = "2.4"
|
||||
anyhow = "1.0.65"
|
||||
glob = "0.3"
|
||||
libbpf-cargo = "0.24.1"
|
||||
sscanf = "0.4"
|
||||
lazy_static = "1.4"
|
||||
version-compare = "0.1"
|
||||
|
||||
[features]
|
||||
default = []
|
||||
|
@ -3,43 +3,18 @@
|
||||
// This software may be used and distributed according to the terms of the
|
||||
// GNU General Public License version 2.
|
||||
|
||||
use crate::clang_info::ClangInfo;
|
||||
use anyhow::anyhow;
|
||||
use anyhow::bail;
|
||||
use anyhow::Context;
|
||||
use anyhow::Result;
|
||||
use glob::glob;
|
||||
use libbpf_cargo::SkeletonBuilder;
|
||||
use sscanf::sscanf;
|
||||
use std::collections::BTreeSet;
|
||||
use std::collections::HashMap;
|
||||
use std::env;
|
||||
use std::ffi::OsStr;
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
use std::process::Command;
|
||||
|
||||
lazy_static::lazy_static! {
|
||||
// Map clang archs to the __TARGET_ARCH list in
|
||||
// tools/lib/bpf/bpf_tracing.h in the kernel tree.
|
||||
static ref ARCH_MAP: HashMap<&'static str, &'static str> = vec![
|
||||
("x86", "x86"),
|
||||
("x86_64", "x86"),
|
||||
("s390", "s390"),
|
||||
("s390x", "s390"),
|
||||
("arm", "arm"),
|
||||
("aarch64", "arm64"),
|
||||
("mips", "mips"),
|
||||
("mips64", "mips"),
|
||||
("ppc32", "powerpc"),
|
||||
("ppc64", "powerpc"),
|
||||
("ppc64le", "powerpc"),
|
||||
("sparc", "sparc"),
|
||||
("sparcv9", "sparc"),
|
||||
("riscv32", "riscv"),
|
||||
("riscv64", "riscv"),
|
||||
("arc", "arc"), // unsure this is supported
|
||||
("loongarch64", "loongarch"), // ditto
|
||||
].into_iter().collect();
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
/// # Build helpers for sched_ext schedulers with Rust userspace component
|
||||
@ -209,7 +184,7 @@ lazy_static::lazy_static! {
|
||||
/// -L$KERNEL/tools/bpf/bpftool/libbpf" cargo build --release
|
||||
/// ```
|
||||
pub struct BpfBuilder {
|
||||
clang: (String, String, String), // (clang, ver, arch)
|
||||
clang: ClangInfo,
|
||||
cflags: Vec<String>,
|
||||
out_dir: PathBuf,
|
||||
|
||||
@ -219,140 +194,6 @@ pub struct BpfBuilder {
|
||||
}
|
||||
|
||||
impl BpfBuilder {
|
||||
fn skip_clang_version_prefix(line: &str) -> &str {
|
||||
if let Some(index) = line.find("clang version") {
|
||||
&line[index..]
|
||||
} else {
|
||||
line
|
||||
}
|
||||
}
|
||||
|
||||
fn find_clang() -> Result<(String, String, String)> {
|
||||
let clang = env::var("BPF_CLANG").unwrap_or("clang".into());
|
||||
let output = Command::new(&clang)
|
||||
.args(["--version"])
|
||||
.output()
|
||||
.with_context(|| format!("Failed to run \"{} --version\"", &clang))?;
|
||||
|
||||
let stdout = String::from_utf8(output.stdout)?;
|
||||
let (mut ver, mut arch) = (None, None);
|
||||
for line in stdout.lines() {
|
||||
if let Ok(v) = sscanf!(
|
||||
Self::skip_clang_version_prefix(line),
|
||||
"clang version {String}"
|
||||
) {
|
||||
// Version could be followed by (URL SHA1). Only take
|
||||
// the first word.
|
||||
ver = Some(v.split_whitespace().next().unwrap().to_string());
|
||||
continue;
|
||||
}
|
||||
if let Ok(v) = sscanf!(line, "Target: {String}") {
|
||||
arch = Some(v.split('-').next().unwrap().to_string());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
let (ver, arch) = (
|
||||
ver.ok_or(anyhow!("Failed to read clang version"))?,
|
||||
arch.ok_or(anyhow!("Failed to read clang target arch"))?,
|
||||
);
|
||||
|
||||
if version_compare::compare(&ver, "16") == Ok(version_compare::Cmp::Lt) {
|
||||
bail!(
|
||||
"clang < 16 loses high 32 bits of 64 bit enums when compiling BPF ({:?} ver={:?})",
|
||||
&clang,
|
||||
&ver
|
||||
);
|
||||
}
|
||||
if version_compare::compare(&ver, "17") == Ok(version_compare::Cmp::Lt) {
|
||||
println!(
|
||||
"cargo:warning=clang >= 17 recommended ({:?} ver={:?})",
|
||||
&clang, &ver
|
||||
);
|
||||
}
|
||||
|
||||
Ok((clang, ver, arch))
|
||||
}
|
||||
|
||||
fn determine_base_cflags(
|
||||
(clang, _ver, arch): &(String, String, String),
|
||||
) -> Result<Vec<String>> {
|
||||
// Determine kernel target arch.
|
||||
let kernel_target = match ARCH_MAP.get(arch.as_str()) {
|
||||
Some(v) => v,
|
||||
None => bail!("CPU arch {:?} not found in ARCH_MAP", &arch),
|
||||
};
|
||||
|
||||
// Determine system includes.
|
||||
let output = Command::new(&clang)
|
||||
.args(["-v", "-E", "-"])
|
||||
.output()
|
||||
.with_context(|| format!("Failed to run \"{} -v -E - < /dev/null", &clang))?;
|
||||
let stderr = String::from_utf8(output.stderr)?;
|
||||
|
||||
let mut sys_incls = None;
|
||||
for line in stderr.lines() {
|
||||
if line == "#include <...> search starts here:" {
|
||||
sys_incls = Some(vec![]);
|
||||
continue;
|
||||
}
|
||||
if sys_incls.is_none() {
|
||||
continue;
|
||||
}
|
||||
if line == "End of search list." {
|
||||
break;
|
||||
}
|
||||
|
||||
sys_incls.as_mut().unwrap().push(line.trim());
|
||||
}
|
||||
let sys_incls = match sys_incls {
|
||||
Some(v) => v,
|
||||
None => bail!("Failed to find system includes from {:?}", &clang),
|
||||
};
|
||||
|
||||
// Determine endian.
|
||||
let output = Command::new(&clang)
|
||||
.args(["-dM", "-E", "-"])
|
||||
.output()
|
||||
.with_context(|| format!("Failed to run \"{} -dM E - < /dev/null", &clang))?;
|
||||
let stdout = String::from_utf8(output.stdout)?;
|
||||
|
||||
let mut endian = None;
|
||||
for line in stdout.lines() {
|
||||
match sscanf!(line, "#define __BYTE_ORDER__ {str}") {
|
||||
Ok(v) => {
|
||||
endian = Some(match v {
|
||||
"__ORDER_LITTLE_ENDIAN__" => "little",
|
||||
"__ORDER_BIG_ENDIAN__" => "big",
|
||||
v => bail!("Unknown __BYTE_ORDER__ {:?}", v),
|
||||
});
|
||||
break;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
let endian = match endian {
|
||||
Some(v) => v,
|
||||
None => bail!("Failed to find __BYTE_ORDER__ from {:?}", &clang),
|
||||
};
|
||||
|
||||
// Assemble cflags.
|
||||
let mut cflags: Vec<String> = ["-g", "-O2", "-Wall", "-Wno-compare-distinct-pointer-types"]
|
||||
.into_iter()
|
||||
.map(|x| x.into())
|
||||
.collect();
|
||||
cflags.push(format!("-D__TARGET_ARCH_{}", &kernel_target));
|
||||
cflags.push("-mcpu=v3".into());
|
||||
cflags.push(format!("-m{}-endian", endian));
|
||||
cflags.append(
|
||||
&mut sys_incls
|
||||
.into_iter()
|
||||
.flat_map(|x| ["-idirafter".into(), x.into()])
|
||||
.collect(),
|
||||
);
|
||||
Ok(cflags)
|
||||
}
|
||||
|
||||
const BPF_H_TAR: &'static [u8] = include_bytes!(concat!(env!("OUT_DIR"), "/bpf_h.tar"));
|
||||
|
||||
fn install_bpf_h<P: AsRef<Path>>(dest: P) -> Result<()> {
|
||||
@ -361,30 +202,36 @@ impl BpfBuilder {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Return `(VER, SHA1)` from which the bulit-in `vmlinux.h` is generated.
|
||||
pub fn vmlinux_h_ver_sha1() -> (String, String) {
|
||||
let mut ar = tar::Archive::new(Self::BPF_H_TAR);
|
||||
fn ln_vmlinux_h<P: AsRef<Path> + AsRef<OsStr>>(dest: P, kernel_target: &str) -> Result<()> {
|
||||
let entries = fs::read_dir(&dest)?;
|
||||
|
||||
for file in ar.entries().unwrap() {
|
||||
let file = file.unwrap();
|
||||
if file.header().path().unwrap() != Path::new("vmlinux/vmlinux.h") {
|
||||
continue;
|
||||
for entry in entries {
|
||||
let entry = entry?;
|
||||
let file_name = entry.file_name();
|
||||
let file_name_str = file_name.to_string_lossy();
|
||||
|
||||
if file_name_str.contains(&kernel_target) {
|
||||
let source = entry.path();
|
||||
let destination = Path::new(&dest).join("vmlinux.h");
|
||||
|
||||
// Create symlink to the matched file
|
||||
if destination.exists() {
|
||||
fs::remove_file(&destination)?;
|
||||
}
|
||||
|
||||
std::os::unix::fs::symlink(&source, &destination)?;
|
||||
println!(
|
||||
"Created symlink from {} to {}",
|
||||
source.display(),
|
||||
destination.display()
|
||||
);
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let name = file
|
||||
.link_name()
|
||||
.unwrap()
|
||||
.unwrap()
|
||||
.to_string_lossy()
|
||||
.to_string();
|
||||
|
||||
return sscanf!(name, "vmlinux-v{String}-g{String}.h").unwrap();
|
||||
}
|
||||
|
||||
panic!("vmlinux/vmlinux.h not found");
|
||||
Err(anyhow!("vmlinux.h for arch {} is not found", kernel_target))
|
||||
}
|
||||
|
||||
fn determine_cflags<P>(clang: &(String, String, String), out_dir: P) -> Result<Vec<String>>
|
||||
fn determine_cflags<P>(clang: &ClangInfo, out_dir: P) -> Result<Vec<String>>
|
||||
where
|
||||
P: AsRef<Path> + std::fmt::Debug,
|
||||
{
|
||||
@ -399,11 +246,18 @@ impl BpfBuilder {
|
||||
.to_string();
|
||||
Self::install_bpf_h(&bpf_h)?;
|
||||
|
||||
let vmlinux_dir = Path::new(&bpf_h)
|
||||
.join("vmlinux")
|
||||
.to_str()
|
||||
.ok_or(anyhow!("{:?}/vmlinux can't be converted to str", &bpf_h))?
|
||||
.to_string();
|
||||
Self::ln_vmlinux_h(&vmlinux_dir, &clang.kernel_target()?)?;
|
||||
|
||||
let mut cflags = Vec::<String>::new();
|
||||
|
||||
cflags.append(&mut match env::var("BPF_BASE_CFLAGS") {
|
||||
Ok(v) => v.split_whitespace().map(|x| x.into()).collect(),
|
||||
_ => Self::determine_base_cflags(&clang)?,
|
||||
_ => clang.determine_base_cflags()?,
|
||||
});
|
||||
|
||||
cflags.append(&mut match env::var("BPF_EXTRA_CFLAGS_PRE_INCL") {
|
||||
@ -429,7 +283,7 @@ impl BpfBuilder {
|
||||
pub fn new() -> Result<Self> {
|
||||
let out_dir = PathBuf::from(env::var("OUT_DIR")?);
|
||||
|
||||
let clang = Self::find_clang()?;
|
||||
let clang = ClangInfo::new()?;
|
||||
let cflags = match env::var("BPF_CFLAGS") {
|
||||
Ok(v) => v.split_whitespace().map(|x| x.into()).collect(),
|
||||
_ => Self::determine_cflags(&clang, &out_dir)?,
|
||||
@ -527,7 +381,7 @@ impl BpfBuilder {
|
||||
SkeletonBuilder::new()
|
||||
.source(input)
|
||||
.obj(&obj)
|
||||
.clang(&self.clang.0)
|
||||
.clang(&self.clang.clang)
|
||||
.clang_args(&self.cflags)
|
||||
.build_and_generate(&skel_path)?;
|
||||
|
||||
@ -578,6 +432,10 @@ impl BpfBuilder {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use sscanf::sscanf;
|
||||
|
||||
use crate::builder::ClangInfo;
|
||||
|
||||
#[test]
|
||||
fn test_bpf_builder_new() {
|
||||
let res = super::BpfBuilder::new();
|
||||
@ -586,15 +444,41 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_vmlinux_h_ver_sha1() {
|
||||
let (ver, sha1) = super::BpfBuilder::vmlinux_h_ver_sha1();
|
||||
let clang_info = ClangInfo::new().unwrap();
|
||||
|
||||
println!("vmlinux.h: ver={:?} sha1={:?}", &ver, &sha1,);
|
||||
let mut ar = tar::Archive::new(super::BpfBuilder::BPF_H_TAR);
|
||||
let mut found = false;
|
||||
|
||||
assert!(regex::Regex::new(r"^([1-9][0-9]*\.[1-9][0-9][a-z0-9-]*)$")
|
||||
.unwrap()
|
||||
.is_match(&ver));
|
||||
assert!(regex::Regex::new(r"^[0-9a-z]{12}$")
|
||||
.unwrap()
|
||||
.is_match(&sha1));
|
||||
for entry in ar.entries().unwrap() {
|
||||
let entry = entry.unwrap();
|
||||
let file_name = entry.header().path().unwrap();
|
||||
let file_name_str = file_name.to_string_lossy().to_owned();
|
||||
if file_name_str.contains(&clang_info.kernel_target().unwrap()) {
|
||||
found = true;
|
||||
} else if !file_name_str.contains("vmlinux/vmlinux") {
|
||||
continue;
|
||||
}
|
||||
|
||||
println!("checking {file_name_str}");
|
||||
|
||||
let (arch, ver, sha1) = sscanf!(
|
||||
file_name_str,
|
||||
"vmlinux/vmlinux-{String}-v{String}-g{String}.h"
|
||||
)
|
||||
.unwrap();
|
||||
println!(
|
||||
"vmlinux.h: arch={:?} ver={:?} sha1={:?}",
|
||||
&arch, &ver, &sha1,
|
||||
);
|
||||
|
||||
assert!(regex::Regex::new(r"^([1-9][0-9]*\.[1-9][0-9][a-z0-9-]*)$")
|
||||
.unwrap()
|
||||
.is_match(&ver));
|
||||
assert!(regex::Regex::new(r"^[0-9a-z]{12}$")
|
||||
.unwrap()
|
||||
.is_match(&sha1));
|
||||
}
|
||||
|
||||
assert!(found);
|
||||
}
|
||||
}
|
||||
|
@ -3,9 +3,13 @@
|
||||
// This software may be used and distributed according to the terms of the
|
||||
// GNU General Public License version 2.
|
||||
|
||||
use std::env;
|
||||
use std::fs::File;
|
||||
use std::path::PathBuf;
|
||||
use std::{
|
||||
ffi::OsStr,
|
||||
fs::{self, File},
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
include!("clang_info.rs");
|
||||
|
||||
const BPF_H: &str = "bpf_h";
|
||||
|
||||
@ -33,8 +37,37 @@ impl Builder {
|
||||
}
|
||||
}
|
||||
|
||||
fn find_vmlinux_h<P: AsRef<Path> + AsRef<OsStr>>(
|
||||
dest: P,
|
||||
kernel_target: &str,
|
||||
) -> Result<String> {
|
||||
let entries = fs::read_dir(&dest)?;
|
||||
|
||||
for entry in entries {
|
||||
let entry = entry?;
|
||||
let file_name = entry.file_name();
|
||||
let file_name_str = file_name.to_string_lossy();
|
||||
|
||||
println!("{file_name_str}");
|
||||
if file_name_str.contains(&kernel_target) {
|
||||
return Ok(entry.path().to_string_lossy().into_owned());
|
||||
}
|
||||
}
|
||||
Err(anyhow!("vmlinux.h for arch {} is not found", kernel_target))
|
||||
}
|
||||
|
||||
fn gen_bindings(&self) {
|
||||
let out_dir = env::var("OUT_DIR").unwrap();
|
||||
let clang = ClangInfo::new().unwrap();
|
||||
let vmlinux_dir = Path::new(&BPF_H)
|
||||
.join("vmlinux")
|
||||
.to_str()
|
||||
.ok_or(anyhow!("{:?}/vimlinux can't be converted to str", BPF_H))
|
||||
.unwrap()
|
||||
.to_string();
|
||||
let vmlinux_h =
|
||||
Self::find_vmlinux_h(&vmlinux_dir, &clang.kernel_target().unwrap()).unwrap();
|
||||
|
||||
// FIXME - bindgen's API changed between 0.68 and 0.69 so that
|
||||
// `bindgen::CargoCallbacks::new()` should be used instead of
|
||||
// `bindgen::CargoCallbacks`. Unfortunately, as of Dec 2023, fedora is
|
||||
@ -43,7 +76,7 @@ impl Builder {
|
||||
// fedora can be updated to bindgen >= 0.69.
|
||||
#[allow(deprecated)]
|
||||
let bindings = bindgen::Builder::default()
|
||||
.header("bindings.h")
|
||||
.header(vmlinux_h)
|
||||
.allowlist_type("scx_exit_kind")
|
||||
.allowlist_type("scx_consts")
|
||||
.parse_callbacks(Box::new(bindgen::CargoCallbacks))
|
||||
|
174
rust/scx_utils/src/clang_info.rs
Normal file
174
rust/scx_utils/src/clang_info.rs
Normal file
@ -0,0 +1,174 @@
|
||||
use std::{collections::HashMap, env, process::Command};
|
||||
|
||||
use anyhow::{anyhow, bail, Context, Result};
|
||||
use sscanf::sscanf;
|
||||
|
||||
lazy_static::lazy_static! {
|
||||
// Map clang archs to the __TARGET_ARCH list in
|
||||
// tools/lib/bpf/bpf_tracing.h in the kernel tree.
|
||||
static ref ARCH_MAP: HashMap<&'static str, &'static str> = vec![
|
||||
("x86", "x86"),
|
||||
("x86_64", "x86"),
|
||||
("s390", "s390"),
|
||||
("s390x", "s390"),
|
||||
("arm", "arm"),
|
||||
("aarch64", "arm64"),
|
||||
("mips", "mips"),
|
||||
("mips64", "mips"),
|
||||
("ppc32", "powerpc"),
|
||||
("ppc64", "powerpc"),
|
||||
("ppc64le", "powerpc"),
|
||||
("sparc", "sparc"),
|
||||
("sparcv9", "sparc"),
|
||||
("riscv32", "riscv"),
|
||||
("riscv64", "riscv"),
|
||||
("arc", "arc"), // unsure this is supported
|
||||
("loongarch64", "loongarch"), // ditto
|
||||
].into_iter().collect();
|
||||
}
|
||||
#[derive(Debug)]
|
||||
#[allow(dead_code)]
|
||||
pub struct ClangInfo {
|
||||
pub clang: String,
|
||||
pub ver: String,
|
||||
pub arch: String,
|
||||
}
|
||||
|
||||
impl ClangInfo {
|
||||
pub fn new() -> Result<ClangInfo> {
|
||||
let clang = env::var("BPF_CLANG").unwrap_or("clang".into());
|
||||
let output = Command::new(&clang)
|
||||
.args(["--version"])
|
||||
.output()
|
||||
.with_context(|| format!("Failed to run \"{} --version\"", &clang))?;
|
||||
|
||||
let stdout = String::from_utf8(output.stdout)?;
|
||||
let (mut ver, mut arch) = (None, None);
|
||||
for line in stdout.lines() {
|
||||
if let Ok(v) = sscanf!(
|
||||
Self::skip_clang_version_prefix(line),
|
||||
"clang version {String}"
|
||||
) {
|
||||
// Version could be followed by (URL SHA1). Only take
|
||||
// the first word.
|
||||
ver = Some(v.split_whitespace().next().unwrap().to_string());
|
||||
continue;
|
||||
}
|
||||
if let Ok(v) = sscanf!(line, "Target: {String}") {
|
||||
arch = Some(v.split('-').next().unwrap().to_string());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
let (ver, arch) = (
|
||||
ver.ok_or(anyhow!("Failed to read clang version"))?,
|
||||
arch.ok_or(anyhow!("Failed to read clang target arch"))?,
|
||||
);
|
||||
|
||||
if version_compare::compare(&ver, "16") == Ok(version_compare::Cmp::Lt) {
|
||||
bail!(
|
||||
"clang < 16 loses high 32 bits of 64 bit enums when compiling BPF ({:?} ver={:?})",
|
||||
&clang,
|
||||
&ver
|
||||
);
|
||||
}
|
||||
if version_compare::compare(&ver, "17") == Ok(version_compare::Cmp::Lt) {
|
||||
println!(
|
||||
"cargo:warning=clang >= 17 recommended ({:?} ver={:?})",
|
||||
&clang, &ver
|
||||
);
|
||||
}
|
||||
|
||||
Ok(ClangInfo { clang, ver, arch })
|
||||
}
|
||||
|
||||
fn skip_clang_version_prefix(line: &str) -> &str {
|
||||
if let Some(index) = line.find("clang version") {
|
||||
&line[index..]
|
||||
} else {
|
||||
line
|
||||
}
|
||||
}
|
||||
|
||||
pub fn kernel_target(&self) -> Result<String> {
|
||||
// Determine kernel target arch.
|
||||
match ARCH_MAP.get(self.arch.as_str()) {
|
||||
Some(v) => Ok(v.to_string()),
|
||||
None => Err(anyhow!("CPU arch {} not found in ARCH_MAP", self.arch)),
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)] // for it is not used during build script execution
|
||||
pub fn determine_base_cflags(&self) -> Result<Vec<String>> {
|
||||
let kernel_target = self.kernel_target()?;
|
||||
|
||||
// Determine system includes.
|
||||
let output = Command::new(&self.clang)
|
||||
.args(["-v", "-E", "-"])
|
||||
.output()
|
||||
.with_context(|| format!("Failed to run \"{} -v -E - < /dev/null", self.clang))?;
|
||||
let stderr = String::from_utf8(output.stderr)?;
|
||||
|
||||
let mut sys_incls = None;
|
||||
for line in stderr.lines() {
|
||||
if line == "#include <...> search starts here:" {
|
||||
sys_incls = Some(vec![]);
|
||||
continue;
|
||||
}
|
||||
if sys_incls.is_none() {
|
||||
continue;
|
||||
}
|
||||
if line == "End of search list." {
|
||||
break;
|
||||
}
|
||||
|
||||
sys_incls.as_mut().unwrap().push(line.trim());
|
||||
}
|
||||
let sys_incls = match sys_incls {
|
||||
Some(v) => v,
|
||||
None => bail!("Failed to find system includes from {:?}", self.clang),
|
||||
};
|
||||
|
||||
// Determine endian.
|
||||
let output = Command::new(&self.clang)
|
||||
.args(["-dM", "-E", "-"])
|
||||
.output()
|
||||
.with_context(|| format!("Failed to run \"{} -dM E - < /dev/null", self.clang))?;
|
||||
let stdout = String::from_utf8(output.stdout)?;
|
||||
|
||||
let mut endian = None;
|
||||
for line in stdout.lines() {
|
||||
match sscanf!(line, "#define __BYTE_ORDER__ {str}") {
|
||||
Ok(v) => {
|
||||
endian = Some(match v {
|
||||
"__ORDER_LITTLE_ENDIAN__" => "little",
|
||||
"__ORDER_BIG_ENDIAN__" => "big",
|
||||
v => bail!("Unknown __BYTE_ORDER__ {:?}", v),
|
||||
});
|
||||
break;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
let endian = match endian {
|
||||
Some(v) => v,
|
||||
None => bail!("Failed to find __BYTE_ORDER__ from {:?}", self.clang),
|
||||
};
|
||||
|
||||
// Assemble cflags.
|
||||
let mut cflags: Vec<String> = ["-g", "-O2", "-Wall", "-Wno-compare-distinct-pointer-types"]
|
||||
.into_iter()
|
||||
.map(|x| x.into())
|
||||
.collect();
|
||||
cflags.push(format!("-D__TARGET_ARCH_{}", &kernel_target));
|
||||
cflags.push("-mcpu=v3".into());
|
||||
cflags.push(format!("-m{}-endian", endian));
|
||||
cflags.append(
|
||||
&mut sys_incls
|
||||
.into_iter()
|
||||
.flat_map(|x| ["-idirafter".into(), x.into()])
|
||||
.collect(),
|
||||
);
|
||||
Ok(cflags)
|
||||
}
|
||||
}
|
@ -33,6 +33,8 @@
|
||||
pub use log::warn;
|
||||
pub use paste::paste;
|
||||
|
||||
mod clang_info;
|
||||
|
||||
mod bindings;
|
||||
|
||||
mod bpf_builder;
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1 +0,0 @@
|
||||
vmlinux-v6.12-rc0-ga748db0c8c6a.h
|
Loading…
Reference in New Issue
Block a user