Skip to content

Commit 393444e

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 47eec80 commit 393444e

File tree

5 files changed

+972
-58
lines changed

5 files changed

+972
-58
lines changed

.github/workflows/webrtc-builds.yml

Lines changed: 6 additions & 26 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
@@ -112,36 +112,16 @@ jobs:
112112
run: |
113113
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
@@ -11,12 +11,15 @@ repository = "https://github.com/livekit/client-sdk-rust"
1111
default = []
1212

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

1720
[build-dependencies]
1821
webrtc-sys-build = { workspace = true }
19-
cxx-build = "1.0"
22+
cxx-build = "=1.0.186"
2023
glob = "0.3"
2124
cc = "1.0"
2225
pkg-config = "0.3.22"

webrtc-sys/build.rs

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

webrtc-sys/libwebrtc/build_linux.sh

Lines changed: 74 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,70 @@ 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+
custom_toolchain=\"//build/toolchain/linux/unbundle:default\" \
78+
host_toolchain=\"//build/toolchain/linux/unbundle:default\""
79+
elif [ "$toolchain" == "llvm" ]; then
80+
[ -n "$CC" ] || export CC="$(which clang)"
81+
[ -n "$CXX" ] || export CXX="$(which clang++)"
82+
[ -n "$AR" ] || export AR="$(which llvm-ar)"
83+
[ -n "$NM" ] || export NM="$(which llvm-nm)"
84+
OBJCOPY="$(which llvm-objcopy)"
85+
# Using system libc++ stumbles over
86+
# https://github.com/llvm/llvm-project/issues/50248
87+
# so use Chromium's libc++
88+
chromium_libcxx=true
89+
toolchain_gn_args="is_clang=true \
90+
clang_use_chrome_plugins=false \
91+
custom_toolchain=\"//build/toolchain/linux/unbundle:default\" \
92+
host_toolchain=\"//build/toolchain/linux/unbundle:default\""
93+
elif [ "$toolchain" == "chromium-llvm" ]; then
94+
AR="$COMMAND_DIR/src/third_party/llvm-build/Release+Asserts/bin/llvm-ar"
95+
OBJCOPY="$COMMAND_DIR/src/third_party/llvm-build/Release+Asserts/bin/llvm-objcopy"
96+
chromium_libcxx=true
97+
toolchain_gn_args="is_clang=true use_custom_libcxx=true"
98+
fi
99+
100+
set -x
53101

54102
if [ ! -e "$(pwd)/depot_tools" ]
55103
then
56104
git clone --depth 1 https://chromium.googlesource.com/chromium/tools/depot_tools.git
57105
fi
58106

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

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

69120
cd src
70121
git apply "$COMMAND_DIR/patches/add_licenses.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn
71122
git apply "$COMMAND_DIR/patches/ssl_verify_callback_with_native_handle.patch" -v --ignore-space-change --ignore-whitespace --whitespace=nowarn
72123
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-
82124
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
125+
cd ..
93126

94127
debug="false"
95128
if [ "$profile" = "debug" ]; then
@@ -101,10 +134,11 @@ args="is_debug=$debug \
101134
target_cpu=\"$arch\" \
102135
rtc_enable_protobuf=false \
103136
treat_warnings_as_errors=false \
104-
use_custom_libcxx=false \
137+
use_custom_libcxx=${chromium_libcxx}
105138
use_llvm_libatomic=false \
106139
use_libcxx_modules=false \
107140
use_custom_libcxx_for_host=false \
141+
use_sysroot=false \
108142
rtc_include_tests=false \
109143
rtc_build_tools=false \
110144
rtc_build_examples=false \
@@ -119,19 +153,23 @@ args="is_debug=$debug \
119153
symbol_level=0 \
120154
enable_iterator_debugging=false \
121155
use_rtti=true \
122-
is_clang=false \
123-
rtc_use_x11=true"
156+
rtc_use_x11=true \
157+
$toolchain_gn_args"
158+
159+
set -e
124160

125161
# generate ninja files
126162
gn gen "$OUTPUT_DIR" --root="src" --args="${args}"
127163

128164
# build static library
129165
ninja -C "$OUTPUT_DIR" :default
130166

167+
mkdir -p "$ARTIFACTS_DIR/lib"
168+
131169
# make libwebrtc.a
132170
# 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"
171+
"$AR" -rc "$ARTIFACTS_DIR/lib/libwebrtc.a" `find "$OUTPUT_DIR/obj" -name '*.o' -not -path "*/third_party/nasm/*"`
172+
"$OBJCOPY" --redefine-syms="$COMMAND_DIR/boringssl_prefix_symbols.txt" "$ARTIFACTS_DIR/lib/libwebrtc.a"
135173

136174
python3 "./src/tools_webrtc/libs/generate_licenses.py" \
137175
--target :default "$OUTPUT_DIR" "$OUTPUT_DIR"
@@ -142,5 +180,11 @@ cp "$OUTPUT_DIR/args.gn" "$ARTIFACTS_DIR"
142180
cp "$OUTPUT_DIR/LICENSE.md" "$ARTIFACTS_DIR"
143181

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

0 commit comments

Comments
 (0)