Skip to content

Commit c145af2

Browse files
committed
build_linux.sh: add option to use host toolchain
This adds a --toolchain CLI option to the script that can be either * gnu * llvm * chromium-llvm The gnu and llvm options use the system's toolchain. chromium-llvm uses Chromium's prebuilt LLVM toolchain with its Debian sysroot. Previously, the script tried to combine the system's gcc with libstdc++ from Chromium's Debian sysroot, which failed to find glibc headers: [1/4184] CXX obj/third_party/abseil-cpp/absl/base/base/cycleclock.o FAILED: obj/third_party/abseil-cpp/absl/base/base/cycleclock.o g++ -MMD -MF obj/third_party/abseil-cpp/absl/base/base/cycleclock.o.d -DUSE_UDEV -DUSE_AURA=1 -DUSE_GLIB=1 -DUSE_OZONE=1 -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_NONE -D_GLIBCXX_ASSERTIONS=1 -DCR_SYSROOT_KEY=20250129T203412Z-1 -DNDEBUG -DNVALGRIND -DDYNAMIC_ANNOTATIONS_ENABLED=0 -DABSL_ALLOCATOR_NOTHROW=1 -I.. -Igen -I../third_party/abseil-cpp -fno-strict-overflow -fno-ident -fno-strict-aliasing -fstack-protector -funwind-tables -fPIC -pipe -pthread -m64 -msse3 -Wno-builtin-macro-redefined -D__DATE__= -D__TIME__= -D__TIMESTAMP__= -O2 -fdata-sections -ffunction-sections -fno-math-errno -fno-omit-frame-pointer -g0 -fvisibility=hidden -Wno-unused-local-typedefs -Wno-maybe-uninitialized -Wno-deprecated-declarations -Wno-comments -Wno-packed-not-aligned -Wno-missing-field-initializers -Wno-unused-parameter -Wno-psabi -std=gnu++2a -Wno-changes-meaning -fno-exceptions --sysroot=../build/linux/debian_bullseye_amd64-sysroot -fvisibility-inlines-hidden -Wno-narrowing -Wno-class-memaccess -Wno-invalid-offsetof -c ../third_party/abseil-cpp/absl/base/internal/cycleclock.cc -o obj/third_party/abseil-cpp/absl/base/base/cycleclock.o In file included from /usr/include/c++/15/bits/version.h:51, from /usr/include/c++/15/atomic:50, from ../third_party/abseil-cpp/absl/base/internal/cycleclock.h:45, from ../third_party/abseil-cpp/absl/base/internal/cycleclock.cc:23: /usr/include/c++/15/x86_64-redhat-linux/bits/c++config.h:3:10: fatal error: bits/wordsize.h: No such file or directory 3 | #include <bits/wordsize.h> | ^~~~~~~~~~~~~~~~~
1 parent 23d9546 commit c145af2

File tree

5 files changed

+980
-59
lines changed

5 files changed

+980
-59
lines changed

.github/workflows/webrtc-builds.yml

Lines changed: 7 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,12 @@ jobs:
4747

4848
- name: linux
4949
os: ubuntu-latest
50-
cmd: ./build_linux.sh
50+
cmd: ./build_linux.sh --toolchain chromium-llvm
5151
arch: x64
5252

5353
- name: linux
5454
os: ubuntu-latest
55-
cmd: ./build_linux.sh
55+
cmd: ./build_linux.sh --toolchain chromium-llvm
5656
arch: arm64
5757

5858
- name: android
@@ -110,38 +110,18 @@ jobs:
110110
- name: install setuptools (none-macOS)
111111
if: ${{ matrix.target.os != 'macos-latest' }}
112112
run: |
113-
pip3 install setuptools # pkg_resources is sometimes not found?
113+
pip3 install setuptools # pkg_resources is sometimes not found?
114114
115-
- name: Add GCC PPA and install GCC 14
116-
if: ${{ matrix.target.os == 'ubuntu-latest' }}
117-
run: |
118-
sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y
119-
sudo apt update
120-
sudo apt install gcc-14 g++-14 g++-14-aarch64-linux-gnu -y
121-
122-
- name: Verify GCC 14 installation
123-
if: ${{ matrix.target.os == 'ubuntu-latest' }}
124-
run: |
125-
gcc-14 --version
126-
g++-14 --version
127-
aarch64-linux-gnu-g++-14 --version
128-
129-
- name: Set GCC 14 as default (optional)
130-
if: ${{ matrix.target.os == 'ubuntu-latest' }}
131-
run: |
132-
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-14 140 --slave /usr/bin/g++ g++ /usr/bin/g++-14
133-
sudo update-alternatives --config gcc
134-
gcc --version
135-
sudo update-alternatives --install /usr/bin/aarch64-linux-gnu-gcc aarch64-linux-gnu-gcc /usr/bin/aarch64-linux-gnu-gcc-14 140 --slave /usr/bin/aarch64-linux-gnu-g++ aarch64-linux-gnu-g++ /usr/bin/aarch64-linux-gnu-g++-14
136-
sudo update-alternatives --config aarch64-linux-gnu-gcc
137-
aarch64-linux-gnu-gcc --version
138-
139115
- name: Install linux dependencies
140116
if: ${{ matrix.target.os == 'ubuntu-latest' }}
141117
run: |
142118
sudo apt update -y
143119
sudo apt install -y ninja-build pkg-config openjdk-11-jdk
144120
121+
- name: Disable __GLIBC_USE_ISOC2X macro
122+
if: ${{ matrix.target.name == 'linux' && matrix.target.arch == 'arm64' }}
123+
run: sudo sed -i 's/__GLIBC_USE_ISOC2X[[:space:]]*1/__GLIBC_USE_ISOC2X\t0/' /usr/include/features.h
124+
145125
- name: Install macos dependencies
146126
if: ${{ matrix.target.os == 'macos-latest' }}
147127
run: brew install ninja

webrtc-sys/Cargo.toml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,15 @@ use_vaapi = []
1313
use_nvidia = []
1414

1515
[dependencies]
16-
cxx = "1.0"
16+
# Copy an updated version of the cxx.cc file from cxx's repository
17+
# into the src directory when updating to a new version of cxx
18+
# and change the include path for cxx.h to "rust/cxx.h"
19+
cxx = "=1.0.186"
1720
log = "0.4"
1821

1922
[build-dependencies]
2023
webrtc-sys-build = { workspace = true }
21-
cxx-build = "1.0"
24+
cxx-build = "=1.0.186"
2225
glob = "0.3"
2326
cc = "1.0"
2427

webrtc-sys/build.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,23 @@ fn main() {
148148
.flag("/EHsc");
149149
}
150150
"linux" => {
151+
// If libwebrtc was built with Chromium's libc++, the C++ in this crate needs to be built with it too.
152+
let buildtools = webrtc_include.join("buildtools/third_party/libc++");
153+
if buildtools.exists() {
154+
// Chromium's libc++ doesn't build with GCC
155+
if env::var("CC").is_err() {
156+
builder.compiler("clang++");
157+
}
158+
builder.include(buildtools);
159+
builder.flag("-nostdinc++");
160+
let webrtc_include = webrtc_include.to_string_lossy();
161+
builder.flag(format!("-isystem{webrtc_include}/third_party/libc++/src/include"));
162+
builder.flag(format!("-isystem{webrtc_include}/third_party/libc++abi/src/include"));
163+
// The cxx crate builds this C++ file. However, this crate needs to rebuild it when using a
164+
// different C++ standard library or linking will fail with unresolved symbol errors.
165+
builder.file("src/cxx.cc");
166+
}
167+
151168
println!("cargo:rustc-link-lib=dylib=rt");
152169
println!("cargo:rustc-link-lib=dylib=dl");
153170
println!("cargo:rustc-link-lib=dylib=pthread");

webrtc-sys/libwebrtc/build_linux.sh

Lines changed: 81 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
arch=""
1818
profile="release"
19+
toolchain="gnu"
1920

2021
while [ "$#" -gt 0 ]; do
2122
case "$1" in
@@ -35,6 +36,14 @@ while [ "$#" -gt 0 ]; do
3536
fi
3637
shift 2
3738
;;
39+
--toolchain)
40+
toolchain="$2"
41+
if [ "$toolchain" != "gnu" ] && [ "$toolchain" != "llvm" ] && [ "$toolchain" != "chromium-llvm" ]; then
42+
echo "Error: Invalid value for --toolchain. Must be 'gnu', 'llvm', or 'chromium-llvm' (Chromium's bundled Clang with Debian sysroot)"
43+
exit 1
44+
fi
45+
shift 2
46+
;;
3847
*)
3948
echo "Error: Unknown argument '$1'"
4049
exit 1
@@ -50,46 +59,78 @@ fi
5059
echo "Building LiveKit WebRTC - Linux"
5160
echo "Arch: $arch"
5261
echo "Profile: $profile"
62+
echo "Toolchain: $toolchain"
63+
64+
export COMMAND_DIR=$(cd $(dirname $0); pwd)
65+
export OUTPUT_DIR="$(pwd)/build-$arch-$profile"
66+
export ARTIFACTS_DIR="$(pwd)/linux-$arch-$profile"
67+
68+
if [ "$toolchain" == "gnu" ]; then
69+
[ -n "$CC" ] || export CC="$(which gcc)"
70+
[ -n "$CXX" ] || export CXX="$(which g++)"
71+
[ -n "$AR" ] || export AR="$(which ar)"
72+
[ -n "$NM" ] || export NM="$(which nm)"
73+
export CXXFLAGS="${CXXFLAGS} -Wno-changes-meaning -Wno-unknown-pragmas -D_DEFAULT_SOURCE"
74+
OBJCOPY="$(which objcopy)"
75+
chromium_libcxx=false
76+
toolchain_gn_args="is_clang=false \
77+
use_sysroot=false \
78+
custom_toolchain=\"//build/toolchain/linux/unbundle:default\" \
79+
host_toolchain=\"//build/toolchain/linux/unbundle:default\""
80+
elif [ "$toolchain" == "llvm" ]; then
81+
[ -n "$CC" ] || export CC="$(which clang)"
82+
[ -n "$CXX" ] || export CXX="$(which clang++)"
83+
[ -n "$AR" ] || export AR="$(which llvm-ar)"
84+
[ -n "$NM" ] || export NM="$(which llvm-nm)"
85+
OBJCOPY="$(which llvm-objcopy)"
86+
# Using system libc++ stumbles over
87+
# https://github.com/llvm/llvm-project/issues/50248
88+
# so use Chromium's libc++
89+
chromium_libcxx=true
90+
toolchain_gn_args="is_clang=true \
91+
clang_use_chrome_plugins=false \
92+
use_sysroot=false \
93+
custom_toolchain=\"//build/toolchain/linux/unbundle:default\" \
94+
host_toolchain=\"//build/toolchain/linux/unbundle:default\""
95+
elif [ "$toolchain" == "chromium-llvm" ]; then
96+
AR="$COMMAND_DIR/src/third_party/llvm-build/Release+Asserts/bin/llvm-ar"
97+
OBJCOPY="$COMMAND_DIR/src/third_party/llvm-build/Release+Asserts/bin/llvm-objcopy"
98+
chromium_libcxx=true
99+
toolchain_gn_args="is_clang=true \
100+
use_custom_libcxx=true \
101+
use_sysroot=true"
102+
fi
103+
104+
set -x
53105

54106
if [ ! -e "$(pwd)/depot_tools" ]
55107
then
56108
git clone --depth 1 https://chromium.googlesource.com/chromium/tools/depot_tools.git
57109
fi
58110

59-
export COMMAND_DIR=$(cd $(dirname $0); pwd)
111+
# must be done after runing `which` to find toolchain's executables above
60112
export PATH="$(pwd)/depot_tools:$PATH"
61-
export OUTPUT_DIR="$(pwd)/src/out-$arch-$profile"
62-
export ARTIFACTS_DIR="$(pwd)/linux-$arch-$profile"
63113

64-
if [ ! -e "$(pwd)/src" ]
65-
then
66-
gclient sync -D --no-history
114+
if [ ! -e "$(pwd)/src" ]; then
115+
# use --nohooks to avoid the download_from_google_storage hook that takes > 6 minutes
116+
# then manually run the other hooks
117+
gclient sync -D --no-history --nohooks
118+
python3 src/tools/rust/update_rust.py
119+
if [ "$toolchain" == "chromium-llvm" ] || [ "$toolchain" == "llvm" ]; then
120+
python3 src/tools/clang/scripts/update.py
121+
fi
122+
if [ "$toolchain" == "chromium-llvm" ]; then
123+
python3 src/build/linux/sysroot_scripts/install-sysroot.py --arch=x64
124+
python3 src/build/linux/sysroot_scripts/install-sysroot.py --arch=arm64
125+
fi
67126
fi
68127

69128
cd src
70129
git apply "$COMMAND_DIR/patches/add_licenses.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn
71130
git apply "$COMMAND_DIR/patches/ssl_verify_callback_with_native_handle.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn
72131
git apply "$COMMAND_DIR/patches/add_deps.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn
73-
74-
cd build
75-
76-
git apply "$COMMAND_DIR/patches/force_gcc.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn
77-
78-
cd ..
79-
80-
cd third_party
81-
82132
git apply "$COMMAND_DIR/patches/david_disable_gun_source_macro.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn
83-
84-
cd ../..
85-
86-
mkdir -p "$ARTIFACTS_DIR/lib"
87-
88-
python3 "./src/build/linux/sysroot_scripts/install-sysroot.py" --arch="$arch"
89-
90-
if [ "$arch" = "arm64" ]; then
91-
sudo sed -i 's/__GLIBC_USE_ISOC2X[[:space:]]*1/__GLIBC_USE_ISOC2X\t0/' /usr/aarch64-linux-gnu/include/features.h
92-
fi
133+
cd ..
93134

94135
debug="false"
95136
if [ "$profile" = "debug" ]; then
@@ -101,7 +142,7 @@ args="is_debug=$debug \
101142
target_cpu=\"$arch\" \
102143
rtc_enable_protobuf=false \
103144
treat_warnings_as_errors=false \
104-
use_custom_libcxx=false \
145+
use_custom_libcxx=${chromium_libcxx}
105146
use_llvm_libatomic=false \
106147
use_libcxx_modules=false \
107148
use_custom_libcxx_for_host=false \
@@ -119,19 +160,23 @@ args="is_debug=$debug \
119160
symbol_level=0 \
120161
enable_iterator_debugging=false \
121162
use_rtti=true \
122-
is_clang=false \
123-
rtc_use_x11=false"
163+
rtc_use_x11=false \
164+
$toolchain_gn_args"
165+
166+
set -e
124167

125168
# generate ninja files
126169
gn gen "$OUTPUT_DIR" --root="src" --args="${args}"
127170

128171
# build static library
129172
ninja -C "$OUTPUT_DIR" :default
130173

174+
mkdir -p "$ARTIFACTS_DIR/lib"
175+
131176
# make libwebrtc.a
132177
# don't include nasm
133-
ar -rc "$ARTIFACTS_DIR/lib/libwebrtc.a" `find "$OUTPUT_DIR/obj" -name '*.o' -not -path "*/third_party/nasm/*"`
134-
objcopy --redefine-syms="$COMMAND_DIR/boringssl_prefix_symbols.txt" "$ARTIFACTS_DIR/lib/libwebrtc.a"
178+
"$AR" -rc "$ARTIFACTS_DIR/lib/libwebrtc.a" `find "$OUTPUT_DIR/obj" -name '*.o' -not -path "*/third_party/nasm/*"`
179+
"$OBJCOPY" --redefine-syms="$COMMAND_DIR/boringssl_prefix_symbols.txt" "$ARTIFACTS_DIR/lib/libwebrtc.a"
135180

136181
python3 "./src/tools_webrtc/libs/generate_licenses.py" \
137182
--target :default "$OUTPUT_DIR" "$OUTPUT_DIR"
@@ -141,5 +186,11 @@ cp "$OUTPUT_DIR/args.gn" "$ARTIFACTS_DIR"
141186
cp "$OUTPUT_DIR/LICENSE.md" "$ARTIFACTS_DIR"
142187

143188
cd src
189+
if [ $chromium_libcxx == "true" ]; then
190+
mkdir -p "$ARTIFACTS_DIR/include/buildtools/third_party"
191+
cp -R buildtools/third_party/libc++ "$ARTIFACTS_DIR/include/buildtools/third_party"
192+
mkdir -p "$ARTIFACTS_DIR/include/third_party/libc++/src"
193+
cp -R third_party/libc++/src/include "$ARTIFACTS_DIR/include/third_party/libc++/src"
194+
fi
144195
find . -name "*.h" -print | cpio -pd "$ARTIFACTS_DIR/include"
145196
find . -name "*.inc" -print | cpio -pd "$ARTIFACTS_DIR/include"

0 commit comments

Comments
 (0)