2023-11-07 21:06:29 -05:00
|
|
|
use filetime::{set_file_mtime, FileTime};
|
2023-10-08 12:40:17 -04:00
|
|
|
use glob::glob;
|
|
|
|
use std::{
|
2023-11-07 19:27:08 -05:00
|
|
|
env, fs, io,
|
|
|
|
path::Path,
|
2023-10-08 12:40:17 -04:00
|
|
|
process::{Command, Stdio},
|
|
|
|
};
|
2023-09-15 11:45:12 -04:00
|
|
|
|
2023-11-07 19:27:08 -05:00
|
|
|
const CAPNP_VERSION: &str = "1.0.1";
|
2023-09-16 12:23:56 -04:00
|
|
|
|
2023-09-15 11:45:12 -04:00
|
|
|
fn get_desired_capnp_version_string() -> String {
|
2023-09-19 19:12:51 -04:00
|
|
|
CAPNP_VERSION.to_string()
|
|
|
|
}
|
|
|
|
|
2023-09-15 11:45:12 -04:00
|
|
|
fn get_capnp_version_string() -> String {
|
2023-09-16 13:07:12 -04:00
|
|
|
let output = Command::new("capnp")
|
2023-09-15 11:45:12 -04:00
|
|
|
.arg("--version")
|
|
|
|
.stdout(Stdio::piped())
|
|
|
|
.output()
|
2023-11-07 20:38:36 -05:00
|
|
|
.expect("capnp was not in the PATH, and is required for the build when you have changed any .capnp files");
|
2023-09-15 11:45:12 -04:00
|
|
|
let s = String::from_utf8(output.stdout)
|
2023-09-16 13:07:12 -04:00
|
|
|
.expect("'capnp --version' output was not a valid string")
|
2023-09-15 11:45:12 -04:00
|
|
|
.trim()
|
|
|
|
.to_owned();
|
|
|
|
|
|
|
|
if !s.starts_with("Cap'n Proto version ") {
|
2023-09-16 13:07:12 -04:00
|
|
|
panic!("invalid capnp version string: {}", s);
|
2023-09-15 11:45:12 -04:00
|
|
|
}
|
|
|
|
s[20..].to_owned()
|
|
|
|
}
|
|
|
|
|
2023-11-07 19:27:08 -05:00
|
|
|
fn is_input_file_outdated<P1, P2>(input: P1, output: P2) -> io::Result<bool>
|
|
|
|
where
|
|
|
|
P1: AsRef<Path>,
|
|
|
|
P2: AsRef<Path>,
|
|
|
|
{
|
|
|
|
let out_meta = fs::metadata(output);
|
|
|
|
if let Ok(meta) = out_meta {
|
|
|
|
let output_mtime = meta.modified()?;
|
2023-09-15 11:45:12 -04:00
|
|
|
|
2023-11-07 19:27:08 -05:00
|
|
|
// if input file is more recent than our output, we are outdated
|
|
|
|
let input_meta = fs::metadata(input)?;
|
|
|
|
let input_mtime = input_meta.modified()?;
|
2023-09-15 11:45:12 -04:00
|
|
|
|
2023-11-07 19:27:08 -05:00
|
|
|
Ok(input_mtime > output_mtime)
|
|
|
|
} else {
|
|
|
|
// output file not found, we are outdated
|
|
|
|
Ok(true)
|
2023-10-17 22:13:00 -04:00
|
|
|
}
|
2023-11-07 19:27:08 -05:00
|
|
|
}
|
2023-09-15 11:45:12 -04:00
|
|
|
|
2023-11-07 19:27:08 -05:00
|
|
|
fn do_capnp_build() {
|
2023-10-17 22:13:00 -04:00
|
|
|
let desired_capnp_version_string = get_desired_capnp_version_string();
|
|
|
|
let capnp_version_string = get_capnp_version_string();
|
2023-09-15 11:45:12 -04:00
|
|
|
|
2023-10-17 22:13:00 -04:00
|
|
|
// Check capnp version
|
|
|
|
let desired_capnp_major_version = desired_capnp_version_string
|
|
|
|
.split_once('.')
|
|
|
|
.unwrap()
|
|
|
|
.0
|
|
|
|
.parse::<usize>()
|
|
|
|
.expect("should be valid int");
|
2023-09-19 19:12:51 -04:00
|
|
|
|
2023-10-17 22:13:00 -04:00
|
|
|
if capnp_version_string
|
|
|
|
.split_once('.')
|
|
|
|
.unwrap()
|
|
|
|
.0
|
|
|
|
.parse::<usize>()
|
|
|
|
.expect("should be valid int")
|
|
|
|
!= desired_capnp_major_version
|
|
|
|
{
|
|
|
|
panic!(
|
|
|
|
"capnproto version should be major version 1, preferably {} but is {}",
|
|
|
|
desired_capnp_version_string, capnp_version_string
|
|
|
|
);
|
|
|
|
} else if capnp_version_string != desired_capnp_version_string {
|
|
|
|
println!(
|
|
|
|
"cargo:warning=capnproto version may be untested: {}",
|
|
|
|
capnp_version_string
|
|
|
|
);
|
|
|
|
}
|
2023-09-19 19:12:51 -04:00
|
|
|
|
2023-10-17 22:13:00 -04:00
|
|
|
::capnpc::CompilerCommand::new()
|
|
|
|
.file("proto/veilid.capnp")
|
2023-11-07 14:19:28 -05:00
|
|
|
.output_path(".")
|
2023-10-17 22:13:00 -04:00
|
|
|
.run()
|
|
|
|
.expect("compiling schema");
|
2023-11-07 21:06:29 -05:00
|
|
|
|
|
|
|
// If successful, update modification time
|
|
|
|
set_file_mtime("proto/veilid_capnp.rs", FileTime::now()).unwrap();
|
2023-11-07 19:27:08 -05:00
|
|
|
}
|
2023-10-17 22:13:00 -04:00
|
|
|
|
2023-11-07 19:27:08 -05:00
|
|
|
// Fix for missing __extenddftf2 on Android x86_64 Emulator
|
|
|
|
fn fix_android_emulator() {
|
2023-10-08 12:40:17 -04:00
|
|
|
let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap();
|
|
|
|
let target_arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap();
|
|
|
|
if target_arch == "x86_64" && target_os == "android" {
|
|
|
|
let missing_library = "clang_rt.builtins-x86_64-android";
|
2023-11-12 16:47:17 -05:00
|
|
|
let android_home = env::var("ANDROID_HOME").expect("ANDROID_HOME not set");
|
|
|
|
let lib_path = glob(&format!("{android_home}/ndk/25.1.8937393/**/lib{missing_library}.a"))
|
2023-10-08 12:40:17 -04:00
|
|
|
.expect("failed to glob")
|
|
|
|
.next()
|
|
|
|
.expect("Need libclang_rt.builtins-x86_64-android.a")
|
|
|
|
.unwrap();
|
|
|
|
let lib_dir = lib_path.parent().unwrap();
|
|
|
|
println!("cargo:rustc-link-search={}", lib_dir.display());
|
|
|
|
println!("cargo:rustc-link-lib=static={missing_library}");
|
|
|
|
}
|
2021-11-22 11:28:30 -05:00
|
|
|
}
|
2023-11-07 19:27:08 -05:00
|
|
|
|
|
|
|
fn main() {
|
|
|
|
if std::env::var("DOCS_RS").is_ok()
|
|
|
|
|| std::env::var("CARGO_CFG_DOC").is_ok()
|
|
|
|
|| std::env::var("BUILD_DOCS").is_ok()
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if is_input_file_outdated("./proto/veilid.capnp", "./proto/veilid_capnp.rs").unwrap() {
|
2023-11-07 21:06:29 -05:00
|
|
|
println!("cargo:warning=rebuilding proto/veilid_capnp.rs because it is older than proto/veilid.capnp");
|
2023-11-07 19:27:08 -05:00
|
|
|
do_capnp_build();
|
|
|
|
}
|
|
|
|
|
|
|
|
fix_android_emulator();
|
|
|
|
}
|