mirror of
https://github.com/mofeng-git/One-KVM.git
synced 2026-01-28 08:31:52 +08:00
- 移除公共 RustDesk ID 服务器 (用户需自行配置) - 移除公共 TURN 服务器 (仅保留 Google STUN) - 清理废弃代码: PublicServerInfo, is_using_public_server 等 - 更新前端 UI 和国际化文本 - 重新生成 TypeScript 类型 破坏性变更: 不再提供内置公共服务器。用户必须配置自己的 RustDesk 服务器和 TURN 服务器才能在生产环境中使用。
313 lines
10 KiB
Rust
313 lines
10 KiB
Rust
use std::{
|
|
env,
|
|
path::{Path, PathBuf},
|
|
process::Command,
|
|
};
|
|
|
|
fn main() {
|
|
let manifest_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
|
let cpp_dir = manifest_dir.join("cpp");
|
|
|
|
println!("cargo:rerun-if-changed=cpp/yuv_ffi.h");
|
|
|
|
// Generate FFI bindings
|
|
generate_bindings(&cpp_dir);
|
|
|
|
// Link libyuv library
|
|
link_libyuv();
|
|
}
|
|
|
|
fn generate_bindings(cpp_dir: &Path) {
|
|
let ffi_header = cpp_dir.join("yuv_ffi.h");
|
|
|
|
bindgen::builder()
|
|
.header(ffi_header.to_string_lossy().to_string())
|
|
// YUYV conversions
|
|
.allowlist_function("YUY2ToI420")
|
|
.allowlist_function("YUY2ToNV12")
|
|
// UYVY conversions
|
|
.allowlist_function("UYVYToI420")
|
|
.allowlist_function("UYVYToNV12")
|
|
// I420 conversions
|
|
.allowlist_function("I420ToNV12")
|
|
.allowlist_function("I420ToNV21")
|
|
.allowlist_function("I420Copy")
|
|
// I422 conversions
|
|
.allowlist_function("I422ToI420")
|
|
// NV12/NV21 conversions
|
|
.allowlist_function("NV12ToI420")
|
|
.allowlist_function("NV21ToI420")
|
|
.allowlist_function("NV12Copy")
|
|
// ARGB/BGRA conversions
|
|
.allowlist_function("ARGBToI420")
|
|
.allowlist_function("ARGBToNV12")
|
|
.allowlist_function("ABGRToI420")
|
|
.allowlist_function("ABGRToNV12")
|
|
.allowlist_function("ARGBToABGR")
|
|
.allowlist_function("ABGRToARGB")
|
|
// RGB24/BGR24 conversions
|
|
.allowlist_function("RGB24ToI420")
|
|
.allowlist_function("RAWToI420")
|
|
.allowlist_function("RGB24ToARGB")
|
|
.allowlist_function("RAWToARGB")
|
|
// YUV to RGB conversions
|
|
.allowlist_function("I420ToRGB24")
|
|
.allowlist_function("I420ToARGB")
|
|
.allowlist_function("NV12ToRGB24")
|
|
.allowlist_function("NV12ToARGB")
|
|
.allowlist_function("YUY2ToARGB")
|
|
.allowlist_function("UYVYToARGB")
|
|
.allowlist_function("ARGBToRGB24")
|
|
.allowlist_function("ARGBToRAW")
|
|
// MJPEG decoding
|
|
.allowlist_function("MJPGToI420")
|
|
.allowlist_function("MJPGToNV12")
|
|
.allowlist_function("MJPGToARGB")
|
|
.allowlist_function("MJPGSize")
|
|
// Scaling
|
|
.allowlist_function("I420Scale")
|
|
.allowlist_function("NV12Scale")
|
|
.allowlist_function("ARGBScale")
|
|
// Rotation
|
|
.allowlist_function("I420Rotate")
|
|
.allowlist_function("NV12ToI420Rotate")
|
|
// Enums
|
|
.allowlist_type("FilterMode")
|
|
.allowlist_type("RotationMode")
|
|
.rustified_enum("FilterMode")
|
|
.rustified_enum("RotationMode")
|
|
.generate()
|
|
.expect("Failed to generate libyuv bindings")
|
|
.write_to_file(Path::new(&env::var_os("OUT_DIR").unwrap()).join("yuv_ffi.rs"))
|
|
.expect("Failed to write yuv_ffi.rs");
|
|
}
|
|
|
|
fn link_libyuv() {
|
|
// Try vcpkg first
|
|
if let Ok(vcpkg_root) = env::var("VCPKG_ROOT") {
|
|
if link_vcpkg(vcpkg_root.into()) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Try pkg-config
|
|
if link_pkg_config() {
|
|
return;
|
|
}
|
|
|
|
// Try system library directly
|
|
if link_system() {
|
|
return;
|
|
}
|
|
|
|
panic!(
|
|
"libyuv not found!\n\
|
|
\n\
|
|
Install via one of:\n\
|
|
- vcpkg: vcpkg install libyuv && export VCPKG_ROOT=/path/to/vcpkg\n\
|
|
- apt (Debian/Ubuntu): sudo apt install libyuv-dev\n\
|
|
- dnf (Fedora): sudo dnf install libyuv-devel\n\
|
|
- pacman (Arch): sudo pacman -S libyuv\n"
|
|
);
|
|
}
|
|
|
|
fn link_vcpkg(mut path: PathBuf) -> bool {
|
|
let target_arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap_or_default();
|
|
let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap_or_default();
|
|
|
|
let triplet = match (target_os.as_str(), target_arch.as_str()) {
|
|
("linux", "x86_64") => "x64-linux",
|
|
("linux", "aarch64") => "arm64-linux",
|
|
("linux", "arm") => "arm-linux",
|
|
("windows", "x86_64") => "x64-windows-static",
|
|
("windows", "x86") => "x86-windows-static",
|
|
("macos", "x86_64") => "x64-osx",
|
|
("macos", "aarch64") => "arm64-osx",
|
|
_ => {
|
|
println!(
|
|
"cargo:warning=Unsupported vcpkg target: {}-{}",
|
|
target_os, target_arch
|
|
);
|
|
return false;
|
|
}
|
|
};
|
|
|
|
path.push("installed");
|
|
path.push(triplet);
|
|
|
|
let include_path = path.join("include");
|
|
let lib_path = path.join("lib");
|
|
|
|
if !lib_path.exists() {
|
|
println!(
|
|
"cargo:warning=vcpkg libyuv not found at: {}",
|
|
lib_path.display()
|
|
);
|
|
return false;
|
|
}
|
|
|
|
println!("cargo:rustc-link-search=native={}", lib_path.display());
|
|
|
|
// Check if static linking is requested via environment variable
|
|
let use_static = env::var("LIBYUV_STATIC").map(|v| v == "1").unwrap_or(false);
|
|
|
|
let static_lib = lib_path.join("libyuv.a");
|
|
let jpeg_static = lib_path.join("libjpeg.a");
|
|
let turbojpeg_static = lib_path.join("libturbojpeg.a");
|
|
|
|
if use_static && static_lib.exists() {
|
|
// Static linking (for deb packaging)
|
|
println!("cargo:rustc-link-lib=static=yuv");
|
|
if turbojpeg_static.exists() {
|
|
println!("cargo:rustc-link-lib=static=turbojpeg");
|
|
} else if jpeg_static.exists() {
|
|
println!("cargo:rustc-link-lib=static=jpeg");
|
|
} else {
|
|
println!("cargo:rustc-link-lib=jpeg");
|
|
}
|
|
println!("cargo:rustc-link-lib=stdc++");
|
|
println!("cargo:info=Using libyuv from vcpkg (static linking)");
|
|
} else {
|
|
// Dynamic linking (default for development)
|
|
println!("cargo:rustc-link-lib=yuv");
|
|
println!("cargo:rustc-link-lib=jpeg");
|
|
println!("cargo:rustc-link-lib=stdc++");
|
|
println!("cargo:info=Using libyuv from vcpkg (dynamic linking)");
|
|
}
|
|
|
|
println!(
|
|
"cargo:info=Using libyuv from vcpkg: {}",
|
|
include_path.display()
|
|
);
|
|
true
|
|
}
|
|
|
|
fn link_pkg_config() -> bool {
|
|
let output = match Command::new("pkg-config")
|
|
.args(["--libs", "--cflags", "libyuv"])
|
|
.output()
|
|
{
|
|
Ok(o) => o,
|
|
Err(_) => return false,
|
|
};
|
|
|
|
if !output.status.success() {
|
|
return false;
|
|
}
|
|
|
|
let flags = String::from_utf8_lossy(&output.stdout);
|
|
for flag in flags.split_whitespace() {
|
|
if flag.starts_with("-L") {
|
|
println!("cargo:rustc-link-search=native={}", &flag[2..]);
|
|
} else if flag.starts_with("-l") {
|
|
println!("cargo:rustc-link-lib={}", &flag[2..]);
|
|
}
|
|
}
|
|
|
|
// Also need libjpeg
|
|
if let Ok(jpeg_output) = Command::new("pkg-config")
|
|
.args(["--libs", "libjpeg"])
|
|
.output()
|
|
{
|
|
if jpeg_output.status.success() {
|
|
let jpeg_flags = String::from_utf8_lossy(&jpeg_output.stdout);
|
|
for flag in jpeg_flags.split_whitespace() {
|
|
if flag.starts_with("-L") {
|
|
println!("cargo:rustc-link-search=native={}", &flag[2..]);
|
|
} else if flag.starts_with("-l") {
|
|
println!("cargo:rustc-link-lib={}", &flag[2..]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#[cfg(target_os = "linux")]
|
|
println!("cargo:rustc-link-lib=stdc++");
|
|
|
|
println!("cargo:info=Using libyuv from pkg-config (dynamic linking)");
|
|
true
|
|
}
|
|
|
|
fn link_system() -> bool {
|
|
// Check if static linking is requested
|
|
let use_static = env::var("LIBYUV_STATIC").map(|v| v == "1").unwrap_or(false);
|
|
let target_arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap_or_default();
|
|
|
|
// Build custom library paths based on target architecture:
|
|
// 1. Check ONE_KVM_LIBS_PATH environment variable (explicit override)
|
|
// 2. Fall back to architecture-based detection
|
|
let custom_lib_path = if let Ok(path) = env::var("ONE_KVM_LIBS_PATH") {
|
|
format!("{}/lib", path)
|
|
} else {
|
|
match target_arch.as_str() {
|
|
"x86_64" => "/opt/one-kvm-libs/x86_64-linux-gnu/lib",
|
|
"aarch64" => "/opt/one-kvm-libs/aarch64-linux-gnu/lib",
|
|
"arm" => "/opt/one-kvm-libs/armv7-linux-gnueabihf/lib",
|
|
_ => "",
|
|
}
|
|
.to_string()
|
|
};
|
|
|
|
// Try common system library paths (custom paths first)
|
|
let mut lib_paths: Vec<String> = Vec::new();
|
|
|
|
// Add custom build path first (highest priority)
|
|
if !custom_lib_path.is_empty() {
|
|
lib_paths.push(custom_lib_path);
|
|
}
|
|
|
|
// Then standard paths
|
|
lib_paths.extend([
|
|
"/usr/local/lib", // Custom builds
|
|
"/usr/local/lib64",
|
|
"/usr/lib",
|
|
"/usr/lib64",
|
|
"/usr/lib/x86_64-linux-gnu", // Debian/Ubuntu x86_64
|
|
"/usr/lib/aarch64-linux-gnu", // Debian/Ubuntu ARM64
|
|
"/usr/lib/arm-linux-gnueabihf", // Debian/Ubuntu ARMv7
|
|
].iter().map(|s| s.to_string()));
|
|
|
|
for path in &lib_paths {
|
|
let lib_path = Path::new(path);
|
|
let libyuv_static = lib_path.join("libyuv.a");
|
|
let libyuv_so = lib_path.join("libyuv.so");
|
|
|
|
// Prefer static library if LIBYUV_STATIC=1
|
|
if use_static && libyuv_static.exists() {
|
|
println!("cargo:rustc-link-search=native={}", path);
|
|
println!("cargo:rustc-link-lib=static=yuv");
|
|
|
|
// Check for static libjpeg-turbo in the same directory
|
|
let turbojpeg_static = lib_path.join("libturbojpeg.a");
|
|
let jpeg_static = lib_path.join("libjpeg.a");
|
|
if turbojpeg_static.exists() {
|
|
println!("cargo:rustc-link-lib=static=turbojpeg");
|
|
} else if jpeg_static.exists() {
|
|
println!("cargo:rustc-link-lib=static=jpeg");
|
|
} else {
|
|
// Fall back to dynamic jpeg
|
|
println!("cargo:rustc-link-lib=jpeg");
|
|
}
|
|
|
|
println!("cargo:rustc-link-lib=stdc++");
|
|
println!("cargo:info=Using system libyuv from {} (static linking)", path);
|
|
return true;
|
|
}
|
|
|
|
// Fall back to dynamic linking
|
|
if libyuv_so.exists() {
|
|
println!("cargo:rustc-link-search=native={}", path);
|
|
println!("cargo:rustc-link-lib=yuv");
|
|
println!("cargo:rustc-link-lib=jpeg");
|
|
|
|
#[cfg(target_os = "linux")]
|
|
println!("cargo:rustc-link-lib=stdc++");
|
|
|
|
println!("cargo:info=Using system libyuv from {} (dynamic linking)", path);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
false
|
|
}
|