extern crate bindgen;
use bindgen::callbacks::{DeriveInfo, MacroParsingBehavior, ParseCallbacks};
use cmake::{self, Config};
use std::collections::HashSet;
use std::env;
use std::path::PathBuf;
const IGNORE_MACROS: [&str; 5] = [
"FP_NAN",
"FP_INFINITE",
"FP_NORMAL",
"FP_SUBNORMAL",
"FP_ZERO",
];
const SERDE_TYPES: [&str; 8] = [
"dxf_trade_t",
"dxf_quote_t",
"dxf_summary",
"dxf_candle_t",
"dxf_greeks",
"dx_theo_price",
"dxf_underlying",
"dxf_series",
];
#[derive(Debug)]
struct CustomParser {
ignore_macros: HashSet<String>,
serde_types: HashSet<String>,
}
impl ParseCallbacks for CustomParser {
fn will_parse_macro(&self, name: &str) -> MacroParsingBehavior {
if self.ignore_macros.contains(name) {
MacroParsingBehavior::Ignore
} else {
MacroParsingBehavior::Default
}
}
fn add_derives(&self, info: &DeriveInfo<'_>) -> Vec<String> {
let enabled = std::env::var("CARGO_FEATURE_SERDE").unwrap_or("0".to_string()) == "1";
if enabled && self.serde_types.contains(info.name) {
eprintln!("Adding Serialize/Deserialize");
vec!["Serialize".to_string(), "Deserialize".to_string()]
} else {
vec![]
}
}
}
impl CustomParser {
fn new() -> Self {
let ignore_macros = IGNORE_MACROS.iter().map(|s| s.to_string()).collect();
let serde_types = SERDE_TYPES.iter().map(|s| s.to_string()).collect();
Self {
ignore_macros,
serde_types,
}
}
}
fn main() {
let dst = Config::new("dxfeed-c-api")
.define("DISABLE_TLS", "ON")
.define("BUILD_STATIC_LIBS", "ON")
.build();
println!("cargo:rustc-link-search=native={}", dst.display());
#[cfg(unix)]
{
println!("cargo:rustc-link-search=native={}/build", dst.display());
#[cfg(any(target_os = "macos", target_os = "ios"))]
{
println!("cargo:rustc-link-lib=c++");
}
#[cfg(all(not(target_os = "macos"), not(target_os = "ios")))]
{
println!("cargo:rustc-link-lib=stdc++");
}
}
#[cfg(windows)]
{
println!("cargo:rustc-link-search=native={}/build/Debug", dst.display());
println!("cargo:rustc-link-search=native={}/build/Release", dst.display());
}
let profile = std::env::var("PROFILE").unwrap();
let suffix = if profile == "debug" { "d" } else { "" };
println!("cargo:rustc-link-lib=static={}{}", "DXFeed", suffix);
println!("cargo:rerun-if-changed=wrapper.h");
let bindings = bindgen::Builder::default()
.header("wrapper.h")
.blocklist_file(r".*c?math.*")
.blocklist_function("wcstold")
.parse_callbacks(Box::new(CustomParser::new()))
.derive_partialeq(true)
.generate()
.expect("Unable to generate bindings");
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
bindings
.write_to_file(out_path.join("bindings.rs"))
.expect("Couldn't write bindings!");
}