build.rs 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. use std::collections::HashSet;
  2. use std::env;
  3. use std::path::PathBuf;
  4. #[derive(Debug)]
  5. struct IgnoreMacros(HashSet<String>);
  6. impl bindgen::callbacks::ParseCallbacks for IgnoreMacros {
  7. fn will_parse_macro(&self, name: &str) -> bindgen::callbacks::MacroParsingBehavior {
  8. if self.0.contains(name) {
  9. bindgen::callbacks::MacroParsingBehavior::Ignore
  10. } else {
  11. bindgen::callbacks::MacroParsingBehavior::Default
  12. }
  13. }
  14. }
  15. fn get_git_commit_version() {
  16. let result = std::process::Command::new("git")
  17. .args(&["describe", "--tags", "--always", "--dirty"])
  18. .output();
  19. let git_version = match result {
  20. Ok(output) => output.stdout,
  21. Err(_) => Vec::new(),
  22. };
  23. let git_version = String::from_utf8(git_version).expect("Invalid UTF-8 sequence");
  24. println!("cargo:rustc-env=GIT_VERSION={}", git_version.trim());
  25. }
  26. fn link_rename_lib() {
  27. /*
  28. rename the output file to smartdns_ui.so
  29. */
  30. let release_plugin = env::var("RELEASE_PLUGIN").is_ok();
  31. if release_plugin == false {
  32. // In debug mode, we don't rename the output file
  33. return;
  34. }
  35. let curr_source_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
  36. let target_dir =
  37. env::var("CARGO_TARGET_DIR").unwrap_or_else(|_| format!("{}/target", curr_source_dir));
  38. let crate_name = std::env::var("CARGO_PKG_NAME").unwrap().replace("-", "_");
  39. let so_path = format!("{}/{}.so", target_dir, crate_name);
  40. println!("cargo:rustc-link-arg=-o");
  41. println!("cargo:rustc-link-arg={}", so_path);
  42. }
  43. fn link_smartdns_lib() {
  44. let curr_source_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
  45. let smartdns_src_dir = format!("{}/../../src", curr_source_dir);
  46. let smartdns_inc_dir = format!("{}/include", smartdns_src_dir);
  47. let smartdns_lib_file = format!("{}/libsmartdns-test.a", smartdns_src_dir);
  48. let cc = env::var("RUSTC_LINKER")
  49. .unwrap_or_else(|_| env::var("CC").unwrap_or_else(|_| "cc".to_string()));
  50. let sysroot_output = std::process::Command::new(&cc)
  51. .arg("--print-sysroot")
  52. .output();
  53. let mut sysroot = None;
  54. if let Ok(output) = sysroot_output {
  55. if output.status.success() {
  56. let path = String::from_utf8(output.stdout).unwrap();
  57. sysroot = Some(path.trim().to_string());
  58. }
  59. }
  60. let ignored_macros = IgnoreMacros(vec!["IPPORT_RESERVED".into()].into_iter().collect());
  61. let mut bindings_builder =
  62. bindgen::Builder::default().header(format!("{}/smartdns/smartdns.h", smartdns_inc_dir));
  63. if let Some(sysroot) = sysroot {
  64. bindings_builder = bindings_builder.clang_arg(format!("--sysroot={}", sysroot));
  65. }
  66. let bindings = bindings_builder
  67. .clang_arg(format!("-I{}/include", smartdns_src_dir))
  68. .parse_callbacks(Box::new(ignored_macros))
  69. .generate()
  70. .expect("Unable to generate bindings");
  71. let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
  72. bindings
  73. .write_to_file(out_path.join("smartdns_bindings.rs"))
  74. .expect("Couldn't write bindings!");
  75. /*
  76. to run tests, please run the following command:
  77. make test-prepare
  78. */
  79. if std::path::Path::new(&smartdns_lib_file).exists() && !cfg!(feature = "build-release") {
  80. println!("cargo:rerun-if-changed={}", smartdns_lib_file);
  81. println!("cargo:rustc-link-lib=static=smartdns-test");
  82. println!("cargo:rustc-link-lib=ssl");
  83. println!("cargo:rustc-link-lib=crypto");
  84. println!("cargo:rustc-link-search=native={}", smartdns_src_dir);
  85. }
  86. }
  87. fn main() {
  88. get_git_commit_version();
  89. link_smartdns_lib();
  90. link_rename_lib();
  91. }