use std::{env, path::Path};
const PROTO_SRC_DIR: &str = "protocol";
fn main() {
if env::var("DOCS_RS").is_ok() {
return;
}
download_webrtc();
copy_webrtc_license();
configure_linker();
generate_protobuf();
}
fn download_webrtc() {
let webrtc_dir = webrtc_sys_build::webrtc_dir();
if !webrtc_dir.exists() {
webrtc_sys_build::download_webrtc().unwrap();
}
}
fn copy_webrtc_license() {
let webrtc_dir = webrtc_sys_build::webrtc_dir();
let license = webrtc_dir.join("LICENSE.md");
let target_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
let out_file = Path::new(&target_dir).join("WEBRTC_LICENSE.md");
std::fs::copy(license, out_file).unwrap();
}
fn configure_linker() {
let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap();
match target_os.as_str() {
"windows" => {}
"linux" => {
println!("cargo:rustc-link-lib=static=webrtc");
}
"android" => {
webrtc_sys_build::configure_jni_symbols().unwrap();
}
"macos" | "ios" => {
println!("cargo:rustc-link-arg=-ObjC");
}
_ => {
panic!("Unsupported target, {}", target_os);
}
}
}
fn generate_protobuf() {
let paths: Vec<_> = std::fs::read_dir(PROTO_SRC_DIR)
.expect("Failed to read protobuf source directory")
.map(|entry| entry.unwrap().path())
.filter(|path| path.extension().is_some_and(|ext| ext == "proto"))
.collect();
for path in &paths {
println!("cargo:rerun-if-changed={}", path.display());
}
prost_build::Config::new()
.derive_from_variants("livekit.proto.FfiRequest.message")
.derive_from_variants("livekit.proto.FfiResponse.message")
.derive_from_variants("livekit.proto.FfiEvent.message")
.derive_from_variants("livekit.proto.RoomEvent.message")
.from_variants_skip_field("livekit.proto.RoomEvent.message.room_updated")
.from_variants_skip_field("livekit.proto.RoomEvent.message.moved")
.derive_from_variants("livekit.proto.AudioStreamEvent.message")
.derive_from_variants("livekit.proto.TextStreamReaderEvent.detail")
.derive_from_variants("livekit.proto.ByteStreamReaderEvent.detail")
.compile_protos(&paths, &[PROTO_SRC_DIR])
.expect("Protobuf generation failed");
}
trait ProstConfigExt {
fn derive_from_variants(&mut self, path: impl AsRef<str>) -> &mut Self;
fn from_variants_skip_field(&mut self, path: impl AsRef<str>) -> &mut Self;
}
impl ProstConfigExt for prost_build::Config {
fn derive_from_variants(&mut self, path: impl AsRef<str>) -> &mut Self {
self.enum_attribute(path, "#[derive(from_variants::FromVariants)]")
}
fn from_variants_skip_field(&mut self, path: impl AsRef<str>) -> &mut Self {
self.field_attribute(path, "#[from_variants(skip)]")
}
}