Skip to content

Commit

Permalink
Merge pull request #5981 from FreezyLemon/reduce-ffmpeg-size
Browse files Browse the repository at this point in the history
  • Loading branch information
peppy authored Oct 3, 2023
2 parents 49e1fbc + eadd42f commit 6e22832
Show file tree
Hide file tree
Showing 15 changed files with 294 additions and 239 deletions.
42 changes: 21 additions & 21 deletions .github/workflows/build-ffmpeg.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ on: workflow_dispatch
jobs:
build-macos:
name: Build macOS
runs-on: macos-latest
runs-on: macos-12
strategy:
fail-fast: false
matrix:
Expand All @@ -18,19 +18,19 @@ jobs:
- uses: ilammy/setup-nasm@v1

- name: Build
run: osu.Framework.NativeLibs/scripts/ffmpeg/macOS/fetch_and_build.sh
run: osu.Framework.NativeLibs/scripts/ffmpeg/build-macOS.sh
env:
arch: ${{ matrix.arch }}

- name: Upload
uses: actions/upload-artifact@v3
with:
name: macOS-${{ matrix.arch }}
path: build-${{ matrix.arch }}
path: macOS-${{ matrix.arch }}

combine-macos:
name: Combine macOS libs
runs-on: macos-latest
runs-on: macos-12
needs: build-macos
steps:
- name: Checkout
Expand All @@ -46,7 +46,7 @@ jobs:
path: macOS-arm64

- name: Combine
run: osu.Framework.NativeLibs/scripts/ffmpeg/macOS/combine_universal.sh
run: osu.Framework.NativeLibs/scripts/ffmpeg/combine_dylibs.sh

- name: Upload
uses: actions/upload-artifact@v3
Expand All @@ -56,7 +56,7 @@ jobs:

build-win:
name: Build Windows
runs-on: ubuntu-latest
runs-on: ubuntu-22.04
strategy:
fail-fast: false
matrix:
Expand All @@ -69,67 +69,66 @@ jobs:

- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install make nasm gcc mingw-w64
sudo apt-get update && sudo apt-get upgrade
sudo apt-get install -y make nasm gcc mingw-w64
- name: Build
run: osu.Framework.NativeLibs/scripts/ffmpeg/win/fetch_and_build.sh
run: osu.Framework.NativeLibs/scripts/ffmpeg/build-win.sh
env:
arch: ${{ matrix.arch }}

- name: Upload
uses: actions/upload-artifact@v3
with:
name: win-${{ matrix.arch }}
path: build-${{ matrix.arch }}
path: win-${{ matrix.arch }}

# The win-arm64 build runs in a special MinGW container to cross-compile successfully.
build-win-arm64:
name: Build Windows (arm64)
runs-on: ubuntu-latest
runs-on: ubuntu-22.04
container:
image: mstorsjo/llvm-mingw:latest
steps:
- name: Checkout
uses: actions/checkout@v3

- name: Build
run: osu.Framework.NativeLibs/scripts/ffmpeg/win/fetch_and_build.sh
run: osu.Framework.NativeLibs/scripts/ffmpeg/build-win.sh
env:
arch: arm64

- name: Upload
uses: actions/upload-artifact@v3
with:
name: win-arm64
path: build-arm64
path: win-arm64

build-linux:
name: Build Linux (x64)
runs-on: ubuntu-latest
container:
image: ubuntu:16.04
# Use 20.04 to target glibc 2.31 like the other native libs
runs-on: ubuntu-20.04
steps:
- name: Install dependencies
run: |
apt-get update
apt-get install -y git curl gcc make nasm
sudo apt-get update && sudo apt-get upgrade
sudo apt-get install -y git curl gcc make nasm pkg-config libva-dev libvdpau-dev
- name: Checkout
uses: actions/checkout@v3

- name: Build
run: osu.Framework.NativeLibs/scripts/ffmpeg/linux/fetch_and_build.sh
run: osu.Framework.NativeLibs/scripts/ffmpeg/build-linux.sh

- name: Upload
uses: actions/upload-artifact@v3
with:
name: linux-x64
path: build-x64
path: linux-x64

make-pr:
name: Create pull request
runs-on: ubuntu-latest
runs-on: ubuntu-22.04
needs:
- combine-macos
- build-win
Expand Down Expand Up @@ -166,5 +165,6 @@ jobs:
title: Update FFmpeg binaries
body: This PR has been auto-generated to update the FFmpeg binaries.
branch: update-ffmpeg-binaries
delete-branch: true
env:
ACTIONS_ALLOW_UNSECURE_COMMANDS: 'true'
63 changes: 63 additions & 0 deletions osu.Framework.NativeLibs/scripts/ffmpeg/BUILDING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Build Instructions

1. Install the dependencies for your platform(s)
2. Run the build script for your platform(s)
3. (macOS only) Run `combine_dylibs.sh` to create universal dylibs

## Build dependencies

In general, you need `gcc`, `make`, and `nasm`.
If external libraries need to be included in the build, `pkg-config` is also required.

### Windows Dependencies (compiling on Ubuntu/Debian)

Targetting x86 and x86_64:

```sh
sudo apt install make nasm gcc mingw-w64 mingw-w64-tools
```

Targetting aarch64:

```sh
sudo apt install make nasm

# Downloading a llvm-mingw release and adding it to PATH #
# If host is x86_64:
url="https://github.com/mstorsjo/llvm-mingw/releases/download/20230614/llvm-mingw-20230614-ucrt-ubuntu-20.04-x86_64.tar.xz"
# If host is aarch64:
#url="https://github.com/mstorsjo/llvm-mingw/releases/download/20230614/llvm-mingw-20230614-ucrt-ubuntu-20.04-aarch64.tar.xz"
curl -Lo llvm-mingw.tar.xz "$url"
mkdir llvm-mingw
tar xfJ llvm-mingw.tar.xz --strip 1 -C llvm-mingw
export PATH="$PATH:$PWD/llvm-mingw/bin"
```

### macOS Dependencies

Check [this page](https://trac.ffmpeg.org/wiki/CompilationGuide/macOS#CompilingFFmpegyourself) for instructions on how to install macOS dependencies.
Note that you don't need packages like `x264` or `libvpx`, it is enough to install these packages in addition to Xcode:

```zsh
brew install gcc make nasm
```

### Linux Dependencies (Ubuntu/Debian)

```sh
sudo apt install make nasm gcc pkg-config libva-dev libvdpau-dev
```

## Output files

For each `<platform>-<arch>` combination, two directories will be created. The directory called `<platform>-<arch>` will
contain the resulting shared libraries, and the directory with a `-build` suffix will contain the respective build files.

### macOS only: Combine arch-specific dylib files into universal dylib files

The `combine_universal.sh` script will combine the `x86_64` and `arm64` dylibs into universal dylibs.
The universal dylibs are output into a folder named `macOS-universal` and should be copied into `osu.Framework.NativeLibs/runtimes/osx`.

## Cleanup

Files are left around for debugging purposes, manually delete the directories to clean up.
31 changes: 31 additions & 0 deletions osu.Framework.NativeLibs/scripts/ffmpeg/build-linux.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#!/bin/bash
set -eu

pushd "$(dirname "$0")" > /dev/null
SCRIPT_PATH=$(pwd)
popd > /dev/null
source "$SCRIPT_PATH/common.sh"

FFMPEG_FLAGS+=(
--enable-vaapi
--enable-vdpau
--enable-hwaccel='h264_vaapi,h264_vdpau'
--enable-hwaccel='hevc_vaapi,hevc_vdpau'
--enable-hwaccel='vp8_vaapi,vp8_vdpau'
--enable-hwaccel='vp9_vaapi,vp9_vdpau'

--target-os=linux
)

pushd . > /dev/null
prep_ffmpeg linux-x64
build_ffmpeg
popd > /dev/null

# gcc creates multiple symlinks per .so file for versioning.
# We want to delete the symlinks to prevent weird behaviour with GitHub actions.
rm linux-x64/*.so
for f in linux-x64/*.so.*.*.*; do
mv -v "$f" "${f%.*.*.*}"
done
rm linux-x64/*.so.*
48 changes: 48 additions & 0 deletions osu.Framework.NativeLibs/scripts/ffmpeg/build-macOS.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#!/bin/bash
set -eu

pushd "$(dirname "$0")" > /dev/null
SCRIPT_PATH=$(pwd)
popd > /dev/null
source "$SCRIPT_PATH/common.sh"

if [ -z "${arch-}" ]; then
PS3='Build for which arch? '
select arch in "arm64" "x86_64"; do
if [ -z "$arch" ]; then
echo "invalid option"
else
break
fi
done
fi

FFMPEG_FLAGS+=(
--enable-videotoolbox
--enable-hwaccel=h264_videotoolbox
--enable-hwaccel=hevc_videotoolbox
--enable-hwaccel=vp9_videotoolbox

--enable-cross-compile
--target-os=darwin
--arch=$arch
--extra-cflags="-arch $arch"
--extra-ldflags="-arch $arch"

--install-name-dir='@loader_path'
)

pushd . > /dev/null
prep_ffmpeg "macOS-$arch"
build_ffmpeg
popd > /dev/null

# Rename dylibs that have a full version string (A.B.C) in their filename
# Example: avcodec.58.10.72.dylib -> avcodec.58.dylib
pushd . > /dev/null
cd "macOS-$arch"
for f in *.*.*.*.dylib; do
[ -f "$f" ] || continue
mv -v "$f" "${f%.*.*.*}.dylib"
done
popd > /dev/null
69 changes: 69 additions & 0 deletions osu.Framework.NativeLibs/scripts/ffmpeg/build-win.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#!/bin/bash
set -eu

pushd "$(dirname "$0")" > /dev/null
SCRIPT_PATH=$(pwd)
popd > /dev/null
source "$SCRIPT_PATH/common.sh"

if [ -z "${arch-}" ]; then
PS3='Build for which arch? '
select arch in "x86" "x64" "arm64"; do
if [ -z "$arch" ]; then
echo "invalid option"
else
break
fi
done
fi

cross_arch=''
cross_prefix=''

case $arch in
x86)
cross_arch='x86'
cross_prefix='i686-w64-mingw32-'
;;

x64)
cross_arch='x86_64'
cross_prefix='x86_64-w64-mingw32-'
;;

arm64)
cross_arch='aarch64'
cross_prefix='aarch64-w64-mingw32-'
;;
esac

FFMPEG_FLAGS+=(
--enable-w32threads

--enable-dxva2
--enable-d3d11va
--enable-hwaccel='h264_dxva2,h264_d3d11va,h264_d3d11va2'
--enable-hwaccel='hevc_dxva2,hevc_d3d11va,hevc_d3d11va2'
--enable-hwaccel='vp9_dxva2,vp9_d3d11va,vp9_d3d11va2'

--enable-cross-compile
--target-os=mingw32
--arch=$cross_arch
--cross-prefix=$cross_prefix
)

pushd . > /dev/null
prep_ffmpeg "win-$arch"

# FFmpeg doesn't do this correctly when building, so we do it instead.
# A newer FFmpeg release might make this unnecessary.
echo '-> Creating resource objects...'
make .version
for res in lib*/*res.rc; do
"${cross_prefix}windres" -I. "$res" "${res%.rc}.o"
done

build_ffmpeg
popd > /dev/null

find "win-$arch" -not -name "win-$arch" -not -name '*.dll' -delete
13 changes: 13 additions & 0 deletions osu.Framework.NativeLibs/scripts/ffmpeg/combine_dylibs.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/bin/bash
set -eu

pushd . > /dev/null
mkdir -p macOS-universal
cd macOS-arm64
for lib_arm in *.dylib; do
lib_x86="../macOS-x86_64/$lib_arm"

echo "-> Creating universal $lib_arm..."
lipo -create "$lib_arm" "$lib_x86" -output "../macOS-universal/$lib_arm"
done
popd > /dev/null
Loading

0 comments on commit 6e22832

Please sign in to comment.