From 5650af3131fe66716841d4e5883c82f8c6fdc6a4 Mon Sep 17 00:00:00 2001 From: cloudwebrtc Date: Mon, 27 Jul 2026 11:00:01 +0800 Subject: [PATCH 01/53] fix build for win. --- webrtc-sys/libwebrtc/build_windows.cmd | 1 - webrtc-sys/libwebrtc/patches/add_deps.patch | 20 ++++---- .../patches/external_audio_source.patch | 49 ++++++++++--------- .../patches/windows_silence_warnings.patch | 14 ------ 4 files changed, 34 insertions(+), 50 deletions(-) delete mode 100644 webrtc-sys/libwebrtc/patches/windows_silence_warnings.patch diff --git a/webrtc-sys/libwebrtc/build_windows.cmd b/webrtc-sys/libwebrtc/build_windows.cmd index b4c3b5f15..9fcb8d12b 100644 --- a/webrtc-sys/libwebrtc/build_windows.cmd +++ b/webrtc-sys/libwebrtc/build_windows.cmd @@ -52,7 +52,6 @@ if not exist src ( cd src call git apply "%COMMAND_DIR%/patches/add_licenses.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn call git apply "%COMMAND_DIR%/patches/add_deps.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn -call git apply "%COMMAND_DIR%/patches/windows_silence_warnings.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn call git apply "%COMMAND_DIR%/patches/ssl_verify_callback_with_native_handle.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn call git apply "%COMMAND_DIR%/patches/external_audio_source.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn diff --git a/webrtc-sys/libwebrtc/patches/add_deps.patch b/webrtc-sys/libwebrtc/patches/add_deps.patch index 92ae3fa8f..fb626d61c 100644 --- a/webrtc-sys/libwebrtc/patches/add_deps.patch +++ b/webrtc-sys/libwebrtc/patches/add_deps.patch @@ -1,18 +1,16 @@ diff --git a/BUILD.gn b/BUILD.gn -index ca8d8faa61..13e07a2f28 100644 +index b484f5b938..378349c45e 100644 --- a/BUILD.gn +++ b/BUILD.gn -@@ -24,6 +24,9 @@ - import("//build/config/linux/pkg_config.gni") +@@ -25,6 +25,7 @@ import("//build/config/linux/pkg_config.gni") import("//build/config/sanitizers/sanitizers.gni") + import("//testing/test.gni") import("webrtc.gni") +import("//third_party/libaom/options.gni") -+ -+ - if (rtc_enable_protobuf) { - import("//third_party/protobuf/proto_library.gni") - } -@@ -331,6 +334,10 @@ config("common_config") { + + if (rtc_rust) { + import("//build/rust/rust_unit_tests_group.gni") +@@ -332,6 +333,10 @@ config("common_config") { defines += [ "WEBRTC_INCLUDE_INTERNAL_AUDIO_DEVICE" ] } @@ -23,9 +21,9 @@ index ca8d8faa61..13e07a2f28 100644 if (rtc_libvpx_build_vp9) { defines += [ "RTC_ENABLE_VP9" ] } -@@ -565,6 +572,10 @@ if (!build_with_chromium) { +@@ -564,6 +569,10 @@ if (!build_with_chromium) { + "pc:libjingle_peerconnection", "pc:rtc_pc", - "sdk", "video", + "//third_party/zlib", + "rtc_base:log_sinks", diff --git a/webrtc-sys/libwebrtc/patches/external_audio_source.patch b/webrtc-sys/libwebrtc/patches/external_audio_source.patch index 088be4044..c51846c72 100644 --- a/webrtc-sys/libwebrtc/patches/external_audio_source.patch +++ b/webrtc-sys/libwebrtc/patches/external_audio_source.patch @@ -1,11 +1,11 @@ diff --git a/api/media_stream_interface.h b/api/media_stream_interface.h -index fb1cc4e58e..85062ba60e 100644 +index 643b5f273b..7b5b568692 100644 --- a/api/media_stream_interface.h +++ b/api/media_stream_interface.h -@@ -267,6 +267,11 @@ class RTC_EXPORT AudioSourceInterface : public MediaSourceInterface { - // (for some of the settings this approach is broken, e.g. setting +@@ -270,6 +270,11 @@ class RTC_EXPORT AudioSourceInterface : public MediaSourceInterface { // audio network adaptation on the source is the wrong layer of abstraction). virtual const AudioOptions options() const; + virtual void SetOptions(const AudioOptions & /* options */) {} + + // Returns true if this source delivers audio externally (via AddSink), + // bypassing the ADM/AudioState audio distribution path. @@ -15,10 +15,10 @@ index fb1cc4e58e..85062ba60e 100644 // Interface of the audio processor used by the audio track to collect diff --git a/audio/audio_send_stream.cc b/audio/audio_send_stream.cc -index 76156ce830..10b59d3ff6 100644 +index e9e72b48e7..ca21052ff7 100644 --- a/audio/audio_send_stream.cc +++ b/audio/audio_send_stream.cc -@@ -373,8 +373,13 @@ void AudioSendStream::Start() { +@@ -377,8 +377,13 @@ void AudioSendStream::Start() { } channel_send_->StartSend(); sending_ = true; @@ -34,10 +34,11 @@ index 76156ce830..10b59d3ff6 100644 } void AudioSendStream::Stop() { -@@ -386,7 +391,10 @@ void AudioSendStream::Stop() { +@@ -389,8 +394,10 @@ void AudioSendStream::Stop() { + RTC_LOG(LS_INFO) << "AudioSendStream::Stop: " << config_.rtp.ssrc; RemoveBitrateObserver(); channel_send_->StopSend(); - sending_ = false; +- sending_ = false; - audio_state()->RemoveSendingStream(this); + // Only unregister if we registered (when not using external source). + if (!config_.external_source) { @@ -47,10 +48,10 @@ index 76156ce830..10b59d3ff6 100644 void AudioSendStream::SendAudioData(std::unique_ptr audio_frame) { diff --git a/call/audio_send_stream.h b/call/audio_send_stream.h -index 84341b5cb1..9359777bc9 100644 +index 40bfd812a4..a482b16d70 100644 --- a/call/audio_send_stream.h +++ b/call/audio_send_stream.h -@@ -178,6 +178,12 @@ class AudioSendStream : public AudioSender { +@@ -176,6 +176,12 @@ class AudioSendStream : public AudioSender { // An optional frame transformer used by insertable streams to transform // encoded frames. scoped_refptr frame_transformer; @@ -62,7 +63,7 @@ index 84341b5cb1..9359777bc9 100644 + bool external_source = false; }; - virtual ~AudioSendStream() = default; + ~AudioSendStream() override = default; diff --git a/media/base/audio_source.h b/media/base/audio_source.h index 04a7d19dfa..9f513f3c75 100644 --- a/media/base/audio_source.h @@ -79,10 +80,10 @@ index 04a7d19dfa..9f513f3c75 100644 virtual ~AudioSource() {} }; diff --git a/media/engine/webrtc_voice_engine.cc b/media/engine/webrtc_voice_engine.cc -index 762f9d584c..4ce07ddc9d 100644 +index 38a3a2f2d9..e3a3bfdfe7 100644 --- a/media/engine/webrtc_voice_engine.cc +++ b/media/engine/webrtc_voice_engine.cc -@@ -1017,6 +1017,14 @@ class WebRtcVoiceSendChannel::WebRtcAudioSendStream : public AudioSource::Sink { +@@ -936,6 +936,14 @@ class WebRtcVoiceSendChannel::WebRtcAudioSendStream : public AudioSource::Sink { RTC_DCHECK(source_ == source); return; } @@ -98,13 +99,13 @@ index 762f9d584c..4ce07ddc9d 100644 source_ = source; UpdateSendState(); diff --git a/pc/rtp_sender.cc b/pc/rtp_sender.cc -index d5edbbf0ed..c14ddfe868 100644 +index b360be5ec6..55f8bcfb87 100644 --- a/pc/rtp_sender.cc +++ b/pc/rtp_sender.cc -@@ -786,6 +786,13 @@ void AudioRtpSender::SetSend() { - RTC_DCHECK_RUN_ON(signaling_thread_); - RTC_DCHECK(!stopped_); - RTC_DCHECK(can_send_track()); +@@ -1265,6 +1265,13 @@ void AudioRtpSender::SetSend() { + if (stopped_) { + return; + } + + // Propagate is_external_source from AudioSourceInterface to the sink adapter. + // This ensures the voice engine knows not to mix ADM audio with external sources. @@ -112,16 +113,16 @@ index d5edbbf0ed..c14ddfe868 100644 + sink_adapter_->set_is_external_source(true); + } + - if (!media_channel_) { - RTC_LOG(LS_ERROR) << "SetAudioSend: No audio channel exists."; - return; + AudioOptions options; + const bool track_enabled = track_->enabled(); + std::optional track_source_options; diff --git a/pc/rtp_sender.h b/pc/rtp_sender.h -index eaffd4ef0f..d0489df9e7 100644 +index a8f3bbd08a..85ab34497e 100644 --- a/pc/rtp_sender.h +++ b/pc/rtp_sender.h -@@ -307,6 +307,12 @@ class LocalAudioSinkAdapter : public AudioTrackSinkInterface, +@@ -368,6 +368,12 @@ class LocalAudioSinkAdapter : public AudioTrackSinkInterface, LocalAudioSinkAdapter(); - virtual ~LocalAudioSinkAdapter(); + ~LocalAudioSinkAdapter() override; + // Set whether the original AudioSourceInterface is an external source. + // This propagates the is_external_source state from AudioSourceInterface @@ -132,7 +133,7 @@ index eaffd4ef0f..d0489df9e7 100644 private: // AudioSinkInterface implementation. void OnData(const void* audio_data, -@@ -337,6 +343,7 @@ class LocalAudioSinkAdapter : public AudioTrackSinkInterface, +@@ -398,6 +404,7 @@ class LocalAudioSinkAdapter : public AudioTrackSinkInterface, // Critical section protecting `sink_`. Mutex lock_; int num_preferred_channels_ = -1; diff --git a/webrtc-sys/libwebrtc/patches/windows_silence_warnings.patch b/webrtc-sys/libwebrtc/patches/windows_silence_warnings.patch deleted file mode 100644 index b10ca992d..000000000 --- a/webrtc-sys/libwebrtc/patches/windows_silence_warnings.patch +++ /dev/null @@ -1,14 +0,0 @@ -diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn -index 8048ec5e8..4e00f7e53 100644 ---- a/build/config/compiler/BUILD.gn -+++ b/build/config/compiler/BUILD.gn -@@ -1424,6 +1424,9 @@ config("default_warnings") { - # gethostbyname. Fires mostly in non-Chromium code. We probably - # want to remove this define eventually. - "_WINSOCK_DEPRECATED_NO_WARNINGS", -+ -+ "_SILENCE_ALL_CXX17_DEPRECATION_WARNINGS", -+ "_SILENCE_ALL_CXX20_DEPRECATION_WARNINGS", - ] - if (!is_clang) { - # TODO(thakis): Remove this once From da62c247a4c97d5984157a1976125b75e45e9124 Mon Sep 17 00:00:00 2001 From: cloudwebrtc Date: Mon, 27 Jul 2026 11:01:53 +0800 Subject: [PATCH 02/53] bump libwebrtc deps. --- webrtc-sys/libwebrtc/.gclient | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webrtc-sys/libwebrtc/.gclient b/webrtc-sys/libwebrtc/.gclient index 6305d0cbc..2d52a10f7 100644 --- a/webrtc-sys/libwebrtc/.gclient +++ b/webrtc-sys/libwebrtc/.gclient @@ -1,7 +1,7 @@ solutions = [ { "name": 'src', - "url": 'https://github.com/webrtc-sdk/webrtc.git@m144_release', + "url": 'https://github.com/webrtc-sdk/webrtc.git@duan/m150-patching', "custom_deps": {}, "deps_file": "DEPS", "managed": False, From c7723dd1d737f4513e39e7693aa3a6f64f131dcf Mon Sep 17 00:00:00 2001 From: cloudwebrtc Date: Mon, 27 Jul 2026 13:42:58 +0800 Subject: [PATCH 03/53] fix build on linux. --- webrtc-sys/libwebrtc/build_linux.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/webrtc-sys/libwebrtc/build_linux.sh b/webrtc-sys/libwebrtc/build_linux.sh index 52ebbad13..25a9c1d02 100755 --- a/webrtc-sys/libwebrtc/build_linux.sh +++ b/webrtc-sys/libwebrtc/build_linux.sh @@ -75,7 +75,7 @@ git apply "$COMMAND_DIR/patches/add_licenses.patch" -v --ignore-space-change --i git apply "$COMMAND_DIR/patches/fix_license_json_parsing.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn git apply "$COMMAND_DIR/patches/ssl_verify_callback_with_native_handle.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn git apply "$COMMAND_DIR/patches/add_deps.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn -git apply "$COMMAND_DIR/patches/fix_desktop_capture_compile.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn +#git apply "$COMMAND_DIR/patches/fix_desktop_capture_compile.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn git apply "$COMMAND_DIR/patches/external_audio_source.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn # Disable CREL (compact relocations). Chromium's build enables experimental @@ -113,7 +113,7 @@ args="is_debug=$debug \ rtc_enable_protobuf=false \ treat_warnings_as_errors=false \ use_llvm_libatomic=false \ - use_custom_libcxx=false \ + use_custom_libcxx=true \ use_custom_libcxx_for_host=false \ use_clang_modules=false \ rtc_include_tests=false \ From baae74ab662d030290130a58c32c6df9000cba0a Mon Sep 17 00:00:00 2001 From: cloudwebrtc Date: Mon, 27 Jul 2026 15:32:57 +0800 Subject: [PATCH 04/53] fix build for android. --- .../patches/android_use_libunwind.patch | 12 +-- webrtc-sys/libwebrtc/patches/jni_prefix.patch | 96 ++++++++++--------- .../libwebrtc/prefixed-jni/build.gradle | 21 ++-- .../gradle/wrapper/gradle-wrapper.properties | 2 +- 4 files changed, 70 insertions(+), 61 deletions(-) diff --git a/webrtc-sys/libwebrtc/patches/android_use_libunwind.patch b/webrtc-sys/libwebrtc/patches/android_use_libunwind.patch index 1339b31d8..c27026466 100644 --- a/webrtc-sys/libwebrtc/patches/android_use_libunwind.patch +++ b/webrtc-sys/libwebrtc/patches/android_use_libunwind.patch @@ -1,8 +1,8 @@ --- src/buildtools/third_party/libunwind/BUILD.gn 2023-07-10 10:19:16 +++ src/buildtools/third_party/libunwind/BUILD.gn 2023-07-10 10:19:23 -@@ -21,7 +21,7 @@ config("libunwind_config") { - - # TODO(crbug.com/40273848): Move this build file to third_party/libc++/BUILD.gn once submodule migration is done +@@ -22,7 +22,7 @@ config("libunwind_config") { + # TODO(crbug.com/40273848): Move this build file to third_party/libc++/BUILD.gn + # once submodule migration is done source_set("libunwind") { - visibility = [ "//buildtools/third_party/libc++abi" ] + visibility = [ "//buildtools/third_party/libc++abi", "//build/config:common_deps" ] @@ -11,12 +11,12 @@ } --- src/build/config/BUILD.gn 2023-07-10 10:23:49 +++ src/build/config/BUILD.gn 2023-07-10 10:23:54 -@@ -296,6 +296,8 @@ group("common_deps") { - +@@ -285,6 +285,8 @@ group("common_deps") { + if (use_custom_libcxx) { public_deps += [ "//buildtools/third_party/libc++" ] + } else { + public_deps += [ "//buildtools/third_party/libunwind" ] } - + if (use_llvm_libatomic) { diff --git a/webrtc-sys/libwebrtc/patches/jni_prefix.patch b/webrtc-sys/libwebrtc/patches/jni_prefix.patch index 2cf457718..680816e97 100644 --- a/webrtc-sys/libwebrtc/patches/jni_prefix.patch +++ b/webrtc-sys/libwebrtc/patches/jni_prefix.patch @@ -1,5 +1,5 @@ diff --git a/modules/video_coding/codecs/test/android_codec_factory_helper.cc b/modules/video_coding/codecs/test/android_codec_factory_helper.cc -index f6a5046210..4ce5a79d25 100644 +index f6a5046210..103d979d2a 100644 --- a/modules/video_coding/codecs/test/android_codec_factory_helper.cc +++ b/modules/video_coding/codecs/test/android_codec_factory_helper.cc @@ -54,9 +54,9 @@ void InitializeAndroidObjects() { @@ -7,10 +7,10 @@ index f6a5046210..4ce5a79d25 100644 JNIEnv* env = AttachCurrentThreadIfNeeded(); ScopedJavaLocalRef factory_class = - GetClass(env, "org/webrtc/HardwareVideoEncoderFactory"); -+ GetClass(env, "livekit/org/webrtc/HardwareVideoEncoderFactory"); ++ GetClass(env, "livekit/livekit/org/webrtc/HardwareVideoEncoderFactory"); jmethodID factory_constructor = env->GetMethodID( - factory_class.obj(), "", "(Lorg/webrtc/EglBase$Context;ZZ)V"); -+ factory_class.obj(), "", "(Llivekit/org/webrtc/EglBase$Context;ZZ)V"); ++ factory_class.obj(), "", "(Llivekit/livekit/org/webrtc/EglBase$Context;ZZ)V"); ScopedJavaLocalRef factory_object = ScopedJavaLocalRef::Adopt( env, env->NewObject(factory_class.obj(), factory_constructor, @@ -27,10 +27,10 @@ index f6a5046210..4ce5a79d25 100644 ScopedJavaLocalRef::Adopt( env, env->NewObject(factory_class.obj(), factory_constructor, diff --git a/sdk/android/BUILD.gn b/sdk/android/BUILD.gn -index 8ce74e2c8c..2e88760d0a 100644 +index 06fcf84a9d..627e204582 100644 --- a/sdk/android/BUILD.gn +++ b/sdk/android/BUILD.gn -@@ -1446,11 +1446,13 @@ if (current_os == "linux" || is_android) { +@@ -1493,11 +1493,13 @@ if (current_os == "linux" || is_android) { generate_jni("generated_environment_jni") { sources = [ "api/org/webrtc/Environment.java" ] namespace = "webrtc::jni" @@ -44,7 +44,7 @@ index 8ce74e2c8c..2e88760d0a 100644 } # Generated JNI for public JNI targets, matching order of targets -@@ -1464,6 +1466,7 @@ if (current_os == "linux" || is_android) { +@@ -1511,6 +1513,7 @@ if (current_os == "linux" || is_android) { "src/java/org/webrtc/JniCommon.java", ] namespace = "webrtc::jni" @@ -52,7 +52,7 @@ index 8ce74e2c8c..2e88760d0a 100644 } generate_jni("generated_video_jni") { -@@ -1493,11 +1496,13 @@ if (current_os == "linux" || is_android) { +@@ -1540,11 +1543,13 @@ if (current_os == "linux" || is_android) { "src/java/org/webrtc/WrappedNativeI420Buffer.java", ] namespace = "webrtc::jni" @@ -66,7 +66,7 @@ index 8ce74e2c8c..2e88760d0a 100644 } generate_jni("generated_libvpx_vp8_jni") { -@@ -1507,6 +1512,7 @@ if (current_os == "linux" || is_android) { +@@ -1554,6 +1559,7 @@ if (current_os == "linux" || is_android) { ] namespace = "webrtc::jni" @@ -74,7 +74,7 @@ index 8ce74e2c8c..2e88760d0a 100644 } generate_jni("generated_libvpx_vp9_jni") { -@@ -1516,18 +1522,21 @@ if (current_os == "linux" || is_android) { +@@ -1563,18 +1569,21 @@ if (current_os == "linux" || is_android) { ] namespace = "webrtc::jni" @@ -96,7 +96,7 @@ index 8ce74e2c8c..2e88760d0a 100644 } generate_jni("generated_swcodecs_jni") { -@@ -1537,11 +1546,13 @@ if (current_os == "linux" || is_android) { +@@ -1584,11 +1593,13 @@ if (current_os == "linux" || is_android) { ] namespace = "webrtc::jni" @@ -110,8 +110,8 @@ index 8ce74e2c8c..2e88760d0a 100644 } generate_jni("generated_peerconnection_jni") { -@@ -1585,11 +1596,13 @@ if (current_os == "linux" || is_android) { - "api/org/webrtc/TurnCustomizer.java", +@@ -1637,11 +1648,13 @@ if (current_os == "linux" || is_android) { + "api/org/webrtc/audio/AudioProcessingState.java", ] namespace = "webrtc::jni" + package_prefix = android_package_prefix @@ -124,7 +124,7 @@ index 8ce74e2c8c..2e88760d0a 100644 } generate_jni("generated_builtin_audio_codecs_jni") { -@@ -1598,6 +1611,7 @@ if (current_os == "linux" || is_android) { +@@ -1650,6 +1663,7 @@ if (current_os == "linux" || is_android) { "api/org/webrtc/BuiltinAudioEncoderFactoryFactory.java", ] namespace = "webrtc::jni" @@ -132,7 +132,7 @@ index 8ce74e2c8c..2e88760d0a 100644 } # Generated JNI for native API targets -@@ -1609,17 +1623,20 @@ if (current_os == "linux" || is_android) { +@@ -1661,17 +1675,20 @@ if (current_os == "linux" || is_android) { "src/java/org/webrtc/WebRtcClassLoader.java", ] namespace = "webrtc::jni" @@ -153,7 +153,7 @@ index 8ce74e2c8c..2e88760d0a 100644 } generate_jni("generated_java_audio_device_module_native_jni") { -@@ -1628,6 +1645,7 @@ if (current_os == "linux" || is_android) { +@@ -1680,6 +1697,7 @@ if (current_os == "linux" || is_android) { "src/java/org/webrtc/audio/WebRtcAudioTrack.java", ] namespace = "webrtc::jni" @@ -161,11 +161,19 @@ index 8ce74e2c8c..2e88760d0a 100644 } } +@@ -1937,6 +1955,7 @@ if (is_android) { + "native_unittests/org/webrtc/PeerConnectionFactoryInitializationHelper.java", + ] + namespace = "webrtc::jni" ++ package_prefix = android_package_prefix + } + + robolectric_binary("android_sdk_junit_tests") { diff --git a/sdk/android/api/org/webrtc/PeerConnectionFactory.java b/sdk/android/api/org/webrtc/PeerConnectionFactory.java -index 01679ad12b..7b8545902d 100644 +index 8cfa52b033..e878b80f36 100644 --- a/sdk/android/api/org/webrtc/PeerConnectionFactory.java +++ b/sdk/android/api/org/webrtc/PeerConnectionFactory.java -@@ -88,7 +88,7 @@ public class PeerConnectionFactory { +@@ -90,7 +90,7 @@ public class PeerConnectionFactory { private String fieldTrials = ""; private boolean enableInternalTracer; private NativeLibraryLoader nativeLibraryLoader = new NativeLibrary.DefaultLoader(); @@ -175,7 +183,7 @@ index 01679ad12b..7b8545902d 100644 @Nullable private Severity loggableSeverity; diff --git a/sdk/android/src/jni/jni_helpers.h b/sdk/android/src/jni/jni_helpers.h -index d86c8fa4ad..30f307a2ca 100644 +index 950190ece0..7d7b3618c7 100644 --- a/sdk/android/src/jni/jni_helpers.h +++ b/sdk/android/src/jni/jni_helpers.h @@ -29,10 +29,10 @@ @@ -225,10 +233,10 @@ index 2fbce97c60..130b3d5fa7 100755 def main(): diff --git a/webrtc.gni b/webrtc.gni -index 468ba33b01..ca81ce298c 100644 +index 0d2db4d1d6..2468184608 100644 --- a/webrtc.gni +++ b/webrtc.gni -@@ -241,6 +241,10 @@ declare_args() { +@@ -234,6 +234,10 @@ declare_args() { # hasn't been registered. rtc_strict_field_trials = "" @@ -240,7 +248,7 @@ index 468ba33b01..ca81ce298c 100644 # with this string. # See the definition of RTC_OBJC_TYPE_PREFIX in the code. diff --git a/third_party/jni_zero/BUILD.gn b/third_party/jni_zero/BUILD.gn -index 7056bdd033c1..2b97de476de7 100644 +index 58e0233e52..325b0e36c7 100644 --- a/third_party/jni_zero/BUILD.gn +++ b/third_party/jni_zero/BUILD.gn @@ -17,6 +17,7 @@ generate_jni("generate_jni") { @@ -250,12 +258,12 @@ index 7056bdd033c1..2b97de476de7 100644 + package_prefix = "livekit" } - generate_jar_jni("system_jni") { + # Common classes to save projects from having to generate them. diff --git a/third_party/jni_zero/codegen/header_common.py b/third_party/jni_zero/codegen/header_common.py -index 338cd748079f..be2577281a91 100644 +index 3967f94ed5..1f5cee6d81 100644 --- a/third_party/jni_zero/codegen/header_common.py +++ b/third_party/jni_zero/codegen/header_common.py -@@ -12,7 +12,8 @@ def class_accessors(sb, java_classes, module_name): +@@ -11,7 +11,8 @@ def class_accessors(sb, java_classes): for java_class in java_classes: if java_class in (java_types.OBJECT_CLASS, java_types.STRING_CLASS): continue @@ -265,7 +273,7 @@ index 338cd748079f..be2577281a91 100644 # #ifdef needed when multple .h files are #included that common classes. sb(f"""\ #ifndef {escaped_name}_clazz_defined -@@ -44,7 +45,7 @@ def class_accessor_expression(java_class): +@@ -42,7 +43,7 @@ def class_accessor_expression(java_class): if java_class == java_types.STRING_CLASS: return 'jni_zero::g_string_class' @@ -274,17 +282,20 @@ index 338cd748079f..be2577281a91 100644 def header_preamble(script_name, -@@ -53,7 +54,7 @@ def header_preamble(script_name, - user_includes=None, - header_guard=None): +@@ -53,9 +54,9 @@ def header_preamble(script_name, + is_shared_header=False): if header_guard is None: -- header_guard = f'{java_class.to_cpp()}_JNI' -+ header_guard = f'{java_class.class_without_prefix.to_cpp()}_JNI' + if is_shared_header: +- header_guard = f'{java_class.to_cpp()}_SHARED_JNI' ++ header_guard = f'{java_class.class_without_prefix.to_cpp()}_SHARED_JNI' + else: +- header_guard = f'{java_class.to_cpp()}_JNI' ++ header_guard = f'{java_class.class_without_prefix.to_cpp()}_JNI' sb = [] sb.append(f"""\ // This file was generated by diff --git a/third_party/jni_zero/jni_zero.gni b/third_party/jni_zero/jni_zero.gni -index 71826b906d10..22d8eaf6e232 100644 +index edc5364c59..40726f5cfb 100644 --- a/third_party/jni_zero/jni_zero.gni +++ b/third_party/jni_zero/jni_zero.gni @@ -123,7 +123,7 @@ template("_invoke_jni_zero") { @@ -296,7 +307,7 @@ index 71826b906d10..22d8eaf6e232 100644 # Example # generate_jni_registration("chrome_jni_registration") { # java_targets = [ ":chrome_public_apk" ] -@@ -327,6 +327,7 @@ template("generate_jni_impl") { +@@ -345,6 +347,7 @@ template("generate_jni_impl") { "deps", "metadata", "public_deps", @@ -304,14 +315,13 @@ index 71826b906d10..22d8eaf6e232 100644 ]) if (!defined(public_deps)) { public_deps = [] -@@ -421,7 +422,9 @@ template("generate_jni_impl") { - if (defined(invoker.split_name)) { - args += [ "--split-name=${invoker.split_name}" ] - } -- -+ if (defined(package_prefix)) { -+ args += [ "--package-prefix=${package_prefix}" ] -+ } - foreach(_name, _input_names) { - _name = - string_replace(get_path_info(_name, "name"), "\$", "__") + "_jni.h" +@@ -396,6 +399,9 @@ template("generate_jni_impl") { + if (defined(invoker.namespace)) { + args += [ "--namespace=${invoker.namespace}" ] + } ++ if (defined(package_prefix)) { ++ args += [ "--package-prefix=${package_prefix}" ] ++ } + if (defined(invoker.module_name)) { + args += [ "--module-name=${invoker.module_name}" ] + } diff --git a/webrtc-sys/libwebrtc/prefixed-jni/build.gradle b/webrtc-sys/libwebrtc/prefixed-jni/build.gradle index 9b8c5840f..14c33f6c6 100644 --- a/webrtc-sys/libwebrtc/prefixed-jni/build.gradle +++ b/webrtc-sys/libwebrtc/prefixed-jni/build.gradle @@ -1,11 +1,14 @@ plugins { id 'java-library' - id 'com.github.johnrengelman.shadow' version '7.1.2' + // com.gradleup.shadow is the maintained successor of com.github.johnrengelman.shadow. + // 7.1.2 bundled an ASM too old to read the Java 21 (major 65) bytecode that + // libwebrtc's libwebrtc.jar ships since m150. + id 'com.gradleup.shadow' version '9.6.1' } java { - sourceCompatibility = JavaVersion.VERSION_1_7 - targetCompatibility = JavaVersion.VERSION_1_7 + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 } dependencies { @@ -13,12 +16,8 @@ dependencies { } shadowJar { - -} -import com.github.jengelman.gradle.plugins.shadow.tasks.ConfigureShadowRelocation - -task relocateShadowJar(type: ConfigureShadowRelocation) { - target = tasks.shadowJar - prefix = "livekit" // Default value is "shadow" + // Replaces the old ConfigureShadowRelocation task: prefix every package in + // the merged jar with "livekit". + enableAutoRelocation = true + relocationPrefix = "livekit" } -tasks.shadowJar.dependsOn tasks.relocateShadowJar diff --git a/webrtc-sys/libwebrtc/prefixed-jni/gradle/wrapper/gradle-wrapper.properties b/webrtc-sys/libwebrtc/prefixed-jni/gradle/wrapper/gradle-wrapper.properties index c5c6e9b84..f30c2b908 100644 --- a/webrtc-sys/libwebrtc/prefixed-jni/gradle/wrapper/gradle-wrapper.properties +++ b/webrtc-sys/libwebrtc/prefixed-jni/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ #Thu Apr 29 14:50:17 JST 2021 distributionBase=GRADLE_USER_HOME -distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.6.1-bin.zip distributionPath=wrapper/dists zipStorePath=wrapper/dists zipStoreBase=GRADLE_USER_HOME From 11f6bd0cc3564416bb69f9b735be6917f9c63e6e Mon Sep 17 00:00:00 2001 From: CloudWebRTC Date: Tue, 28 Jul 2026 10:52:02 +0800 Subject: [PATCH 05/53] Create feat_upgrade_libwebrtc_to_m150.md --- .changeset/feat_upgrade_libwebrtc_to_m150.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/feat_upgrade_libwebrtc_to_m150.md diff --git a/.changeset/feat_upgrade_libwebrtc_to_m150.md b/.changeset/feat_upgrade_libwebrtc_to_m150.md new file mode 100644 index 000000000..625f04b53 --- /dev/null +++ b/.changeset/feat_upgrade_libwebrtc_to_m150.md @@ -0,0 +1,5 @@ +--- +webrtc-sys: patch +--- + +feat: upgrade libwebrtc to m150. - #1284 (@cloudwebrtc) From 49dbff12e19d4c03928508ea47fb8dae8e7f5910 Mon Sep 17 00:00:00 2001 From: cloudwebrtc Date: Tue, 28 Jul 2026 11:24:32 +0800 Subject: [PATCH 06/53] bump libwebrtc to webrtc-a970b87 (m150 pre-release). --- webrtc-sys/build/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webrtc-sys/build/src/lib.rs b/webrtc-sys/build/src/lib.rs index 4b07707df..8fc2f5cab 100644 --- a/webrtc-sys/build/src/lib.rs +++ b/webrtc-sys/build/src/lib.rs @@ -28,7 +28,7 @@ use regex::Regex; use reqwest::StatusCode; pub const SCRATH_PATH: &str = "livekit_webrtc"; -pub const WEBRTC_TAG: &str = "webrtc-51ef663"; +pub const WEBRTC_TAG: &str = "webrtc-a970b87"; pub const IGNORE_DEFINES: [&str; 2] = ["CR_CLANG_REVISION", "CR_XCODE_VERSION"]; pub fn target_os() -> String { From f4c43f28aa5976ded7282fc9e08df1ac538871d4 Mon Sep 17 00:00:00 2001 From: cloudwebrtc Date: Tue, 28 Jul 2026 12:10:15 +0800 Subject: [PATCH 07/53] fix ffi build. --- webrtc-sys/include/livekit/packet_trailer.h | 7 ++++--- webrtc-sys/include/livekit/packet_trailer_av1.h | 8 ++++---- webrtc-sys/src/packet_trailer.cpp | 12 ++++++------ webrtc-sys/src/packet_trailer_av1.cpp | 16 ++++++++-------- 4 files changed, 22 insertions(+), 21 deletions(-) diff --git a/webrtc-sys/include/livekit/packet_trailer.h b/webrtc-sys/include/livekit/packet_trailer.h index 4aa1261e4..0554d4fac 100644 --- a/webrtc-sys/include/livekit/packet_trailer.h +++ b/webrtc-sys/include/livekit/packet_trailer.h @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -102,7 +103,7 @@ struct PacketTrailerMetadata { /// /// Shared by the codec-agnostic trailer path and the AV1 OBU path. std::optional ParseTrailerPayload( - webrtc::ArrayView trailer); + std::span trailer); /// Frame transformer that appends/extracts packet trailers. /// This transformer can be used standalone or in conjunction with e2ee. @@ -193,7 +194,7 @@ class PacketTrailerTransformer : public webrtc::FrameTransformerInterface { /// Append frame metadata trailer to frame data std::vector AppendTrailer( - webrtc::ArrayView data, + std::span data, uint64_t user_timestamp, uint32_t frame_id, const std::vector& user_data, @@ -201,7 +202,7 @@ class PacketTrailerTransformer : public webrtc::FrameTransformerInterface { /// Extract and remove frame metadata trailer from frame data std::optional ExtractTrailer( - webrtc::ArrayView data, + std::span data, std::vector& out_data, bool is_av1); diff --git a/webrtc-sys/include/livekit/packet_trailer_av1.h b/webrtc-sys/include/livekit/packet_trailer_av1.h index dabbb9740..f2cfe4f8d 100644 --- a/webrtc-sys/include/livekit/packet_trailer_av1.h +++ b/webrtc-sys/include/livekit/packet_trailer_av1.h @@ -18,9 +18,9 @@ #include #include +#include #include -#include "api/array_view.h" #include "api/frame_transformer_interface.h" #include "livekit/packet_trailer.h" @@ -36,8 +36,8 @@ bool IsAv1Frame(const webrtc::TransformableFrameInterface& frame); /// [`PacketTrailerTransformer`]). The OBU is placed after any temporal /// delimiter and sequence header OBUs so it is not mistaken for frame data. std::vector InsertTrailerObu( - webrtc::ArrayView data, - webrtc::ArrayView trailer); + std::span data, + std::span trailer); /// Extracts and removes a LiveKit packet-trailer metadata OBU from an AV1 /// temporal unit. @@ -46,7 +46,7 @@ std::vector InsertTrailerObu( /// frame data with the metadata OBU removed. Otherwise `out_data` receives /// an unchanged copy of `data` and `std::nullopt` is returned. std::optional ExtractTrailer( - webrtc::ArrayView data, + std::span data, std::vector& out_data); } // namespace av1 diff --git a/webrtc-sys/src/packet_trailer.cpp b/webrtc-sys/src/packet_trailer.cpp index 6dbeabaeb..20135a700 100644 --- a/webrtc-sys/src/packet_trailer.cpp +++ b/webrtc-sys/src/packet_trailer.cpp @@ -121,7 +121,7 @@ std::vector BuildTrailerPayload(uint64_t user_timestamp, } // namespace std::optional ParseTrailerPayload( - webrtc::ArrayView trailer) { + std::span trailer) { if (trailer.size() < kTrailerEnvelopeSize) { return std::nullopt; } @@ -245,7 +245,7 @@ void PacketTrailerTransformer::TransformSend( new_data = AppendTrailer(data, meta_to_embed.user_timestamp, meta_to_embed.frame_id, meta_to_embed.user_data, is_av1); - frame->SetData(webrtc::ArrayView(new_data)); + frame->SetData(std::span(new_data)); } // Forward to the appropriate callback (either global or per-SSRC sink). @@ -352,7 +352,7 @@ void PacketTrailerTransformer::TransformReceive( } // Update frame with stripped data - frame->SetData(webrtc::ArrayView(stripped_data)); + frame->SetData(std::span(stripped_data)); } uint64_t receive_timestamp_us = subscribe_timing_enabled() ? CurrentUnixTimeMicros() : 0; @@ -384,7 +384,7 @@ void PacketTrailerTransformer::TransformReceive( } std::vector PacketTrailerTransformer::AppendTrailer( - webrtc::ArrayView data, + std::span data, uint64_t user_timestamp, uint32_t frame_id, const std::vector& user_data, @@ -410,7 +410,7 @@ std::vector PacketTrailerTransformer::AppendTrailer( } std::optional PacketTrailerTransformer::ExtractTrailer( - webrtc::ArrayView data, + std::span data, std::vector& out_data, bool is_av1) { if (is_av1) { @@ -439,7 +439,7 @@ std::optional PacketTrailerTransformer::ExtractTrailer( // Walk the TLV region: everything from trailer_start up to the envelope. const uint8_t* trailer_start = data.data() + data.size() - trailer_len; auto meta = ParseTrailerPayload( - webrtc::ArrayView(trailer_start, trailer_len)); + std::span(trailer_start, trailer_len)); if (!meta.has_value()) { out_data.assign(data.begin(), data.end()); return std::nullopt; diff --git a/webrtc-sys/src/packet_trailer_av1.cpp b/webrtc-sys/src/packet_trailer_av1.cpp index c1349feb7..872aa939e 100644 --- a/webrtc-sys/src/packet_trailer_av1.cpp +++ b/webrtc-sys/src/packet_trailer_av1.cpp @@ -42,7 +42,7 @@ void WriteLeb128(uint64_t value, std::vector& out) { out.push_back(static_cast(value)); } -bool ReadLeb128(webrtc::ArrayView data, +bool ReadLeb128(std::span data, size_t& pos, uint64_t& value) { value = 0; @@ -62,7 +62,7 @@ bool ReadLeb128(webrtc::ArrayView data, } std::vector BuildMetadataObu( - webrtc::ArrayView trailer) { + std::span trailer) { std::vector metadata_payload; WriteLeb128(kAv1MetadataTypeLiveKitPacketTrailer, metadata_payload); metadata_payload.insert(metadata_payload.end(), trailer.begin(), trailer.end()); @@ -76,7 +76,7 @@ std::vector BuildMetadataObu( return obu; } -size_t FindMetadataInsertOffset(webrtc::ArrayView data) { +size_t FindMetadataInsertOffset(std::span data) { size_t pos = 0; size_t insert_offset = 0; @@ -138,8 +138,8 @@ bool IsAv1Frame(const webrtc::TransformableFrameInterface& frame) { } std::vector InsertTrailerObu( - webrtc::ArrayView data, - webrtc::ArrayView trailer) { + std::span data, + std::span trailer) { std::vector obu = BuildMetadataObu(trailer); if (data.empty()) { return obu; @@ -155,7 +155,7 @@ std::vector InsertTrailerObu( } std::optional ExtractTrailer( - webrtc::ArrayView data, + std::span data, std::vector& out_data) { std::vector stripped_data; stripped_data.reserve(data.size()); @@ -193,13 +193,13 @@ std::optional ExtractTrailer( const size_t obu_end = payload_start + payload_size; if (obu_type == kAv1ObuTypeMetadata) { - auto metadata_payload = data.subview(payload_start, obu_end - payload_start); + auto metadata_payload = data.subspan(payload_start, obu_end - payload_start); size_t metadata_pos = 0; uint64_t metadata_type = 0; if (ReadLeb128(metadata_payload, metadata_pos, metadata_type) && metadata_type == kAv1MetadataTypeLiveKitPacketTrailer && metadata_pos <= metadata_payload.size()) { - auto trailer_payload = metadata_payload.subview( + auto trailer_payload = metadata_payload.subspan( metadata_pos, metadata_payload.size() - metadata_pos); if (auto meta = ParseTrailerPayload(trailer_payload)) { stripped_data.insert(stripped_data.end(), data.begin() + obu_end, From b216c99ebbfce2a82d06da08d60367d9f540b962 Mon Sep 17 00:00:00 2001 From: cloudwebrtc Date: Tue, 28 Jul 2026 12:55:29 +0800 Subject: [PATCH 08/53] fix h264 compile. --- webrtc-sys/src/jetson/h264_encoder_impl.cpp | 3 +-- webrtc-sys/src/nvidia/h264_encoder_impl.cpp | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/webrtc-sys/src/jetson/h264_encoder_impl.cpp b/webrtc-sys/src/jetson/h264_encoder_impl.cpp index bef7e5012..45539745f 100644 --- a/webrtc-sys/src/jetson/h264_encoder_impl.cpp +++ b/webrtc-sys/src/jetson/h264_encoder_impl.cpp @@ -335,8 +335,7 @@ int32_t JetsonH264EncoderImpl::ProcessEncodedFrame( : VideoFrameType::kVideoFrameDelta; encoded_image_.SetColorSpace(input_frame.color_space()); - std::vector nalu_indices = - H264::FindNaluIndices(MakeArrayView(packet.data(), packet.size())); + std::vector nalu_indices = H264::FindNaluIndices(packet); for (uint32_t i = 0; i < nalu_indices.size(); i++) { const H264::NaluType nalu_type = H264::ParseNaluType(packet[nalu_indices[i].payload_start_offset]); diff --git a/webrtc-sys/src/nvidia/h264_encoder_impl.cpp b/webrtc-sys/src/nvidia/h264_encoder_impl.cpp index bc56f8264..d2a64ad10 100644 --- a/webrtc-sys/src/nvidia/h264_encoder_impl.cpp +++ b/webrtc-sys/src/nvidia/h264_encoder_impl.cpp @@ -372,8 +372,7 @@ int32_t NvidiaH264EncoderImpl::ProcessEncodedFrame( encoded_image_.timing_.flags = VideoSendTiming::kInvalid; encoded_image_._frameType = VideoFrameType::kVideoFrameDelta; encoded_image_.SetColorSpace(inputFrame.color_space()); - std::vector naluIndices = - H264::FindNaluIndices(MakeArrayView(packet.data(), packet.size())); + std::vector naluIndices = H264::FindNaluIndices(packet); for (uint32_t i = 0; i < naluIndices.size(); i++) { const H264::NaluType naluType = H264::ParseNaluType(packet[naluIndices[i].payload_start_offset]); From 2ebb2bc3fbd8b0ba4021fa0c68cfa8bda5072124 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 28 Jul 2026 05:18:44 +0000 Subject: [PATCH 09/53] fix: use libyuv directly in yuv_helper.h to fix win-arm64 linker errors The webrtc::I420ToARGB etc. symbols from api/video/yuv_helper.h were not present in the webrtc.lib for aarch64-pc-windows-msvc, causing 22 linker errors. Replace the webrtc:: namespace wrappers with direct libyuv:: calls using third_party/libyuv/include/libyuv.h, which is already in the include path and whose symbols are always compiled into webrtc.lib. Also removes the erroneous duplicate i420_to_nv12 overload that incorrectly called NV12ToI420 instead of I420ToNV12. --- webrtc-sys/include/livekit/yuv_helper.h | 63 +++++++++---------------- 1 file changed, 23 insertions(+), 40 deletions(-) diff --git a/webrtc-sys/include/livekit/yuv_helper.h b/webrtc-sys/include/livekit/yuv_helper.h index 9e4d0b637..377067d8b 100644 --- a/webrtc-sys/include/livekit/yuv_helper.h +++ b/webrtc-sys/include/livekit/yuv_helper.h @@ -20,7 +20,7 @@ #include #include -#include "api/video/yuv_helper.h" +#include "third_party/libyuv/include/libyuv.h" #include "webrtc-sys/src/yuv_helper.rs.h" namespace livekit_ffi { @@ -40,7 +40,7 @@ static void i420_to_argb(const uint8_t* src_y, int dst_stride_argb, int width, int height) { - THROW_ON_ERROR(webrtc::I420ToARGB(src_y, src_stride_y, src_u, src_stride_u, + THROW_ON_ERROR(libyuv::I420ToARGB(src_y, src_stride_y, src_u, src_stride_u, src_v, src_stride_v, dst_argb, dst_stride_argb, width, height)); } @@ -55,7 +55,7 @@ static void i420_to_bgra(const uint8_t* src_y, int dst_stride_bgra, int width, int height) { - THROW_ON_ERROR(webrtc::I420ToBGRA(src_y, src_stride_y, src_u, src_stride_u, + THROW_ON_ERROR(libyuv::I420ToBGRA(src_y, src_stride_y, src_u, src_stride_u, src_v, src_stride_v, dst_bgra, dst_stride_bgra, width, height)); } @@ -70,7 +70,7 @@ static void i420_to_abgr(const uint8_t* src_y, int dst_stride_abgr, int width, int height) { - THROW_ON_ERROR(webrtc::I420ToABGR(src_y, src_stride_y, src_u, src_stride_u, + THROW_ON_ERROR(libyuv::I420ToABGR(src_y, src_stride_y, src_u, src_stride_u, src_v, src_stride_v, dst_abgr, dst_stride_abgr, width, height)); } @@ -85,7 +85,7 @@ static void i420_to_rgba(const uint8_t* src_y, int dst_stride_rgba, int width, int height) { - THROW_ON_ERROR(webrtc::I420ToRGBA(src_y, src_stride_y, src_u, src_stride_u, + THROW_ON_ERROR(libyuv::I420ToRGBA(src_y, src_stride_y, src_u, src_stride_u, src_v, src_stride_v, dst_rgba, dst_stride_rgba, width, height)); } @@ -100,7 +100,7 @@ static void argb_to_i420(const uint8_t* src_argb, int dst_stride_v, int width, int height) { - THROW_ON_ERROR(webrtc::ARGBToI420(src_argb, src_stride_argb, dst_y, + THROW_ON_ERROR(libyuv::ARGBToI420(src_argb, src_stride_argb, dst_y, dst_stride_y, dst_u, dst_stride_u, dst_v, dst_stride_v, width, height)); } @@ -115,7 +115,7 @@ static void abgr_to_i420(const uint8_t* src_abgr, int dst_stride_v, int width, int height) { - THROW_ON_ERROR(webrtc::ABGRToI420(src_abgr, src_stride_abgr, dst_y, + THROW_ON_ERROR(libyuv::ABGRToI420(src_abgr, src_stride_abgr, dst_y, dst_stride_y, dst_u, dst_stride_u, dst_v, dst_stride_v, width, height)); } @@ -126,7 +126,7 @@ static void argb_to_rgb24(const uint8_t* src_argb, int dst_stride_rgb24, int width, int height) { - THROW_ON_ERROR(webrtc::ARGBToRGB24(src_argb, src_stride_argb, dst_rgb24, + THROW_ON_ERROR(libyuv::ARGBToRGB24(src_argb, src_stride_argb, dst_rgb24, dst_stride_rgb24, width, height)); } @@ -142,7 +142,7 @@ static void i420_to_nv12(const uint8_t* src_y, int dst_stride_uv, int width, int height) { - THROW_ON_ERROR(webrtc::I420ToNV12(src_y, src_stride_y, src_u, src_stride_u, + THROW_ON_ERROR(libyuv::I420ToNV12(src_y, src_stride_y, src_u, src_stride_u, src_v, src_stride_v, dst_y, dst_stride_y, dst_uv, dst_stride_uv, width, height)); } @@ -159,28 +159,11 @@ static void nv12_to_i420(const uint8_t* src_y, int dst_stride_v, int width, int height) { - THROW_ON_ERROR(webrtc::NV12ToI420(src_y, src_stride_y, src_uv, src_stride_uv, + THROW_ON_ERROR(libyuv::NV12ToI420(src_y, src_stride_y, src_uv, src_stride_uv, dst_y, dst_stride_y, dst_u, dst_stride_u, dst_v, dst_stride_v, width, height)); } -static void i420_to_nv12(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - uint8_t* src_v, - int src_stride_v, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_uv, - int dst_stride_uv, - int width, - int height) { - THROW_ON_ERROR(webrtc::NV12ToI420(src_y, src_stride_y, src_u, src_stride_u, - src_v, src_stride_v, dst_y, dst_stride_y, - dst_uv, dst_stride_uv, width, height)); -} - static void i444_to_i420(const uint8_t* src_y, int src_stride_y, const uint8_t* src_u, @@ -195,7 +178,7 @@ static void i444_to_i420(const uint8_t* src_y, int dst_stride_v, int width, int height) { - THROW_ON_ERROR(webrtc::I444ToI420( + THROW_ON_ERROR(libyuv::I444ToI420( src_y, src_stride_y, src_u, src_stride_u, src_v, src_stride_v, dst_y, dst_stride_y, dst_u, dst_stride_u, dst_v, dst_stride_v, width, height)); } @@ -214,7 +197,7 @@ static void i422_to_i420(const uint8_t* src_y, int dst_stride_v, int width, int height) { - THROW_ON_ERROR(webrtc::I422ToI420( + THROW_ON_ERROR(libyuv::I422ToI420( src_y, src_stride_y, src_u, src_stride_u, src_v, src_stride_v, dst_y, dst_stride_y, dst_u, dst_stride_u, dst_v, dst_stride_v, width, height)); } @@ -233,7 +216,7 @@ static void i010_to_i420(const uint16_t* src_y, int dst_stride_v, int width, int height) { - THROW_ON_ERROR(webrtc::I010ToI420( + THROW_ON_ERROR(libyuv::I010ToI420( src_y, src_stride_y, src_u, src_stride_u, src_v, src_stride_v, dst_y, dst_stride_y, dst_u, dst_stride_u, dst_v, dst_stride_v, width, height)); } @@ -246,7 +229,7 @@ static void nv12_to_argb(const uint8_t* src_y, int dst_stride_argb, int width, int height) { - THROW_ON_ERROR(webrtc::NV12ToARGB(src_y, src_stride_y, src_uv, src_stride_uv, + THROW_ON_ERROR(libyuv::NV12ToARGB(src_y, src_stride_y, src_uv, src_stride_uv, dst_argb, dst_stride_argb, width, height)); } @@ -258,7 +241,7 @@ static void nv12_to_abgr(const uint8_t* src_y, int dst_stride_abgr, int width, int height) { - THROW_ON_ERROR(webrtc::NV12ToABGR(src_y, src_stride_y, src_uv, src_stride_uv, + THROW_ON_ERROR(libyuv::NV12ToABGR(src_y, src_stride_y, src_uv, src_stride_uv, dst_abgr, dst_stride_abgr, width, height)); } @@ -272,7 +255,7 @@ static void i444_to_argb(const uint8_t* src_y, int dst_stride_abgr, int width, int height) { - THROW_ON_ERROR(webrtc::I444ToARGB(src_y, src_stride_y, src_u, src_stride_u, + THROW_ON_ERROR(libyuv::I444ToARGB(src_y, src_stride_y, src_u, src_stride_u, src_v, src_stride_v, dst_abgr, dst_stride_abgr, width, height)); } @@ -287,7 +270,7 @@ static void i444_to_abgr(const uint8_t* src_y, int dst_stride_abgr, int width, int height) { - THROW_ON_ERROR(webrtc::I444ToABGR(src_y, src_stride_y, src_u, src_stride_u, + THROW_ON_ERROR(libyuv::I444ToABGR(src_y, src_stride_y, src_u, src_stride_u, src_v, src_stride_v, dst_abgr, dst_stride_abgr, width, height)); } @@ -302,7 +285,7 @@ static void i422_to_argb(const uint8_t* src_y, int dst_stride_argb, int width, int height) { - THROW_ON_ERROR(webrtc::I422ToARGB(src_y, src_stride_y, src_u, src_stride_u, + THROW_ON_ERROR(libyuv::I422ToARGB(src_y, src_stride_y, src_u, src_stride_u, src_v, src_stride_v, dst_argb, dst_stride_argb, width, height)); } @@ -317,7 +300,7 @@ static void i422_to_abgr(const uint8_t* src_y, int dst_stride_abgr, int width, int height) { - THROW_ON_ERROR(webrtc::I422ToABGR(src_y, src_stride_y, src_u, src_stride_u, + THROW_ON_ERROR(libyuv::I422ToABGR(src_y, src_stride_y, src_u, src_stride_u, src_v, src_stride_v, dst_abgr, dst_stride_abgr, width, height)); } @@ -332,7 +315,7 @@ static void i010_to_argb(const uint16_t* src_y, int dst_stride_argb, int width, int height) { - THROW_ON_ERROR(webrtc::I010ToARGB(src_y, src_stride_y, src_u, src_stride_u, + THROW_ON_ERROR(libyuv::I010ToARGB(src_y, src_stride_y, src_u, src_stride_u, src_v, src_stride_v, dst_argb, dst_stride_argb, width, height)); } @@ -347,7 +330,7 @@ static void i010_to_abgr(const uint16_t* src_y, int dst_stride_abgr, int width, int height) { - THROW_ON_ERROR(webrtc::I010ToABGR(src_y, src_stride_y, src_u, src_stride_u, + THROW_ON_ERROR(libyuv::I010ToABGR(src_y, src_stride_y, src_u, src_stride_u, src_v, src_stride_v, dst_abgr, dst_stride_abgr, width, height)); } @@ -360,7 +343,7 @@ static void abgr_to_nv12(const uint8_t* src_abgr, int dst_stride_uv, int width, int height) { - THROW_ON_ERROR(webrtc::ABGRToNV12(src_abgr, src_stride_abgr, dst_y, + THROW_ON_ERROR(libyuv::ABGRToNV12(src_abgr, src_stride_abgr, dst_y, dst_stride_y, dst_uv, dst_stride_uv, width, height)); } @@ -373,7 +356,7 @@ static void argb_to_nv12(const uint8_t* src_argb, int dst_stride_uv, int width, int height) { - THROW_ON_ERROR(webrtc::ARGBToNV12(src_argb, src_stride_argb, dst_y, + THROW_ON_ERROR(libyuv::ARGBToNV12(src_argb, src_stride_argb, dst_y, dst_stride_y, dst_uv, dst_stride_uv, width, height)); } From 7bc323e7a93c806ab725f634e49bf32fb9368a8a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 28 Jul 2026 08:21:50 +0000 Subject: [PATCH 10/53] fix: revert use_custom_libcxx=false in build_linux.sh to fix Linux linker errors The pre-built libwebrtc.a at webrtc-a970b87 was compiled with use_custom_libcxx=true (Chromium's libc++ with ABI namespace std::__Cr::), making it ABI-incompatible with GCC/libstdc++ (std::__cxx11:: / std::). Every linker error in CI was caused by this mismatch, e.g.: SdpVideoFormat(std::__Cr::basic_string const&) [in library] SdpVideoFormat(std::__cxx11::basic_string const&) [called by our code] Revert to use_custom_libcxx=false so the library links with the system libstdc++, matching the GCC compilation used by our SDK build. The library must be rebuilt at a new webrtc-* tag for this fix to take effect in CI. After the rebuild, update WEBRTC_TAG in build/src/lib.rs. --- webrtc-sys/libwebrtc/build_linux.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webrtc-sys/libwebrtc/build_linux.sh b/webrtc-sys/libwebrtc/build_linux.sh index 25a9c1d02..62d678bf3 100755 --- a/webrtc-sys/libwebrtc/build_linux.sh +++ b/webrtc-sys/libwebrtc/build_linux.sh @@ -113,7 +113,7 @@ args="is_debug=$debug \ rtc_enable_protobuf=false \ treat_warnings_as_errors=false \ use_llvm_libatomic=false \ - use_custom_libcxx=true \ + use_custom_libcxx=false \ use_custom_libcxx_for_host=false \ use_clang_modules=false \ rtc_include_tests=false \ From ffd1d5a9ce5d03458880007d8549939303d51e3f Mon Sep 17 00:00:00 2001 From: cloudwebrtc Date: Tue, 28 Jul 2026 17:21:15 +0800 Subject: [PATCH 11/53] fix build issue on linux. --- webrtc-sys/libwebrtc/build_linux.sh | 6 ++- .../fix_copy_on_write_buffer_compile.patch | 16 +++++++ .../patches/fix_desktop_capture_compile.patch | 47 +++++++++++++++---- .../fix_payload_type_picker_compile.patch | 22 +++++++++ .../patches/fix_pipewire_utils_compile.patch | 27 +++++++++++ .../fix_ssl_stream_adapter_compile.patch | 21 +++++++++ 6 files changed, 129 insertions(+), 10 deletions(-) create mode 100644 webrtc-sys/libwebrtc/patches/fix_copy_on_write_buffer_compile.patch create mode 100644 webrtc-sys/libwebrtc/patches/fix_payload_type_picker_compile.patch create mode 100644 webrtc-sys/libwebrtc/patches/fix_pipewire_utils_compile.patch create mode 100644 webrtc-sys/libwebrtc/patches/fix_ssl_stream_adapter_compile.patch diff --git a/webrtc-sys/libwebrtc/build_linux.sh b/webrtc-sys/libwebrtc/build_linux.sh index 62d678bf3..b1a24154f 100755 --- a/webrtc-sys/libwebrtc/build_linux.sh +++ b/webrtc-sys/libwebrtc/build_linux.sh @@ -75,8 +75,12 @@ git apply "$COMMAND_DIR/patches/add_licenses.patch" -v --ignore-space-change --i git apply "$COMMAND_DIR/patches/fix_license_json_parsing.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn git apply "$COMMAND_DIR/patches/ssl_verify_callback_with_native_handle.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn git apply "$COMMAND_DIR/patches/add_deps.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn -#git apply "$COMMAND_DIR/patches/fix_desktop_capture_compile.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn +git apply "$COMMAND_DIR/patches/fix_desktop_capture_compile.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn git apply "$COMMAND_DIR/patches/external_audio_source.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn +git apply "$COMMAND_DIR/patches/fix_payload_type_picker_compile.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn +git apply "$COMMAND_DIR/patches/fix_pipewire_utils_compile.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn +git apply "$COMMAND_DIR/patches/fix_ssl_stream_adapter_compile.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn +git apply "$COMMAND_DIR/patches/fix_copy_on_write_buffer_compile.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn # Disable CREL (compact relocations). Chromium's build enables experimental # CREL via -Wa,--crel which causes segfaults on aarch64-linux (and is known diff --git a/webrtc-sys/libwebrtc/patches/fix_copy_on_write_buffer_compile.patch b/webrtc-sys/libwebrtc/patches/fix_copy_on_write_buffer_compile.patch new file mode 100644 index 000000000..2e50572bc --- /dev/null +++ b/webrtc-sys/libwebrtc/patches/fix_copy_on_write_buffer_compile.patch @@ -0,0 +1,16 @@ +diff --git a/rtc_base/copy_on_write_buffer.cc b/rtc_base/copy_on_write_buffer.cc +index 68e98ce729..c314d8b123 100644 +--- a/rtc_base/copy_on_write_buffer.cc ++++ b/rtc_base/copy_on_write_buffer.cc +@@ -28,7 +28,10 @@ + namespace webrtc { + + CopyOnWriteBuffer::RawBuffer::RawBuffer(size_t size) +- : size_(size), data_(std::make_unique_for_overwrite(size)) {} ++ // std::make_unique_for_overwrite needs a C++20 standard library ++ // (libstdc++ >= 11). `new T[n]` default-initializes, which is the same ++ // "leave the bytes uninitialized" semantics. ++ : size_(size), data_(new uint8_t[size]) {} + + scoped_refptr + CopyOnWriteBuffer::CreateBuffer(size_t capacity) { diff --git a/webrtc-sys/libwebrtc/patches/fix_desktop_capture_compile.patch b/webrtc-sys/libwebrtc/patches/fix_desktop_capture_compile.patch index 634b69c17..c663b8966 100644 --- a/webrtc-sys/libwebrtc/patches/fix_desktop_capture_compile.patch +++ b/webrtc-sys/libwebrtc/patches/fix_desktop_capture_compile.patch @@ -1,17 +1,46 @@ diff --git a/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc b/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc -index 070257f072..61fd0c8f3b 100644 +index 7366fd5b73..d23505877a 100644 --- a/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc +++ b/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc -@@ -71,10 +71,10 @@ constexpr int CursorMetaSize(int w, int h) { - w * h * kCursorBpp); +@@ -74,12 +74,15 @@ constexpr int CursorMetaSize(int w, int h) { + w * h * kBytesPerPixel); } -constexpr PipeWireVersion kDmaBufModifierMinVersion = {.major = 0, -+const PipeWireVersion kDmaBufModifierMinVersion = {.major = 0, - .minor = 3, - .micro = 33}; +- .minor = 3, +- .micro = 33}; -constexpr PipeWireVersion kDropSingleModifierMinVersion = {.major = 0, -+const PipeWireVersion kDropSingleModifierMinVersion = {.major = 0, - .minor = 3, - .micro = 40}; +- .minor = 3, +- .micro = 40}; ++// Not constexpr constants: PipeWireVersion holds a std::string, so it is only ++// a literal type with a C++20 standard library (libstdc++ >= 12), and ++// namespace-scope instances would need static initializers. ++PipeWireVersion DmaBufModifierMinVersion() { ++ return {.major = 0, .minor = 3, .micro = 33}; ++} ++PipeWireVersion DropSingleModifierMinVersion() { ++ return {.major = 0, .minor = 3, .micro = 40}; ++} + class SharedScreenCastStreamPrivate { + public: +@@ -558,8 +561,8 @@ bool SharedScreenCastStreamPrivate::StartScreenCastStream( + + // Modifiers can be used with PipeWire >= 0.3.33 + const bool has_dmabuf_support = +- egl_dmabuf_ && pw_client_version_ >= kDmaBufModifierMinVersion && +- pw_server_version_ >= kDmaBufModifierMinVersion; ++ egl_dmabuf_ && pw_client_version_ >= DmaBufModifierMinVersion() && ++ pw_server_version_ >= DmaBufModifierMinVersion(); + + struct spa_fraction default_frame_rate = SPA_FRACTION(frame_rate_, 1); + struct spa_rectangle resolution; +@@ -1084,7 +1087,7 @@ bool SharedScreenCastStreamPrivate::ProcessDMABuffer( + spa_video_format_.format) + << "), marking as failed and renegotiating stream parameters"; + +- if (pw_server_version_ >= kDropSingleModifierMinVersion) { ++ if (pw_server_version_ >= DropSingleModifierMinVersion()) { + render_device->MarkModifierFailed(spa_video_format_.format, modifier_); + } else { + // For older PipeWire versions, mark all modifiers as failed for this diff --git a/webrtc-sys/libwebrtc/patches/fix_payload_type_picker_compile.patch b/webrtc-sys/libwebrtc/patches/fix_payload_type_picker_compile.patch new file mode 100644 index 000000000..89e939c01 --- /dev/null +++ b/webrtc-sys/libwebrtc/patches/fix_payload_type_picker_compile.patch @@ -0,0 +1,22 @@ +diff --git a/call/payload_type_picker.cc b/call/payload_type_picker.cc +index 45105a1054..d12c3b34e2 100644 +--- a/call/payload_type_picker.cc ++++ b/call/payload_type_picker.cc +@@ -370,7 +370,7 @@ void PayloadTypeRecorder::Rollback() { + RTCError RtpHeaderExtensionRecorder::AddMapping(RtpHeaderExtensionId id, + absl::string_view uri, + bool encrypt) { +- auto it = uri_to_id_.find(std::pair{uri, encrypt}); ++ auto it = uri_to_id_.find(std::pair{std::string(uri), encrypt}); + if (it != uri_to_id_.end()) { + if (it->second != id) { + RTC_HISTOGRAM_BOOLEAN( +@@ -393,7 +393,7 @@ RTCError RtpHeaderExtensionRecorder::AddMapping(RtpHeaderExtensionId id, + RTCErrorOr RtpHeaderExtensionRecorder::LookupId( + absl::string_view uri, + bool encrypt) const { +- auto it = uri_to_id_.find(std::pair{uri, encrypt}); ++ auto it = uri_to_id_.find(std::pair{std::string(uri), encrypt}); + if (it == uri_to_id_.end()) { + return RTCError(RTCErrorType::INVALID_PARAMETER, + "No ID found for extension"); diff --git a/webrtc-sys/libwebrtc/patches/fix_pipewire_utils_compile.patch b/webrtc-sys/libwebrtc/patches/fix_pipewire_utils_compile.patch new file mode 100644 index 000000000..29663b9bd --- /dev/null +++ b/webrtc-sys/libwebrtc/patches/fix_pipewire_utils_compile.patch @@ -0,0 +1,27 @@ +diff --git a/modules/portal/pipewire_utils.cc b/modules/portal/pipewire_utils.cc +index 850726cc58..cfa30307be 100644 +--- a/modules/portal/pipewire_utils.cc ++++ b/modules/portal/pipewire_utils.cc +@@ -28,10 +28,6 @@ + + namespace webrtc { + +-constexpr PipeWireVersion kReentrantDeinitMinVersion = {.major = 0, +- .minor = 3, +- .micro = 49}; +- + PipeWireVersion PipeWireVersion::Parse(const std::string_view& version) { + std::vector parsed_version = split(version, '.'); + +@@ -104,6 +100,11 @@ PipeWireInitializer::PipeWireInitializer() { + + RTC_NO_SANITIZE("cfi-icall") + PipeWireInitializer::~PipeWireInitializer() { ++ // Not constexpr/global: PipeWireVersion holds a std::string, so it is only a ++ // literal type with a C++20 standard library (libstdc++ >= 12), and a ++ // namespace-scope instance would need a static initializer. ++ const PipeWireVersion kReentrantDeinitMinVersion = { ++ .major = 0, .minor = 3, .micro = 49}; + PipeWireVersion pw_client_version = + PipeWireVersion::Parse(pw_get_library_version()); + if (pw_client_version >= kReentrantDeinitMinVersion) { diff --git a/webrtc-sys/libwebrtc/patches/fix_ssl_stream_adapter_compile.patch b/webrtc-sys/libwebrtc/patches/fix_ssl_stream_adapter_compile.patch new file mode 100644 index 000000000..c04ee0a09 --- /dev/null +++ b/webrtc-sys/libwebrtc/patches/fix_ssl_stream_adapter_compile.patch @@ -0,0 +1,21 @@ +diff --git a/rtc_base/ssl_stream_adapter.h b/rtc_base/ssl_stream_adapter.h +index 0568bd0310..7052a0dbf4 100644 +--- a/rtc_base/ssl_stream_adapter.h ++++ b/rtc_base/ssl_stream_adapter.h +@@ -14,6 +14,7 @@ + #include + #include + ++#include + #include + #include + #include +@@ -129,7 +130,7 @@ class SSLStreamAdapter : public StreamInterface { + static std::unique_ptr Create( + std::unique_ptr stream, + absl::AnyInvocable handshake_error, +- nullptr_t /*field_trials*/) { ++ std::nullptr_t /*field_trials*/) { + return Create(std::move(stream), std::move(handshake_error)); + } + From 1b652e9772ff85e5271c9ead2d8ec570afd5f555 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 28 Jul 2026 09:24:35 +0000 Subject: [PATCH 12/53] chore: update changeset to cover all affected packages --- .changeset/feat_upgrade_libwebrtc_to_m150.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.changeset/feat_upgrade_libwebrtc_to_m150.md b/.changeset/feat_upgrade_libwebrtc_to_m150.md index 625f04b53..4bb54060d 100644 --- a/.changeset/feat_upgrade_libwebrtc_to_m150.md +++ b/.changeset/feat_upgrade_libwebrtc_to_m150.md @@ -1,5 +1,9 @@ --- +libwebrtc: patch +livekit: patch +livekit-ffi: patch webrtc-sys: patch +webrtc-sys-build: patch --- feat: upgrade libwebrtc to m150. - #1284 (@cloudwebrtc) From 27a5748e3f7234d09315edcc08c1b39bd5cd7e08 Mon Sep 17 00:00:00 2001 From: CloudWebRTC Date: Tue, 28 Jul 2026 19:25:09 +0800 Subject: [PATCH 13/53] Update WEBRTC_TAG constant to new version --- webrtc-sys/build/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webrtc-sys/build/src/lib.rs b/webrtc-sys/build/src/lib.rs index 8fc2f5cab..c0e858bfc 100644 --- a/webrtc-sys/build/src/lib.rs +++ b/webrtc-sys/build/src/lib.rs @@ -28,7 +28,7 @@ use regex::Regex; use reqwest::StatusCode; pub const SCRATH_PATH: &str = "livekit_webrtc"; -pub const WEBRTC_TAG: &str = "webrtc-a970b87"; +pub const WEBRTC_TAG: &str = "webrtc-a970b87-2"; pub const IGNORE_DEFINES: [&str; 2] = ["CR_CLANG_REVISION", "CR_XCODE_VERSION"]; pub fn target_os() -> String { From d1b7fdbdb2b7e479f45aa5ceec1d3ac90fe83d43 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 28 Jul 2026 11:50:13 +0000 Subject: [PATCH 14/53] Fix Android build: provide weak NDK r28 compat stub for __hash_memory --- webrtc-sys/build.rs | 7 ++++- webrtc-sys/src/ndk_compat.cpp | 59 +++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 webrtc-sys/src/ndk_compat.cpp diff --git a/webrtc-sys/build.rs b/webrtc-sys/build.rs index adabf9cfe..6d13bdc5f 100644 --- a/webrtc-sys/build.rs +++ b/webrtc-sys/build.rs @@ -374,7 +374,12 @@ fn main() { println!("cargo:rustc-link-lib=c++abi"); configure_android_sysroot(&mut builder); - builder.file("src/android.cpp").flag("-std=c++20"); + builder + .file("src/android.cpp") + // Provides a weak stub for std::__ndk1::__hash_memory, which + // was removed from libc++_static.a exports in NDK r28. + .file("src/ndk_compat.cpp") + .flag("-std=c++20"); } _ => { panic!("Unsupported target, {}", target_os); diff --git a/webrtc-sys/src/ndk_compat.cpp b/webrtc-sys/src/ndk_compat.cpp new file mode 100644 index 000000000..720299406 --- /dev/null +++ b/webrtc-sys/src/ndk_compat.cpp @@ -0,0 +1,59 @@ +// Copyright 2026 LiveKit, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Compatibility shim for Android NDK ABI changes. +// +// The WebRTC M150 prebuilt library was compiled against an older Android NDK +// (via Chromium's bundled toolchain) in which `std::__ndk1::__hash_memory` is +// an out-of-line function exported from `libc++_static.a`. Starting with NDK +// r28 (LLVM 18), this function was annotated with `_LIBCPP_HIDE_FROM_ABI` and +// is no longer present as an exported symbol. This causes a link failure when +// the prebuilt is linked against a newer system NDK. +// +// This file provides a **weak** fallback definition so that the prebuilt can be +// linked against any NDK version: +// - With NDK r27 and older: the strong definition from `libc++_static.a` +// overrides this weak one; behaviour is identical to before. +// - With NDK r28 and newer: this weak definition is used; it implements the +// same FNV-1a algorithm that LLVM libc++ historically used. + +#if defined(__ANDROID__) +#include + +namespace std { +inline namespace __ndk1 { + +__attribute__((weak)) size_t __hash_memory(void const* p, size_t n) noexcept { + auto const* ptr = static_cast(p); +#if defined(__LP64__) + // 64-bit FNV-1a + size_t hash = 14695981039346656037ULL; + for (size_t i = 0; i < n; ++i) { + hash ^= static_cast(ptr[i]); + hash *= 1099511628211ULL; + } +#else + // 32-bit FNV-1a + size_t hash = 2166136261U; + for (size_t i = 0; i < n; ++i) { + hash ^= static_cast(ptr[i]); + hash *= 16777619U; + } +#endif + return hash; +} + +} // namespace __ndk1 +} // namespace std +#endif // defined(__ANDROID__) From 28558eed1743ee0ba883ef6524d08d2da190b9d7 Mon Sep 17 00:00:00 2001 From: CloudWebRTC Date: Mon, 3 Aug 2026 15:27:06 +0800 Subject: [PATCH 15/53] Update WEBRTC_TAG constant to new version --- webrtc-sys/build/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webrtc-sys/build/src/lib.rs b/webrtc-sys/build/src/lib.rs index c0e858bfc..b7f0d5807 100644 --- a/webrtc-sys/build/src/lib.rs +++ b/webrtc-sys/build/src/lib.rs @@ -28,7 +28,7 @@ use regex::Regex; use reqwest::StatusCode; pub const SCRATH_PATH: &str = "livekit_webrtc"; -pub const WEBRTC_TAG: &str = "webrtc-a970b87-2"; +pub const WEBRTC_TAG: &str = "webrtc-2fcf4db"; pub const IGNORE_DEFINES: [&str; 2] = ["CR_CLANG_REVISION", "CR_XCODE_VERSION"]; pub fn target_os() -> String { From bf52ad6149dd519b6f9535122b4128008a1e1515 Mon Sep 17 00:00:00 2001 From: cloudwebrtc Date: Mon, 3 Aug 2026 16:31:08 +0800 Subject: [PATCH 16/53] fix tests. --- .cargo/config.toml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.cargo/config.toml b/.cargo/config.toml index fdd7fbc16..2adead06d 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -8,14 +8,22 @@ rustflags = ["-C", "target-feature=+crt-static"] [target.aarch64-pc-windows-msvc] rustflags = ["-C", "target-feature=+crt-static"] +# `-ObjC` must also be passed to rustdoc: doctest binaries are linked by rustdoc +# and do not inherit `rustflags`. Without it the ObjC categories in libwebrtc's +# static lib (e.g. `NSString (StdString)`) are not loaded, and static +# initializers such as RTCH264ProfileLevelId.mm abort at process startup. [target.x86_64-apple-darwin] rustflags = ["-C", "link-args=-ObjC"] +rustdocflags = ["-C", "link-args=-ObjC"] [target.aarch64-apple-darwin] rustflags = ["-C", "link-args=-ObjC"] +rustdocflags = ["-C", "link-args=-ObjC"] [target.aarch64-apple-ios] rustflags = ["-C", "link-args=-ObjC"] +rustdocflags = ["-C", "link-args=-ObjC"] [target.aarch64-apple-ios-sim] rustflags = ["-C", "link-args=-ObjC"] +rustdocflags = ["-C", "link-args=-ObjC"] From 9413ea568ac0b7a077f360fb0ff002440c99b1e7 Mon Sep 17 00:00:00 2001 From: cloudwebrtc Date: Tue, 4 Aug 2026 16:01:15 +0800 Subject: [PATCH 17/53] fix e2e tests for linux. --- webrtc-sys/libwebrtc/build_linux.sh | 27 ++++++++++++++++--- .../patches/disable_gcc_changes_meaning.patch | 17 ++++++++++++ .../fix_copy_on_write_buffer_compile.patch | 16 ----------- .../patches/fix_gcc_toolchain_ar_input.patch | 23 ++++++++++++++++ .../fix_payload_type_picker_compile.patch | 22 --------------- .../fix_ssl_stream_adapter_compile.patch | 21 --------------- 6 files changed, 64 insertions(+), 62 deletions(-) create mode 100644 webrtc-sys/libwebrtc/patches/disable_gcc_changes_meaning.patch delete mode 100644 webrtc-sys/libwebrtc/patches/fix_copy_on_write_buffer_compile.patch create mode 100644 webrtc-sys/libwebrtc/patches/fix_gcc_toolchain_ar_input.patch delete mode 100644 webrtc-sys/libwebrtc/patches/fix_payload_type_picker_compile.patch delete mode 100644 webrtc-sys/libwebrtc/patches/fix_ssl_stream_adapter_compile.patch diff --git a/webrtc-sys/libwebrtc/build_linux.sh b/webrtc-sys/libwebrtc/build_linux.sh index b1a24154f..bd0df556d 100755 --- a/webrtc-sys/libwebrtc/build_linux.sh +++ b/webrtc-sys/libwebrtc/build_linux.sh @@ -77,10 +77,7 @@ git apply "$COMMAND_DIR/patches/ssl_verify_callback_with_native_handle.patch" -v git apply "$COMMAND_DIR/patches/add_deps.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn git apply "$COMMAND_DIR/patches/fix_desktop_capture_compile.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn git apply "$COMMAND_DIR/patches/external_audio_source.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn -git apply "$COMMAND_DIR/patches/fix_payload_type_picker_compile.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn git apply "$COMMAND_DIR/patches/fix_pipewire_utils_compile.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn -git apply "$COMMAND_DIR/patches/fix_ssl_stream_adapter_compile.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn -git apply "$COMMAND_DIR/patches/fix_copy_on_write_buffer_compile.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn # Disable CREL (compact relocations). Chromium's build enables experimental # CREL via -Wa,--crel which causes segfaults on aarch64-linux (and is known @@ -89,6 +86,15 @@ git apply "$COMMAND_DIR/patches/fix_copy_on_write_buffer_compile.patch" -v --ign # See: https://github.com/zed-industries/zed/pull/51433#discussion_r2944567608 git -C build apply "$COMMAND_DIR/patches/disable_crel.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn +# is_clang=false selects the //build/toolchain/linux GCC toolchains, which pass a bare +# "ar" to be resolved from PATH. gcc_toolchain.gni rebases that against root_out_dir and +# declares the result as an input, so ninja refuses to run any alink edge. +git -C build apply "$COMMAND_DIR/patches/fix_gcc_toolchain_ar_input.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn + +# GCC reports -Wchanges-meaning as an error rather than a warning, so +# treat_warnings_as_errors=false does not cover it and WebRTC does not build without this. +git -C build apply "$COMMAND_DIR/patches/disable_gcc_changes_meaning.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn + cd third_party git apply "$COMMAND_DIR/patches/david_disable_gun_source_macro.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn @@ -111,6 +117,19 @@ fi # Note: use_clang_modules=false is required to avoid C++ module compilation issues. # Without this flag, the build may fail partway through, resulting in missing # or incomplete artifacts. +# +# The C++ standard library choice is an ABI contract with webrtc-sys, which is compiled +# by the cc crate against whatever the host toolchain provides: +# +# use_custom_libcxx=false keeps every std type in libwebrtc.a mangled the way +# libstdc++ mangles it, instead of Chromium's std::__Cr:: ABI namespace. +# use_sysroot=false makes the build use the host's libstdc++ headers rather +# than the bundled Debian Bullseye sysroot's libstdc++ 10. This matters beyond +# mangling: libstdc++ reordered the members of std::span in GCC 15, so a libwebrtc +# built against libstdc++ 10 headers and a webrtc-sys built against 15 agree on the +# mangled name of CopyOnWriteBuffer::Set(std::span) while disagreeing +# on which register holds the pointer and which holds the length. +# is_clang=false builds with the host GCC, so the compiler matches too. args="is_debug=$debug \ target_os=\"linux\" \ target_cpu=\"$arch\" \ @@ -119,6 +138,8 @@ args="is_debug=$debug \ use_llvm_libatomic=false \ use_custom_libcxx=false \ use_custom_libcxx_for_host=false \ + use_sysroot=false \ + is_clang=false \ use_clang_modules=false \ rtc_include_tests=false \ rtc_build_tools=false \ diff --git a/webrtc-sys/libwebrtc/patches/disable_gcc_changes_meaning.patch b/webrtc-sys/libwebrtc/patches/disable_gcc_changes_meaning.patch new file mode 100644 index 000000000..b56bbdd93 --- /dev/null +++ b/webrtc-sys/libwebrtc/patches/disable_gcc_changes_meaning.patch @@ -0,0 +1,17 @@ +diff --git a/config/compiler/BUILD.gn b/config/compiler/BUILD.gn +index e9668caab..87fe8c71b 100644 +--- a/config/compiler/BUILD.gn ++++ b/config/compiler/BUILD.gn +@@ -1857,6 +1849,12 @@ config("default_warnings") { + # -Wno-class-memaccess warns about hash table and vector in blink. + # But the violation is intentional. + "-Wno-class-memaccess", ++ ++ # WebRTC has several members that shadow a class of the same name, e.g. ++ # PortInterface::Network() alongside class Network. GCC diagnoses that as ++ # an error by default, not a warning, so treat_warnings_as_errors=false ++ # does not help. webrtc-sys passes this same flag. ++ "-Wno-changes-meaning", + ] + + # -Wunused-local-typedefs is broken in gcc, diff --git a/webrtc-sys/libwebrtc/patches/fix_copy_on_write_buffer_compile.patch b/webrtc-sys/libwebrtc/patches/fix_copy_on_write_buffer_compile.patch deleted file mode 100644 index 2e50572bc..000000000 --- a/webrtc-sys/libwebrtc/patches/fix_copy_on_write_buffer_compile.patch +++ /dev/null @@ -1,16 +0,0 @@ -diff --git a/rtc_base/copy_on_write_buffer.cc b/rtc_base/copy_on_write_buffer.cc -index 68e98ce729..c314d8b123 100644 ---- a/rtc_base/copy_on_write_buffer.cc -+++ b/rtc_base/copy_on_write_buffer.cc -@@ -28,7 +28,10 @@ - namespace webrtc { - - CopyOnWriteBuffer::RawBuffer::RawBuffer(size_t size) -- : size_(size), data_(std::make_unique_for_overwrite(size)) {} -+ // std::make_unique_for_overwrite needs a C++20 standard library -+ // (libstdc++ >= 11). `new T[n]` default-initializes, which is the same -+ // "leave the bytes uninitialized" semantics. -+ : size_(size), data_(new uint8_t[size]) {} - - scoped_refptr - CopyOnWriteBuffer::CreateBuffer(size_t capacity) { diff --git a/webrtc-sys/libwebrtc/patches/fix_gcc_toolchain_ar_input.patch b/webrtc-sys/libwebrtc/patches/fix_gcc_toolchain_ar_input.patch new file mode 100644 index 000000000..0e7b07001 --- /dev/null +++ b/webrtc-sys/libwebrtc/patches/fix_gcc_toolchain_ar_input.patch @@ -0,0 +1,23 @@ +diff --git a/toolchain/gcc_toolchain.gni b/toolchain/gcc_toolchain.gni +index a6b425828..f8bcd860d 100644 +--- a/toolchain/gcc_toolchain.gni ++++ b/toolchain/gcc_toolchain.gni +@@ -409,8 +409,16 @@ template("single_gcc_toolchain") { + command = "cmd /s /c \"\"$python_path\" $tool_wrapper_path delete-file {{output}} && $command\"" + } else { + command = "rm -f {{output}} && $command" +- inputs = +- [ get_path_info(rebase_path(ar, ".", root_out_dir), "abspath") ] ++ ++ # Only declare the archiver as an input when it actually is a path. The ++ # GCC toolchains in //build/toolchain/linux pass a bare command name ++ # ("ar") to be resolved from PATH, and rebasing that against ++ # root_out_dir names a file that does not exist, which makes ninja ++ # refuse to run every alink edge. ++ if (string_replace(ar, "/", "") != ar) { ++ inputs = ++ [ get_path_info(rebase_path(ar, ".", root_out_dir), "abspath") ] ++ } + } + + # Almost all targets build with //build/config/compiler:thin_archive which diff --git a/webrtc-sys/libwebrtc/patches/fix_payload_type_picker_compile.patch b/webrtc-sys/libwebrtc/patches/fix_payload_type_picker_compile.patch deleted file mode 100644 index 89e939c01..000000000 --- a/webrtc-sys/libwebrtc/patches/fix_payload_type_picker_compile.patch +++ /dev/null @@ -1,22 +0,0 @@ -diff --git a/call/payload_type_picker.cc b/call/payload_type_picker.cc -index 45105a1054..d12c3b34e2 100644 ---- a/call/payload_type_picker.cc -+++ b/call/payload_type_picker.cc -@@ -370,7 +370,7 @@ void PayloadTypeRecorder::Rollback() { - RTCError RtpHeaderExtensionRecorder::AddMapping(RtpHeaderExtensionId id, - absl::string_view uri, - bool encrypt) { -- auto it = uri_to_id_.find(std::pair{uri, encrypt}); -+ auto it = uri_to_id_.find(std::pair{std::string(uri), encrypt}); - if (it != uri_to_id_.end()) { - if (it->second != id) { - RTC_HISTOGRAM_BOOLEAN( -@@ -393,7 +393,7 @@ RTCError RtpHeaderExtensionRecorder::AddMapping(RtpHeaderExtensionId id, - RTCErrorOr RtpHeaderExtensionRecorder::LookupId( - absl::string_view uri, - bool encrypt) const { -- auto it = uri_to_id_.find(std::pair{uri, encrypt}); -+ auto it = uri_to_id_.find(std::pair{std::string(uri), encrypt}); - if (it == uri_to_id_.end()) { - return RTCError(RTCErrorType::INVALID_PARAMETER, - "No ID found for extension"); diff --git a/webrtc-sys/libwebrtc/patches/fix_ssl_stream_adapter_compile.patch b/webrtc-sys/libwebrtc/patches/fix_ssl_stream_adapter_compile.patch deleted file mode 100644 index c04ee0a09..000000000 --- a/webrtc-sys/libwebrtc/patches/fix_ssl_stream_adapter_compile.patch +++ /dev/null @@ -1,21 +0,0 @@ -diff --git a/rtc_base/ssl_stream_adapter.h b/rtc_base/ssl_stream_adapter.h -index 0568bd0310..7052a0dbf4 100644 ---- a/rtc_base/ssl_stream_adapter.h -+++ b/rtc_base/ssl_stream_adapter.h -@@ -14,6 +14,7 @@ - #include - #include - -+#include - #include - #include - #include -@@ -129,7 +130,7 @@ class SSLStreamAdapter : public StreamInterface { - static std::unique_ptr Create( - std::unique_ptr stream, - absl::AnyInvocable handshake_error, -- nullptr_t /*field_trials*/) { -+ std::nullptr_t /*field_trials*/) { - return Create(std::move(stream), std::move(handshake_error)); - } - From 5ec3038e205a4b6d0989c7be0c3dfc114dd30093 Mon Sep 17 00:00:00 2001 From: cloudwebrtc Date: Tue, 4 Aug 2026 16:35:43 +0800 Subject: [PATCH 18/53] update. --- webrtc-sys/libwebrtc/build_linux.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/webrtc-sys/libwebrtc/build_linux.sh b/webrtc-sys/libwebrtc/build_linux.sh index bd0df556d..a5f55c564 100755 --- a/webrtc-sys/libwebrtc/build_linux.sh +++ b/webrtc-sys/libwebrtc/build_linux.sh @@ -138,7 +138,6 @@ args="is_debug=$debug \ use_llvm_libatomic=false \ use_custom_libcxx=false \ use_custom_libcxx_for_host=false \ - use_sysroot=false \ is_clang=false \ use_clang_modules=false \ rtc_include_tests=false \ From 774a9bca068916aa938e3ba95b62a364bcac99bf Mon Sep 17 00:00:00 2001 From: CloudWebRTC Date: Tue, 4 Aug 2026 17:20:10 +0800 Subject: [PATCH 19/53] Update Ubuntu version in WebRTC builds workflow --- .github/workflows/webrtc-builds.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/webrtc-builds.yml b/.github/workflows/webrtc-builds.yml index 98b070580..6642c24e5 100644 --- a/.github/workflows/webrtc-builds.yml +++ b/.github/workflows/webrtc-builds.yml @@ -46,12 +46,12 @@ jobs: arch: arm64 - name: linux - os: ubuntu-latest + os: ubuntu-26.04 cmd: ./build_linux.sh arch: x64 - name: linux - os: ubuntu-latest + os: ubuntu-26.04 cmd: ./build_linux.sh arch: arm64 From 2ce867772bfbeba748a0b9366f7ed5ffba5fa169 Mon Sep 17 00:00:00 2001 From: cloudwebrtc Date: Tue, 4 Aug 2026 17:52:18 +0800 Subject: [PATCH 20/53] fix. --- webrtc-sys/libwebrtc/build_linux.sh | 4 ++++ .../patches/absl_add_x86gprintrin_define.patch | 16 ++++++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 webrtc-sys/libwebrtc/patches/absl_add_x86gprintrin_define.patch diff --git a/webrtc-sys/libwebrtc/build_linux.sh b/webrtc-sys/libwebrtc/build_linux.sh index a5f55c564..b064cb700 100755 --- a/webrtc-sys/libwebrtc/build_linux.sh +++ b/webrtc-sys/libwebrtc/build_linux.sh @@ -103,6 +103,10 @@ cd libyuv git apply "$COMMAND_DIR/patches/disable_sme_for_libyuv.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn +cd ../abseil-cpp + +git apply "$COMMAND_DIR/patches/absl_add_x86gprintrin_define.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn + cd ../../.. mkdir -p "$ARTIFACTS_DIR/lib" diff --git a/webrtc-sys/libwebrtc/patches/absl_add_x86gprintrin_define.patch b/webrtc-sys/libwebrtc/patches/absl_add_x86gprintrin_define.patch new file mode 100644 index 000000000..74758d4f7 --- /dev/null +++ b/webrtc-sys/libwebrtc/patches/absl_add_x86gprintrin_define.patch @@ -0,0 +1,16 @@ +diff --git a/abseil-cpp/BUILD.gn b/abseil-cpp/BUILD.gn +index 1e29a61520..ed87f624a7 100644 +--- a/abseil-cpp/BUILD.gn ++++ b/abseil-cpp/BUILD.gn +@@ -222,6 +222,11 @@ config("absl_define_config") { + "_ENABLE_EXTENDED_ALIGNED_STORAGE", + ] + } ++ if (is_linux && !use_custom_libcxx) { ++ defines += [ ++ "X86GPRINTRIN_H_" ++ ] ++ } + } + + config("absl_default_cflags_cc") { From fc7c1c3a8dadfcb3b2d7bbef170b607a8fda3a68 Mon Sep 17 00:00:00 2001 From: CloudWebRTC Date: Tue, 4 Aug 2026 18:49:42 +0800 Subject: [PATCH 21/53] Update webrtc-builds.yml --- .github/workflows/webrtc-builds.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/webrtc-builds.yml b/.github/workflows/webrtc-builds.yml index 6642c24e5..d3b808820 100644 --- a/.github/workflows/webrtc-builds.yml +++ b/.github/workflows/webrtc-builds.yml @@ -51,7 +51,7 @@ jobs: arch: x64 - name: linux - os: ubuntu-26.04 + os: ubuntu-26.04-arm cmd: ./build_linux.sh arch: arm64 From f1eb9e224cd148c2777da05bb3916d18c1793575 Mon Sep 17 00:00:00 2001 From: cloudwebrtc Date: Tue, 4 Aug 2026 18:48:41 +0800 Subject: [PATCH 22/53] fix --- webrtc-sys/libwebrtc/build_linux.sh | 7 +++---- .../patches/absl_add_x86gprintrin_define.patch | 16 ---------------- 2 files changed, 3 insertions(+), 20 deletions(-) delete mode 100644 webrtc-sys/libwebrtc/patches/absl_add_x86gprintrin_define.patch diff --git a/webrtc-sys/libwebrtc/build_linux.sh b/webrtc-sys/libwebrtc/build_linux.sh index b064cb700..03d7bf986 100755 --- a/webrtc-sys/libwebrtc/build_linux.sh +++ b/webrtc-sys/libwebrtc/build_linux.sh @@ -103,10 +103,6 @@ cd libyuv git apply "$COMMAND_DIR/patches/disable_sme_for_libyuv.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn -cd ../abseil-cpp - -git apply "$COMMAND_DIR/patches/absl_add_x86gprintrin_define.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn - cd ../../.. mkdir -p "$ARTIFACTS_DIR/lib" @@ -118,6 +114,8 @@ if [ "$profile" = "debug" ]; then debug="true" fi +./upgrade_sysroot_libstdcxx.sh --arch "$arch" + # Note: use_clang_modules=false is required to avoid C++ module compilation issues. # Without this flag, the build may fail partway through, resulting in missing # or incomplete artifacts. @@ -142,6 +140,7 @@ args="is_debug=$debug \ use_llvm_libatomic=false \ use_custom_libcxx=false \ use_custom_libcxx_for_host=false \ + use_sysroot=true \ is_clang=false \ use_clang_modules=false \ rtc_include_tests=false \ diff --git a/webrtc-sys/libwebrtc/patches/absl_add_x86gprintrin_define.patch b/webrtc-sys/libwebrtc/patches/absl_add_x86gprintrin_define.patch deleted file mode 100644 index 74758d4f7..000000000 --- a/webrtc-sys/libwebrtc/patches/absl_add_x86gprintrin_define.patch +++ /dev/null @@ -1,16 +0,0 @@ -diff --git a/abseil-cpp/BUILD.gn b/abseil-cpp/BUILD.gn -index 1e29a61520..ed87f624a7 100644 ---- a/abseil-cpp/BUILD.gn -+++ b/abseil-cpp/BUILD.gn -@@ -222,6 +222,11 @@ config("absl_define_config") { - "_ENABLE_EXTENDED_ALIGNED_STORAGE", - ] - } -+ if (is_linux && !use_custom_libcxx) { -+ defines += [ -+ "X86GPRINTRIN_H_" -+ ] -+ } - } - - config("absl_default_cflags_cc") { From 504e46bb52e0165c67bdecf7e7b325319fccf555 Mon Sep 17 00:00:00 2001 From: cloudwebrtc Date: Tue, 4 Aug 2026 18:52:38 +0800 Subject: [PATCH 23/53] add upgrade_sysroot_libdtcxx.sh for linux build. --- .../libwebrtc/upgrade_sysroot_libstdcxx.sh | 166 ++++++++++++++++++ 1 file changed, 166 insertions(+) create mode 100755 webrtc-sys/libwebrtc/upgrade_sysroot_libstdcxx.sh diff --git a/webrtc-sys/libwebrtc/upgrade_sysroot_libstdcxx.sh b/webrtc-sys/libwebrtc/upgrade_sysroot_libstdcxx.sh new file mode 100755 index 000000000..d36bd4d9a --- /dev/null +++ b/webrtc-sys/libwebrtc/upgrade_sysroot_libstdcxx.sh @@ -0,0 +1,166 @@ +#!/bin/bash +# Copyright 2025 LiveKit, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Replaces the libstdc++ 10 that Chromium's Debian Bullseye sysroot ships with the +# host's libstdc++, so that libwebrtc.a and webrtc-sys end up on one C++ ABI. +# +# Why this is needed +# ------------------ +# libstdc++ reordered the members of std::span in GCC 15: it used to be +# {extent, pointer} and is now {pointer, extent}. The mangled name did not change, so +# a libwebrtc built against libstdc++ 10 headers links cleanly against a webrtc-sys +# built against libstdc++ 15 headers, and then disagrees at runtime about which +# register holds the pointer and which holds the length. Sending on a data channel +# calls CopyOnWriteBuffer::Set(std::span), which reads the data pointer +# as an allocation size and aborts in operator new with std::bad_alloc. +# +# Who reads the sysroot's C++ headers +# ----------------------------------- +# Only clang. It resolves libstdc++ from the newest GCC installation it finds *inside* +# --sysroot, i.e. /usr/lib/gcc//10, and takes the headers next to it. +# The host GCC keeps using its own /usr/include/c++/ even under --sysroot, so +# an is_clang=false build does not need this script at all. +# +# Run this after install-sysroot.py and before gn gen, when building with +# is_clang=true and use_sysroot=true. + +set -euo pipefail + +arch="x64" +gcc_version="" + +while [ "$#" -gt 0 ]; do + case "$1" in + --arch) + arch="$2" + if [ "$arch" != "x64" ] && [ "$arch" != "arm64" ]; then + echo "Error: Invalid value for --arch. Must be 'x64' or 'arm64'." + exit 1 + fi + shift 2 + ;; + --gcc-version) + gcc_version="$2" + shift 2 + ;; + *) + echo "Error: Unknown argument '$1'" + echo "Usage: $0 [--arch x64|arm64] [--gcc-version N]" + exit 1 + ;; + esac +done + +COMMAND_DIR=$(cd "$(dirname "$0")"; pwd) + +case "$arch" in + x64) + triple="x86_64-linux-gnu" + debarch="amd64" + ;; + arm64) + triple="aarch64-linux-gnu" + debarch="arm64" + ;; +esac + +sysroot="$COMMAND_DIR/src/build/linux/debian_bullseye_${debarch}-sysroot" + +if [ ! -d "$sysroot" ]; then + echo "Error: sysroot not found at $sysroot" + echo "Run this first: python3 ./src/build/linux/sysroot_scripts/install-sysroot.py --arch=$arch" + exit 1 +fi + +# The host toolchain is the ABI we are matching, so default to whatever it is rather +# than hardcoding a version that will go stale. +if [ -z "$gcc_version" ]; then + gcc_version=$(gcc -dumpversion | cut -d. -f1) +fi + +host_cxx_include="/usr/include/c++/$gcc_version" +host_cxx_include_arch="/usr/include/$triple/c++/$gcc_version" +host_gcc_lib="/usr/lib/gcc/$triple/$gcc_version" + +for dir in "$host_cxx_include" "$host_cxx_include_arch" "$host_gcc_lib"; do + if [ ! -d "$dir" ]; then + echo "Error: $dir is missing." + if [ "$arch" = "arm64" ] && [ "$(uname -m)" != "aarch64" ]; then + echo "Cross-compiling to arm64 needs the cross toolchain: apt install g++-$gcc_version-aarch64-linux-gnu" + else + echo "Install the matching toolchain: apt install g++-$gcc_version" + fi + exit 1 + fi +done + +echo "Upgrading sysroot libstdc++ -> $gcc_version" +echo " sysroot: $sysroot" +echo " from: $host_cxx_include" + +# Headers. -L dereferences symlinks, because a symlink pointing outside the sysroot +# would resolve against the build machine's / once the compiler is given --sysroot. +rm -rf "$sysroot/usr/include/c++/$gcc_version" +mkdir -p "$sysroot/usr/include/c++" +cp -rL "$host_cxx_include" "$sysroot/usr/include/c++/$gcc_version" + +rm -rf "$sysroot/usr/include/$triple/c++/$gcc_version" +mkdir -p "$sysroot/usr/include/$triple/c++" +cp -rL "$host_cxx_include_arch" "$sysroot/usr/include/$triple/c++/$gcc_version" + +# clang only treats /usr/lib/gcc// as a GCC installation +# when the startup files are there, and it is that discovery which picks the header +# version. Without this the headers above are simply never found. +rm -rf "$sysroot/usr/lib/gcc/$triple/$gcc_version" +mkdir -p "$sysroot/usr/lib/gcc/$triple" +cp -rL "$host_gcc_lib" "$sysroot/usr/lib/gcc/$triple/$gcc_version" + +# Runtime library, for anything that links libstdc++ out of the sysroot. +host_libstdcxx=$(ls -1 "/usr/lib/$triple"/libstdc++.so.6.0.* 2>/dev/null | sort -V | tail -1) +if [ -n "$host_libstdcxx" ]; then + cp "$host_libstdcxx" "$sysroot/usr/lib/$triple/" + ln -sf "$(basename "$host_libstdcxx")" "$sysroot/usr/lib/$triple/libstdc++.so.6" + echo " runtime: $(basename "$host_libstdcxx")" +fi + +# Leave the old tree in place. clang picks the highest version it finds, and other +# parts of the sysroot still reference gcc 10 paths. + +# Verify that clang actually resolves the new version, since getting this wrong fails +# silently: the build succeeds and only misbehaves at runtime. +clang="$COMMAND_DIR/src/third_party/llvm-build/Release+Asserts/bin/clang++" +if [ -x "$clang" ]; then + probe=$(mktemp --suffix=.cpp) + echo 'int main(){}' > "$probe" + search=$("$clang" --sysroot="$sysroot" --target="$triple" -stdlib=libstdc++ \ + -E -v -x c++ "$probe" -o /dev/null 2>&1 | + sed -n '/#include <...> search starts here/,/End of search list/p') + rm -f "$probe" + + if ! echo "$search" | grep -q "include/c++/$gcc_version"; then + echo "Error: clang still does not resolve libstdc++ $gcc_version from the sysroot:" + echo "$search" + exit 1 + fi + if echo "$search" | grep -o "include/c++/[0-9]*" | grep -qv "include/c++/$gcc_version"; then + echo "Warning: another libstdc++ version is also on the include path:" + echo "$search" | grep -o "include/c++/[0-9]*" | sort -u + fi + echo " verified: clang resolves libstdc++ $gcc_version" +else + echo " skipped verification: $clang not built yet" +fi + +echo "Done." From 309c4b3cd0b1557a020769750b26476a040ecc7f Mon Sep 17 00:00:00 2001 From: cloudwebrtc Date: Tue, 4 Aug 2026 19:12:25 +0800 Subject: [PATCH 24/53] fix. --- webrtc-sys/libwebrtc/build_linux.sh | 8 +- .../patches/abseil-cpp_include_fix.patch | 13 ++ .../libwebrtc/upgrade_sysroot_libstdcxx.sh | 166 ------------------ 3 files changed, 18 insertions(+), 169 deletions(-) create mode 100644 webrtc-sys/libwebrtc/patches/abseil-cpp_include_fix.patch delete mode 100755 webrtc-sys/libwebrtc/upgrade_sysroot_libstdcxx.sh diff --git a/webrtc-sys/libwebrtc/build_linux.sh b/webrtc-sys/libwebrtc/build_linux.sh index 03d7bf986..a74603d80 100755 --- a/webrtc-sys/libwebrtc/build_linux.sh +++ b/webrtc-sys/libwebrtc/build_linux.sh @@ -103,6 +103,10 @@ cd libyuv git apply "$COMMAND_DIR/patches/disable_sme_for_libyuv.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn +cd ../abseil-cpp + +git apply "$COMMAND_DIR/patches/abseil-cpp_include_fix.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn + cd ../../.. mkdir -p "$ARTIFACTS_DIR/lib" @@ -114,8 +118,6 @@ if [ "$profile" = "debug" ]; then debug="true" fi -./upgrade_sysroot_libstdcxx.sh --arch "$arch" - # Note: use_clang_modules=false is required to avoid C++ module compilation issues. # Without this flag, the build may fail partway through, resulting in missing # or incomplete artifacts. @@ -140,7 +142,7 @@ args="is_debug=$debug \ use_llvm_libatomic=false \ use_custom_libcxx=false \ use_custom_libcxx_for_host=false \ - use_sysroot=true \ + use_sysroot=false \ is_clang=false \ use_clang_modules=false \ rtc_include_tests=false \ diff --git a/webrtc-sys/libwebrtc/patches/abseil-cpp_include_fix.patch b/webrtc-sys/libwebrtc/patches/abseil-cpp_include_fix.patch new file mode 100644 index 000000000..f12045cb4 --- /dev/null +++ b/webrtc-sys/libwebrtc/patches/abseil-cpp_include_fix.patch @@ -0,0 +1,13 @@ +diff --git a/abseil-cpp/absl/container/internal/raw_hash_set.h b/abseil-cpp/absl/container/internal/raw_hash_set.h +index 191b1c9bb8..ebf884e908 100644 +--- a/abseil-cpp/absl/container/internal/raw_hash_set.h ++++ b/abseil-cpp/absl/container/internal/raw_hash_set.h +@@ -226,7 +226,7 @@ + #endif + + #ifdef __BMI2__ +-#include ++#include + #endif // __BMI2__ + + namespace absl { diff --git a/webrtc-sys/libwebrtc/upgrade_sysroot_libstdcxx.sh b/webrtc-sys/libwebrtc/upgrade_sysroot_libstdcxx.sh deleted file mode 100755 index d36bd4d9a..000000000 --- a/webrtc-sys/libwebrtc/upgrade_sysroot_libstdcxx.sh +++ /dev/null @@ -1,166 +0,0 @@ -#!/bin/bash -# Copyright 2025 LiveKit, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Replaces the libstdc++ 10 that Chromium's Debian Bullseye sysroot ships with the -# host's libstdc++, so that libwebrtc.a and webrtc-sys end up on one C++ ABI. -# -# Why this is needed -# ------------------ -# libstdc++ reordered the members of std::span in GCC 15: it used to be -# {extent, pointer} and is now {pointer, extent}. The mangled name did not change, so -# a libwebrtc built against libstdc++ 10 headers links cleanly against a webrtc-sys -# built against libstdc++ 15 headers, and then disagrees at runtime about which -# register holds the pointer and which holds the length. Sending on a data channel -# calls CopyOnWriteBuffer::Set(std::span), which reads the data pointer -# as an allocation size and aborts in operator new with std::bad_alloc. -# -# Who reads the sysroot's C++ headers -# ----------------------------------- -# Only clang. It resolves libstdc++ from the newest GCC installation it finds *inside* -# --sysroot, i.e. /usr/lib/gcc//10, and takes the headers next to it. -# The host GCC keeps using its own /usr/include/c++/ even under --sysroot, so -# an is_clang=false build does not need this script at all. -# -# Run this after install-sysroot.py and before gn gen, when building with -# is_clang=true and use_sysroot=true. - -set -euo pipefail - -arch="x64" -gcc_version="" - -while [ "$#" -gt 0 ]; do - case "$1" in - --arch) - arch="$2" - if [ "$arch" != "x64" ] && [ "$arch" != "arm64" ]; then - echo "Error: Invalid value for --arch. Must be 'x64' or 'arm64'." - exit 1 - fi - shift 2 - ;; - --gcc-version) - gcc_version="$2" - shift 2 - ;; - *) - echo "Error: Unknown argument '$1'" - echo "Usage: $0 [--arch x64|arm64] [--gcc-version N]" - exit 1 - ;; - esac -done - -COMMAND_DIR=$(cd "$(dirname "$0")"; pwd) - -case "$arch" in - x64) - triple="x86_64-linux-gnu" - debarch="amd64" - ;; - arm64) - triple="aarch64-linux-gnu" - debarch="arm64" - ;; -esac - -sysroot="$COMMAND_DIR/src/build/linux/debian_bullseye_${debarch}-sysroot" - -if [ ! -d "$sysroot" ]; then - echo "Error: sysroot not found at $sysroot" - echo "Run this first: python3 ./src/build/linux/sysroot_scripts/install-sysroot.py --arch=$arch" - exit 1 -fi - -# The host toolchain is the ABI we are matching, so default to whatever it is rather -# than hardcoding a version that will go stale. -if [ -z "$gcc_version" ]; then - gcc_version=$(gcc -dumpversion | cut -d. -f1) -fi - -host_cxx_include="/usr/include/c++/$gcc_version" -host_cxx_include_arch="/usr/include/$triple/c++/$gcc_version" -host_gcc_lib="/usr/lib/gcc/$triple/$gcc_version" - -for dir in "$host_cxx_include" "$host_cxx_include_arch" "$host_gcc_lib"; do - if [ ! -d "$dir" ]; then - echo "Error: $dir is missing." - if [ "$arch" = "arm64" ] && [ "$(uname -m)" != "aarch64" ]; then - echo "Cross-compiling to arm64 needs the cross toolchain: apt install g++-$gcc_version-aarch64-linux-gnu" - else - echo "Install the matching toolchain: apt install g++-$gcc_version" - fi - exit 1 - fi -done - -echo "Upgrading sysroot libstdc++ -> $gcc_version" -echo " sysroot: $sysroot" -echo " from: $host_cxx_include" - -# Headers. -L dereferences symlinks, because a symlink pointing outside the sysroot -# would resolve against the build machine's / once the compiler is given --sysroot. -rm -rf "$sysroot/usr/include/c++/$gcc_version" -mkdir -p "$sysroot/usr/include/c++" -cp -rL "$host_cxx_include" "$sysroot/usr/include/c++/$gcc_version" - -rm -rf "$sysroot/usr/include/$triple/c++/$gcc_version" -mkdir -p "$sysroot/usr/include/$triple/c++" -cp -rL "$host_cxx_include_arch" "$sysroot/usr/include/$triple/c++/$gcc_version" - -# clang only treats /usr/lib/gcc// as a GCC installation -# when the startup files are there, and it is that discovery which picks the header -# version. Without this the headers above are simply never found. -rm -rf "$sysroot/usr/lib/gcc/$triple/$gcc_version" -mkdir -p "$sysroot/usr/lib/gcc/$triple" -cp -rL "$host_gcc_lib" "$sysroot/usr/lib/gcc/$triple/$gcc_version" - -# Runtime library, for anything that links libstdc++ out of the sysroot. -host_libstdcxx=$(ls -1 "/usr/lib/$triple"/libstdc++.so.6.0.* 2>/dev/null | sort -V | tail -1) -if [ -n "$host_libstdcxx" ]; then - cp "$host_libstdcxx" "$sysroot/usr/lib/$triple/" - ln -sf "$(basename "$host_libstdcxx")" "$sysroot/usr/lib/$triple/libstdc++.so.6" - echo " runtime: $(basename "$host_libstdcxx")" -fi - -# Leave the old tree in place. clang picks the highest version it finds, and other -# parts of the sysroot still reference gcc 10 paths. - -# Verify that clang actually resolves the new version, since getting this wrong fails -# silently: the build succeeds and only misbehaves at runtime. -clang="$COMMAND_DIR/src/third_party/llvm-build/Release+Asserts/bin/clang++" -if [ -x "$clang" ]; then - probe=$(mktemp --suffix=.cpp) - echo 'int main(){}' > "$probe" - search=$("$clang" --sysroot="$sysroot" --target="$triple" -stdlib=libstdc++ \ - -E -v -x c++ "$probe" -o /dev/null 2>&1 | - sed -n '/#include <...> search starts here/,/End of search list/p') - rm -f "$probe" - - if ! echo "$search" | grep -q "include/c++/$gcc_version"; then - echo "Error: clang still does not resolve libstdc++ $gcc_version from the sysroot:" - echo "$search" - exit 1 - fi - if echo "$search" | grep -o "include/c++/[0-9]*" | grep -qv "include/c++/$gcc_version"; then - echo "Warning: another libstdc++ version is also on the include path:" - echo "$search" | grep -o "include/c++/[0-9]*" | sort -u - fi - echo " verified: clang resolves libstdc++ $gcc_version" -else - echo " skipped verification: $clang not built yet" -fi - -echo "Done." From 6e3c62e39b70ac011d95a372b90bd222966d0db1 Mon Sep 17 00:00:00 2001 From: CloudWebRTC Date: Wed, 5 Aug 2026 14:55:07 +0800 Subject: [PATCH 25/53] Update Linux dependency installation conditions --- .github/workflows/webrtc-builds.yml | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/.github/workflows/webrtc-builds.yml b/.github/workflows/webrtc-builds.yml index d3b808820..57d6af52d 100644 --- a/.github/workflows/webrtc-builds.yml +++ b/.github/workflows/webrtc-builds.yml @@ -112,12 +112,18 @@ jobs: run: | pip3 install setuptools # pkg_resources is sometimes not found? - - name: Install linux dependencies - if: ${{ matrix.target.os == 'ubuntu-latest' }} + - name: Install Linux dependencies + if: ${{ (matrix.target.os == 'ubuntu-latest') || (matrix.target.name == 'linux') }} run: | sudo apt update -y sudo apt install -y ninja-build pkg-config openjdk-11-jdk + - name: Install Linux dependencies for Ubuntu 26 + if: ${{ matrix.target.name == 'linux' }} + run: | + sudo apt update -y + sudo apt install -y libc6-dev libstdc++-15-dev libasound2-dev libpulse-dev libudev-dev libexpat1-dev libnss3-dev python-dev-is-python3 libgtk-3-dev + - name: Select Xcode 26.0 if: ${{ matrix.target.os == 'macos-latest' }} run: sudo xcode-select --switch /Applications/Xcode_26.0.app/Contents/Developer @@ -143,7 +149,7 @@ jobs: - name: Free Disk Space (Ubuntu) uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be - if: ${{ matrix.target.os == 'ubuntu-latest' }} + if: ${{ (matrix.target.os == 'ubuntu-latest') || (matrix.target.name == 'linux') }} with: android: false tool-cache: true From 09062d7101babe06f870456504d18d503ad64608 Mon Sep 17 00:00:00 2001 From: CloudWebRTC Date: Wed, 5 Aug 2026 14:56:39 +0800 Subject: [PATCH 26/53] Clean up build_linux.sh by removing unused patches Removed unnecessary patches and comments related to GCC toolchain and Abseil. --- webrtc-sys/libwebrtc/build_linux.sh | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/webrtc-sys/libwebrtc/build_linux.sh b/webrtc-sys/libwebrtc/build_linux.sh index a74603d80..f94280340 100755 --- a/webrtc-sys/libwebrtc/build_linux.sh +++ b/webrtc-sys/libwebrtc/build_linux.sh @@ -86,11 +86,6 @@ git apply "$COMMAND_DIR/patches/fix_pipewire_utils_compile.patch" -v --ignore-sp # See: https://github.com/zed-industries/zed/pull/51433#discussion_r2944567608 git -C build apply "$COMMAND_DIR/patches/disable_crel.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn -# is_clang=false selects the //build/toolchain/linux GCC toolchains, which pass a bare -# "ar" to be resolved from PATH. gcc_toolchain.gni rebases that against root_out_dir and -# declares the result as an input, so ninja refuses to run any alink edge. -git -C build apply "$COMMAND_DIR/patches/fix_gcc_toolchain_ar_input.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn - # GCC reports -Wchanges-meaning as an error rather than a warning, so # treat_warnings_as_errors=false does not cover it and WebRTC does not build without this. git -C build apply "$COMMAND_DIR/patches/disable_gcc_changes_meaning.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn @@ -103,10 +98,6 @@ cd libyuv git apply "$COMMAND_DIR/patches/disable_sme_for_libyuv.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn -cd ../abseil-cpp - -git apply "$COMMAND_DIR/patches/abseil-cpp_include_fix.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn - cd ../../.. mkdir -p "$ARTIFACTS_DIR/lib" @@ -127,12 +118,6 @@ fi # # use_custom_libcxx=false keeps every std type in libwebrtc.a mangled the way # libstdc++ mangles it, instead of Chromium's std::__Cr:: ABI namespace. -# use_sysroot=false makes the build use the host's libstdc++ headers rather -# than the bundled Debian Bullseye sysroot's libstdc++ 10. This matters beyond -# mangling: libstdc++ reordered the members of std::span in GCC 15, so a libwebrtc -# built against libstdc++ 10 headers and a webrtc-sys built against 15 agree on the -# mangled name of CopyOnWriteBuffer::Set(std::span) while disagreeing -# on which register holds the pointer and which holds the length. # is_clang=false builds with the host GCC, so the compiler matches too. args="is_debug=$debug \ target_os=\"linux\" \ @@ -142,7 +127,6 @@ args="is_debug=$debug \ use_llvm_libatomic=false \ use_custom_libcxx=false \ use_custom_libcxx_for_host=false \ - use_sysroot=false \ is_clang=false \ use_clang_modules=false \ rtc_include_tests=false \ From 6a894c21ffe0b665f8d29a58068ca281adb4ebee Mon Sep 17 00:00:00 2001 From: cloudwebrtc Date: Wed, 5 Aug 2026 15:08:39 +0800 Subject: [PATCH 27/53] update. --- webrtc-sys/libwebrtc/build_linux.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/webrtc-sys/libwebrtc/build_linux.sh b/webrtc-sys/libwebrtc/build_linux.sh index f94280340..fed985384 100755 --- a/webrtc-sys/libwebrtc/build_linux.sh +++ b/webrtc-sys/libwebrtc/build_linux.sh @@ -86,6 +86,11 @@ git apply "$COMMAND_DIR/patches/fix_pipewire_utils_compile.patch" -v --ignore-sp # See: https://github.com/zed-industries/zed/pull/51433#discussion_r2944567608 git -C build apply "$COMMAND_DIR/patches/disable_crel.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn +# is_clang=false selects the //build/toolchain/linux GCC toolchains, which pass a bare +# "ar" to be resolved from PATH. gcc_toolchain.gni rebases that against root_out_dir and +# declares the result as an input, so ninja refuses to run any alink edge. +git -C build apply "$COMMAND_DIR/patches/fix_gcc_toolchain_ar_input.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn + # GCC reports -Wchanges-meaning as an error rather than a warning, so # treat_warnings_as_errors=false does not cover it and WebRTC does not build without this. git -C build apply "$COMMAND_DIR/patches/disable_gcc_changes_meaning.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn From b4946328136fc12a6776f1c1ec36ee1c90a26bfc Mon Sep 17 00:00:00 2001 From: CloudWebRTC Date: Wed, 5 Aug 2026 15:30:31 +0800 Subject: [PATCH 28/53] Update Linux dependencies for arm64 architecture --- .github/workflows/webrtc-builds.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/webrtc-builds.yml b/.github/workflows/webrtc-builds.yml index 57d6af52d..d9eaaf9eb 100644 --- a/.github/workflows/webrtc-builds.yml +++ b/.github/workflows/webrtc-builds.yml @@ -122,7 +122,7 @@ jobs: if: ${{ matrix.target.name == 'linux' }} run: | sudo apt update -y - sudo apt install -y libc6-dev libstdc++-15-dev libasound2-dev libpulse-dev libudev-dev libexpat1-dev libnss3-dev python-dev-is-python3 libgtk-3-dev + sudo apt install -y libc6-dev:arm64 libstdc++-15-dev:arm64 libc6-dev libstdc++-15-dev libasound2-dev libpulse-dev libudev-dev libexpat1-dev libnss3-dev python-dev-is-python3 libgtk-3-dev - name: Select Xcode 26.0 if: ${{ matrix.target.os == 'macos-latest' }} From 50da6c6a4be4642486326ae69c7f94864ea7fffe Mon Sep 17 00:00:00 2001 From: CloudWebRTC Date: Wed, 5 Aug 2026 16:00:19 +0800 Subject: [PATCH 29/53] Update webrtc-builds.yml --- .github/workflows/webrtc-builds.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/webrtc-builds.yml b/.github/workflows/webrtc-builds.yml index d9eaaf9eb..f08f211b6 100644 --- a/.github/workflows/webrtc-builds.yml +++ b/.github/workflows/webrtc-builds.yml @@ -121,8 +121,7 @@ jobs: - name: Install Linux dependencies for Ubuntu 26 if: ${{ matrix.target.name == 'linux' }} run: | - sudo apt update -y - sudo apt install -y libc6-dev:arm64 libstdc++-15-dev:arm64 libc6-dev libstdc++-15-dev libasound2-dev libpulse-dev libudev-dev libexpat1-dev libnss3-dev python-dev-is-python3 libgtk-3-dev + sudo apt install -y libc6-dev libstdc++-15-dev libasound2-dev libpulse-dev libudev-dev libexpat1-dev libnss3-dev python-dev-is-python3 libgtk-3-dev - name: Select Xcode 26.0 if: ${{ matrix.target.os == 'macos-latest' }} From 0c3c32627587f73978f9b6ff9f7931c61cba5a11 Mon Sep 17 00:00:00 2001 From: cloudwebrtc Date: Thu, 6 Aug 2026 08:28:59 +0800 Subject: [PATCH 30/53] update. --- .../libwebrtc/patches/david_disable_gun_source_macro.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webrtc-sys/libwebrtc/patches/david_disable_gun_source_macro.patch b/webrtc-sys/libwebrtc/patches/david_disable_gun_source_macro.patch index 97fe8701a..144408f04 100644 --- a/webrtc-sys/libwebrtc/patches/david_disable_gun_source_macro.patch +++ b/webrtc-sys/libwebrtc/patches/david_disable_gun_source_macro.patch @@ -7,7 +7,7 @@ index 9348e15c3c..f34db7ff98 100644 } if (is_linux || is_chromeos || is_android || current_os == "aix") { - if (!is_clang) { -+ if (!is_clang && (current_cpu == "x86" || current_cpu == "x64")) { + if (!is_clang && (current_cpu == "x86" || current_cpu == "x64" || current_cpu == "arm" || current_cpu == "arm64")) { dav1d_copts += [ "-D_GNU_SOURCE" ] } } From 2bb70b57d9032c817329364de10268b6f0195475 Mon Sep 17 00:00:00 2001 From: cloudwebrtc Date: Thu, 6 Aug 2026 08:38:55 +0800 Subject: [PATCH 31/53] fix abseil cpp build error. --- webrtc-sys/libwebrtc/build_linux.sh | 4 ++++ .../patches/fix_abseil_cpp_build_on_x64.patch | 13 +++++++++++++ 2 files changed, 17 insertions(+) create mode 100644 webrtc-sys/libwebrtc/patches/fix_abseil_cpp_build_on_x64.patch diff --git a/webrtc-sys/libwebrtc/build_linux.sh b/webrtc-sys/libwebrtc/build_linux.sh index fed985384..1de7fa89d 100755 --- a/webrtc-sys/libwebrtc/build_linux.sh +++ b/webrtc-sys/libwebrtc/build_linux.sh @@ -99,6 +99,10 @@ cd third_party git apply "$COMMAND_DIR/patches/david_disable_gun_source_macro.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn +if [ "$arch" = "x64" ]; then + git apply "$COMMAND_DIR/patches/fix_abseil_cpp_build_on_x64.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn +fi + cd libyuv git apply "$COMMAND_DIR/patches/disable_sme_for_libyuv.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn diff --git a/webrtc-sys/libwebrtc/patches/fix_abseil_cpp_build_on_x64.patch b/webrtc-sys/libwebrtc/patches/fix_abseil_cpp_build_on_x64.patch new file mode 100644 index 000000000..7990c7564 --- /dev/null +++ b/webrtc-sys/libwebrtc/patches/fix_abseil_cpp_build_on_x64.patch @@ -0,0 +1,13 @@ +diff --git a/abseil-cpp/absl/container/internal/raw_hash_set.h b/abseil-cpp/absl/container/internal/raw_hash_set.h +index 191b1c9bb8..57c1cec741 100644 +--- a/abseil-cpp/absl/container/internal/raw_hash_set.h ++++ b/abseil-cpp/absl/container/internal/raw_hash_set.h +@@ -226,7 +226,7 @@ + #endif + + #ifdef __BMI2__ +-#include ++#include + #endif // __BMI2__ + + namespace absl { From c08c9987069395a9722650bc7bc2e2ee85d596ab Mon Sep 17 00:00:00 2001 From: cloudwebrtc Date: Thu, 6 Aug 2026 08:59:00 +0800 Subject: [PATCH 32/53] fix patch. --- .../libwebrtc/patches/david_disable_gun_source_macro.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webrtc-sys/libwebrtc/patches/david_disable_gun_source_macro.patch b/webrtc-sys/libwebrtc/patches/david_disable_gun_source_macro.patch index 144408f04..d025c4394 100644 --- a/webrtc-sys/libwebrtc/patches/david_disable_gun_source_macro.patch +++ b/webrtc-sys/libwebrtc/patches/david_disable_gun_source_macro.patch @@ -7,7 +7,7 @@ index 9348e15c3c..f34db7ff98 100644 } if (is_linux || is_chromeos || is_android || current_os == "aix") { - if (!is_clang) { - if (!is_clang && (current_cpu == "x86" || current_cpu == "x64" || current_cpu == "arm" || current_cpu == "arm64")) { ++ if (!is_clang && (current_cpu == "x86" || current_cpu == "x64" || current_cpu == "arm" || current_cpu == "arm64")) { dav1d_copts += [ "-D_GNU_SOURCE" ] } } From 60a261d7a59bfbc848b36cb4851dc02205c7e5d6 Mon Sep 17 00:00:00 2001 From: cloudwebrtc Date: Thu, 6 Aug 2026 09:59:28 +0800 Subject: [PATCH 33/53] fix. --- webrtc-sys/libwebrtc/build_linux.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webrtc-sys/libwebrtc/build_linux.sh b/webrtc-sys/libwebrtc/build_linux.sh index 1de7fa89d..561f28b3c 100755 --- a/webrtc-sys/libwebrtc/build_linux.sh +++ b/webrtc-sys/libwebrtc/build_linux.sh @@ -163,7 +163,7 @@ ninja -C "$OUTPUT_DIR" :default # make libwebrtc.a # don't include nasm ar -rc "$ARTIFACTS_DIR/lib/libwebrtc.a" `find "$OUTPUT_DIR/obj" -name '*.o' -not -path "*/third_party/nasm/*"` -src/third_party/llvm-build/Release+Asserts/bin/llvm-objcopy --redefine-syms="$COMMAND_DIR/boringssl_prefix_symbols.txt" "$ARTIFACTS_DIR/lib/libwebrtc.a" +objcopy --redefine-syms="$COMMAND_DIR/boringssl_prefix_symbols.txt" "$ARTIFACTS_DIR/lib/libwebrtc.a" # License generation is optional - may fail with some Python versions # Use vpython3 from depot_tools for consistent Python version From 74549926c9f9b8c587117d6afc9acb7246d8e249 Mon Sep 17 00:00:00 2001 From: cloudwebrtc Date: Thu, 6 Aug 2026 11:20:55 +0800 Subject: [PATCH 34/53] revert changes. --- webrtc-sys/libwebrtc/build_linux.sh | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/webrtc-sys/libwebrtc/build_linux.sh b/webrtc-sys/libwebrtc/build_linux.sh index 561f28b3c..64adb5cba 100755 --- a/webrtc-sys/libwebrtc/build_linux.sh +++ b/webrtc-sys/libwebrtc/build_linux.sh @@ -86,11 +86,6 @@ git apply "$COMMAND_DIR/patches/fix_pipewire_utils_compile.patch" -v --ignore-sp # See: https://github.com/zed-industries/zed/pull/51433#discussion_r2944567608 git -C build apply "$COMMAND_DIR/patches/disable_crel.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn -# is_clang=false selects the //build/toolchain/linux GCC toolchains, which pass a bare -# "ar" to be resolved from PATH. gcc_toolchain.gni rebases that against root_out_dir and -# declares the result as an input, so ninja refuses to run any alink edge. -git -C build apply "$COMMAND_DIR/patches/fix_gcc_toolchain_ar_input.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn - # GCC reports -Wchanges-meaning as an error rather than a warning, so # treat_warnings_as_errors=false does not cover it and WebRTC does not build without this. git -C build apply "$COMMAND_DIR/patches/disable_gcc_changes_meaning.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn @@ -127,7 +122,6 @@ fi # # use_custom_libcxx=false keeps every std type in libwebrtc.a mangled the way # libstdc++ mangles it, instead of Chromium's std::__Cr:: ABI namespace. -# is_clang=false builds with the host GCC, so the compiler matches too. args="is_debug=$debug \ target_os=\"linux\" \ target_cpu=\"$arch\" \ @@ -136,7 +130,6 @@ args="is_debug=$debug \ use_llvm_libatomic=false \ use_custom_libcxx=false \ use_custom_libcxx_for_host=false \ - is_clang=false \ use_clang_modules=false \ rtc_include_tests=false \ rtc_build_tools=false \ @@ -163,7 +156,7 @@ ninja -C "$OUTPUT_DIR" :default # make libwebrtc.a # don't include nasm ar -rc "$ARTIFACTS_DIR/lib/libwebrtc.a" `find "$OUTPUT_DIR/obj" -name '*.o' -not -path "*/third_party/nasm/*"` -objcopy --redefine-syms="$COMMAND_DIR/boringssl_prefix_symbols.txt" "$ARTIFACTS_DIR/lib/libwebrtc.a" +src/third_party/llvm-build/Release+Asserts/bin/llvm-objcopy --redefine-syms="$COMMAND_DIR/boringssl_prefix_symbols.txt" "$ARTIFACTS_DIR/lib/libwebrtc.a" # License generation is optional - may fail with some Python versions # Use vpython3 from depot_tools for consistent Python version From 9500e32fa0e49dd23bd36b7837d66c75141f8043 Mon Sep 17 00:00:00 2001 From: cloudwebrtc Date: Thu, 6 Aug 2026 13:14:33 +0800 Subject: [PATCH 35/53] fix. --- .github/workflows/webrtc-builds.yml | 13 ++-- webrtc-sys/build.rs | 67 +++++++++++++++++++ webrtc-sys/libwebrtc/build_linux.sh | 41 ++++++++---- .../patches/disable_gcc_changes_meaning.patch | 17 ----- .../patches/fix_abseil_cpp_build_on_x64.patch | 13 ---- 5 files changed, 98 insertions(+), 53 deletions(-) delete mode 100644 webrtc-sys/libwebrtc/patches/disable_gcc_changes_meaning.patch delete mode 100644 webrtc-sys/libwebrtc/patches/fix_abseil_cpp_build_on_x64.patch diff --git a/.github/workflows/webrtc-builds.yml b/.github/workflows/webrtc-builds.yml index f08f211b6..7277761c5 100644 --- a/.github/workflows/webrtc-builds.yml +++ b/.github/workflows/webrtc-builds.yml @@ -46,12 +46,12 @@ jobs: arch: arm64 - name: linux - os: ubuntu-26.04 + os: ubuntu-latest cmd: ./build_linux.sh arch: x64 - name: linux - os: ubuntu-26.04-arm + os: ubuntu-latest cmd: ./build_linux.sh arch: arm64 @@ -113,16 +113,11 @@ jobs: pip3 install setuptools # pkg_resources is sometimes not found? - name: Install Linux dependencies - if: ${{ (matrix.target.os == 'ubuntu-latest') || (matrix.target.name == 'linux') }} + if: ${{ matrix.target.os == 'ubuntu-latest'}} run: | sudo apt update -y sudo apt install -y ninja-build pkg-config openjdk-11-jdk - - name: Install Linux dependencies for Ubuntu 26 - if: ${{ matrix.target.name == 'linux' }} - run: | - sudo apt install -y libc6-dev libstdc++-15-dev libasound2-dev libpulse-dev libudev-dev libexpat1-dev libnss3-dev python-dev-is-python3 libgtk-3-dev - - name: Select Xcode 26.0 if: ${{ matrix.target.os == 'macos-latest' }} run: sudo xcode-select --switch /Applications/Xcode_26.0.app/Contents/Developer @@ -148,7 +143,7 @@ jobs: - name: Free Disk Space (Ubuntu) uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be - if: ${{ (matrix.target.os == 'ubuntu-latest') || (matrix.target.name == 'linux') }} + if: ${{ matrix.target.os == 'ubuntu-latest' }} with: android: false tool-cache: true diff --git a/webrtc-sys/build.rs b/webrtc-sys/build.rs index 6d13bdc5f..3a72596b9 100644 --- a/webrtc-sys/build.rs +++ b/webrtc-sys/build.rs @@ -176,6 +176,8 @@ fn main() { println!("cargo:rustc-link-lib=dylib=pthread"); println!("cargo:rustc-link-lib=dylib=m"); + configure_hermetic_libcxx(&mut builder, &webrtc_include); + // In order to avoid any ABI mismatches we use the sysroot's headers. add_gio_headers(&mut builder); @@ -496,6 +498,71 @@ fn add_lazy_load_so(builder: &mut cc::Build, name: &str, libraries: Vec) } } +/// Compile against the same hermetic libc++ that is baked into libwebrtc.a. +/// +/// The Linux libwebrtc build sets `use_custom_libcxx=true`, so every std type in +/// its public API lives in the `std::__Cr` ABI namespace with libc++ layouts. +/// Using the host's libstdc++ here instead is not merely a mangling mismatch that +/// the linker would catch: `std::span` is layout-different between the two, so a +/// span handed to libwebrtc silently arrives with its pointer and size swapped. +/// +/// Mirrors the flags in the WebRTC checkout's `build/config/c++/BUILD.gn`. The +/// matching `_LIBCPP_*` defines come from webrtc.ninja via `webrtc_defines()`. +fn configure_hermetic_libcxx(builder: &mut cc::Build, webrtc_include: &path::Path) { + let libcxx = webrtc_include.join("third_party/libc++/src/include"); + let libcxxabi = webrtc_include.join("third_party/libc++abi/src/include"); + if !libcxx.join("span").exists() { + panic!( + "hermetic libc++ headers missing from {}.\n\ + This libwebrtc artifact predates use_custom_libcxx=true; rebuild it with \ + build_linux.sh or point LK_CUSTOM_WEBRTC at a newer one.", + libcxx.display() + ); + } + + // Chromium's libc++ is clang-only. At _LIBCPP_ABI_VERSION 2 it marks unique_ptr + // and shared_ptr __attribute__((trivial_abi)), which GCC accepts and silently + // ignores (a -Wattributes warning that cc's `-w` swallows). That attribute + // changes the calling convention, not just layout: libwebrtc.a returns + // std::unique_ptr in a register, while a GCC caller reads it back from an sret + // slot the callee never wrote, yielding a garbage pointer at the first use. + if env::var_os("CXX").is_none() { + if Command::new("clang++").arg("--version").output().is_err() { + panic!( + "clang++ is required to build webrtc-sys on Linux: libwebrtc.a is built \ + against Chromium's hermetic libc++, whose trivial_abi annotations GCC \ + ignores, which silently breaks the calling convention for std::unique_ptr \ + and std::shared_ptr. Install clang, or set CXX to a clang.", + ); + } + builder.compiler("clang++"); + } + + builder + .flag("-nostdinc++") + .flag(format!("-isystem{}", libcxx.display())) + .flag(format!("-isystem{}", libcxxabi.display())) + // Holds __config_site, which pins _LIBCPP_ABI_NAMESPACE=__Cr. + .include(webrtc_include.join("buildtools/third_party/libc++")); + + // libc++/libc++abi are already archived into libwebrtc.a, so linking the + // host libstdc++ on top would only add a second, incompatible stdlib. + builder.cpp_link_stdlib(None); + + // The cxx crate builds its own runtime (cxx.cc) with the host default stdlib, + // so the rust::String <-> std::string conversions it exports are mangled for + // libstdc++ and cannot satisfy the std::__Cr call sites in the generated + // bridges. Compile a second copy with the flags above to provide those. + // DEP_CXXBRIDGE1_HEADER is `cargo:HEADER` from the cxx crate: /include/cxx.h. + let cxx_h = env::var("DEP_CXXBRIDGE1_HEADER") + .expect("cxx crate did not export HEADER; cannot locate its cxx.cc"); + let cxx_root = path::Path::new(&cxx_h) + .parent() + .and_then(path::Path::parent) + .expect("unexpected DEP_CXXBRIDGE1_HEADER layout"); + builder.file(cxx_root.join("src/cxx.cc")); +} + fn add_gio_headers(builder: &mut cc::Build) { let webrtc_dir = webrtc_sys_build::webrtc_dir(); let target_arch = webrtc_sys_build::target_arch(); diff --git a/webrtc-sys/libwebrtc/build_linux.sh b/webrtc-sys/libwebrtc/build_linux.sh index 64adb5cba..a253caa81 100755 --- a/webrtc-sys/libwebrtc/build_linux.sh +++ b/webrtc-sys/libwebrtc/build_linux.sh @@ -86,18 +86,10 @@ git apply "$COMMAND_DIR/patches/fix_pipewire_utils_compile.patch" -v --ignore-sp # See: https://github.com/zed-industries/zed/pull/51433#discussion_r2944567608 git -C build apply "$COMMAND_DIR/patches/disable_crel.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn -# GCC reports -Wchanges-meaning as an error rather than a warning, so -# treat_warnings_as_errors=false does not cover it and WebRTC does not build without this. -git -C build apply "$COMMAND_DIR/patches/disable_gcc_changes_meaning.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn - cd third_party git apply "$COMMAND_DIR/patches/david_disable_gun_source_macro.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn -if [ "$arch" = "x64" ]; then - git apply "$COMMAND_DIR/patches/fix_abseil_cpp_build_on_x64.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn -fi - cd libyuv git apply "$COMMAND_DIR/patches/disable_sme_for_libyuv.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn @@ -117,19 +109,23 @@ fi # Without this flag, the build may fail partway through, resulting in missing # or incomplete artifacts. # -# The C++ standard library choice is an ABI contract with webrtc-sys, which is compiled -# by the cc crate against whatever the host toolchain provides: +# The C++ standard library choice is an ABI contract with webrtc-sys: # -# use_custom_libcxx=false keeps every std type in libwebrtc.a mangled the way -# libstdc++ mangles it, instead of Chromium's std::__Cr:: ABI namespace. +# use_custom_libcxx=true builds against Chromium's hermetic libc++, whose +# headers we ship in the artifacts (see below) so webrtc-sys compiles against +# byte-identical std types. The alternative -- letting each side use its own +# host stdlib -- is unsound now that WebRTC puts std types like std::span in +# public API signatures: libstdc++ reordered std::span's members after GCC 10, +# so a span built by the host and read inside libwebrtc.a had its pointer and +# size swapped, turning a 14-byte DataChannel::Send into new uint8_t[93TB]. args="is_debug=$debug \ target_os=\"linux\" \ target_cpu=\"$arch\" \ rtc_enable_protobuf=false \ treat_warnings_as_errors=false \ use_llvm_libatomic=false \ - use_custom_libcxx=false \ - use_custom_libcxx_for_host=false \ + use_custom_libcxx=true \ + use_custom_libcxx_for_host=true \ use_clang_modules=false \ rtc_include_tests=false \ rtc_build_tools=false \ @@ -155,6 +151,9 @@ ninja -C "$OUTPUT_DIR" :default # make libwebrtc.a # don't include nasm +# Start from scratch: `ar -rc` only replaces members it is given, so members left +# over from a previous build with different args would survive into the archive. +rm -f "$ARTIFACTS_DIR/lib/libwebrtc.a" ar -rc "$ARTIFACTS_DIR/lib/libwebrtc.a" `find "$OUTPUT_DIR/obj" -name '*.o' -not -path "*/third_party/nasm/*"` src/third_party/llvm-build/Release+Asserts/bin/llvm-objcopy --redefine-syms="$COMMAND_DIR/boringssl_prefix_symbols.txt" "$ARTIFACTS_DIR/lib/libwebrtc.a" @@ -172,3 +171,17 @@ cp "$OUTPUT_DIR/LICENSE.md" "$ARTIFACTS_DIR" cd src find . -name "*.h" -print | cpio -pd "$ARTIFACTS_DIR/include" find . -name "*.inc" -print | cpio -pd "$ARTIFACTS_DIR/include" + +# Ship Chromium's hermetic libc++ so webrtc-sys can compile against the exact +# same standard library that is baked into libwebrtc.a (see use_custom_libcxx +# above). The find calls cannot do this: libc++ headers have no extension. +# Paths mirror the -isystem/-I flags in build/config/c++/BUILD.gn, so build.rs +# can point at them the same way the WebRTC build does. +for inc in third_party/libc++/src/include third_party/libc++abi/src/include; do + mkdir -p "$ARTIFACTS_DIR/include/$inc" + cp -R "$inc/." "$ARTIFACTS_DIR/include/$inc/" +done +mkdir -p "$ARTIFACTS_DIR/include/buildtools/third_party/libc++" +cp buildtools/third_party/libc++/__config_site \ + buildtools/third_party/libc++/__assertion_handler \ + "$ARTIFACTS_DIR/include/buildtools/third_party/libc++/" diff --git a/webrtc-sys/libwebrtc/patches/disable_gcc_changes_meaning.patch b/webrtc-sys/libwebrtc/patches/disable_gcc_changes_meaning.patch deleted file mode 100644 index b56bbdd93..000000000 --- a/webrtc-sys/libwebrtc/patches/disable_gcc_changes_meaning.patch +++ /dev/null @@ -1,17 +0,0 @@ -diff --git a/config/compiler/BUILD.gn b/config/compiler/BUILD.gn -index e9668caab..87fe8c71b 100644 ---- a/config/compiler/BUILD.gn -+++ b/config/compiler/BUILD.gn -@@ -1857,6 +1849,12 @@ config("default_warnings") { - # -Wno-class-memaccess warns about hash table and vector in blink. - # But the violation is intentional. - "-Wno-class-memaccess", -+ -+ # WebRTC has several members that shadow a class of the same name, e.g. -+ # PortInterface::Network() alongside class Network. GCC diagnoses that as -+ # an error by default, not a warning, so treat_warnings_as_errors=false -+ # does not help. webrtc-sys passes this same flag. -+ "-Wno-changes-meaning", - ] - - # -Wunused-local-typedefs is broken in gcc, diff --git a/webrtc-sys/libwebrtc/patches/fix_abseil_cpp_build_on_x64.patch b/webrtc-sys/libwebrtc/patches/fix_abseil_cpp_build_on_x64.patch deleted file mode 100644 index 7990c7564..000000000 --- a/webrtc-sys/libwebrtc/patches/fix_abseil_cpp_build_on_x64.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/abseil-cpp/absl/container/internal/raw_hash_set.h b/abseil-cpp/absl/container/internal/raw_hash_set.h -index 191b1c9bb8..57c1cec741 100644 ---- a/abseil-cpp/absl/container/internal/raw_hash_set.h -+++ b/abseil-cpp/absl/container/internal/raw_hash_set.h -@@ -226,7 +226,7 @@ - #endif - - #ifdef __BMI2__ --#include -+#include - #endif // __BMI2__ - - namespace absl { From 6643976bfdc4ca4589025800a0be9c86b12b82cc Mon Sep 17 00:00:00 2001 From: CloudWebRTC Date: Thu, 6 Aug 2026 13:20:56 +0800 Subject: [PATCH 36/53] Update webrtc-builds.yml --- .github/workflows/webrtc-builds.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/webrtc-builds.yml b/.github/workflows/webrtc-builds.yml index 7277761c5..98b070580 100644 --- a/.github/workflows/webrtc-builds.yml +++ b/.github/workflows/webrtc-builds.yml @@ -112,8 +112,8 @@ jobs: run: | pip3 install setuptools # pkg_resources is sometimes not found? - - name: Install Linux dependencies - if: ${{ matrix.target.os == 'ubuntu-latest'}} + - name: Install linux dependencies + if: ${{ matrix.target.os == 'ubuntu-latest' }} run: | sudo apt update -y sudo apt install -y ninja-build pkg-config openjdk-11-jdk From c410744d7e9c6be6e759b3cd8a2f867955ce4ae7 Mon Sep 17 00:00:00 2001 From: CloudWebRTC Date: Thu, 6 Aug 2026 18:30:24 +0800 Subject: [PATCH 37/53] Update WEBRTC_TAG constant to new version --- webrtc-sys/build/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webrtc-sys/build/src/lib.rs b/webrtc-sys/build/src/lib.rs index b7f0d5807..f81deb3ba 100644 --- a/webrtc-sys/build/src/lib.rs +++ b/webrtc-sys/build/src/lib.rs @@ -28,7 +28,7 @@ use regex::Regex; use reqwest::StatusCode; pub const SCRATH_PATH: &str = "livekit_webrtc"; -pub const WEBRTC_TAG: &str = "webrtc-2fcf4db"; +pub const WEBRTC_TAG: &str = "webrtc-f8a0b64"; pub const IGNORE_DEFINES: [&str; 2] = ["CR_CLANG_REVISION", "CR_XCODE_VERSION"]; pub fn target_os() -> String { From cbec2b879ac34902629a4ce0cb613e8d4bcb2d5e Mon Sep 17 00:00:00 2001 From: cloudwebrtc Date: Fri, 7 Aug 2026 22:20:51 +0800 Subject: [PATCH 38/53] fix jni_prefix.patch. --- webrtc-sys/libwebrtc/patches/jni_prefix.patch | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/webrtc-sys/libwebrtc/patches/jni_prefix.patch b/webrtc-sys/libwebrtc/patches/jni_prefix.patch index 680816e97..b4c6eb402 100644 --- a/webrtc-sys/libwebrtc/patches/jni_prefix.patch +++ b/webrtc-sys/libwebrtc/patches/jni_prefix.patch @@ -7,10 +7,10 @@ index f6a5046210..103d979d2a 100644 JNIEnv* env = AttachCurrentThreadIfNeeded(); ScopedJavaLocalRef factory_class = - GetClass(env, "org/webrtc/HardwareVideoEncoderFactory"); -+ GetClass(env, "livekit/livekit/org/webrtc/HardwareVideoEncoderFactory"); ++ GetClass(env, "livekit/org/webrtc/HardwareVideoEncoderFactory"); jmethodID factory_constructor = env->GetMethodID( - factory_class.obj(), "", "(Lorg/webrtc/EglBase$Context;ZZ)V"); -+ factory_class.obj(), "", "(Llivekit/livekit/org/webrtc/EglBase$Context;ZZ)V"); ++ factory_class.obj(), "", "(Llivekit/org/webrtc/EglBase$Context;ZZ)V"); ScopedJavaLocalRef factory_object = ScopedJavaLocalRef::Adopt( env, env->NewObject(factory_class.obj(), factory_constructor, From 2da38918cb1cee2917de109ff369ccbb3ed47b47 Mon Sep 17 00:00:00 2001 From: cloudwebrtc Date: Mon, 10 Aug 2026 09:56:11 +0800 Subject: [PATCH 39/53] Require clang 21+ for the m150 hermetic libc++ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The m150 libwebrtc artifact ships libc++ 23 headers and is built with Chromium's clang 23. webrtc-sys compiles against those headers via -nostdinc++, so an older clang fails inside and — __builtin_popcountg, __is_nothrow_convertible and __GCC_DESTRUCTIVE_SIZE are all missing, which cascades into ~20 lines about dynamic_extent not being a constant expression, in headers nobody wrote. build.rs now probes __clang_major__ before configuring the build and reports the real floor, which it reads from the artifact's own __configuration/compiler.h rather than hardcoding. Nothing in CI or the README provided a clang that new: Ubuntu 24 has 18 and AlmaLinux 8 has 17. Add .github/scripts/install-clang.sh, which fetches the official LLVM release tarball for the host arch, and wire it into the four Linux jobs that build webrtc-sys. tests.yml previously pointed CC/CXX at the host GCC through sccache, which build.rs now rejects outright — GCC ignores libc++'s trivial_abi annotations and miscompiles unique_ptr returns. uniffi-cdylib.yml is left alone; livekit-uniffi does not link libwebrtc. Co-Authored-By: Claude Opus 5 --- .github/scripts/install-clang.sh | 61 ++++++++++++++++++++++++++++++ .github/workflows/builds.yml | 7 ++++ .github/workflows/ffi-builds.yml | 8 ++++ .github/workflows/node-builds.yml | 12 +++++- .github/workflows/tests.yml | 15 +++++++- README.md | 10 ++++- webrtc-sys/build.rs | 62 +++++++++++++++++++++++++++++++ 7 files changed, 170 insertions(+), 5 deletions(-) create mode 100755 .github/scripts/install-clang.sh diff --git a/.github/scripts/install-clang.sh b/.github/scripts/install-clang.sh new file mode 100755 index 000000000..076f26210 --- /dev/null +++ b/.github/scripts/install-clang.sh @@ -0,0 +1,61 @@ +#!/usr/bin/env bash +# +# Install a clang new enough to build webrtc-sys on Linux. +# +# webrtc-sys compiles against the hermetic libc++ shipped inside the libwebrtc +# artifact (use_custom_libcxx=true). That libc++ tracks LLVM trunk and uses +# builtins that only exist in a recent clang, so the distro clang in our build +# images (AlmaLinux 8: clang 17, Ubuntu 24: clang 18) fails deep inside +# and instead of saying the compiler is too old. webrtc-sys/build.rs +# checks the version up front and reports the real floor, which it reads from +# the artifact's own __configuration/compiler.h. +# +# The distro package managers have nothing recent enough, so pull the official +# LLVM release tarball instead. If a build image ever rejects it for glibc +# reasons, LLVM_VERSION is the knob to turn. +# +# Prints the bin directory on stdout; everything else goes to stderr. Also +# exports CC/CXX via $GITHUB_ENV when running as a workflow step. +# +# Usage: +# runner: .github/scripts/install-clang.sh # sets CC/CXX for later steps +# docker: export LLVM_ROOT=/opt/llvm +# .github/scripts/install-clang.sh +# export CC=$LLVM_ROOT/bin/clang CXX=$LLVM_ROOT/bin/clang++ + +set -euo pipefail + +LLVM_VERSION="${LLVM_VERSION:-21.1.8}" +LLVM_ROOT="${LLVM_ROOT:-/opt/llvm-$LLVM_VERSION}" + +case "$(uname -m)" in + x86_64) llvm_arch=X64 ;; + aarch64 | arm64) llvm_arch=ARM64 ;; + *) echo "install-clang.sh: unsupported architecture $(uname -m)" >&2; exit 1 ;; +esac + +if [ "$(id -u)" -eq 0 ]; then + sudo="" +else + sudo="sudo" +fi + +if [ ! -x "$LLVM_ROOT/bin/clang++" ]; then + url="https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION/LLVM-$LLVM_VERSION-Linux-$llvm_arch.tar.xz" + echo "install-clang.sh: fetching $url" >&2 + $sudo mkdir -p "$LLVM_ROOT" + # --strip-components=1 drops the LLVM--Linux-/ prefix. + curl --fail --location --silent --show-error "$url" \ + | $sudo tar -xJ --strip-components=1 -C "$LLVM_ROOT" +fi + +"$LLVM_ROOT/bin/clang++" --version >&2 + +if [ -n "${GITHUB_ENV:-}" ]; then + { + echo "CC=$LLVM_ROOT/bin/clang" + echo "CXX=$LLVM_ROOT/bin/clang++" + } >> "$GITHUB_ENV" +fi + +echo "$LLVM_ROOT/bin" diff --git a/.github/workflows/builds.yml b/.github/workflows/builds.yml index 06fa9a297..1d527737c 100644 --- a/.github/workflows/builds.yml +++ b/.github/workflows/builds.yml @@ -111,6 +111,13 @@ jobs: run: | sudo apt install -y libva-dev libdrm-dev libnvidia-compute-570 libnvidia-decode-570 nvidia-cuda-dev -y + # Ubuntu 24 ships clang 18; webrtc-sys needs 21+ for libwebrtc's hermetic + # libc++. Sets CC/CXX for the steps below. Android targets are excluded: + # cargo-ndk supplies its own NDK clang. + - name: Install clang for webrtc-sys + if: ${{ contains(matrix.target, 'unknown-linux-gnu') }} + run: .github/scripts/install-clang.sh + - name: Setup Rust toolchain uses: actions-rust-lang/setup-rust-toolchain@46268bd060767258de96ed93c1251119784f2ab6 # v1.16.1 with: diff --git a/.github/workflows/ffi-builds.yml b/.github/workflows/ffi-builds.yml index 112773e43..34594ed7a 100644 --- a/.github/workflows/ffi-builds.yml +++ b/.github/workflows/ffi-builds.yml @@ -210,6 +210,11 @@ jobs: cargo build --profile $env:CARGO_RUST_PROFILE --target ${{ matrix.target }} ${{ matrix.buildargs }} # Use Docker on linux, so we can use manylinux images (ensure maximum mcompatibility) + # + # Two clangs on purpose: the yum one stays for its libclang, which bindgen + # loads (yuv-sys), while CC/CXX point at a newer clang from install-clang.sh + # because webrtc-sys needs 21+ for libwebrtc's hermetic libc++ and + # AlmaLinux 8 tops out around 17. - name: Build (Linux) if: ${{ matrix.platform == 'linux' }} run: | @@ -222,6 +227,9 @@ jobs: yum groupinstall 'Development Tools' -y; \ clang --version; \ yum install openssl-devel libX11-devel mesa-libGL-devel libXext-devel libva-devel libdrm-devel libgbm-devel libXdamage-devel libXrandr-devel libXfixes-devel libXcomposite-devel -y; \ + export LLVM_ROOT=/opt/llvm; \ + /workspace/.github/scripts/install-clang.sh; \ + export CC=\$LLVM_ROOT/bin/clang CXX=\$LLVM_ROOT/bin/clang++; \ curl --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y; \ cd livekit-ffi && cargo build --profile \"\$CARGO_RUST_PROFILE\" --target ${{ matrix.target }} ${{ matrix.buildargs }}" diff --git a/.github/workflows/node-builds.yml b/.github/workflows/node-builds.yml index 8508e802f..cc73023a8 100644 --- a/.github/workflows/node-builds.yml +++ b/.github/workflows/node-builds.yml @@ -133,6 +133,14 @@ jobs: g++ --version clang --version clang++ --version + + # The yum clang above stays for its libclang (bindgen, via yuv-sys). + # webrtc-sys needs clang 21+ for the hermetic libc++ inside + # libwebrtc, which AlmaLinux 8 cannot provide, so fetch one into + # /opt/llvm as root; the hostuser build below only reads it. + export LLVM_ROOT=/opt/llvm + /workspace/.github/scripts/install-clang.sh + curl -fsSL https://rpm.nodesource.com/setup_20.x | bash - yum install -y nodejs --setopt=nodesource-nodejs.module_hotfixes=1 npm install --global pnpm @@ -146,8 +154,8 @@ jobs: curl --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y export PATH=\$HOME/.cargo/bin:\$PATH source /opt/rh/gcc-toolset-12/enable - export CC=clang - export CXX=clang++ + export CC=/opt/llvm/bin/clang + export CXX=/opt/llvm/bin/clang++ TOOLCHAIN_ROOT=/opt/rh/gcc-toolset-12/root/usr export CFLAGS=\"--gcc-toolchain=\$TOOLCHAIN_ROOT\" export CXXFLAGS=\"--gcc-toolchain=\$TOOLCHAIN_ROOT\" diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index d747112bb..fd3508eaa 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -74,6 +74,15 @@ jobs: version: "25.2" repo-token: ${{ secrets.GITHUB_TOKEN }} + # Ubuntu 24 ships clang 18; webrtc-sys needs 21+ for libwebrtc's hermetic + # libc++. Must run before the sccache step, which wraps whatever CC/CXX + # this sets. (The previous default here was the host `cc`/`c++`, i.e. GCC, + # which webrtc-sys/build.rs now rejects outright: GCC silently ignores + # libc++'s trivial_abi annotations and miscompiles unique_ptr returns.) + - name: Install clang for webrtc-sys + if: ${{ runner.os == 'Linux' }} + run: .github/scripts/install-clang.sh + # sccache wraps both rustc and the C/C++ compilers used by `cxx_build` # in `webrtc-sys`. The Mozilla action installs the binary; the probe # step below only enables wrapping if the GHA cache backend is reachable @@ -94,9 +103,11 @@ jobs: # All three matrix targets in tests.yml are host targets (no # cross-compile), so wrapping CC/CXX is safe. Skip on Windows: # MSVC `cl` setup needs more care. + # On Linux CC/CXX already point at the clang installed above; keep + # that compiler and just prepend the wrapper. if [ "${{ runner.os }}" != "Windows" ]; then - echo "CC=sccache cc" >> "$GITHUB_ENV" - echo "CXX=sccache c++" >> "$GITHUB_ENV" + echo "CC=sccache ${CC:-cc}" >> "$GITHUB_ENV" + echo "CXX=sccache ${CXX:-c++}" >> "$GITHUB_ENV" fi echo "::notice::sccache enabled (RUSTC_WRAPPER=sccache)" else diff --git a/README.md b/README.md index 046181b14..c1cca1149 100644 --- a/README.md +++ b/README.md @@ -179,9 +179,17 @@ Building on Ubuntu 24 x86_64: ``` # install required libs sudo apt install -y \ - libglib2.0-dev build-essential clang \ + libglib2.0-dev build-essential \ libclang-dev libc6-dev pkg-config libjpeg-turbo8-dev +# webrtc-sys compiles against the hermetic libc++ shipped inside the libwebrtc +# artifact, which tracks LLVM trunk and needs clang 21 or later. Ubuntu 24's +# clang is 18, so install a newer one from apt.llvm.org: +wget https://apt.llvm.org/llvm.sh +chmod +x llvm.sh +sudo ./llvm.sh 21 +export CC=clang-21 CXX=clang++-21 + # install cuda-toolkit if you have an Nvidia GPU and want to use NVENC for video encoding wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2404/x86_64/cuda-keyring_1.1-1_all.deb sudo dpkg -i cuda-keyring_1.1-1_all.deb diff --git a/webrtc-sys/build.rs b/webrtc-sys/build.rs index 3a72596b9..437ef0329 100644 --- a/webrtc-sys/build.rs +++ b/webrtc-sys/build.rs @@ -538,6 +538,8 @@ fn configure_hermetic_libcxx(builder: &mut cc::Build, webrtc_include: &path::Pat builder.compiler("clang++"); } + check_clang_version(builder, &libcxx); + builder .flag("-nostdinc++") .flag(format!("-isystem{}", libcxx.display())) @@ -563,6 +565,66 @@ fn configure_hermetic_libcxx(builder: &mut cc::Build, webrtc_include: &path::Pat builder.file(cxx_root.join("src/cxx.cc")); } +/// The hermetic libc++ tracks LLVM trunk, so it freely uses builtins that only +/// exist in a recent clang (`__builtin_popcountg`, `__is_nothrow_convertible`, +/// `__GCC_DESTRUCTIVE_SIZE`, ...). A compiler below its floor does not fail with +/// "your clang is too old" — it fails deep inside and with +/// hundreds of lines about `dynamic_extent` not being a constant expression, in +/// headers the user never wrote. Catch it up front instead. +fn check_clang_version(builder: &cc::Build, libcxx: &path::Path) { + let min = libcxx_min_clang_major(libcxx); + + let compiler = builder.get_compiler(); + let defines = compiler + .to_command() + .args(["-dM", "-E", "-x", "c++", "/dev/null"]) + .output() + .unwrap_or_else(|e| panic!("failed to run {}: {e}", compiler.path().display())); + + let major = String::from_utf8_lossy(&defines.stdout).lines().find_map(|line| { + line.strip_prefix("#define __clang_major__ ").and_then(|v| v.trim().parse::().ok()) + }); + + match major { + Some(major) if major >= min => {} + Some(major) => panic!( + "{} is clang {major}, but the hermetic libc++ shipped with this libwebrtc \ + requires clang {min} or later. Install a newer clang and point CC/CXX at it, \ + or use the exact toolchain libwebrtc was built with (see CR_CLANG_REVISION in \ + the artifact's webrtc.ninja).", + compiler.path().display(), + ), + None => panic!( + "{} does not define __clang_major__, so it is not a clang. libwebrtc.a is built \ + against Chromium's hermetic libc++, which requires clang {min} or later; GCC \ + additionally ignores its trivial_abi annotations, silently breaking the calling \ + convention for std::unique_ptr and std::shared_ptr.", + compiler.path().display(), + ), + } +} + +/// libc++ states its own floor in `__configuration/compiler.h`, as +/// `#if _LIBCPP_CLANG_VER < 2101` (major * 100 + minor). Read it from the +/// artifact rather than hardcoding, so a libwebrtc bump moves the floor with it. +fn libcxx_min_clang_major(libcxx: &path::Path) -> u32 { + const FALLBACK: u32 = 21; + + let header = libcxx.join("__configuration/compiler.h"); + let Ok(source) = std::fs::read_to_string(&header) else { + return FALLBACK; + }; + + source + .lines() + .find_map(|line| { + let (_, rest) = line.split_once("_LIBCPP_CLANG_VER < ")?; + let ver: u32 = rest.trim().parse().ok()?; + Some(ver / 100) + }) + .unwrap_or(FALLBACK) +} + fn add_gio_headers(builder: &mut cc::Build) { let webrtc_dir = webrtc_sys_build::webrtc_dir(); let target_arch = webrtc_sys_build::target_arch(); From 0b5d9be748bc9906f6a0250aa8935ddfc5bde233 Mon Sep 17 00:00:00 2001 From: CloudWebRTC Date: Mon, 10 Aug 2026 10:18:18 +0800 Subject: [PATCH 40/53] Add additional link arguments for aarch64 target --- .cargo/config.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.cargo/config.toml b/.cargo/config.toml index 2adead06d..42d520db6 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,6 +1,6 @@ # We need lld to link libwebrtc.a successfully on aarch64-linux [target.aarch64-unknown-linux-gnu] -rustflags = ["-C", "link-arg=-fuse-ld=lld"] +rustflags = ["-C", "link-arg=-fuse-ld=lld", "-C", "link-arg=-lc++", "-C", "link-arg=-lc++abi"] [target.x86_64-pc-windows-msvc] rustflags = ["-C", "target-feature=+crt-static"] From b75ae7e5b8b61a041c79ad5b7c45efff44136a53 Mon Sep 17 00:00:00 2001 From: CloudWebRTC Date: Mon, 10 Aug 2026 10:30:16 +0800 Subject: [PATCH 41/53] Update config.toml --- .cargo/config.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.cargo/config.toml b/.cargo/config.toml index 42d520db6..2adead06d 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,6 +1,6 @@ # We need lld to link libwebrtc.a successfully on aarch64-linux [target.aarch64-unknown-linux-gnu] -rustflags = ["-C", "link-arg=-fuse-ld=lld", "-C", "link-arg=-lc++", "-C", "link-arg=-lc++abi"] +rustflags = ["-C", "link-arg=-fuse-ld=lld"] [target.x86_64-pc-windows-msvc] rustflags = ["-C", "target-feature=+crt-static"] From d40f0166de39ad0a1e3a5a169bebb358d207018e Mon Sep 17 00:00:00 2001 From: cloudwebrtc Date: Mon, 10 Aug 2026 10:20:58 +0800 Subject: [PATCH 42/53] Keep m150's libwebrtc logs inside the Rust log facade MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit m150 replaced the old "release builds don't log" default with a LoggingConfig that defaults to log_to_stderr=true and debug_severity=LS_INFO, and installs itself on the first log call if nobody called InitializeLogging first. So libwebrtc started writing straight to stderr in parallel with our LogSink, and that copy is invisible to `log`/RUST_LOG — a bare PeerConnectionFactory::default() emits 29 unfilterable "(audio_device_impl.cc:146): ..." lines. Turn the debug stream off when the sink is installed so the sink is the only path out. While here, map LoggingSeverity onto log::Level instead of flattening everything to DEBUG. The sink is registered at LS_VERBOSE, so the old behavior left RUST_LOG choosing between all of libwebrtc's output and none of it. LS_INFO still maps to DEBUG, keeping libwebrtc's INFO chatter out of a RUST_LOG=info run as before. Co-Authored-By: Claude Opus 5 --- libwebrtc/src/native/peer_connection_factory.rs | 15 +++++++++++++-- webrtc-sys/src/webrtc.cpp | 8 ++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/libwebrtc/src/native/peer_connection_factory.rs b/libwebrtc/src/native/peer_connection_factory.rs index 16e6244f3..307bab7fc 100644 --- a/libwebrtc/src/native/peer_connection_factory.rs +++ b/libwebrtc/src/native/peer_connection_factory.rs @@ -38,9 +38,20 @@ lazy_static! { fn ensure_log_sink() { let mut log_sink = LOG_SINK.lock(); if log_sink.is_none() { - *log_sink = Some(sys_rtc::ffi::new_log_sink(|msg, _| { + *log_sink = Some(sys_rtc::ffi::new_log_sink(|msg, severity| { let msg = msg.strip_suffix("\r\n").or(msg.strip_suffix('\n')).unwrap_or(&msg); - log::debug!(target: "libwebrtc", "{}", msg); + // The sink is registered at LS_VERBOSE, so map the severity through + // instead of flattening everything to DEBUG: otherwise `RUST_LOG` + // can only choose between all of libwebrtc's output and none of it. + let level = match severity { + sys_rtc::ffi::LoggingSeverity::Verbose => log::Level::Trace, + sys_rtc::ffi::LoggingSeverity::Info => log::Level::Debug, + sys_rtc::ffi::LoggingSeverity::Warning => log::Level::Warn, + sys_rtc::ffi::LoggingSeverity::Error => log::Level::Error, + // LS_NONE never reaches a sink; nothing sensible to map it to. + _ => log::Level::Trace, + }; + log::log!(target: "libwebrtc", level, "{}", msg); })); } } diff --git a/webrtc-sys/src/webrtc.cpp b/webrtc-sys/src/webrtc.cpp index 2a2c257ae..b70034cbf 100644 --- a/webrtc-sys/src/webrtc.cpp +++ b/webrtc-sys/src/webrtc.cpp @@ -152,6 +152,14 @@ std::shared_ptr RtcRuntime::get_or_create_video_track( LogSink::LogSink( rust::Fn fnc) : fnc_(fnc) { + // m150 replaced the old "release builds don't log" default with LoggingConfig, + // which defaults to log_to_stderr=true / debug_severity=LS_INFO and installs + // itself on the first log call. That writes straight to stderr, bypassing this + // sink and therefore the Rust log facade, so nothing downstream can filter it. + // Route everything through the sink only. + webrtc::LogMessage::SetLogToStderr(false); + webrtc::LogMessage::LogToDebug(webrtc::LoggingSeverity::LS_NONE); + webrtc::LogMessage::AddLogToStream(this, webrtc::LoggingSeverity::LS_VERBOSE); } From 9a572195fa2b4546b2b108f4999ee26155e2a25a Mon Sep 17 00:00:00 2001 From: cloudwebrtc Date: Mon, 10 Aug 2026 11:07:46 +0800 Subject: [PATCH 43/53] fix ffi build. 1 --- .github/workflows/ffi-builds.yml | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ffi-builds.yml b/.github/workflows/ffi-builds.yml index 34594ed7a..643abbe76 100644 --- a/.github/workflows/ffi-builds.yml +++ b/.github/workflows/ffi-builds.yml @@ -212,9 +212,19 @@ jobs: # Use Docker on linux, so we can use manylinux images (ensure maximum mcompatibility) # # Two clangs on purpose: the yum one stays for its libclang, which bindgen - # loads (yuv-sys), while CC/CXX point at a newer clang from install-clang.sh - # because webrtc-sys needs 21+ for libwebrtc's hermetic libc++ and - # AlmaLinux 8 tops out around 17. + # loads (yuv-sys), while CC/CXX point at clang 21 because webrtc-sys needs + # 21+ for libwebrtc's hermetic libc++ and AlmaLinux 8 tops out around 17. + # + # That second clang comes from manylinux-install-clang rather than + # .github/scripts/install-clang.sh (which the ubuntu runners use): LLVM's + # own Linux release tarballs are built against glibc 2.34+ and refuse to + # run on manylinux_2_28's glibc 2.28. manylinux-install-clang fetches a + # statically linked toolchain instead, so glibc is irrelevant. It unpacks + # into /opt/clang, which these images already have on PATH, and writes + # clang config files pointing at the image's gcc-toolset. -v is the + # static-clang release (LLVM 21.1.8, packaging revision 1) and -c is the + # sha256 of that release's sha256sums.txt; `manylinux-install-clang -l` + # lists what an image knows about. - name: Build (Linux) if: ${{ matrix.platform == 'linux' }} run: | @@ -222,14 +232,12 @@ jobs: uname -a; \ export PATH=/root/.cargo/bin:\$PATH; \ yum install llvm llvm-libs lld -y; \ - yum install clang -y; \ yum install protobuf-compiler -y; \ yum groupinstall 'Development Tools' -y; \ - clang --version; \ yum install openssl-devel libX11-devel mesa-libGL-devel libXext-devel libva-devel libdrm-devel libgbm-devel libXdamage-devel libXrandr-devel libXfixes-devel libXcomposite-devel -y; \ - export LLVM_ROOT=/opt/llvm; \ - /workspace/.github/scripts/install-clang.sh; \ - export CC=\$LLVM_ROOT/bin/clang CXX=\$LLVM_ROOT/bin/clang++; \ + manylinux-install-clang -m \$(uname -m) -v 21.1.8.1; \ + export CC=/opt/clang/bin/clang CXX=/opt/clang/bin/clang++; \ + \$CXX --version; \ curl --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y; \ cd livekit-ffi && cargo build --profile \"\$CARGO_RUST_PROFILE\" --target ${{ matrix.target }} ${{ matrix.buildargs }}" From 988c5e54dce105515401f321f950258bc2e29a6b Mon Sep 17 00:00:00 2001 From: cloudwebrtc Date: Mon, 10 Aug 2026 11:16:34 +0800 Subject: [PATCH 44/53] fix. --- .github/workflows/ffi-builds.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ffi-builds.yml b/.github/workflows/ffi-builds.yml index 643abbe76..24ce34363 100644 --- a/.github/workflows/ffi-builds.yml +++ b/.github/workflows/ffi-builds.yml @@ -236,6 +236,7 @@ jobs: yum groupinstall 'Development Tools' -y; \ yum install openssl-devel libX11-devel mesa-libGL-devel libXext-devel libva-devel libdrm-devel libgbm-devel libXdamage-devel libXrandr-devel libXfixes-devel libXcomposite-devel -y; \ manylinux-install-clang -m \$(uname -m) -v 21.1.8.1; \ + export LLVM_ROOT=/opt/llvm; \ export CC=/opt/clang/bin/clang CXX=/opt/clang/bin/clang++; \ \$CXX --version; \ curl --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y; \ From db162a7d155cc81e34184e453fd7562ae1d4d8ea Mon Sep 17 00:00:00 2001 From: cloudwebrtc Date: Mon, 10 Aug 2026 11:27:24 +0800 Subject: [PATCH 45/53] fix. --- .github/workflows/ffi-builds.yml | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/.github/workflows/ffi-builds.yml b/.github/workflows/ffi-builds.yml index 24ce34363..a3c42c284 100644 --- a/.github/workflows/ffi-builds.yml +++ b/.github/workflows/ffi-builds.yml @@ -211,19 +211,25 @@ jobs: # Use Docker on linux, so we can use manylinux images (ensure maximum mcompatibility) # - # Two clangs on purpose: the yum one stays for its libclang, which bindgen - # loads (yuv-sys), while CC/CXX point at clang 21 because webrtc-sys needs - # 21+ for libwebrtc's hermetic libc++ and AlmaLinux 8 tops out around 17. + # Two clangs on purpose. yum only supplies libclang.so, which bindgen + # dlopens (yuv-sys): that lives in clang-libs, which is why the llvm + # packages go in one transaction — el8 AppStream now carries several llvm + # streams, and two separate installs can pick llvm-libs from one and + # clang-libs from another, which fails the whole install. LIBCLANG_PATH + # points bindgen straight at it instead of letting clang-sys guess from + # llvm-config, which /opt/clang below shadows. # - # That second clang comes from manylinux-install-clang rather than - # .github/scripts/install-clang.sh (which the ubuntu runners use): LLVM's - # own Linux release tarballs are built against glibc 2.34+ and refuse to - # run on manylinux_2_28's glibc 2.28. manylinux-install-clang fetches a - # statically linked toolchain instead, so glibc is irrelevant. It unpacks - # into /opt/clang, which these images already have on PATH, and writes - # clang config files pointing at the image's gcc-toolset. -v is the - # static-clang release (LLVM 21.1.8, packaging revision 1) and -c is the - # sha256 of that release's sha256sums.txt; `manylinux-install-clang -l` + # CC/CXX are a different clang: webrtc-sys needs 21+ for libwebrtc's + # hermetic libc++, and it comes from manylinux-install-clang rather than + # .github/scripts/install-clang.sh (which the ubuntu runners use) because + # LLVM's own Linux release tarballs are built against glibc 2.34+ and + # refuse to run on manylinux_2_28's glibc 2.28. manylinux-install-clang + # fetches a statically linked toolchain instead, so glibc is irrelevant. It + # unpacks into /opt/clang, which these images already have on PATH, and + # writes clang config files pointing at the image's gcc-toolset. -m picks + # the toolchain's own architecture (x86_64 or aarch64 — both jobs run + # natively, so it is the container's) and -v is the static-clang release, + # i.e. LLVM 21.1.8 packaging revision 1; `manylinux-install-clang -l` # lists what an image knows about. - name: Build (Linux) if: ${{ matrix.platform == 'linux' }} @@ -237,6 +243,7 @@ jobs: yum install openssl-devel libX11-devel mesa-libGL-devel libXext-devel libva-devel libdrm-devel libgbm-devel libXdamage-devel libXrandr-devel libXfixes-devel libXcomposite-devel -y; \ manylinux-install-clang -m \$(uname -m) -v 21.1.8.1; \ export LLVM_ROOT=/opt/llvm; \ + export LIBCLANG_PATH=/usr/lib64; \ export CC=/opt/clang/bin/clang CXX=/opt/clang/bin/clang++; \ \$CXX --version; \ curl --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y; \ From 6691a7876957b99aa63f899cd07d3aa1c726cd71 Mon Sep 17 00:00:00 2001 From: cloudwebrtc Date: Mon, 10 Aug 2026 11:39:57 +0800 Subject: [PATCH 46/53] update clang for node-builds.yml. --- .github/workflows/node-builds.yml | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/.github/workflows/node-builds.yml b/.github/workflows/node-builds.yml index cc73023a8..b5d55366c 100644 --- a/.github/workflows/node-builds.yml +++ b/.github/workflows/node-builds.yml @@ -126,20 +126,23 @@ jobs: cp /tmp/protoc /usr/local/bin/protoc chmod +x /usr/local/bin/protoc - yum install -y openssl-devel libX11-devel mesa-libGL-devel libXext-devel libva-devel libdrm-devel clang clang-devel lld + yum install -y openssl-devel libX11-devel mesa-libGL-devel libXext-devel libva-devel libdrm-devel lld yum install -y gcc-toolset-12-gcc gcc-toolset-12-gcc-c++ gcc-toolset-12-libstdc++-devel libstdc++-devel source /opt/rh/gcc-toolset-12/enable gcc --version g++ --version - clang --version - clang++ --version + + manylinux-install-clang -m \$(uname -m) -v 21.1.8.1 # The yum clang above stays for its libclang (bindgen, via yuv-sys). # webrtc-sys needs clang 21+ for the hermetic libc++ inside # libwebrtc, which AlmaLinux 8 cannot provide, so fetch one into # /opt/llvm as root; the hostuser build below only reads it. export LLVM_ROOT=/opt/llvm - /workspace/.github/scripts/install-clang.sh + export LIBCLANG_PATH=/usr/lib64 + export CC=/opt/clang/bin/clang CXX=/opt/clang/bin/clang++ + $CC --version + $CXX --version curl -fsSL https://rpm.nodesource.com/setup_20.x | bash - yum install -y nodejs --setopt=nodesource-nodejs.module_hotfixes=1 @@ -154,8 +157,9 @@ jobs: curl --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y export PATH=\$HOME/.cargo/bin:\$PATH source /opt/rh/gcc-toolset-12/enable - export CC=/opt/llvm/bin/clang - export CXX=/opt/llvm/bin/clang++ + export LIBCLANG_PATH=/usr/lib64 + export CC=/opt/clang/bin/clang + export CXX=/opt/clang/bin/clang++ TOOLCHAIN_ROOT=/opt/rh/gcc-toolset-12/root/usr export CFLAGS=\"--gcc-toolchain=\$TOOLCHAIN_ROOT\" export CXXFLAGS=\"--gcc-toolchain=\$TOOLCHAIN_ROOT\" From f6083e66fdc1d49f96416d4ec62b250c9935ec95 Mon Sep 17 00:00:00 2001 From: cloudwebrtc Date: Mon, 10 Aug 2026 11:47:19 +0800 Subject: [PATCH 47/53] fix. --- .github/workflows/node-builds.yml | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/.github/workflows/node-builds.yml b/.github/workflows/node-builds.yml index b5d55366c..4d768f3dc 100644 --- a/.github/workflows/node-builds.yml +++ b/.github/workflows/node-builds.yml @@ -126,23 +126,30 @@ jobs: cp /tmp/protoc /usr/local/bin/protoc chmod +x /usr/local/bin/protoc - yum install -y openssl-devel libX11-devel mesa-libGL-devel libXext-devel libva-devel libdrm-devel lld + yum install -y openssl-devel libX11-devel mesa-libGL-devel libXext-devel libva-devel libdrm-devel clang clang-devel lld yum install -y gcc-toolset-12-gcc gcc-toolset-12-gcc-c++ gcc-toolset-12-libstdc++-devel libstdc++-devel source /opt/rh/gcc-toolset-12/enable gcc --version g++ --version + clang --version + clang++ --version - manylinux-install-clang -m \$(uname -m) -v 21.1.8.1 - - # The yum clang above stays for its libclang (bindgen, via yuv-sys). + # The yum clang above stays for its libclang, which bindgen dlopens + # (yuv-sys); LIBCLANG_PATH below points it straight at that copy. + # # webrtc-sys needs clang 21+ for the hermetic libc++ inside - # libwebrtc, which AlmaLinux 8 cannot provide, so fetch one into - # /opt/llvm as root; the hostuser build below only reads it. - export LLVM_ROOT=/opt/llvm - export LIBCLANG_PATH=/usr/lib64 - export CC=/opt/clang/bin/clang CXX=/opt/clang/bin/clang++ - $CC --version - $CXX --version + # libwebrtc, which AlmaLinux 8 cannot provide. LLVM's own Linux + # release tarballs are built against glibc 2.34+ and refuse to run + # on manylinux_2_28's glibc 2.28, so instead of + # .github/scripts/install-clang.sh (which the ubuntu runners use) + # this uses the image's own manylinux-install-clang, which fetches a + # statically linked toolchain — glibc is irrelevant to it. -m picks + # the toolchain's architecture (x86_64 or aarch64 — both jobs run + # natively, so it is the container's) and -v is the static-clang + # release, i.e. LLVM 21.1.8 packaging revision 1. It unpacks into + # /opt/clang as root here; the hostuser build below only reads it. + manylinux-install-clang -m $(uname -m) -v 21.1.8.1 + /opt/clang/bin/clang++ --version curl -fsSL https://rpm.nodesource.com/setup_20.x | bash - yum install -y nodejs --setopt=nodesource-nodejs.module_hotfixes=1 @@ -157,9 +164,9 @@ jobs: curl --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y export PATH=\$HOME/.cargo/bin:\$PATH source /opt/rh/gcc-toolset-12/enable - export LIBCLANG_PATH=/usr/lib64 export CC=/opt/clang/bin/clang export CXX=/opt/clang/bin/clang++ + export LIBCLANG_PATH=/usr/lib64 TOOLCHAIN_ROOT=/opt/rh/gcc-toolset-12/root/usr export CFLAGS=\"--gcc-toolchain=\$TOOLCHAIN_ROOT\" export CXXFLAGS=\"--gcc-toolchain=\$TOOLCHAIN_ROOT\" From 4e9896c225af16460a780949b04ec8d7514e7201 Mon Sep 17 00:00:00 2001 From: cloudwebrtc Date: Mon, 10 Aug 2026 11:55:17 +0800 Subject: [PATCH 48/53] revert changes. --- .github/workflows/node-builds.yml | 23 ++--------------------- 1 file changed, 2 insertions(+), 21 deletions(-) diff --git a/.github/workflows/node-builds.yml b/.github/workflows/node-builds.yml index 4d768f3dc..8508e802f 100644 --- a/.github/workflows/node-builds.yml +++ b/.github/workflows/node-builds.yml @@ -133,24 +133,6 @@ jobs: g++ --version clang --version clang++ --version - - # The yum clang above stays for its libclang, which bindgen dlopens - # (yuv-sys); LIBCLANG_PATH below points it straight at that copy. - # - # webrtc-sys needs clang 21+ for the hermetic libc++ inside - # libwebrtc, which AlmaLinux 8 cannot provide. LLVM's own Linux - # release tarballs are built against glibc 2.34+ and refuse to run - # on manylinux_2_28's glibc 2.28, so instead of - # .github/scripts/install-clang.sh (which the ubuntu runners use) - # this uses the image's own manylinux-install-clang, which fetches a - # statically linked toolchain — glibc is irrelevant to it. -m picks - # the toolchain's architecture (x86_64 or aarch64 — both jobs run - # natively, so it is the container's) and -v is the static-clang - # release, i.e. LLVM 21.1.8 packaging revision 1. It unpacks into - # /opt/clang as root here; the hostuser build below only reads it. - manylinux-install-clang -m $(uname -m) -v 21.1.8.1 - /opt/clang/bin/clang++ --version - curl -fsSL https://rpm.nodesource.com/setup_20.x | bash - yum install -y nodejs --setopt=nodesource-nodejs.module_hotfixes=1 npm install --global pnpm @@ -164,9 +146,8 @@ jobs: curl --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y export PATH=\$HOME/.cargo/bin:\$PATH source /opt/rh/gcc-toolset-12/enable - export CC=/opt/clang/bin/clang - export CXX=/opt/clang/bin/clang++ - export LIBCLANG_PATH=/usr/lib64 + export CC=clang + export CXX=clang++ TOOLCHAIN_ROOT=/opt/rh/gcc-toolset-12/root/usr export CFLAGS=\"--gcc-toolchain=\$TOOLCHAIN_ROOT\" export CXXFLAGS=\"--gcc-toolchain=\$TOOLCHAIN_ROOT\" From b7e9c5a2489a0143f312913e5fdb39674854a62b Mon Sep 17 00:00:00 2001 From: cloudwebrtc Date: Mon, 10 Aug 2026 12:07:07 +0800 Subject: [PATCH 49/53] update. --- .github/workflows/ffi-builds.yml | 32 +++++--------------------------- 1 file changed, 5 insertions(+), 27 deletions(-) diff --git a/.github/workflows/ffi-builds.yml b/.github/workflows/ffi-builds.yml index a3c42c284..65379ae08 100644 --- a/.github/workflows/ffi-builds.yml +++ b/.github/workflows/ffi-builds.yml @@ -209,43 +209,21 @@ jobs: cd livekit-ffi cargo build --profile $env:CARGO_RUST_PROFILE --target ${{ matrix.target }} ${{ matrix.buildargs }} - # Use Docker on linux, so we can use manylinux images (ensure maximum mcompatibility) - # - # Two clangs on purpose. yum only supplies libclang.so, which bindgen - # dlopens (yuv-sys): that lives in clang-libs, which is why the llvm - # packages go in one transaction — el8 AppStream now carries several llvm - # streams, and two separate installs can pick llvm-libs from one and - # clang-libs from another, which fails the whole install. LIBCLANG_PATH - # points bindgen straight at it instead of letting clang-sys guess from - # llvm-config, which /opt/clang below shadows. - # - # CC/CXX are a different clang: webrtc-sys needs 21+ for libwebrtc's - # hermetic libc++, and it comes from manylinux-install-clang rather than - # .github/scripts/install-clang.sh (which the ubuntu runners use) because - # LLVM's own Linux release tarballs are built against glibc 2.34+ and - # refuse to run on manylinux_2_28's glibc 2.28. manylinux-install-clang - # fetches a statically linked toolchain instead, so glibc is irrelevant. It - # unpacks into /opt/clang, which these images already have on PATH, and - # writes clang config files pointing at the image's gcc-toolset. -m picks - # the toolchain's own architecture (x86_64 or aarch64 — both jobs run - # natively, so it is the container's) and -v is the static-clang release, - # i.e. LLVM 21.1.8 packaging revision 1; `manylinux-install-clang -l` - # lists what an image knows about. - name: Build (Linux) if: ${{ matrix.platform == 'linux' }} run: | docker run --rm -e CARGO_RUST_PROFILE="$CARGO_RUST_PROFILE" -v $PWD:/workspace -w /workspace ${{ matrix.build_image }} bash -c "\ uname -a; \ export PATH=/root/.cargo/bin:\$PATH; \ - yum install llvm llvm-libs lld -y; \ + yum install clang clang-devel lld -y; \ yum install protobuf-compiler -y; \ yum groupinstall 'Development Tools' -y; \ yum install openssl-devel libX11-devel mesa-libGL-devel libXext-devel libva-devel libdrm-devel libgbm-devel libXdamage-devel libXrandr-devel libXfixes-devel libXcomposite-devel -y; \ - manylinux-install-clang -m \$(uname -m) -v 21.1.8.1; \ - export LLVM_ROOT=/opt/llvm; \ + clang --version; \ + clang++ --version; \ export LIBCLANG_PATH=/usr/lib64; \ - export CC=/opt/clang/bin/clang CXX=/opt/clang/bin/clang++; \ - \$CXX --version; \ + export CC=clang; \ + export CXX=clang++; \ curl --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y; \ cd livekit-ffi && cargo build --profile \"\$CARGO_RUST_PROFILE\" --target ${{ matrix.target }} ${{ matrix.buildargs }}" From 75555bc0d256670706fcc7ac173ffad9b0115574 Mon Sep 17 00:00:00 2001 From: cloudwebrtc Date: Mon, 10 Aug 2026 12:13:27 +0800 Subject: [PATCH 50/53] update. --- .github/workflows/ffi-builds.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ffi-builds.yml b/.github/workflows/ffi-builds.yml index 65379ae08..8c76c1557 100644 --- a/.github/workflows/ffi-builds.yml +++ b/.github/workflows/ffi-builds.yml @@ -209,6 +209,7 @@ jobs: cd livekit-ffi cargo build --profile $env:CARGO_RUST_PROFILE --target ${{ matrix.target }} ${{ matrix.buildargs }} + # Use Docker on linux, so we can use manylinux images (ensure maximum mcompatibility) - name: Build (Linux) if: ${{ matrix.platform == 'linux' }} run: | From 29ba605d66d477372be07be872bc9ad401f36a29 Mon Sep 17 00:00:00 2001 From: cloudwebrtc Date: Mon, 10 Aug 2026 12:19:34 +0800 Subject: [PATCH 51/53] revert changes. --- libwebrtc/src/native/peer_connection_factory.rs | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/libwebrtc/src/native/peer_connection_factory.rs b/libwebrtc/src/native/peer_connection_factory.rs index 307bab7fc..16e6244f3 100644 --- a/libwebrtc/src/native/peer_connection_factory.rs +++ b/libwebrtc/src/native/peer_connection_factory.rs @@ -38,20 +38,9 @@ lazy_static! { fn ensure_log_sink() { let mut log_sink = LOG_SINK.lock(); if log_sink.is_none() { - *log_sink = Some(sys_rtc::ffi::new_log_sink(|msg, severity| { + *log_sink = Some(sys_rtc::ffi::new_log_sink(|msg, _| { let msg = msg.strip_suffix("\r\n").or(msg.strip_suffix('\n')).unwrap_or(&msg); - // The sink is registered at LS_VERBOSE, so map the severity through - // instead of flattening everything to DEBUG: otherwise `RUST_LOG` - // can only choose between all of libwebrtc's output and none of it. - let level = match severity { - sys_rtc::ffi::LoggingSeverity::Verbose => log::Level::Trace, - sys_rtc::ffi::LoggingSeverity::Info => log::Level::Debug, - sys_rtc::ffi::LoggingSeverity::Warning => log::Level::Warn, - sys_rtc::ffi::LoggingSeverity::Error => log::Level::Error, - // LS_NONE never reaches a sink; nothing sensible to map it to. - _ => log::Level::Trace, - }; - log::log!(target: "libwebrtc", level, "{}", msg); + log::debug!(target: "libwebrtc", "{}", msg); })); } } From 3e01861335163061658005f32ca3049fc43a949e Mon Sep 17 00:00:00 2001 From: cloudwebrtc Date: Mon, 10 Aug 2026 12:48:59 +0800 Subject: [PATCH 52/53] fix CI build issue for linux arm64. --- webrtc-sys/libwebrtc/build_linux.sh | 46 +++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/webrtc-sys/libwebrtc/build_linux.sh b/webrtc-sys/libwebrtc/build_linux.sh index a253caa81..417c9b9f6 100755 --- a/webrtc-sys/libwebrtc/build_linux.sh +++ b/webrtc-sys/libwebrtc/build_linux.sh @@ -149,6 +149,32 @@ gn gen "$OUTPUT_DIR" --root="src" --args="${args}" # build static library ninja -C "$OUTPUT_DIR" :default +# Build the hermetic libc++/libc++abi for the *target* explicitly. +# +# :default does not: nothing here links a target binary (no tests, tools or +# examples, and libwebrtc is a static library), so the libc++ headers get used +# but its own translation units are never compiled. On x64 that went unnoticed +# because use_custom_libcxx_for_host builds libc++ for the host toolchain, which +# in a native build shares $OUTPUT_DIR/obj with the target — so the host copy +# landed in the archive below by accident. Cross-compiling arm64 puts the host +# copy under $OUTPUT_DIR/clang_x64/obj instead, and the arm64 artifact shipped +# with every out-of-line std::__Cr symbol undefined (std::__Cr::locale, +# __libcpp_verbose_abort, __cxa_throw, ...). Nothing in this build notices; it +# only surfaces when a downstream crate links webrtc-sys. +# +# Ask ninja for the archive paths rather than hardcoding a GN label, so this +# fails loudly instead of silently no-opping if libc++ ever moves. Host copies +# live under a toolchain subdir, so anchoring at obj/ keeps them out. +libcxx_archives=$(ninja -C "$OUTPUT_DIR" -t targets all \ + | grep -oE '^obj/[^:]*/libc\+\+(abi)?\.a' | sort -u) +if [ -z "$libcxx_archives" ]; then + echo "Error: no hermetic libc++ static library in the ninja graph for $OUTPUT_DIR." >&2 + echo " use_custom_libcxx=true is an ABI contract with webrtc-sys; aborting." >&2 + exit 1 +fi +echo "Building hermetic libc++: $libcxx_archives" +ninja -C "$OUTPUT_DIR" $libcxx_archives + # make libwebrtc.a # don't include nasm # Start from scratch: `ar -rc` only replaces members it is given, so members left @@ -157,6 +183,26 @@ rm -f "$ARTIFACTS_DIR/lib/libwebrtc.a" ar -rc "$ARTIFACTS_DIR/lib/libwebrtc.a" `find "$OUTPUT_DIR/obj" -name '*.o' -not -path "*/third_party/nasm/*"` src/third_party/llvm-build/Release+Asserts/bin/llvm-objcopy --redefine-syms="$COMMAND_DIR/boringssl_prefix_symbols.txt" "$ARTIFACTS_DIR/lib/libwebrtc.a" +# The archive is the whole standard library for webrtc-sys (build.rs passes +# cpp_link_stdlib(None), since mixing in the host libstdc++ would be a second, +# incompatible stdlib). Check the out-of-line half is really in there instead of +# publishing an artifact that only fails at the downstream link step. One nm pass +# over an 80MB archive is enough for both markers: libc++ and libc++abi land in +# obj/ together or not at all. +libcxx_markers=$(src/third_party/llvm-build/Release+Asserts/bin/llvm-nm --defined-only \ + "$ARTIFACTS_DIR/lib/libwebrtc.a" 2>/dev/null \ + | grep -oE '__libcpp_verbose_abort|__cxa_throw' | sort -u | tr '\n' ' ') +for sym in __libcpp_verbose_abort __cxa_throw; do + case " $libcxx_markers " in + *" $sym "*) ;; + *) + echo "Error: $ARTIFACTS_DIR/lib/libwebrtc.a defines no $sym." >&2 + echo " The hermetic libc++/libc++abi objects are missing from the archive." >&2 + exit 1 + ;; + esac +done + # License generation is optional - may fail with some Python versions # Use vpython3 from depot_tools for consistent Python version vpython3 "./src/tools_webrtc/libs/generate_licenses.py" \ From 9f0c33227a4918d52391678f894b1c2999d96e37 Mon Sep 17 00:00:00 2001 From: CloudWebRTC Date: Mon, 10 Aug 2026 14:13:47 +0800 Subject: [PATCH 53/53] Update lib.rs --- webrtc-sys/build/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webrtc-sys/build/src/lib.rs b/webrtc-sys/build/src/lib.rs index f81deb3ba..e08f374a2 100644 --- a/webrtc-sys/build/src/lib.rs +++ b/webrtc-sys/build/src/lib.rs @@ -28,7 +28,7 @@ use regex::Regex; use reqwest::StatusCode; pub const SCRATH_PATH: &str = "livekit_webrtc"; -pub const WEBRTC_TAG: &str = "webrtc-f8a0b64"; +pub const WEBRTC_TAG: &str = "webrtc-f8a0b64-1"; pub const IGNORE_DEFINES: [&str; 2] = ["CR_CLANG_REVISION", "CR_XCODE_VERSION"]; pub fn target_os() -> String {