mirror of
https://github.com/openai/codex.git
synced 2026-04-23 22:24:57 +00:00
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:
33
MODULE.bazel
33
MODULE.bazel
@@ -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",
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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,
|
||||
)
|
||||
|
||||
@@ -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,
|
||||
)
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
)
|
||||
|
||||
12
defs.bzl
12
defs.bzl
@@ -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(
|
||||
|
||||
@@ -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",
|
||||
|
||||
75
patches/webrtc-sys_hermetic_darwin_sysroot.patch
Normal file
75
patches/webrtc-sys_hermetic_darwin_sysroot.patch
Normal 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();
|
||||
Reference in New Issue
Block a user