Skip to content

Commit

Permalink
Overhaul vendoring/linking features
Browse files Browse the repository at this point in the history
This change overhauls the vendoring & static linking features that the
library exposes. Please refer to the larger discussion [0] for
additional context, but in short we introduce separate features for
vendoring/linking each of the three system library dependencies: libbpf,
libelf, zlib. That is to say, conceptually we fully decouple

[0] libbpf#64 (comment)

Signed-off-by: Daniel Müller <deso@posteo.net>
  • Loading branch information
d-e-s-o committed Nov 29, 2023
1 parent 3dbf06c commit 0690b74
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 34 deletions.
23 changes: 21 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,25 @@ num_cpus = "^1.16.0"
crate-type = ["lib", "staticlib"]

[features]
default = ["vendored-libbpf"]
# Don't vendor anything. This feature is deprecated. Simply build without
# any features instead.
novendor = []
static = []
vendored = ["static"]
# Meta-feature to use vendored versions of all dependencies.
vendored = ["vendored-libbpf", "vendored-libelf", "vendored-zlib"]
# Use vendored `libbpf`. Implies linking it statically.
vendored-libbpf = ["static-libbpf"]
# Use vendored `libelf`. Implies linking it statically.
vendored-libelf = ["static-libelf"]
# Use vendored `zlib`. Implies linking it statically.
vendored-zlib = ["static-zlib"]
# Meta-feature to link against all dependencies statically.
static = ["static-libbpf", "static-libelf", "static-zlib"]
# Link libbpf statically.
static-libbpf = []
# Link libelf statically. Implies linking libbpf statically, because libbpf is
# the libelf consumer.
static-libelf = ["static-libbpf"]
# Link zlib statically. Implies linking libbpf statically, because libbpf is
# the libelf consumer.
static-zlib = ["static-libbpf"]
83 changes: 52 additions & 31 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,20 +80,10 @@ fn generate_bindings(src_dir: path::PathBuf) {
#[cfg(not(feature = "bindgen"))]
fn generate_bindings(_: path::PathBuf) {}

#[cfg(feature = "static")]
fn library_prefix() -> String {
"static=".to_string()
}

#[cfg(not(feature = "static"))]
fn library_prefix() -> String {
"".to_string()
}

fn pkg_check(pkg: &str) {
if process::Command::new(pkg).status().is_err() {
panic!(
"{} is required to compile libbpf-sys using the vendored copy of libbpf",
"{} is required to compile libbpf-sys with the selected set of features",
pkg
);
}
Expand All @@ -104,17 +94,42 @@ fn main() {

generate_bindings(src_dir.clone());

let vendored_libbpf = cfg!(feature = "vendored-libbpf");
let vendored_libelf = cfg!(feature = "vendored-libelf");
let vendored_zlib = cfg!(feature = "vendored-zlib");
println!("Using feature vendored-libbpf={}", vendored_libbpf);
println!("Using feature vendored-libelf={}", vendored_libelf);
println!("Using feature vendored-zlib={}", vendored_zlib);

let static_libbpf = cfg!(feature = "static-libbpf");
let static_libelf = cfg!(feature = "static-libelf");
let static_zlib = cfg!(feature = "static-zlib");
println!("Using feature static-libbpf={}", static_libbpf);
println!("Using feature static-libelf={}", static_libelf);
println!("Using feature static-zlib={}", static_zlib);

if cfg!(feature = "novendor") {
println!("cargo:rustc-link-lib={}bpf\n", library_prefix());
println!("cargo:warning=the `novendor` feature of `libbpf-sys` is deprecated; build without features instead");
println!(
"cargo:rustc-link-lib={}bpf",
if cfg!(feature = "static-libbpf") {
"static="
} else {
""
}
);
return;
}

let out_dir = path::PathBuf::from(env::var_os("OUT_DIR").unwrap());

// check for all necessary compilation tools
pkg_check("make");
pkg_check("pkg-config");
if cfg!(feature = "vendored") {
// TODO: Not all packages are required for all builds. Dependencies should
// be clarified and these checks be pushed into individual `make_*`
// functions.
if vendored_libbpf || vendored_libelf || vendored_zlib {
pkg_check("make");
pkg_check("pkg-config");
pkg_check("autoreconf");
pkg_check("autopoint");
pkg_check("flex");
Expand All @@ -129,32 +144,38 @@ fn main() {
),
};

if cfg!(feature = "vendored") {
let mut cflags = compiler.cflags_env();

if vendored_zlib {
make_zlib(&compiler, &src_dir, &out_dir);
make_elfutils(&compiler, &src_dir, &out_dir);
cflags.push(&format!(" -I{}/zlib/", src_dir.display()));
}

let cflags = if cfg!(feature = "vendored") {
// make sure that the headerfiles from libelf and zlib
// for libbpf come from the vendorized version

let mut cflags = compiler.cflags_env();
if vendored_libelf {
make_elfutils(&compiler, &src_dir, &out_dir);
cflags.push(&format!(" -I{}/elfutils/libelf/", src_dir.display()));
cflags.push(&format!(" -I{}/zlib/", src_dir.display()));
cflags
} else {
compiler.cflags_env()
};
}

make_libbpf(&compiler, &cflags, &src_dir, &out_dir);
if vendored_libbpf {
make_libbpf(&compiler, &cflags, &src_dir, &out_dir);
}

println!(
"cargo:rustc-link-search=native={}",
out_dir.to_string_lossy()
);
println!("cargo:rustc-link-lib={}elf", library_prefix());
println!("cargo:rustc-link-lib={}z", library_prefix());
println!("cargo:rustc-link-lib=static=bpf");
println!(
"cargo:rustc-link-lib={}elf",
if static_libelf { "static=" } else { "" }
);
println!(
"cargo:rustc-link-lib={}z",
if static_zlib { "static=" } else { "" }
);
println!(
"cargo:rustc-link-lib={}bpf",
if static_libbpf { "static=" } else { "" }
);
println!("cargo:include={}/include", out_dir.to_string_lossy());

if let Ok(ld_path) = env::var("LD_LIBRARY_PATH") {
Expand Down
3 changes: 2 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

include!("bindings.rs");

#[cfg(feature = "vendor-libbpf")]
macro_rules! header {
($file:literal) => {
($file, include_str!(concat!("../libbpf/src/", $file)))
Expand All @@ -15,7 +16,7 @@ macro_rules! header {
/// Vendored libbpf headers
///
/// Tuple format is: (header filename, header contents)
#[cfg(not(feature = "novendor"))]
#[cfg(feature = "vendor-libbpf")]
pub const API_HEADERS: [(&str, &str); 10] = [
header!("bpf.h"),
header!("libbpf.h"),
Expand Down

0 comments on commit 0690b74

Please sign in to comment.