build.rs 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. use anyhow::{bail, Result};
  2. use std::env;
  3. use std::path::{Path, PathBuf};
  4. use std::process::Command;
  5. fn cfiles<P: AsRef<Path>>(out: &mut Vec<PathBuf>, path: P) -> Result<()> {
  6. for entry in std::fs::read_dir(path)? {
  7. let entry = entry?;
  8. let p = entry.path();
  9. if !p.is_dir() {
  10. out.push(p);
  11. continue;
  12. }
  13. let file = p.file_name().unwrap();
  14. if file == "target" || file == ".git" || file == "dependencies" {
  15. continue;
  16. }
  17. cfiles(out, p)?;
  18. }
  19. Ok(())
  20. }
  21. fn main() -> Result<()> {
  22. // Generate C bindings from rust
  23. {
  24. println!("Generating rtypes");
  25. let mut conf = cbindgen::Config::default();
  26. conf.language = cbindgen::Language::C;
  27. conf.autogen_warning =
  28. Some("// This file is generated from src/rtypes.rs using cbindgen".to_owned());
  29. conf.style = cbindgen::Style::Type;
  30. conf.include_guard = Some("RTypes_H".to_owned());
  31. conf.export.include = vec!["RTypes_ExportMe".to_owned()];
  32. conf.no_includes = true;
  33. conf.includes = vec!["RTypesPrefix.h".to_owned()];
  34. conf.enumeration.prefix_with_name = true;
  35. cbindgen::Builder::new()
  36. .with_src("./src/rtypes.rs")
  37. .with_config(conf)
  38. .generate()
  39. .expect("Unable to generate rtypes")
  40. .write_to_file("RTypes.h");
  41. println!("Generating rtypes done");
  42. //
  43. println!("Generating rffi");
  44. let mut conf = cbindgen::Config::default();
  45. conf.language = cbindgen::Language::C;
  46. conf.autogen_warning =
  47. Some("// This file is generated from src/rffi.rs using cbindgen".to_owned());
  48. conf.style = cbindgen::Style::Type;
  49. conf.include_guard = Some("rffi_H".to_owned());
  50. conf.no_includes = true;
  51. conf.includes = vec!["RffiPrefix.h".to_owned()];
  52. cbindgen::Builder::new()
  53. .with_src("./src/rffi.rs")
  54. .with_config(conf)
  55. .generate()
  56. .expect("Unable to generate rffi")
  57. .write_to_file("Rffi.h");
  58. println!("Generating rffi done");
  59. }
  60. let ret = Command::new("/bin/sh")
  61. .current_dir("../../")
  62. .env("MAINJS", "./node_build/make.js")
  63. .arg("./node_build/node.sh")
  64. .status()?
  65. .code()
  66. .unwrap();
  67. if ret != 0 {
  68. bail!("Failed to build cjdns");
  69. }
  70. let mut cf: Vec<PathBuf> = Vec::new();
  71. cfiles(&mut cf, "../../")?;
  72. cf.sort();
  73. for f in cf {
  74. println!("cargo:rerun-if-changed={}", f.to_str().unwrap());
  75. }
  76. let out_dir = env::var("OUT_DIR").unwrap();
  77. let target = env::var("TARGET").unwrap();
  78. if target.contains("-windows-gnu") {
  79. println!("cargo:rustc-link-lib=iphlpapi"); // ConvertInterfaceAliasToLuid (cjdns)
  80. println!("cargo:rustc-link-lib=psapi"); // GetProcessMemoryInfo (libuv)
  81. println!("cargo:rustc-link-lib=ssp"); // memcpy_chk (libuv)
  82. }
  83. let mut build = cc::Build::new();
  84. let mut paths = std::fs::read_dir(out_dir)?
  85. .map(|x| x.unwrap().path())
  86. .collect::<Vec<PathBuf>>();
  87. paths.sort();
  88. for path in paths {
  89. if !path.is_dir() && path.extension().unwrap() == "o" {
  90. build.object(path);
  91. }
  92. }
  93. build.compile("cjdns_sys");
  94. // Generate rust bindings from C
  95. #[cfg(feature = "generate-cffi")]
  96. {
  97. let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
  98. bindgen::Builder::default()
  99. .header(out_path.join("rust_cjdns_sys_cffi_h.i").to_str().unwrap())
  100. .generate_comments(false)
  101. .layout_tests(false)
  102. .default_enum_style(bindgen::EnumVariation::Rust {
  103. non_exhaustive: false,
  104. })
  105. .raw_line("#![allow(non_snake_case)]")
  106. .raw_line("#![allow(dead_code)]")
  107. .raw_line("#![allow(non_camel_case_types)]")
  108. .whitelist_function(".*")
  109. .whitelist_type("RBindings_Whitelist")
  110. .generate()
  111. .expect("Unable to generate rbindings")
  112. .write_to_file("src/cffi.rs")
  113. .expect("Couldn't write rbindings");
  114. }
  115. Ok(())
  116. }