build.rs 4.3 KB

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