use std::env;
use std::path::PathBuf;
fn write_placeholder_bindings() {
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
std::fs::write(
out_path.join("bindings.rs"),
"// Placeholder bindings generated for non-Harmony/doc builds.\n",
)
.expect("Couldn't write placeholder bindings!");
}
fn harmony_setup() {
let ndk = env::var("OHOS_NDK_HOME").expect("OHOS_NDK_HOME is not set!");
unsafe {
env::set_var(
"CC",
format!("{ndk}/native/llvm/bin/aarch64-unknown-linux-ohos-clang"),
);
env::set_var("AR", format!("{ndk}/native/llvm/bin/llvm-ar"));
env::set_var(
"BINDGEN_EXTRA_CLANG_ARGS",
format!("--sysroot {ndk}/native/sysroot"),
);
}
}
fn main() {
let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap_or_default();
let target_env = env::var("CARGO_CFG_TARGET_ENV").unwrap_or_default();
let docs_rs = env::var_os("DOCS_RS").is_some();
if docs_rs {
println!("cargo:warning=Generating placeholder ArkJS bindings for docs.rs");
write_placeholder_bindings();
return;
}
if target_os != "linux" || target_env != "ohos" {
write_placeholder_bindings();
return;
}
harmony_setup();
build_harmony_arkjs();
}
fn build_harmony_arkjs() {
let ohos_ndk_home = env::var("OHOS_NDK_HOME")
.expect("OHOS_NDK_HOME environment variable must be set for HarmonyOS builds");
let ark_runtime_path = PathBuf::from(&ohos_ndk_home)
.join("native")
.join("sysroot")
.join("usr")
.join("include")
.join("ark_runtime");
println!(
"cargo:warning=Ark Runtime header path: {:?}",
ark_runtime_path
);
if !ark_runtime_path.exists() {
panic!(
"Ark Runtime headers not found at: {}. Please ensure OHOS_NDK_HOME is correctly set.",
ark_runtime_path.to_string_lossy()
);
}
let jsvm_header = ark_runtime_path.join("jsvm.h");
let jsvm_types_header = ark_runtime_path.join("jsvm_types.h");
if !jsvm_header.exists() {
panic!("jsvm.h not found at: {}", jsvm_header.to_string_lossy());
}
if !jsvm_types_header.exists() {
panic!(
"jsvm_types.h not found at: {}",
jsvm_types_header.to_string_lossy()
);
}
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rerun-if-env-changed=OHOS_NDK_HOME");
let lib_path = PathBuf::from(&ohos_ndk_home)
.join("native")
.join("sysroot")
.join("usr")
.join("lib");
println!(
"cargo:rustc-link-search=native={}",
lib_path.to_string_lossy()
);
println!("cargo:rustc-link-lib=dylib=jsvm");
let bindings = bindgen::Builder::default()
.header(jsvm_header.to_string_lossy())
.clang_arg(format!("-I{}", ark_runtime_path.to_string_lossy()))
.clang_arg(format!("--sysroot={}/native/sysroot", ohos_ndk_home))
.allowlist_function("JSVM_.*")
.allowlist_type("JSVM_.*")
.allowlist_var("JSVM_.*")
.allowlist_function("OH_.*")
.allowlist_type("OH_.*")
.allowlist_var("OH_.*")
.generate()
.expect("Unable to generate bindings for Harmony Ark JS");
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
bindings
.write_to_file(out_path.join("bindings.rs"))
.expect("Couldn't write bindings!");
}