Wire realtime WebRTC native media into Bazel (#17145)

- Builds codex-realtime-webrtc through the normal Bazel Rust macro so
native macOS WebRTC sources are included.\n- Shares the macOS -ObjC link
flag with Bazel targets that can link libwebrtc.

---------

Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
Ahmed Ibrahim
2026-04-08 15:15:55 -07:00
committed by GitHub
parent 56dfe41605
commit 19bd018300
9 changed files with 137 additions and 18 deletions

View File

@@ -40,9 +40,17 @@ osx.frameworks(names = [
"ColorSync",
"CoreFoundation",
"CoreGraphics",
"CoreImage",
"CoreMedia",
"CoreMIDI",
"CoreServices",
"CoreText",
"CoreVideo",
"DiskArbitration",
"AudioToolbox",
"AVFoundation",
"AVFAudio",
"AVRouting",
"CFNetwork",
"FontServices",
"AudioUnit",
@@ -50,11 +58,19 @@ osx.frameworks(names = [
"CoreAudioTypes",
"Foundation",
"ImageIO",
"IOSurface",
"IOKit",
"Kernel",
"Metal",
"MetalKit",
"OpenGL",
"OSLog",
"QuartzCore",
"ScreenCaptureKit",
"Security",
"SystemConfiguration",
"UniformTypeIdentifiers",
"VideoToolbox",
])
use_repo(osx, "macos_sdk")
@@ -345,6 +361,23 @@ crate.annotation(
inject_repo(crate, "llvm", "llvm-project", "macos_sdk")
crate.annotation(
# Provide the hermetic SDK path so the build script doesn't try to invoke an unavailable `xcrun --show-sdk-path`.
build_script_data = [
"@macos_sdk//sysroot",
],
build_script_env = {
"WEBRTC_SYS_DARWIN_SDK_PATH": "$(location @macos_sdk//sysroot)",
"WEBRTC_SYS_LINK_OUT_DIR": "1",
},
crate = "webrtc-sys",
gen_build_script = "on",
patch_args = ["-p1"],
patches = [
"//patches:webrtc-sys_hermetic_darwin_sysroot.patch",
],
)
# Fix readme inclusions
crate.annotation(
crate = "windows-link",

View File

@@ -1,8 +1,9 @@
load("//:defs.bzl", "codex_rust_crate", "multiplatform_binaries")
load("//:defs.bzl", "MACOS_WEBRTC_RUSTC_LINK_FLAGS", "codex_rust_crate", "multiplatform_binaries")
codex_rust_crate(
name = "cli",
crate_name = "codex_cli",
rustc_flags_extra = MACOS_WEBRTC_RUSTC_LINK_FLAGS,
)
multiplatform_binaries(

View File

@@ -1,6 +1,7 @@
load("//:defs.bzl", "codex_rust_crate")
load("//:defs.bzl", "MACOS_WEBRTC_RUSTC_LINK_FLAGS", "codex_rust_crate")
codex_rust_crate(
name = "cloud-tasks",
crate_name = "codex_cloud_tasks",
rustc_flags_extra = MACOS_WEBRTC_RUSTC_LINK_FLAGS,
)

View File

@@ -1,12 +1,7 @@
load("@rules_rust//rust:defs.bzl", "rust_library")
load("//:defs.bzl", "MACOS_WEBRTC_RUSTC_LINK_FLAGS", "codex_rust_crate")
rust_library(
codex_rust_crate(
name = "realtime-webrtc",
crate_name = "codex_realtime_webrtc",
crate_root = "src/lib.rs",
srcs = ["src/lib.rs"],
edition = "2024",
rustc_flags = ["--cfg=codex_bazel"],
deps = ["@crates//:thiserror"],
visibility = ["//visibility:public"],
rustc_flags_extra = MACOS_WEBRTC_RUSTC_LINK_FLAGS,
)

View File

@@ -1,4 +1,4 @@
#[cfg(all(target_os = "macos", not(codex_bazel)))]
#[cfg(target_os = "macos")]
mod native;
use std::fmt;
@@ -31,7 +31,7 @@ pub struct StartedRealtimeWebrtcSession {
}
pub struct RealtimeWebrtcSessionHandle {
#[cfg(all(target_os = "macos", not(codex_bazel)))]
#[cfg(target_os = "macos")]
inner: native::SessionHandle,
local_audio_peak: Arc<AtomicU16>,
}
@@ -45,11 +45,11 @@ impl fmt::Debug for RealtimeWebrtcSessionHandle {
impl RealtimeWebrtcSessionHandle {
pub fn apply_answer_sdp(&self, answer_sdp: String) -> Result<()> {
#[cfg(all(target_os = "macos", not(codex_bazel)))]
#[cfg(target_os = "macos")]
{
self.inner.apply_answer_sdp(answer_sdp)
}
#[cfg(any(not(target_os = "macos"), codex_bazel))]
#[cfg(not(target_os = "macos"))]
{
let _ = answer_sdp;
Err(RealtimeWebrtcError::UnsupportedPlatform)
@@ -57,7 +57,7 @@ impl RealtimeWebrtcSessionHandle {
}
pub fn close(&self) {
#[cfg(all(target_os = "macos", not(codex_bazel)))]
#[cfg(target_os = "macos")]
self.inner.close();
}
@@ -70,7 +70,7 @@ pub struct RealtimeWebrtcSession;
impl RealtimeWebrtcSession {
pub fn start() -> Result<StartedRealtimeWebrtcSession> {
#[cfg(all(target_os = "macos", not(codex_bazel)))]
#[cfg(target_os = "macos")]
{
let started = native::start()?;
Ok(StartedRealtimeWebrtcSession {
@@ -82,7 +82,7 @@ impl RealtimeWebrtcSession {
events: started.events,
})
}
#[cfg(any(not(target_os = "macos"), codex_bazel))]
#[cfg(not(target_os = "macos"))]
{
Err(RealtimeWebrtcError::UnsupportedPlatform)
}

View File

@@ -1,4 +1,4 @@
load("//:defs.bzl", "codex_rust_crate")
load("//:defs.bzl", "MACOS_WEBRTC_RUSTC_LINK_FLAGS", "codex_rust_crate")
codex_rust_crate(
name = "tui",
@@ -23,4 +23,5 @@ codex_rust_crate(
extra_binaries = [
"//codex-rs/cli:codex",
],
rustc_flags_extra = MACOS_WEBRTC_RUSTC_LINK_FLAGS,
)

View File

@@ -31,6 +31,18 @@ WINDOWS_RUSTC_LINK_FLAGS = select({
"//conditions:default": [],
})
# libwebrtc uses Objective-C categories from native archives. Any Bazel-linked
# macOS binary/test that can pull it in must keep category symbols alive.
MACOS_WEBRTC_RUSTC_LINK_FLAGS = select({
"@platforms//os:macos": [
"-C",
"link-arg=-ObjC",
"-C",
"link-arg=-lc++",
],
"//conditions:default": [],
})
def multiplatform_binaries(name, platforms = PLATFORMS):
for platform in platforms:
platform_data(

View File

@@ -20,6 +20,7 @@ exports_files([
"v8_bazel_rules.patch",
"v8_module_deps.patch",
"v8_source_portability.patch",
"webrtc-sys_hermetic_darwin_sysroot.patch",
"windows-link.patch",
"xz_windows_stack_args.patch",
"zstd-sys_windows_msvc_include_dirs.patch",

View File

@@ -0,0 +1,75 @@
diff --git a/build.rs b/build.rs
index 3b4a24a..6aa06ff 100644
--- a/build.rs
+++ b/build.rs
@@ -15,1 +15,2 @@
-use std::path::Path;
+use std::fs;
+use std::path::Path;
@@ -118,1 +119,9 @@
- println!("cargo:rustc-link-search=native={}", webrtc_lib.to_str().unwrap());
+ let webrtc_link_lib = if env::var_os("WEBRTC_SYS_LINK_OUT_DIR").is_some() {
+ let out_lib = PathBuf::from(env::var_os("OUT_DIR").unwrap()).join("lib");
+ fs::create_dir_all(&out_lib).unwrap();
+ fs::copy(webrtc_lib.join("libwebrtc.a"), out_lib.join("libwebrtc.a")).unwrap();
+ out_lib
+ } else {
+ webrtc_lib
+ };
+ println!("cargo:rustc-link-search=native={}", webrtc_link_lib.to_str().unwrap());
@@ -255,1 +264,1 @@
- println!("cargo:rustc-link-lib=framework=Appkit");
+ println!("cargo:rustc-link-lib=framework=AppKit");
@@ -320,1 +329,18 @@
- builder.warnings(false).compile("webrtcsys-cxx");
+ builder.warnings(false).compile("webrtcsys-cxx");
+ let cxxbridge_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap()).join("cxxbridge");
+ let cxx_header = cxxbridge_dir.join("include/rust/cxx.h");
+ if fs::symlink_metadata(&cxx_header)
+ .is_ok_and(|metadata| metadata.file_type().is_symlink())
+ {
+ if let Ok(header) = fs::read(&cxx_header) {
+ fs::remove_file(&cxx_header).unwrap();
+ fs::write(&cxx_header, header).unwrap();
+ }
+ }
+ let crate_link = cxxbridge_dir.join("crate/webrtc-sys");
+ if fs::symlink_metadata(&crate_link)
+ .is_ok_and(|metadata| metadata.file_type().is_symlink())
+ {
+ fs::remove_file(crate_link).unwrap();
+ }
+
@@ -375,1 +384,3 @@
- println!("cargo:rustc-link-lib={}", clang_rt);
+ if env::var_os("WEBRTC_SYS_LINK_OUT_DIR").is_none() {
+ println!("cargo:rustc-link-lib={}", clang_rt);
+ }
@@ -378,6 +389,21 @@
- let sysroot = Command::new("xcrun").args(["--sdk", sdk, "--show-sdk-path"]).output().unwrap();
-
- let sysroot = String::from_utf8_lossy(&sysroot.stdout);
- let sysroot = sysroot.trim();
-
- let search_dirs = Command::new("cc").arg("--print-search-dirs").output().unwrap();
+ let sysroot = env::var("WEBRTC_SYS_DARWIN_SDK_PATH").unwrap_or_else(|_| {
+ let output = Command::new("xcrun")
+ .args(["--sdk", sdk, "--show-sdk-path"])
+ .output()
+ .unwrap();
+ String::from_utf8_lossy(&output.stdout).into_owned()
+ });
+
+ let sysroot = sysroot.as_str();
+ let sysroot = sysroot.trim();
+ builder.flag(format!("-F{sysroot}/System/Library/Frameworks"));
+ builder.define("__APPLICATIONSERVICES__", None);
+ builder.flag("-include");
+ builder.flag("CoreGraphics/CoreGraphics.h");
+ builder.include(format!("{sysroot}/usr/include"));
+
+ let cc = env::var("CC").unwrap_or_else(|_| "cc".to_string());
+ let search_dirs = Command::new(cc)
+ .arg("--print-search-dirs")
+ .output()
+ .unwrap();