Skip to content

Opus Compile

Opus Compile #56

Workflow file for this run

name: Opus Compile
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
workflow_dispatch:
permissions:
contents: write
packages: write
jobs:
Android:
runs-on: ubuntu-latest
env:
CHECK_ALIGNMENT: false
strategy:
matrix:
arch: [x64, x86, arm64, arm32]
fail-fast: false
steps:
- uses: actions/checkout@v4
- uses: nttld/setup-ndk@v1
id: setup-ndk
with:
ndk-version: r28c
add-to-path: false
env:
ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }}
# Not much I can do to reduce the bloat.
- name: Setup Environment
run: |
if [[ "${{ matrix.arch }}" == "x64" ]]; then
echo "ABI=x86_64" >> $GITHUB_ENV
elif [[ "${{ matrix.arch }}" == "x86" ]]; then
echo "ABI=x86" >> $GITHUB_ENV
elif [[ "${{ matrix.arch }}" == "arm64" ]]; then
echo "ABI=arm64-v8a" >> $GITHUB_ENV
elif [[ "${{ matrix.arch }}" == "arm32" ]]; then
echo "ABI=armeabi-v7a" >> $GITHUB_ENV
fi
- name: Create Build Directory
run: mkdir build
- name: Clone Repository
run: git clone https://github.com/xiph/opus.git
- name: Autogen
run: ./opus/autogen.sh
- name: Configure
working-directory: ./build
run: cmake ../opus -DCMAKE_TOOLCHAIN_FILE=${ANDROID_NDK_HOME}/build/cmake/android.toolchain.cmake -DANDROID_ABI=${{ env.ABI }} -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DOPUS_BUILD_PROGRAMS=ON -DBUILD_TESTING=ON -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_SHARED_LINKER_FLAGS='-Wl,-z,max-page-size=16384,-z,common-page-size=16384' -DCMAKE_EXE_LINKER_FLAGS='-Wl,-z,max-page-size=16384,-z,common-page-size=16384'
- name: Build
working-directory: ./build
run: cmake --build . -j 2 --config Release
- name: Build with shim
working-directory: ./build
run: |
${ANDROID_NDK_HOME}/toolchains/llvm/prebuilt/linux-x86_64/bin/clang \
--target=$(case "${{ env.ABI }}" in x86_64) echo x86_64-linux-android21;; x86) echo i686-linux-android21;; arm64-v8a) echo aarch64-linux-android21;; armeabi-v7a) echo armv7a-linux-androideabi21;; esac) \
--sysroot=${ANDROID_NDK_HOME}/toolchains/llvm/prebuilt/linux-x86_64/sysroot \
-shared -o libopus.so \
-I../opus/include \
../OpusSharp.Natives/opus_shim.c \
-Wl,--whole-archive libopus.a -Wl,--no-whole-archive \
-Wl,-z,max-page-size=16384,-z,common-page-size=16384
- name: Check Alignment
if: ${{ env.CHECK_ALIGNMENT == 'true' }}
working-directory: ./build
run: sudo apt install llvm && llvm-objdump -p libopus.so | grep LOAD
- name: Upload Artifact
uses: actions/upload-artifact@v4
with:
name: android-${{ matrix.arch }}-libopus.so
path: ./build/libopus.so
Linux:
runs-on: ubuntu-latest
strategy:
matrix:
arch: [x64, x86, arm64, arm32]
fail-fast: false
steps:
- uses: actions/checkout@v4
# Not much I can do to reduce the bloat.
- name: Setup Environment
run: |
if [[ "${{ matrix.arch }}" == "x64" ]]; then
echo "C_FLAGS=-m64" >> $GITHUB_ENV
echo "CXX_FLAGS=-m64" >> $GITHUB_ENV
elif [[ "${{ matrix.arch }}" == "x86" ]]; then
sudo apt-get update
sudo apt-get install g++-multilib
echo "C_FLAGS=-m32" >> $GITHUB_ENV
echo "CXX_FLAGS=-m32" >> $GITHUB_ENV
elif [[ "${{ matrix.arch }}" == "arm64" ]]; then
sudo apt-get update
sudo apt-get install g++-aarch64-linux-gnu
echo "C_COMPILER=aarch64-linux-gnu-gcc" >> $GITHUB_ENV
echo "CXX_COMPILER=aarch64-linux-gnu-g++" >> $GITHUB_ENV
elif [[ "${{ matrix.arch }}" == "arm32" ]]; then
sudo apt-get update
sudo apt-get install g++-arm-linux-gnueabi
echo "C_COMPILER=arm-linux-gnueabi-gcc" >> $GITHUB_ENV
echo "CXX_COMPILER=arm-linux-gnueabi-g++" >> $GITHUB_ENV
fi
- name: Create Build Directory
run: mkdir build
- name: Clone Repository
run: git clone https://github.com/xiph/opus.git
- name: Autogen
run: ./opus/autogen.sh
- name: Configure
working-directory: ./build
run: |
if [[ "${{ matrix.arch }}" == "x64" || "${{ matrix.arch }}" == "x86" ]]; then
cmake ../opus -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DOPUS_BUILD_PROGRAMS=ON -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_C_FLAGS=${{ env.C_FLAGS }} -DCMAKE_CXX_FLAGS=${{ env.CXX_FLAGS }}
elif [[ "${{ matrix.arch }}" == "arm64" || "${{ matrix.arch }}" == "arm32" ]]; then
cmake ../opus -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DOPUS_BUILD_PROGRAMS=ON -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_C_COMPILER=${{ env.C_COMPILER }} -DCMAKE_CXX_COMPILER=${{ env.CXX_COMPILER }}
fi
- name: Build
working-directory: ./build
run: cmake --build . -j 2 --config Release
- name: Build with shim
working-directory: ./build
run: |
if [[ "${{ matrix.arch }}" == "x64" ]]; then
CC="gcc -m64"
elif [[ "${{ matrix.arch }}" == "x86" ]]; then
CC="gcc -m32"
elif [[ "${{ matrix.arch }}" == "arm64" ]]; then
CC=${{ env.C_COMPILER }}
elif [[ "${{ matrix.arch }}" == "arm32" ]]; then
CC=${{ env.C_COMPILER }}
fi
$CC -shared -o opus.so \
-I../opus/include \
../OpusSharp.Natives/opus_shim.c \
-Wl,--whole-archive libopus.a -Wl,--no-whole-archive \
-lm
- name: Upload Artifact
uses: actions/upload-artifact@v4
with:
name: linux-${{ matrix.arch }}-opus.so
path: ./build/opus.so
Windows:
runs-on: windows-latest
strategy:
matrix:
arch: [x64, x86, arm64] # Disabled arm32
fail-fast: false
steps:
- uses: actions/checkout@v4
# Not much I can do to reduce the bloat.
- name: Setup Environment
run: |
if ( "${{ matrix.arch }}" -eq "x64" ) {
echo "ARCH=x64" >> $env:GITHUB_ENV
} elseif ( "${{ matrix.arch }}" -eq "x86" ) {
echo "ARCH=Win32" >> $env:GITHUB_ENV
} elseif ( "${{ matrix.arch }}" -eq "arm64" ) {
echo "ARCH=ARM64" >> $env:GITHUB_ENV
} elseif ( "${{ matrix.arch }}" -eq "arm32" ) {
echo "ARCH=ARM" >> $env:GITHUB_ENV
}
- name: Create Build Directory
run: mkdir build
- name: Clone Repository
run: git clone https://github.com/xiph/opus.git
- name: Autogen
run: ./opus/autogen.bat
- name: Configure
working-directory: ./build
run: |
if ( "${{ matrix.arch }}" -eq "arm32" ) {
cmake ../opus -G "Visual Studio 17 2022" -A ARM,version=10.0.22621.0 -DCMAKE_BUILD_TYPE=Release -DOPUS_BUILD_PROGRAMS=ON -DBUILD_TESTING=ON -DBUILD_SHARED_LIBS=OFF
}
else {
cmake ../opus -G "Visual Studio 17 2022" -A ${{ env.ARCH }} -DCMAKE_BUILD_TYPE=Release -DOPUS_BUILD_PROGRAMS=ON -DBUILD_TESTING=ON -DBUILD_SHARED_LIBS=OFF
}
- name: Build
working-directory: ./build
run: cmake --build . -j 2 --config Release
- name: Build with shim
working-directory: ./build
shell: cmd
run: |
if "${{ env.ARCH }}"=="Win32" (set "VCARCH=x86") else if "${{ env.ARCH }}"=="x64" (set "VCARCH=amd64") else if "${{ env.ARCH }}"=="ARM64" (set "VCARCH=amd64_arm64") else if "${{ env.ARCH }}"=="ARM" (set "VCARCH=amd64_arm")
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" %VCARCH%
cl /O2 /MD /I..\opus\include /c ..\OpusSharp.Natives\opus_shim.c /Foopus_shim.obj
link /DLL /OUT:opus.dll opus_shim.obj Release\opus.lib ucrt.lib vcruntime.lib msvcrt.lib
- name: Upload Artifact
uses: actions/upload-artifact@v4
with:
name: win-${{ matrix.arch }}-opus.dll
path: ./build/opus.dll
MacOS:
runs-on: macos-latest
strategy:
matrix:
arch: [x64, arm64]
fail-fast: false
steps:
- uses: actions/checkout@v4
# Not much I can do to reduce the bloat.
- name: Setup Environment
run: |
brew install autoconf automake libtool
if [[ "${{ matrix.arch }}" == "x64" ]]; then
echo "OSX_ARCH=x86_64" >> $GITHUB_ENV
elif [[ "${{ matrix.arch }}" == "arm64" ]]; then
echo "OSX_ARCH=arm64" >> $GITHUB_ENV
fi
- name: Create Build Directory
run: mkdir build
- name: Clone Repository
run: git clone https://github.com/xiph/opus.git
- name: Autogen
run: ./opus/autogen.sh
- name: Configure
working-directory: ./build
run: cmake ../opus -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DCMAKE_OSX_ARCHITECTURES=${{ env.OSX_ARCH }} -DCMAKE_POSITION_INDEPENDENT_CODE=ON
- name: Build
working-directory: ./build
run: cmake --build .
- name: Build with shim
working-directory: ./build
run: |
cc -arch ${{ env.OSX_ARCH }} -shared -o opus.dylib \
-I../opus/include \
../OpusSharp.Natives/opus_shim.c \
-Wl,-force_load,libopus.a \
-install_name @rpath/opus.dylib
- name: Upload Artifact
uses: actions/upload-artifact@v4
with:
name: macos-${{ matrix.arch }}-opus.dylib
path: ./build/opus.dylib
iOS:
runs-on: macos-latest
strategy:
matrix:
target: [device, simulator-arm64, simulator-x86_64]
fail-fast: false
steps:
- uses: actions/checkout@v4
- name: Setup Environment
run: |
brew install autoconf automake libtool
if [[ "${{ matrix.target }}" == "device" ]]; then
echo "SDK=iphoneos" >> $GITHUB_ENV
echo "ARCH=arm64" >> $GITHUB_ENV
echo "OUTPUT_NAME=ios-device-arm64" >> $GITHUB_ENV
elif [[ "${{ matrix.target }}" == "simulator-arm64" ]]; then
echo "SDK=iphonesimulator" >> $GITHUB_ENV
echo "ARCH=arm64" >> $GITHUB_ENV
echo "OUTPUT_NAME=ios-simulator-arm64" >> $GITHUB_ENV
elif [[ "${{ matrix.target }}" == "simulator-x86_64" ]]; then
echo "SDK=iphonesimulator" >> $GITHUB_ENV
echo "ARCH=x86_64" >> $GITHUB_ENV
echo "OUTPUT_NAME=ios-simulator-x86_64" >> $GITHUB_ENV
fi
- name: Create Build Directory
run: mkdir build
- name: Clone Repository
run: git clone https://github.com/xiph/opus.git
- name: Generate Build Scripts
run: |
export PATH="/opt/homebrew/bin:/opt/homebrew/opt/libtool/libexec/gnubin:$PATH"
cd ./opus
git fetch --tags --force
OPUS_VERSION="$(git describe --tags --always --match 'v*' | sed 's/^v//')"
echo "PACKAGE_VERSION=\"$OPUS_VERSION\"" > package_version
autoreconf -isf
- name: Build Static Library
run: |
export PATH="/opt/homebrew/bin:/opt/homebrew/opt/libtool/libexec/gnubin:$PATH"
SDKROOT="$(xcrun --sdk "${{ env.SDK }}" --show-sdk-path)"
CC="$(xcrun --sdk "${{ env.SDK }}" --find clang)"
AR="$(xcrun --sdk "${{ env.SDK }}" --find ar)"
RANLIB="$(xcrun --sdk "${{ env.SDK }}" --find ranlib)"
if [[ "${{ matrix.target }}" == "device" ]]; then
HOST_TRIPLE="aarch64-apple-darwin"
MIN_VERSION_FLAG="-miphoneos-version-min=13.0"
elif [[ "${{ matrix.target }}" == "simulator-arm64" ]]; then
HOST_TRIPLE="aarch64-apple-darwin"
MIN_VERSION_FLAG="-mios-simulator-version-min=13.0"
else
HOST_TRIPLE="x86_64-apple-darwin"
MIN_VERSION_FLAG="-mios-simulator-version-min=13.0"
fi
cd ./build
../opus/configure \
--host="$HOST_TRIPLE" \
--disable-shared \
--enable-static \
--disable-extra-programs \
--disable-doc \
CC="$CC" \
CFLAGS="-arch ${{ env.ARCH }} -isysroot $SDKROOT $MIN_VERSION_FLAG -O3" \
AR="$AR" \
RANLIB="$RANLIB"
make -j "$(sysctl -n hw.ncpu)" libopus.la
- name: Compile shim and add to archive
run: |
export PATH="/opt/homebrew/bin:/opt/homebrew/opt/libtool/libexec/gnubin:$PATH"
SDKROOT="$(xcrun --sdk "${{ env.SDK }}" --show-sdk-path)"
CC="$(xcrun --sdk "${{ env.SDK }}" --find clang)"
AR="$(xcrun --sdk "${{ env.SDK }}" --find ar)"
RANLIB="$(xcrun --sdk "${{ env.SDK }}" --find ranlib)"
if [[ "${{ matrix.target }}" == "device" ]]; then
MIN_VERSION_FLAG="-miphoneos-version-min=13.0"
else
MIN_VERSION_FLAG="-mios-simulator-version-min=13.0"
fi
$CC -arch ${{ env.ARCH }} -isysroot $SDKROOT $MIN_VERSION_FLAG -O3 \
-I./opus/include -c ./OpusSharp.Natives/opus_shim.c -o build/opus_shim.o
$AR rcs build/.libs/libopus.a build/opus_shim.o
$RANLIB build/.libs/libopus.a
- name: Verify Library
working-directory: ./build
run: |
echo "=== Built library for ${{ matrix.target }} ==="
find . -path "*.libs/libopus.a" -exec file {} \;
find . -path "*.libs/libopus.a" -exec lipo -info {} \;
- name: Sanitize symbols to avoid Unity symbol conflicts
working-directory: ./build
run: |
echo "Installing llvm (provides llvm-objcopy)..."
brew install llvm
# Ensure llvm tools are on PATH for the remainder of this step
export PATH="/opt/homebrew/opt/llvm/bin:$PATH"
set -euo pipefail
echo "Collecting global defined symbols from .libs/libopus.a..."
# Select only defined symbols (T,D,B,S) from the archive and deduplicate
nm -g .libs/libopus.a | awk '/ [TDBS] /{print $3}' | sort -u > allsyms.txt
echo "Creating symbol mapping for renaming (skipping public 'opus' symbols)..."
: > mapping.txt
grep -v -E '^_opus' allsyms.txt | while read -r sym; do
[ -z "$sym" ] && continue
echo "$sym ${sym}_libopus" >> mapping.txt
done
if [ -s mapping.txt ]; then
echo "Applying symbol renames..."
llvm-objcopy --redefine-syms=mapping.txt .libs/libopus.a
echo "Verification:"
nm -g .libs/libopus.a | grep compute_allocation || true
else
echo "No non-opus symbols found to rename. Skipping sanitization."
fi
- name: Upload Artifact
uses: actions/upload-artifact@v4
with:
name: ${{ env.OUTPUT_NAME }}-libopus.a
path: ./build/.libs/libopus.a
iOS-universal:
runs-on: macos-latest
needs: iOS
steps:
- uses: actions/checkout@v4
- name: Clone opus for headers
run: git clone --depth 1 https://github.com/xiph/opus.git
- name: Download device artifact
uses: actions/download-artifact@v4
with:
name: ios-device-arm64-libopus.a
path: device
- name: Download simulator-arm64 artifact
uses: actions/download-artifact@v4
with:
name: ios-simulator-arm64-libopus.a
path: sim_arm64
- name: Download simulator-x86_64 artifact
uses: actions/download-artifact@v4
with:
name: ios-simulator-x86_64-libopus.a
path: sim_x86
- name: Create XCFramework
run: |
set -euo pipefail
mkdir -p universal
echo "=== Checking downloaded artifacts ==="
ls -la device/ sim_arm64/ sim_x86/ || true
echo "=== Architecture info ==="
lipo -info device/libopus.a || true
lipo -info sim_arm64/libopus.a || true
lipo -info sim_x86/libopus.a || true
# Combine simulator slices (arm64 + x86_64) into a fat library
echo "=== Creating fat simulator library ==="
mkdir -p simulator
lipo -create sim_arm64/libopus.a sim_x86/libopus.a -output simulator/libopus.a
echo "Fat simulator library:"
lipo -info simulator/libopus.a
# Create XCFramework with device (arm64) and simulator (arm64+x86_64)
echo "=== Creating XCFramework ==="
xcodebuild -create-xcframework \
-library device/libopus.a -headers opus/include \
-library simulator/libopus.a -headers opus/include \
-output universal/libopus.xcframework
echo "=== XCFramework created ==="
ls -laR universal/
- name: Upload Universal Artifact
uses: actions/upload-artifact@v4
with:
name: ios-universal-libopus
path: universal/*
Wasm:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: mymindstorm/setup-emsdk@v14
- name: Create Build Dir
run: mkdir build
- name: Clone Repository
run: git clone https://github.com/xiph/opus.git
- name: Autogen
run: ./opus/autogen.sh
- name: Configure
working-directory: ./build
run: emcmake cmake ../opus -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DOPUS_BUILD_PROGRAMS=ON
- name: Build
working-directory: ./build
run: cmake --build . -j 2 --config Release
- name: Add shim to archive
working-directory: ./build
run: |
emcc -O2 -I../opus/include -c ../OpusSharp.Natives/opus_shim.c -o opus_shim.o
emar rcs libopus.a opus_shim.o
- name: Upload Artifact
uses: actions/upload-artifact@v4
with:
name: wasm-libopus.a
path: ./build/libopus.a
Create-Runtimes:
runs-on: ubuntu-latest
needs: [Android, iOS-universal, MacOS, Linux, Windows, Wasm]
steps:
- uses: actions/checkout@v4
# Android
- name: Download android-arm32-libopus.so
uses: actions/download-artifact@v4
with:
name: android-arm32-libopus.so
path: runtimes/android-arm/native
- name: Download android-arm64-libopus.so
uses: actions/download-artifact@v4
with:
name: android-arm64-libopus.so
path: runtimes/android-arm64/native
- name: Download android-x64-libopus.so
uses: actions/download-artifact@v4
with:
name: android-x64-libopus.so
path: runtimes/android-x64/native
- name: Download android-x86-libopus.so
uses: actions/download-artifact@v4
with:
name: android-x86-libopus.so
path: runtimes/android-x86/native
# iOS
- name: Download ios-universal-libopus
uses: actions/download-artifact@v4
with:
name: ios-universal-libopus
path: runtimes/ios/native
# Linux
- name: Download linux-arm32-opus.so
uses: actions/download-artifact@v4
with:
name: linux-arm32-opus.so
path: runtimes/linux-arm/native
- name: Download linux-arm64-opus.so
uses: actions/download-artifact@v4
with:
name: linux-arm64-opus.so
path: runtimes/linux-arm64/native
- name: Download linux-x64-opus.so
uses: actions/download-artifact@v4
with:
name: linux-x64-opus.so
path: runtimes/linux-x64/native
- name: Download linux-x86-opus.so
uses: actions/download-artifact@v4
with:
name: linux-x86-opus.so
path: runtimes/linux-x86/native
# MacOS
- name: Download macos-arm64-opus.dylib
uses: actions/download-artifact@v4
with:
name: macos-arm64-opus.dylib
path: runtimes/osx-arm64/native
- name: Download macos-x64-opus.dylib
uses: actions/download-artifact@v4
with:
name: macos-x64-opus.dylib
path: runtimes/osx-x64/native
# Windows
- name: Download win-arm64-opus.dll
uses: actions/download-artifact@v4
with:
name: win-arm64-opus.dll
path: runtimes/win-arm64/native
- name: Download win-x64-opus.dll
uses: actions/download-artifact@v4
with:
name: win-x64-opus.dll
path: runtimes/win-x64/native
- name: Download win-x86-opus.dll
uses: actions/download-artifact@v4
with:
name: win-x86-opus.dll
path: runtimes/win-x86/native
- name: Upload Artifact
uses: actions/upload-artifact@v4
with:
name: All-Runtimes
path: ./runtimes