Skip to content

Commit 8ce0e89

Browse files
committed
build_linux.sh: add option to choose 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. 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 8ce0e89

File tree

5 files changed

+975
-59
lines changed

5 files changed

+975
-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: 76 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,72 @@ 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 use_custom_libcxx=true"
100+
fi
101+
102+
set -x
53103

54104
if [ ! -e "$(pwd)/depot_tools" ]
55105
then
56106
git clone --depth 1 https://chromium.googlesource.com/chromium/tools/depot_tools.git
57107
fi
58108

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

64-
if [ ! -e "$(pwd)/src" ]
65-
then
66-
gclient sync -D --no-history
112+
if [ ! -e "$(pwd)/src" ]; then
113+
# use --nohooks to avoid the download_from_google_storage hook that takes > 6 minutes
114+
# then manually run the other hooks
115+
gclient sync -D --no-history --nohooks
116+
python3 src/tools/rust/update_rust.py
117+
if [ "$toolchain" == "chromium-llvm" ] || [ "$toolchain" == "llvm" ]; then
118+
python3 src/tools/clang/scripts/update.py
119+
fi
67120
fi
68121

69122
cd src
70123
git apply "$COMMAND_DIR/patches/add_licenses.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn
71124
git apply "$COMMAND_DIR/patches/ssl_verify_callback_with_native_handle.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn
72125
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-
82126
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
127+
cd ..
93128

94129
debug="false"
95130
if [ "$profile" = "debug" ]; then
@@ -101,10 +136,11 @@ args="is_debug=$debug \
101136
target_cpu=\"$arch\" \
102137
rtc_enable_protobuf=false \
103138
treat_warnings_as_errors=false \
104-
use_custom_libcxx=false \
139+
use_custom_libcxx=${chromium_libcxx}
105140
use_llvm_libatomic=false \
106141
use_libcxx_modules=false \
107142
use_custom_libcxx_for_host=false \
143+
use_sysroot=false \
108144
rtc_include_tests=false \
109145
rtc_build_tools=false \
110146
rtc_build_examples=false \
@@ -119,19 +155,23 @@ args="is_debug=$debug \
119155
symbol_level=0 \
120156
enable_iterator_debugging=false \
121157
use_rtti=true \
122-
is_clang=false \
123-
rtc_use_x11=false"
158+
rtc_use_x11=false \
159+
$toolchain_gn_args"
160+
161+
set -e
124162

125163
# generate ninja files
126164
gn gen "$OUTPUT_DIR" --root="src" --args="${args}"
127165

128166
# build static library
129167
ninja -C "$OUTPUT_DIR" :default
130168

169+
mkdir -p "$ARTIFACTS_DIR/lib"
170+
131171
# make libwebrtc.a
132172
# 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"
173+
"$AR" -rc "$ARTIFACTS_DIR/lib/libwebrtc.a" `find "$OUTPUT_DIR/obj" -name '*.o' -not -path "*/third_party/nasm/*"`
174+
"$OBJCOPY" --redefine-syms="$COMMAND_DIR/boringssl_prefix_symbols.txt" "$ARTIFACTS_DIR/lib/libwebrtc.a"
135175

136176
python3 "./src/tools_webrtc/libs/generate_licenses.py" \
137177
--target :default "$OUTPUT_DIR" "$OUTPUT_DIR"
@@ -141,5 +181,11 @@ cp "$OUTPUT_DIR/args.gn" "$ARTIFACTS_DIR"
141181
cp "$OUTPUT_DIR/LICENSE.md" "$ARTIFACTS_DIR"
142182

143183
cd src
184+
if [ $chromium_libcxx == "true" ]; then
185+
mkdir -p "$ARTIFACTS_DIR/include/buildtools/third_party"
186+
cp -R buildtools/third_party/libc++ "$ARTIFACTS_DIR/include/buildtools/third_party"
187+
mkdir -p "$ARTIFACTS_DIR/include/third_party/libc++/src"
188+
cp -R third_party/libc++/src/include "$ARTIFACTS_DIR/include/third_party/libc++/src"
189+
fi
144190
find . -name "*.h" -print | cpio -pd "$ARTIFACTS_DIR/include"
145191
find . -name "*.inc" -print | cpio -pd "$ARTIFACTS_DIR/include"

0 commit comments

Comments
 (0)