2025-10-09 22:44:12 +07:00

103 lines
3.3 KiB
Rust
Executable File

use crate::dirs;
use std::{
path::{Path, PathBuf},
process::Command,
};
const TARGETS: &[&str] = &[
// macos
"aarch64-apple-darwin",
"x86_64-apple-darwin",
// windows
"x86_64-pc-windows-msvc",
"aarch64-pc-windows-msvc",
"i686-pc-windows-msvc",
// linux
"x86_64-unknown-linux-gnu",
"aarch64-unknown-linux-gnu",
"arm-unknown-linux-gnueabi",
];
pub fn download(url: &str, target: &str, version: &str) -> PathBuf {
assert!(TARGETS.contains(&target), "unsupported target {target}");
let archive =
download_cef::download_target_archive_from(url, target, version, dirs::get_out_dir(), true)
.expect("download failed");
download_cef::extract_target_archive(target, &archive, dirs::get_out_dir(), true)
.expect("extraction failed")
}
pub fn sys_bindgen(target: &str) -> crate::Result<()> {
assert!(TARGETS.contains(&target), "unsupported target {target}");
let (os, arch) = target_to_os_arch(target);
let cef_path = dirs::get_cef_root(os, arch);
bindgen(target, &cef_path)
}
pub fn get_target_bindings(target: &str) -> String {
assert!(TARGETS.contains(&target), "unsupported target {target}");
format!("{}.rs", target.replace('-', "_"))
}
fn bindgen(target: &str, cef_path: &Path) -> crate::Result<()> {
let mut sys_bindings = dirs::get_sys_dir()?;
let mut wrapper = sys_bindings.clone();
sys_bindings.push("src");
sys_bindings.push("bindings");
sys_bindings.push(format!("{}.rs", target.replace('-', "_")));
wrapper.push("wrapper.h");
let mut bindings = bindgen::Builder::default()
.header(wrapper.display().to_string())
.default_enum_style(bindgen::EnumVariation::Rust {
non_exhaustive: true,
})
.allowlist_type("cef_.*")
.allowlist_function("cef_.*")
.allowlist_item("CEF_API_VERSION(_.+)?")
.allowlist_item("CEF_VERSION(_.+)?")
.allowlist_item("CHROME_VERSION(_.+)?")
.default_macro_constant_type(bindgen::MacroTypeVariation::Signed)
.bitfield_enum(".*_mask_t")
.clang_args([
format!("-I{}", cef_path.display()),
format!("--target={target}"),
]);
if target.contains("windows") {
bindings = bindings.new_type_alias("HINSTANCE").new_type_alias("HWND");
} else if target.contains("apple") {
let sdk_path = Command::new("xcrun")
.args(["--sdk", "macosx", "--show-sdk-path"])
.output()
.unwrap()
.stdout;
bindings = bindings.clang_arg(format!(
"--sysroot={}",
String::from_utf8_lossy(&sdk_path).trim()
));
}
let bindings = bindings.generate()?;
bindings.write_to_file(&sys_bindings)?;
Ok(())
}
fn target_to_os_arch(target: &str) -> (&str, &str) {
match target {
"aarch64-apple-darwin" => ("macos", "aarch64"),
"x86_64-apple-darwin" => ("macos", "x86_64"),
"x86_64-pc-windows-msvc" => ("windows", "x86_64"),
"aarch64-pc-windows-msvc" => ("windows", "aarch64"),
"i686-pc-windows-msvc" => ("windows", "x86"),
"x86_64-unknown-linux-gnu" => ("linux", "x86_64"),
"aarch64-unknown-linux-gnu" => ("linux", "aarch64"),
"arm-unknown-linux-gnueabi" => ("linux", "arm"),
v => panic!("unsupported {v:?}"),
}
}