Skip to content

Commit 9500e32

Browse files
committed
fix.
1 parent 7454992 commit 9500e32

5 files changed

Lines changed: 98 additions & 53 deletions

File tree

.github/workflows/webrtc-builds.yml

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,12 @@ jobs:
4646
arch: arm64
4747

4848
- name: linux
49-
os: ubuntu-26.04
49+
os: ubuntu-latest
5050
cmd: ./build_linux.sh
5151
arch: x64
5252

5353
- name: linux
54-
os: ubuntu-26.04-arm
54+
os: ubuntu-latest
5555
cmd: ./build_linux.sh
5656
arch: arm64
5757

@@ -113,16 +113,11 @@ jobs:
113113
pip3 install setuptools # pkg_resources is sometimes not found?
114114
115115
- name: Install Linux dependencies
116-
if: ${{ (matrix.target.os == 'ubuntu-latest') || (matrix.target.name == 'linux') }}
116+
if: ${{ matrix.target.os == 'ubuntu-latest'}}
117117
run: |
118118
sudo apt update -y
119119
sudo apt install -y ninja-build pkg-config openjdk-11-jdk
120120
121-
- name: Install Linux dependencies for Ubuntu 26
122-
if: ${{ matrix.target.name == 'linux' }}
123-
run: |
124-
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
125-
126121
- name: Select Xcode 26.0
127122
if: ${{ matrix.target.os == 'macos-latest' }}
128123
run: sudo xcode-select --switch /Applications/Xcode_26.0.app/Contents/Developer
@@ -148,7 +143,7 @@ jobs:
148143

149144
- name: Free Disk Space (Ubuntu)
150145
uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be
151-
if: ${{ (matrix.target.os == 'ubuntu-latest') || (matrix.target.name == 'linux') }}
146+
if: ${{ matrix.target.os == 'ubuntu-latest' }}
152147
with:
153148
android: false
154149
tool-cache: true

webrtc-sys/build.rs

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,8 @@ fn main() {
176176
println!("cargo:rustc-link-lib=dylib=pthread");
177177
println!("cargo:rustc-link-lib=dylib=m");
178178

179+
configure_hermetic_libcxx(&mut builder, &webrtc_include);
180+
179181
// In order to avoid any ABI mismatches we use the sysroot's headers.
180182
add_gio_headers(&mut builder);
181183

@@ -496,6 +498,71 @@ fn add_lazy_load_so(builder: &mut cc::Build, name: &str, libraries: Vec<String>)
496498
}
497499
}
498500

501+
/// Compile against the same hermetic libc++ that is baked into libwebrtc.a.
502+
///
503+
/// The Linux libwebrtc build sets `use_custom_libcxx=true`, so every std type in
504+
/// its public API lives in the `std::__Cr` ABI namespace with libc++ layouts.
505+
/// Using the host's libstdc++ here instead is not merely a mangling mismatch that
506+
/// the linker would catch: `std::span` is layout-different between the two, so a
507+
/// span handed to libwebrtc silently arrives with its pointer and size swapped.
508+
///
509+
/// Mirrors the flags in the WebRTC checkout's `build/config/c++/BUILD.gn`. The
510+
/// matching `_LIBCPP_*` defines come from webrtc.ninja via `webrtc_defines()`.
511+
fn configure_hermetic_libcxx(builder: &mut cc::Build, webrtc_include: &path::Path) {
512+
let libcxx = webrtc_include.join("third_party/libc++/src/include");
513+
let libcxxabi = webrtc_include.join("third_party/libc++abi/src/include");
514+
if !libcxx.join("span").exists() {
515+
panic!(
516+
"hermetic libc++ headers missing from {}.\n\
517+
This libwebrtc artifact predates use_custom_libcxx=true; rebuild it with \
518+
build_linux.sh or point LK_CUSTOM_WEBRTC at a newer one.",
519+
libcxx.display()
520+
);
521+
}
522+
523+
// Chromium's libc++ is clang-only. At _LIBCPP_ABI_VERSION 2 it marks unique_ptr
524+
// and shared_ptr __attribute__((trivial_abi)), which GCC accepts and silently
525+
// ignores (a -Wattributes warning that cc's `-w` swallows). That attribute
526+
// changes the calling convention, not just layout: libwebrtc.a returns
527+
// std::unique_ptr in a register, while a GCC caller reads it back from an sret
528+
// slot the callee never wrote, yielding a garbage pointer at the first use.
529+
if env::var_os("CXX").is_none() {
530+
if Command::new("clang++").arg("--version").output().is_err() {
531+
panic!(
532+
"clang++ is required to build webrtc-sys on Linux: libwebrtc.a is built \
533+
against Chromium's hermetic libc++, whose trivial_abi annotations GCC \
534+
ignores, which silently breaks the calling convention for std::unique_ptr \
535+
and std::shared_ptr. Install clang, or set CXX to a clang.",
536+
);
537+
}
538+
builder.compiler("clang++");
539+
}
540+
541+
builder
542+
.flag("-nostdinc++")
543+
.flag(format!("-isystem{}", libcxx.display()))
544+
.flag(format!("-isystem{}", libcxxabi.display()))
545+
// Holds __config_site, which pins _LIBCPP_ABI_NAMESPACE=__Cr.
546+
.include(webrtc_include.join("buildtools/third_party/libc++"));
547+
548+
// libc++/libc++abi are already archived into libwebrtc.a, so linking the
549+
// host libstdc++ on top would only add a second, incompatible stdlib.
550+
builder.cpp_link_stdlib(None);
551+
552+
// The cxx crate builds its own runtime (cxx.cc) with the host default stdlib,
553+
// so the rust::String <-> std::string conversions it exports are mangled for
554+
// libstdc++ and cannot satisfy the std::__Cr call sites in the generated
555+
// bridges. Compile a second copy with the flags above to provide those.
556+
// DEP_CXXBRIDGE1_HEADER is `cargo:HEADER` from the cxx crate: <root>/include/cxx.h.
557+
let cxx_h = env::var("DEP_CXXBRIDGE1_HEADER")
558+
.expect("cxx crate did not export HEADER; cannot locate its cxx.cc");
559+
let cxx_root = path::Path::new(&cxx_h)
560+
.parent()
561+
.and_then(path::Path::parent)
562+
.expect("unexpected DEP_CXXBRIDGE1_HEADER layout");
563+
builder.file(cxx_root.join("src/cxx.cc"));
564+
}
565+
499566
fn add_gio_headers(builder: &mut cc::Build) {
500567
let webrtc_dir = webrtc_sys_build::webrtc_dir();
501568
let target_arch = webrtc_sys_build::target_arch();

webrtc-sys/libwebrtc/build_linux.sh

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -86,18 +86,10 @@ git apply "$COMMAND_DIR/patches/fix_pipewire_utils_compile.patch" -v --ignore-sp
8686
# See: https://github.com/zed-industries/zed/pull/51433#discussion_r2944567608
8787
git -C build apply "$COMMAND_DIR/patches/disable_crel.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn
8888

89-
# GCC reports -Wchanges-meaning as an error rather than a warning, so
90-
# treat_warnings_as_errors=false does not cover it and WebRTC does not build without this.
91-
git -C build apply "$COMMAND_DIR/patches/disable_gcc_changes_meaning.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn
92-
9389
cd third_party
9490

9591
git apply "$COMMAND_DIR/patches/david_disable_gun_source_macro.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn
9692

97-
if [ "$arch" = "x64" ]; then
98-
git apply "$COMMAND_DIR/patches/fix_abseil_cpp_build_on_x64.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn
99-
fi
100-
10193
cd libyuv
10294

10395
git apply "$COMMAND_DIR/patches/disable_sme_for_libyuv.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn
@@ -117,19 +109,23 @@ fi
117109
# Without this flag, the build may fail partway through, resulting in missing
118110
# or incomplete artifacts.
119111
#
120-
# The C++ standard library choice is an ABI contract with webrtc-sys, which is compiled
121-
# by the cc crate against whatever the host toolchain provides:
112+
# The C++ standard library choice is an ABI contract with webrtc-sys:
122113
#
123-
# use_custom_libcxx=false keeps every std type in libwebrtc.a mangled the way
124-
# libstdc++ mangles it, instead of Chromium's std::__Cr:: ABI namespace.
114+
# use_custom_libcxx=true builds against Chromium's hermetic libc++, whose
115+
# headers we ship in the artifacts (see below) so webrtc-sys compiles against
116+
# byte-identical std types. The alternative -- letting each side use its own
117+
# host stdlib -- is unsound now that WebRTC puts std types like std::span in
118+
# public API signatures: libstdc++ reordered std::span's members after GCC 10,
119+
# so a span built by the host and read inside libwebrtc.a had its pointer and
120+
# size swapped, turning a 14-byte DataChannel::Send into new uint8_t[93TB].
125121
args="is_debug=$debug \
126122
target_os=\"linux\" \
127123
target_cpu=\"$arch\" \
128124
rtc_enable_protobuf=false \
129125
treat_warnings_as_errors=false \
130126
use_llvm_libatomic=false \
131-
use_custom_libcxx=false \
132-
use_custom_libcxx_for_host=false \
127+
use_custom_libcxx=true \
128+
use_custom_libcxx_for_host=true \
133129
use_clang_modules=false \
134130
rtc_include_tests=false \
135131
rtc_build_tools=false \
@@ -155,6 +151,9 @@ ninja -C "$OUTPUT_DIR" :default
155151

156152
# make libwebrtc.a
157153
# don't include nasm
154+
# Start from scratch: `ar -rc` only replaces members it is given, so members left
155+
# over from a previous build with different args would survive into the archive.
156+
rm -f "$ARTIFACTS_DIR/lib/libwebrtc.a"
158157
ar -rc "$ARTIFACTS_DIR/lib/libwebrtc.a" `find "$OUTPUT_DIR/obj" -name '*.o' -not -path "*/third_party/nasm/*"`
159158
src/third_party/llvm-build/Release+Asserts/bin/llvm-objcopy --redefine-syms="$COMMAND_DIR/boringssl_prefix_symbols.txt" "$ARTIFACTS_DIR/lib/libwebrtc.a"
160159

@@ -172,3 +171,17 @@ cp "$OUTPUT_DIR/LICENSE.md" "$ARTIFACTS_DIR"
172171
cd src
173172
find . -name "*.h" -print | cpio -pd "$ARTIFACTS_DIR/include"
174173
find . -name "*.inc" -print | cpio -pd "$ARTIFACTS_DIR/include"
174+
175+
# Ship Chromium's hermetic libc++ so webrtc-sys can compile against the exact
176+
# same standard library that is baked into libwebrtc.a (see use_custom_libcxx
177+
# above). The find calls cannot do this: libc++ headers have no extension.
178+
# Paths mirror the -isystem/-I flags in build/config/c++/BUILD.gn, so build.rs
179+
# can point at them the same way the WebRTC build does.
180+
for inc in third_party/libc++/src/include third_party/libc++abi/src/include; do
181+
mkdir -p "$ARTIFACTS_DIR/include/$inc"
182+
cp -R "$inc/." "$ARTIFACTS_DIR/include/$inc/"
183+
done
184+
mkdir -p "$ARTIFACTS_DIR/include/buildtools/third_party/libc++"
185+
cp buildtools/third_party/libc++/__config_site \
186+
buildtools/third_party/libc++/__assertion_handler \
187+
"$ARTIFACTS_DIR/include/buildtools/third_party/libc++/"

webrtc-sys/libwebrtc/patches/disable_gcc_changes_meaning.patch

Lines changed: 0 additions & 17 deletions
This file was deleted.

webrtc-sys/libwebrtc/patches/fix_abseil_cpp_build_on_x64.patch

Lines changed: 0 additions & 13 deletions
This file was deleted.

0 commit comments

Comments
 (0)