use std::env;
use std::fs;
use std::io::Write;
use std::path::PathBuf;
fn main() {
let ndrx_home = std::env::var("NDRX_HOME").unwrap_or_else(|_| "/opt/endurox".to_string());
println!("cargo:rustc-link-search=native={}/lib", ndrx_home);
println!("cargo:rustc-link-lib=atmi");
println!("cargo:rustc-link-lib=ubf");
println!("cargo:rustc-link-lib=netproto");
println!("cargo:rustc-link-lib=nstd");
println!("cargo:rustc-link-lib=pthread");
#[cfg(target_os = "linux")]
println!("cargo:rustc-link-lib=rt");
#[cfg(target_os = "linux")]
println!("cargo:rustc-link-lib=dl");
println!("cargo:rustc-link-lib=m");
println!("cargo:rerun-if-env-changed=NDRX_HOME");
println!("cargo:rerun-if-env-changed=NDRX_APPHOME");
println!("cargo:rerun-if-changed=build.rs");
generate_ubf_constants();
}
fn generate_ubf_constants() {
let ubftab_dir = if let Ok(apphome) = env::var("NDRX_APPHOME") {
PathBuf::from(apphome).join("ubftab")
} else {
PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()).join("../ubftab")
};
let mut rust_code = String::from("// Auto-generated UBF field constants\n");
rust_code.push_str("// DO NOT EDIT - generated from *.fd.h files in ubftab/\n\n");
if !ubftab_dir.exists() {
println!("cargo:warning=ubftab directory not found, skipping UBF constants generation");
} else {
let mut found_files = false;
if let Ok(entries) = fs::read_dir(&ubftab_dir) {
for entry in entries.flatten() {
let path = entry.path();
if let Some(ext) = path.extension() {
if ext == "h"
&& path
.file_name()
.unwrap()
.to_str()
.unwrap()
.ends_with(".fd.h")
{
found_files = true;
let filename = path.file_name().unwrap().to_str().unwrap();
println!("cargo:rerun-if-changed=../ubftab/{}", filename);
rust_code.push_str(&format!("\n// Fields from {}\n", filename));
if let Ok(content) = fs::read_to_string(&path) {
parse_ubf_header(&content, &mut rust_code);
}
}
}
}
}
if !found_files {
println!(
"cargo:warning=No *.fd.h files found in ubftab/, skipping UBF constants generation"
);
}
println!("cargo:rerun-if-changed=../ubftab");
}
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()).join("ubf_fields.rs");
let mut file = fs::File::create(&out_path).expect("Failed to create ubf_fields.rs");
file.write_all(rust_code.as_bytes())
.expect("Failed to write ubf_fields.rs");
}
fn parse_ubf_header(content: &str, rust_code: &mut String) {
for line in content.lines() {
if line.trim().starts_with("#define") && line.contains("((BFLDID32)") {
let parts: Vec<&str> = line.split_whitespace().collect();
if parts.len() >= 3 {
let name = parts[1];
let value_part = parts[2];
if let Some(start) = value_part.find("((BFLDID32)") {
let num_start = start + 11; if let Some(end) = value_part[num_start..].find(')') {
let value = &value_part[num_start..num_start + end];
if let Some(comment_start) = line.find("/*") {
if let Some(comment_end) = line.find("*/") {
let _comment = line[comment_start + 2..comment_end].trim();
}
}
rust_code.push_str(&format!("pub const {}: i32 = {};\n\n", name, value));
}
}
}
}
}
}