use std::env;
use std::path::{Path, PathBuf};
fn main() {
println!("cargo:rerun-if-changed=build.rs");
if cfg!(feature = "embedded_runtime") {
link_libgodot();
}
}
fn link_libgodot() {
let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap();
let target_arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap();
match target_os.as_str() {
"macos" => link_macos_libgodot(&target_arch),
"linux" => {
println!(
"cargo:warning=libgodot not yet available for Linux - using stub implementation"
);
}
"windows" => {
println!(
"cargo:warning=libgodot not yet available for Windows - using stub implementation"
);
}
_ => {
println!(
"cargo:warning=libgodot not available for target OS {} - using stub implementation",
target_os
);
}
}
}
fn link_macos_libgodot(target_arch: &str) {
let out_dir = env::var("OUT_DIR").unwrap();
let out_path = PathBuf::from(&out_dir);
let libgodot_dir = out_path.join("libgodot");
let libgodot_path = libgodot_dir
.join("libgodot.xcframework")
.join("macos-arm64_x86_64");
let dylib_path = libgodot_path.join("libgodot.dylib");
if !dylib_path.exists() {
println!(
"cargo:warning=libgodot.dylib not found, downloading from SwiftGodotKit releases..."
);
download_libgodot(&libgodot_dir);
}
println!("cargo:rustc-link-search=native={}", libgodot_path.display());
copy_dylib_to_target_dir(&dylib_path);
println!("cargo:rustc-link-lib=dylib=godot");
println!(
"cargo:rustc-link-arg=-Wl,-rpath,{}",
libgodot_path.display()
);
let target_dir = env::var("CARGO_TARGET_DIR")
.map(PathBuf::from)
.or_else(|_| {
env::var("OUT_DIR")
.map(|out| PathBuf::from(out).ancestors().nth(4).unwrap().to_path_buf())
})
.unwrap_or_else(|_| PathBuf::from("target"));
let debug_dir = target_dir.join("debug");
println!("cargo:rustc-link-arg=-Wl,-rpath,{}", debug_dir.display());
println!(
"cargo:warning=Linking against libgodot.dylib for {} on macOS",
target_arch
);
}
fn copy_dylib_to_target_dir(src_dylib: &Path) {
let target_dir = env::var("CARGO_TARGET_DIR")
.map(PathBuf::from)
.or_else(|_| {
env::var("OUT_DIR")
.map(|out| PathBuf::from(out).ancestors().nth(4).unwrap().to_path_buf())
})
.unwrap_or_else(|_| PathBuf::from("target"));
let debug_dir = target_dir.join("debug");
if let Err(e) = std::fs::create_dir_all(&debug_dir) {
eprintln!("Warning: Failed to create debug directory: {}", e);
return;
}
if src_dylib.exists() {
let deps_dir = debug_dir.join("deps");
if let Ok(()) = std::fs::create_dir_all(&deps_dir) {
let deps_dylib = deps_dir.join("libgodot.dylib");
if let Err(e) = std::fs::copy(src_dylib, &deps_dylib) {
eprintln!(
"Warning: Failed to copy libgodot.dylib to deps directory: {}",
e
);
} else {
println!(
"cargo:warning=Copied libgodot.dylib to {}",
deps_dylib.display()
);
}
}
}
}
fn download_libgodot(libgodot_dir: &Path) {
use std::process::Command;
if let Err(e) = std::fs::create_dir_all(libgodot_dir) {
panic!("Failed to create libgodot directory: {}", e);
}
let zip_path = libgodot_dir.join("libgodot.xcframework.zip");
let url = "https://github.com/migueldeicaza/SwiftGodotKit/releases/download/4.3.5/libgodot.xcframework.zip";
println!("cargo:warning=Downloading libgodot from: {}", url);
let download_result = Command::new("curl")
.args(["-L", "-o", zip_path.to_str().unwrap(), url])
.status();
match download_result {
Ok(status) => {
if !status.success() {
panic!("Failed to download libgodot.xcframework.zip");
}
}
Err(e) => {
panic!(
"Failed to run curl command: {}. Please ensure curl is installed.",
e
);
}
}
let extract_result = Command::new("unzip")
.args([
"-o",
zip_path.to_str().unwrap(),
"-d",
libgodot_dir.to_str().unwrap(),
])
.status();
match extract_result {
Ok(status) => {
if !status.success() {
panic!("Failed to extract libgodot.xcframework.zip");
}
}
Err(e) => {
panic!(
"Failed to run unzip command: {}. Please ensure unzip is installed.",
e
);
}
}
if let Err(e) = std::fs::remove_file(&zip_path) {
println!("cargo:warning=Failed to remove zip file: {}", e);
}
println!("cargo:warning=Successfully downloaded and extracted libgodot.xcframework");
}