build.rs 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. use std::env;
  2. use xtask::AYA_BUILD_INTEGRATION_BPF;
  3. /// Building this crate has an undeclared dependency on the `bpf-linker` binary. This would be
  4. /// better expressed by [artifact-dependencies][bindeps] but issues such as
  5. /// https://github.com/rust-lang/cargo/issues/12385 make their use impractical for the time being.
  6. ///
  7. /// This file implements an imperfect solution: it causes cargo to rebuild the crate whenever the
  8. /// mtime of `which bpf-linker` changes. Note that possibility that a new bpf-linker is added to
  9. /// $PATH ahead of the one used as the cache key still exists. Solving this in the general case
  10. /// would require rebuild-if-changed-env=PATH *and* rebuild-if-changed={every-directory-in-PATH}
  11. /// which would likely mean far too much cache invalidation.
  12. ///
  13. /// [bindeps]: https://doc.rust-lang.org/nightly/cargo/reference/unstable.html?highlight=feature#artifact-dependencies
  14. fn main() {
  15. println!("cargo:rerun-if-env-changed={}", AYA_BUILD_INTEGRATION_BPF);
  16. let build_integration_bpf = env::var(AYA_BUILD_INTEGRATION_BPF)
  17. .as_deref()
  18. .map(str::parse)
  19. .map(Result::unwrap)
  20. .unwrap_or_default();
  21. if build_integration_bpf {
  22. let out_dir = env::var_os("OUT_DIR").unwrap();
  23. let out_dir = std::path::PathBuf::from(out_dir);
  24. let bpf_linker = env::var("CARGO_BIN_FILE_BPF_LINKER").unwrap();
  25. // There seems to be no way to pass `-Clinker={}` to rustc from here.
  26. //
  27. // We assume rustc is going to look for `bpf-linker` on the PATH, so we can create a symlink
  28. // and put it on the PATH.
  29. let bin_dir = out_dir.join("bin");
  30. std::fs::create_dir_all(&bin_dir).unwrap();
  31. let bpf_linker_symlink = bin_dir.join("bpf-linker");
  32. match std::fs::remove_file(&bpf_linker_symlink) {
  33. Ok(()) => {}
  34. Err(err) => {
  35. if err.kind() != std::io::ErrorKind::NotFound {
  36. panic!("failed to remove symlink: {err}")
  37. }
  38. }
  39. }
  40. std::os::unix::fs::symlink(bpf_linker, bpf_linker_symlink).unwrap();
  41. let path = env::var_os("PATH");
  42. let path = path.as_ref();
  43. let paths = std::iter::once(bin_dir).chain(path.into_iter().flat_map(env::split_paths));
  44. let path = env::join_paths(paths).unwrap();
  45. println!("cargo:rustc-env=PATH={}", path.to_str().unwrap());
  46. }
  47. }