Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 9 additions & 29 deletions .github/workflows/webrtc-builds.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
name: WebRTC builds
on:
push:
tags:
- "webrtc-*"
# tags:
# - "webrtc-*"
workflow_dispatch:

jobs:
Expand Down Expand Up @@ -47,12 +47,12 @@ jobs:

- name: linux
os: ubuntu-latest
cmd: ./build_linux.sh
cmd: ./build_linux.sh --toolchain chromium-llvm
arch: x64

- name: linux
os: ubuntu-latest
cmd: ./build_linux.sh
cmd: ./build_linux.sh --toolchain chromium-llvm
arch: arm64

- name: android
Expand Down Expand Up @@ -110,38 +110,18 @@ jobs:
- name: install setuptools (none-macOS)
if: ${{ matrix.target.os != 'macos-latest' }}
run: |
pip3 install setuptools # pkg_resources is sometimes not found?
pip3 install setuptools # pkg_resources is sometimes not found?

- name: Add GCC PPA and install GCC 14
if: ${{ matrix.target.os == 'ubuntu-latest' }}
run: |
sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y
sudo apt update
sudo apt install gcc-14 g++-14 g++-14-aarch64-linux-gnu -y

- name: Verify GCC 14 installation
if: ${{ matrix.target.os == 'ubuntu-latest' }}
run: |
gcc-14 --version
g++-14 --version
aarch64-linux-gnu-g++-14 --version

- name: Set GCC 14 as default (optional)
if: ${{ matrix.target.os == 'ubuntu-latest' }}
run: |
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-14 140 --slave /usr/bin/g++ g++ /usr/bin/g++-14
sudo update-alternatives --config gcc
gcc --version
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
sudo update-alternatives --config aarch64-linux-gnu-gcc
aarch64-linux-gnu-gcc --version

- 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

- name: Disable __GLIBC_USE_ISOC2X macro
if: ${{ matrix.target.name == 'linux' && matrix.target.arch == 'arm64' }}
run: sudo sed -i 's/__GLIBC_USE_ISOC2X[[:space:]]*1/__GLIBC_USE_ISOC2X\t0/' /usr/include/features.h

- name: Install macos dependencies
if: ${{ matrix.target.os == 'macos-latest' }}
run: brew install ninja
Expand Down
7 changes: 5 additions & 2 deletions webrtc-sys/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,15 @@ use_vaapi = []
use_nvidia = []

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

[build-dependencies]
webrtc-sys-build = { workspace = true }
cxx-build = "1.0"
cxx-build = "=1.0.186"
glob = "0.3"
cc = "1.0"

Expand Down
67 changes: 65 additions & 2 deletions webrtc-sys/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,54 @@ fn main() {
"src/apm.cpp",
]);

let webrtc_dir = webrtc_sys_build::webrtc_dir();
let mut webrtc_dir = webrtc_sys_build::webrtc_dir();
let target_arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap();

#[cfg(target_os = "linux")]
println!("cargo:rerun-if-env-changed=LK_LIBWEBRTC_SOURCE");
#[cfg(target_os = "linux")]
if let Ok(source_archive) = env::var("LK_LIBWEBRTC_SOURCE") {
let out_dir = env::var("OUT_DIR").unwrap();
let manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap();

fn check_command_output(output: std::process::Output) {
let status = output.status;
if !status.success() {
let stderr = String::from_utf8_lossy(&output.stderr);
let stdout = String::from_utf8_lossy(&output.stdout);
panic!("Command exited unsuccessfully: {status:?},\nstdout:\n{stdout}\nstderr:\n{stderr}");
}
}

check_command_output(
Command::new("tar").args(["-Jxf", &source_archive, "-C", &out_dir]).output().unwrap(),
);

let script_arch = match target_arch.as_str() {
"x86_64" => "x64",
"aarch64" => "arm64",
a => a,
};
check_command_output(
Command::new("bash")
.args([
&format!("{manifest_dir}/libwebrtc/build_linux.sh"),
"--sources",
&format!("{out_dir}/src"),
"--toolchain",
"gnu",
"--arch",
script_arch,
"--profile",
"release",
])
.output()
.unwrap(),
);

webrtc_dir = PathBuf::from(format!("{out_dir}/linux-{script_arch}-release"));
}

let webrtc_include = webrtc_dir.join("include");
let webrtc_lib = webrtc_dir.join("lib");

Expand Down Expand Up @@ -110,7 +157,6 @@ fn main() {
println!("cargo:rustc-link-lib=static=webrtc");

let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap();
let target_arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap();
match target_os.as_str() {
"windows" => {
println!("cargo:rustc-link-lib=dylib=msdmo");
Expand Down Expand Up @@ -148,6 +194,23 @@ fn main() {
.flag("/EHsc");
}
"linux" => {
// If libwebrtc was built with Chromium's libc++, the C++ in this crate needs to be built with it too.
let buildtools = webrtc_include.join("buildtools/third_party/libc++");
if buildtools.exists() {
// Chromium's libc++ doesn't build with GCC
if env::var("CC").is_err() {
builder.compiler("clang++");
}
builder.include(buildtools);
builder.flag("-nostdinc++");
let webrtc_include = webrtc_include.to_string_lossy();
builder.flag(format!("-isystem{webrtc_include}/third_party/libc++/src/include"));
builder.flag(format!("-isystem{webrtc_include}/third_party/libc++abi/src/include"));
// The cxx crate builds this C++ file. However, this crate needs to rebuild it when using a
// different C++ standard library or linking will fail with unresolved symbol errors.
builder.file("src/cxx.cc");
}

println!("cargo:rustc-link-lib=dylib=rt");
println!("cargo:rustc-link-lib=dylib=dl");
println!("cargo:rustc-link-lib=dylib=pthread");
Expand Down
150 changes: 91 additions & 59 deletions webrtc-sys/libwebrtc/build_linux.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,16 @@

arch=""
profile="release"
toolchain="gnu"

while [ "$#" -gt 0 ]; do
case "$1" in
--sources)
sources="$(realpath $2)"
shift 2
;;
--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
;;
--profile)
Expand All @@ -35,6 +36,14 @@ while [ "$#" -gt 0 ]; do
fi
shift 2
;;
--toolchain)
toolchain="$2"
if [ "$toolchain" != "gnu" ] && [ "$toolchain" != "llvm" ] && [ "$toolchain" != "chromium-llvm" ]; then
echo "Error: Invalid value for --toolchain. Must be 'gnu', 'llvm', or 'chromium-llvm' (Chromium's bundled Clang with Debian sysroot)"
exit 1
fi
shift 2
;;
*)
echo "Error: Unknown argument '$1'"
exit 1
Expand All @@ -47,48 +56,55 @@ if [ -z "$arch" ]; then
exit 1
fi

if [ -z "$sources" ]; then
echo "Error: --sources must be set."
exit 1
fi

echo "Building LiveKit WebRTC - Linux"
echo "Arch: $arch"
echo "Profile: $profile"

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

export COMMAND_DIR=$(cd $(dirname $0); pwd)
export PATH="$(pwd)/depot_tools:$PATH"
export OUTPUT_DIR="$(pwd)/src/out-$arch-$profile"
export ARTIFACTS_DIR="$(pwd)/linux-$arch-$profile"

if [ ! -e "$(pwd)/src" ]
then
gclient sync -D --no-history
fi

cd src
git apply "$COMMAND_DIR/patches/add_licenses.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

cd build

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

cd ..

cd third_party

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

cd ../..

mkdir -p "$ARTIFACTS_DIR/lib"

python3 "./src/build/linux/sysroot_scripts/install-sysroot.py" --arch="$arch"

if [ "$arch" = "arm64" ]; then
sudo sed -i 's/__GLIBC_USE_ISOC2X[[:space:]]*1/__GLIBC_USE_ISOC2X\t0/' /usr/aarch64-linux-gnu/include/features.h
echo "Toolchain: $toolchain"

COMMAND_DIR=$(cd $(dirname $0); pwd)
OUTPUT_DIR="$(dirname "$sources")"
BUILD_DIR="$OUTPUT_DIR/build-$arch-$profile"
ARTIFACTS_DIR="$OUTPUT_DIR/linux-$arch-$profile"

if [ "$toolchain" == "gnu" ]; then
[ -n "$CC" ] || export CC="$(which gcc)"
[ -n "$CXX" ] || export CXX="$(which g++)"
[ -n "$AR" ] || export AR="$(which ar)"
[ -n "$NM" ] || export NM="$(which nm)"
export CXXFLAGS="${CXXFLAGS} -Wno-changes-meaning -Wno-unknown-pragmas -D_DEFAULT_SOURCE"
OBJCOPY="$(which objcopy)"
chromium_libcxx=false
toolchain_gn_args="is_clang=false \
use_sysroot=false \
custom_toolchain=\"//build/toolchain/linux/unbundle:default\" \
host_toolchain=\"//build/toolchain/linux/unbundle:default\""
elif [ "$toolchain" == "llvm" ]; then
[ -n "$CC" ] || export CC="$(which clang)"
[ -n "$CXX" ] || export CXX="$(which clang++)"
[ -n "$AR" ] || export AR="$(which llvm-ar)"
[ -n "$NM" ] || export NM="$(which llvm-nm)"
OBJCOPY="$(which llvm-objcopy)"
# Using system libc++ stumbles over
# https://github.com/llvm/llvm-project/issues/50248
# so use Chromium's libc++
chromium_libcxx=true
toolchain_gn_args="is_clang=true \
clang_use_chrome_plugins=false \
use_sysroot=false \
custom_toolchain=\"//build/toolchain/linux/unbundle:default\" \
host_toolchain=\"//build/toolchain/linux/unbundle:default\""
elif [ "$toolchain" == "chromium-llvm" ]; then
AR="$sources/third_party/llvm-build/Release+Asserts/bin/llvm-ar"
OBJCOPY="$sources/third_party/llvm-build/Release+Asserts/bin/llvm-objcopy"
chromium_libcxx=true
toolchain_gn_args="is_clang=true \
use_custom_libcxx=true \
use_sysroot=true"
fi

debug="false"
Expand All @@ -101,7 +117,7 @@ args="is_debug=$debug \
target_cpu=\"$arch\" \
rtc_enable_protobuf=false \
treat_warnings_as_errors=false \
use_custom_libcxx=false \
use_custom_libcxx=${chromium_libcxx}
use_llvm_libatomic=false \
use_libcxx_modules=false \
use_custom_libcxx_for_host=false \
Expand All @@ -119,27 +135,43 @@ args="is_debug=$debug \
symbol_level=0 \
enable_iterator_debugging=false \
use_rtti=true \
is_clang=false \
rtc_use_x11=false"
rtc_use_x11=false \
$toolchain_gn_args"

set -xe

if [ "$toolchain" == "chromium-llvm" ]; then
python3 "$sources/build/linux/sysroot_scripts/install-sysroot.py" --arch=x64
python3 "$sources/build/linux/sysroot_scripts/install-sysroot.py" --arch=arm64
fi

# generate ninja files
gn gen "$OUTPUT_DIR" --root="src" --args="${args}"
export PATH="$sources/depot_tools:$PATH"
gn gen "$BUILD_DIR" --root="$sources" --args="${args}"

# build static library
ninja -C "$OUTPUT_DIR" :default
ninja -C "$BUILD_DIR" :default

mkdir -p "$ARTIFACTS_DIR/lib"

# 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"

python3 "./src/tools_webrtc/libs/generate_licenses.py" \
--target :default "$OUTPUT_DIR" "$OUTPUT_DIR"

cp "$OUTPUT_DIR/obj/webrtc.ninja" "$ARTIFACTS_DIR"
cp "$OUTPUT_DIR/args.gn" "$ARTIFACTS_DIR"
cp "$OUTPUT_DIR/LICENSE.md" "$ARTIFACTS_DIR"

cd src
"$AR" -rc "$ARTIFACTS_DIR/lib/libwebrtc.a" `find "$BUILD_DIR/obj" -name '*.o' -not -path "*/third_party/nasm/*"`
"$OBJCOPY" --redefine-syms="$COMMAND_DIR/boringssl_prefix_symbols.txt" "$ARTIFACTS_DIR/lib/libwebrtc.a"

python3 "$sources/tools_webrtc/libs/generate_licenses.py" \
--target :default "$BUILD_DIR" "$BUILD_DIR"

cp "$BUILD_DIR/obj/webrtc.ninja" "$ARTIFACTS_DIR"
cp "$BUILD_DIR/args.gn" "$ARTIFACTS_DIR"
cp "$BUILD_DIR/LICENSE.md" "$ARTIFACTS_DIR"

cd $sources
if [ $chromium_libcxx == "true" ]; then
mkdir -p "$ARTIFACTS_DIR/include/buildtools/third_party"
cp -R buildtools/third_party/libc++ "$ARTIFACTS_DIR/include/buildtools/third_party"
mkdir -p "$ARTIFACTS_DIR/include/third_party/libc++/src"
cp -R third_party/libc++/src/include "$ARTIFACTS_DIR/include/third_party/libc++/src"
fi
find . -name "*.h" -print | cpio -pd "$ARTIFACTS_DIR/include"
find . -name "*.inc" -print | cpio -pd "$ARTIFACTS_DIR/include"
Loading