Handy/src-tauri/build.rs
Chirag Agggarwal bfecade869
Apple intel integration (#391)
* feat: add Apple Intelligence post-processing provider

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>

* feat: guide apple intelligence output

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>

* fix(build): add fallback stub for Apple Intelligence on older SDKs

- Checks if 'FoundationModels.framework' is present in the macOS SDK.
- If missing, compiles a stub Swift file that returns 'unavailable' errors instead of failing the build.
- Prevents build errors on older Xcode versions (or macOS versions < 26.0) where the macros are not supported.

* fix(ui): hide Apple Intelligence option when unavailable

- Checks for runtime availability of Apple Intelligence (via 'check_apple_intelligence_availability') in 'settings.rs'.
- Only adds the Apple Intelligence provider to the default settings if it is actually available on the device.
- Ensures the option does not appear in the UI for unsupported Macs (e.g., Intel or older macOS versions), even if the app was built with support enabled.

* move some files around as well as some ui text

* format

---------

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Co-authored-by: CJ Pais <cj@cjpais.com>
2025-12-09 21:04:24 +07:00

128 lines
4.1 KiB
Rust

fn main() {
#[cfg(all(target_os = "macos", target_arch = "aarch64"))]
build_apple_intelligence_bridge();
tauri_build::build()
}
#[cfg(all(target_os = "macos", target_arch = "aarch64"))]
fn build_apple_intelligence_bridge() {
use std::env;
use std::path::{Path, PathBuf};
use std::process::Command;
const REAL_SWIFT_FILE: &str = "swift/apple_intelligence.swift";
const STUB_SWIFT_FILE: &str = "swift/apple_intelligence_stub.swift";
const BRIDGE_HEADER: &str = "swift/apple_intelligence_bridge.h";
println!("cargo:rerun-if-changed={REAL_SWIFT_FILE}");
println!("cargo:rerun-if-changed={STUB_SWIFT_FILE}");
println!("cargo:rerun-if-changed={BRIDGE_HEADER}");
let out_dir = PathBuf::from(env::var("OUT_DIR").expect("OUT_DIR not set"));
let object_path = out_dir.join("apple_intelligence.o");
let static_lib_path = out_dir.join("libapple_intelligence.a");
let sdk_path = String::from_utf8(
Command::new("xcrun")
.args(["--sdk", "macosx", "--show-sdk-path"])
.output()
.expect("Failed to locate macOS SDK")
.stdout,
)
.expect("SDK path is not valid UTF-8")
.trim()
.to_string();
// Check if the SDK supports FoundationModels (required for Apple Intelligence)
let framework_path =
Path::new(&sdk_path).join("System/Library/Frameworks/FoundationModels.framework");
let has_foundation_models = framework_path.exists();
let source_file = if has_foundation_models {
println!("cargo:warning=Building with Apple Intelligence support.");
REAL_SWIFT_FILE
} else {
println!("cargo:warning=Apple Intelligence SDK not found. Building with stubs.");
STUB_SWIFT_FILE
};
if !Path::new(source_file).exists() {
panic!("Source file {} is missing!", source_file);
}
let swiftc_path = String::from_utf8(
Command::new("xcrun")
.args(["--find", "swiftc"])
.output()
.expect("Failed to locate swiftc")
.stdout,
)
.expect("swiftc path is not valid UTF-8")
.trim()
.to_string();
let toolchain_swift_lib = Path::new(&swiftc_path)
.parent()
.and_then(|p| p.parent())
.map(|root| root.join("lib/swift/macosx"))
.expect("Unable to determine Swift toolchain lib directory");
let sdk_swift_lib = Path::new(&sdk_path).join("usr/lib/swift");
let status = Command::new("xcrun")
.args([
"swiftc",
"-target",
"arm64-apple-macosx26.0",
"-sdk",
&sdk_path,
"-O",
"-import-objc-header",
BRIDGE_HEADER,
"-c",
source_file,
"-o",
object_path
.to_str()
.expect("Failed to convert object path to string"),
])
.status()
.expect("Failed to invoke swiftc for Apple Intelligence bridge");
if !status.success() {
panic!("swiftc failed to compile {source_file}");
}
let status = Command::new("libtool")
.args([
"-static",
"-o",
static_lib_path
.to_str()
.expect("Failed to convert static lib path to string"),
object_path
.to_str()
.expect("Failed to convert object path to string"),
])
.status()
.expect("Failed to create static library for Apple Intelligence bridge");
if !status.success() {
panic!("libtool failed for Apple Intelligence bridge");
}
println!("cargo:rustc-link-search=native={}", out_dir.display());
println!("cargo:rustc-link-lib=static=apple_intelligence");
println!(
"cargo:rustc-link-search=native={}",
toolchain_swift_lib.display()
);
println!("cargo:rustc-link-search=native={}", sdk_swift_lib.display());
println!("cargo:rustc-link-lib=framework=Foundation");
if has_foundation_models {
println!("cargo:rustc-link-lib=framework=FoundationModels");
}
println!("cargo:rustc-link-arg=-Wl,-rpath,/usr/lib/swift");
}