|
1 | 1 | // build.rs
|
2 | 2 |
|
3 | 3 | use std::env;
|
4 |
| -use std::ffi; |
5 |
| -use std::fs; |
6 | 4 | use std::fs::read_dir;
|
7 | 5 | use std::path;
|
8 | 6 | use std::path::Path;
|
@@ -155,35 +153,35 @@ fn main() {
|
155 | 153 | pkg_check("aclocal");
|
156 | 154 | }
|
157 | 155 |
|
158 |
| - let (compiler, mut cflags) = if vendored_libbpf || vendored_libelf || vendored_zlib { |
| 156 | + let (compiler, cflags) = if vendored_libbpf || vendored_libelf || vendored_zlib { |
159 | 157 | pkg_check("pkg-config");
|
160 | 158 |
|
161 | 159 | let compiler = cc::Build::new().try_get_compiler().expect(
|
162 | 160 | "a C compiler is required to compile libbpf-sys using the vendored copy of libbpf",
|
163 | 161 | );
|
164 |
| - let mut cflags = compiler.cflags_env(); |
| 162 | + let mut cflags = Vec::new(); |
165 | 163 | println!("cargo:rerun-if-env-changed=LIBBPF_SYS_EXTRA_CFLAGS");
|
166 | 164 | if let Some(extra_cflags) = env::var_os("LIBBPF_SYS_EXTRA_CFLAGS") {
|
167 |
| - cflags.push(" "); |
168 |
| - cflags.push(extra_cflags); |
| 165 | + let flags = extra_cflags.into_string().expect("LIBBPF_SYS_EXTRA_CFLAGS"); |
| 166 | + if let Some(flags) = shlex::split(&flags) { |
| 167 | + cflags.extend(flags); |
| 168 | + } |
169 | 169 | }
|
170 | 170 | (Some(compiler), cflags)
|
171 | 171 | } else {
|
172 |
| - (None, ffi::OsString::new()) |
| 172 | + (None, vec![]) |
173 | 173 | };
|
174 | 174 |
|
175 | 175 | if vendored_zlib {
|
176 | 176 | make_zlib(compiler.as_ref().unwrap(), &src_dir);
|
177 |
| - cflags.push(format!(" -I{}/zlib/", src_dir.display())); |
178 | 177 | }
|
179 | 178 |
|
180 | 179 | if vendored_libelf {
|
181 |
| - make_elfutils(compiler.as_ref().unwrap(), &src_dir, &out_dir); |
182 |
| - cflags.push(format!(" -I{}/elfutils/libelf/", src_dir.display())); |
| 180 | + make_elfutils(compiler.as_ref().unwrap(), &src_dir); |
183 | 181 | }
|
184 | 182 |
|
185 | 183 | if vendored_libbpf {
|
186 |
| - make_libbpf(compiler.as_ref().unwrap(), &cflags, &src_dir, &out_dir); |
| 184 | + make_libbpf(compiler.as_ref().unwrap(), cflags.as_slice(), &src_dir); |
187 | 185 | }
|
188 | 186 |
|
189 | 187 | println!(
|
@@ -284,7 +282,7 @@ fn make_zlib(compiler: &cc::Tool, src_dir: &path::Path) {
|
284 | 282 | emit_rerun_directives_for_contents(&src_dir);
|
285 | 283 | }
|
286 | 284 |
|
287 |
| -fn make_elfutils(compiler: &cc::Tool, src_dir: &path::Path, _: &path::Path) { |
| 285 | +fn make_elfutils(compiler: &cc::Tool, src_dir: &path::Path) { |
288 | 286 | // lock README such that if two crates are trying to compile
|
289 | 287 | // this at the same time (eg libbpf-rs libbpf-cargo)
|
290 | 288 | // they wont trample each other
|
@@ -376,46 +374,56 @@ fn make_elfutils(compiler: &cc::Tool, src_dir: &path::Path, _: &path::Path) {
|
376 | 374 | emit_rerun_directives_for_contents(&src_dir.join("elfutils").join("src"));
|
377 | 375 | }
|
378 | 376 |
|
379 |
| -fn make_libbpf( |
380 |
| - compiler: &cc::Tool, |
381 |
| - cflags: &ffi::OsStr, |
382 |
| - src_dir: &path::Path, |
383 |
| - out_dir: &path::Path, |
384 |
| -) { |
385 |
| - let src_dir = src_dir.join("libbpf/src"); |
386 |
| - // create obj_dir if it doesn't exist |
387 |
| - let obj_dir = path::PathBuf::from(&out_dir.join("obj").into_os_string()); |
388 |
| - let _ = fs::create_dir(&obj_dir); |
389 |
| - |
390 |
| - let status = process::Command::new("make") |
391 |
| - .arg("install") |
392 |
| - .arg("-j") |
393 |
| - .arg(format!("{}", num_cpus())) |
394 |
| - .env("BUILD_STATIC_ONLY", "y") |
395 |
| - .env("PREFIX", "/") |
396 |
| - .env("LIBDIR", "") |
397 |
| - .env("OBJDIR", &obj_dir) |
398 |
| - .env("DESTDIR", out_dir) |
399 |
| - .env("CC", compiler.path()) |
400 |
| - .env("CFLAGS", cflags) |
401 |
| - .current_dir(&src_dir) |
402 |
| - .status() |
403 |
| - .expect("could not execute make"); |
| 377 | +fn make_libbpf(compiler: &cc::Tool, flags: &[String], src_dir: &path::Path) { |
| 378 | + let project_dir = src_dir.join("libbpf"); |
404 | 379 |
|
405 |
| - assert!(status.success(), "make failed"); |
| 380 | + let project = project_dir.to_str().unwrap(); |
406 | 381 |
|
407 |
| - let status = process::Command::new("make") |
408 |
| - .arg("clean") |
409 |
| - .current_dir(&src_dir) |
410 |
| - .status() |
411 |
| - .expect("could not execute make"); |
| 382 | + let mut builder = cc::Build::new(); |
412 | 383 |
|
413 |
| - assert!(status.success(), "make failed"); |
414 |
| - emit_rerun_directives_for_contents(&src_dir); |
415 |
| -} |
| 384 | + builder |
| 385 | + .include(src_dir) |
| 386 | + .include(src_dir.join("zlib")) |
| 387 | + .include(src_dir.join("elfutils").join("libelf")) |
| 388 | + .include(format!("{project}/src")) |
| 389 | + .include(format!("{project}/include")) |
| 390 | + .include(format!("{project}/include/uapi")); |
| 391 | + |
| 392 | + flags.iter().for_each(|flag| { |
| 393 | + builder.flag(flag); |
| 394 | + }); |
| 395 | + |
| 396 | + if build_android() { |
| 397 | + let cflags = ["-DCOMPAT_NEED_REALLOCARRAY"]; |
| 398 | + |
| 399 | + builder.flag("-includeandroid/android.h"); |
| 400 | + |
| 401 | + for flag in cflags { |
| 402 | + builder.flag(flag); |
| 403 | + } |
| 404 | + } else { |
| 405 | + builder.compiler(compiler.path()); |
416 | 406 |
|
417 |
| -fn num_cpus() -> usize { |
418 |
| - std::thread::available_parallelism().map_or(1, |count| count.get()) |
| 407 | + for flag in compiler.args() { |
| 408 | + builder.flag(flag); |
| 409 | + } |
| 410 | + } |
| 411 | + |
| 412 | + for entry in std::fs::read_dir(project_dir.join("src")).expect("Failed to `read_dir`") { |
| 413 | + let entry = entry.unwrap(); |
| 414 | + if entry.file_type().unwrap().is_file() |
| 415 | + && entry.file_name().to_str().unwrap().ends_with(".c") |
| 416 | + { |
| 417 | + builder.file(entry.path()); |
| 418 | + } |
| 419 | + } |
| 420 | + |
| 421 | + builder |
| 422 | + .flag_if_supported("-w") |
| 423 | + .warnings(false) |
| 424 | + .compile("bpf"); |
| 425 | + |
| 426 | + emit_rerun_directives_for_contents(&src_dir); |
419 | 427 | }
|
420 | 428 |
|
421 | 429 | fn build_android() -> bool {
|
|
0 commit comments