Skip to content

Commit 80ad6ba

Browse files
feat(FFmpeg): add FreeBSD build (#459)
1 parent 6ad5cf8 commit 80ad6ba

File tree

8 files changed

+248
-53
lines changed

8 files changed

+248
-53
lines changed

.github/workflows/ci.yml

Lines changed: 117 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ concurrency:
2121
cancel-in-progress: true
2222

2323
env:
24+
FREEBSD_CLANG_VERSION: 19
2425
LINUX_GCC_VERSION: 12
2526
MACOSX_DEPLOYMENT_TARGET: 13.0
2627

@@ -78,16 +79,30 @@ jobs:
7879
shell: msys2 {0}
7980
msystem: clangarm64
8081
toolchain: clang-aarch64
82+
- name: FreeBSD-amd64
83+
os: ubuntu-latest
84+
arch: x86_64
85+
bsd_release: '14.3'
86+
generator: "Unix Makefiles"
87+
shell: freebsd {0}
88+
- name: FreeBSD-aarch64
89+
os: ubuntu-latest # ubuntu-24.04-arm is slower with the FreeBSD VM
90+
arch: aarch64
91+
bsd_release: '14.3'
92+
generator: "Unix Makefiles"
93+
shell: freebsd {0}
8194
defaults:
8295
run:
8396
shell: ${{ matrix.shell }}
8497
steps:
8598
- name: Checkout
8699
uses: actions/checkout@v4
100+
with:
101+
submodules: recursive
87102

88103
- name: Prepare Dependencies Linux
89104
id: cross_compile
90-
if: runner.os == 'Linux'
105+
if: runner.os == 'Linux' && !startsWith(matrix.shell, 'freebsd')
91106
run: |
92107
echo "::group::distro detection"
93108
# detect dist name like bionic, focal, etc
@@ -254,7 +269,7 @@ jobs:
254269
echo "::endgroup::"
255270
256271
- name: Setup Dependencies Linux
257-
if: runner.os == 'Linux'
272+
if: runner.os == 'Linux' && !startsWith(matrix.shell, 'freebsd')
258273
run: |
259274
echo "::group::apt update"
260275
sudo apt-get update
@@ -363,22 +378,59 @@ jobs:
363378
echo "MSYS2_ROOT=${{ runner.temp }}/msys64" >> $GITHUB_ENV
364379
cat "${{ runner.temp }}/setup-msys2/msys2.CMD"
365380
366-
- name: Initialize Submodules
367-
# libx265 has issues when using the recursive method of the first checkout action
368-
# this is after `msys2/setup-msys2@v2` because `msys2` (default) shell is not available until then.
369-
run: |
370-
git submodule update --init --recursive
381+
- name: Setup FreeBSD
382+
if: startsWith(matrix.shell, 'freebsd')
383+
uses: vmactions/[email protected]
384+
with:
385+
arch: ${{ matrix.arch }}
386+
prepare: |
387+
pkg install -y \
388+
devel/autoconf \
389+
devel/automake \
390+
devel/cmake \
391+
devel/git \
392+
devel/gmake \
393+
devel/llvm${{ env.FREEBSD_CLANG_VERSION }} \
394+
devel/nasm \
395+
devel/ninja \
396+
devel/pkgconf \
397+
multimedia/libass \
398+
multimedia/libv4l \
399+
multimedia/libva \
400+
multimedia/v4l_compat \
401+
print/freetype2 \
402+
security/gnutls \
403+
shells/bash \
404+
x11/libx11 \
405+
x11/libxcb \
406+
x11/libXfixes
407+
408+
# create symlink for shebang bash compatibility
409+
ln -s /usr/local/bin/bash /bin/bash
410+
release: ${{ matrix.bsd_release }}
411+
sync: nfs
371412

372413
- name: Setup ENV
373414
id: root
374415
run: |
416+
set -e
417+
cd $GITHUB_WORKSPACE
375418
echo "ROOT_PATH=$PWD" >> $GITHUB_ENV
376419
420+
MAKE_CMD="make"
421+
if [ "${{ startsWith(matrix.shell, 'freebsd') }}" = true ]; then
422+
# use gmake on FreeBSD instead of make
423+
MAKE_CMD="gmake"
424+
fi
425+
echo "MAKE_CMD=${MAKE_CMD}" >> $GITHUB_ENV
426+
377427
- name: Setup cross compilation
378428
id: cross
379429
if: matrix.target != ''
380430
run: |
381-
TOOLCHAIN=${ROOT_PATH}/cmake/toolchains/${{ matrix.target }}.cmake
431+
set -e
432+
cd $GITHUB_WORKSPACE
433+
TOOLCHAIN=${{ env.ROOT_PATH }}/cmake/toolchains/${{ matrix.target }}.cmake
382434
383435
# fail if file does not exist
384436
if [ ! -f $TOOLCHAIN ]; then
@@ -394,33 +446,76 @@ jobs:
394446
- name: Get Processor Count
395447
id: processor_count
396448
run: |
397-
if [[ ${{ runner.os }} == 'macOS' ]]; then
398-
echo "PROCESSOR_COUNT=$(sysctl -n hw.ncpu)" >> $GITHUB_OUTPUT
449+
set -e
450+
cd $GITHUB_WORKSPACE
451+
if [ "${{ runner.os }}" = 'macOS' ]; then
452+
PROCESSOR_COUNT=$(sysctl -n hw.ncpu)
399453
else
400-
echo "PROCESSOR_COUNT=$(nproc)" >> $GITHUB_OUTPUT
454+
PROCESSOR_COUNT=$(nproc)
401455
fi
456+
echo "PROCESSOR_COUNT=${PROCESSOR_COUNT}" >> $GITHUB_OUTPUT
457+
echo "PROCESSOR_COUNT: $PROCESSOR_COUNT"
458+
459+
- name: Get x265 git history
460+
run: |
461+
set -e
462+
463+
# x265.pc will not be installed if their cmake cannot detect the latest tag
464+
# SVT-AV1 cannot determine version if the git history is not available
465+
466+
for repo in "x265_git" "SVT-AV1"; do
467+
cd $GITHUB_WORKSPACE/third-party/FFmpeg/$repo
468+
git config --global --add safe.directory $(pwd)
469+
git fetch --tags --force origin
470+
done
402471
403472
- name: Configure
404473
run: |
474+
set -e
475+
cd $GITHUB_WORKSPACE
476+
477+
if [ "${{ startsWith(matrix.shell, 'freebsd') }}" = true ]; then
478+
export CC=$(which clang${{ env.FREEBSD_CLANG_VERSION }})
479+
export CXX=$(which clang++${{ env.FREEBSD_CLANG_VERSION }})
480+
481+
# make sure they exist
482+
if [ ! -f "$CC" ]; then
483+
echo "Compiler not found: $CC"
484+
exit 1
485+
fi
486+
if [ ! -f "$CXX" ]; then
487+
echo "Compiler not found: $CXX"
488+
exit 1
489+
fi
490+
fi
491+
405492
mkdir -p ./build/dist
406493
cmake \
407494
-B build \
408495
-S . \
409496
-G "${{ matrix.generator }}" \
410-
-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE} \
411-
-DCMAKE_INSTALL_PREFIX="${ROOT_PATH}/build/dist"
497+
-DCMAKE_TOOLCHAIN_FILE=${{ env.CMAKE_TOOLCHAIN_FILE }} \
498+
-DCMAKE_INSTALL_PREFIX="${{ env.ROOT_PATH }}/build/dist" \
499+
-DPARALLEL_BUILDS=${{ steps.processor_count.outputs.PROCESSOR_COUNT || 1 }}
412500
413501
- name: Build
414502
run: |
415-
make -C build -j${{ steps.processor_count.outputs.PROCESSOR_COUNT }}
503+
set -e
504+
cd $GITHUB_WORKSPACE
505+
${{ env.MAKE_CMD }} -C build --jobs=${{ steps.processor_count.outputs.PROCESSOR_COUNT || 1 }}
416506
417507
- name: Install
418508
run: |
419-
make -C build install
509+
set -e
510+
cd $GITHUB_WORKSPACE
511+
${{ env.MAKE_CMD }} -C build install
420512
421513
- name: Debug logs
422514
if: always()
423515
run: |
516+
set -e
517+
cd $GITHUB_WORKSPACE
518+
424519
echo "::group::x264 config.log"
425520
cat ./third-party/FFmpeg/x264/config.log || true
426521
echo "::endgroup::"
@@ -432,20 +527,27 @@ jobs:
432527
- name: Debug build directory
433528
if: always()
434529
run: |
530+
set -e
531+
cd $GITHUB_WORKSPACE
435532
ls -R ./build
436533
437534
- name: Debug build/dist directory
438535
if: always()
439536
run: |
537+
set -e
538+
cd $GITHUB_WORKSPACE
440539
ls -R ./build/dist
441540
442541
- name: Cleanup
443542
run: |
543+
set -e
544+
cd $GITHUB_WORKSPACE
444545
rm -f -r ./build/dist/share
445546
446547
- name: Upload Artifacts
447548
uses: actions/upload-artifact@v4
448549
with:
550+
if-no-files-found: error
449551
name: ${{ matrix.name }}
450552
path: ./build/dist
451553

CMakeLists.txt

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ option(BUILD_FFMPEG_X265_PATCHES "Apply FFmpeg x265 patches" ON)
3333
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/apply_git_patch.cmake)
3434
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/unix_path.cmake)
3535

36+
if(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
37+
set(FREEBSD ON)
38+
endif()
39+
3640
if(UNIX AND NOT APPLE)
3741
include(GNUInstallDirs)
3842
endif()
@@ -44,12 +48,13 @@ if(NOT DEFINED PARALLEL_BUILDS)
4448
else()
4549
set(N_PROC ${PARALLEL_BUILDS})
4650
endif()
47-
if(N EQUAL 0)
51+
if(N_PROC EQUAL 0)
4852
set(N_PROC 1)
49-
elseif(NOT N MATCHES "^[0-9]+$")
53+
elseif(NOT N_PROC MATCHES "^[0-9]+$")
5054
# if not a number, set it to 1
5155
set(N_PROC 1)
5256
endif()
57+
message(STATUS "parallel builds: ${N_PROC}")
5358

5459
set(MSYS2_ROOT "C:/msys64")
5560
if(WIN32 AND DEFINED ENV{MSYS2_ROOT})
@@ -60,14 +65,22 @@ endif()
6065
if(NOT DEFINED BASH_EXECUTABLE)
6166
find_program(BASH_EXECUTABLE
6267
NAMES zsh bash
63-
REQUIRED
64-
HINTS "${MSYS2_ROOT}/usr/bin" /bin /usr/bin /usr/local/bin)
68+
HINTS "${MSYS2_ROOT}/usr/bin" /bin /usr/bin /usr/local/bin
69+
DOC "Bash shell executable"
70+
REQUIRED)
6571
message(STATUS "Found bash: ${BASH_EXECUTABLE}")
6672
endif()
6773

74+
if(FREEBSD)
75+
set(MAKE_FIND_NAMES "gmake") # We get invalid line types in nv-codec-headers Makefile if we use BSD make
76+
else()
77+
set(MAKE_FIND_NAMES "mingw32-make;make;gmake")
78+
endif()
79+
6880
find_program(MAKE_EXECUTABLE
69-
NAMES mingw32-make make gmake
81+
NAMES ${MAKE_FIND_NAMES}
7082
NAMES_PER_DIR
83+
HINTS "${MSYS2_ROOT}/usr/bin" /bin /usr/bin /usr/local/bin
7184
DOC "GNU Make"
7285
REQUIRED)
7386
message(STATUS "Found make: ${MAKE_EXECUTABLE}")
@@ -169,6 +182,10 @@ add_custom_target(${CMAKE_PROJECT_NAME}
169182
# set architecture
170183
string(TOLOWER ${CMAKE_SYSTEM_PROCESSOR} arch)
171184

185+
message(STATUS "Detected system name: ${CMAKE_SYSTEM_NAME}")
186+
message(STATUS "Detected architecture: ${CMAKE_SYSTEM_PROCESSOR}")
187+
message(STATUS "CI Matrix name should be: '${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_PROCESSOR}'")
188+
172189
# set generated source path
173190
set(CMAKE_GENERATED_SRC_PATH ${CMAKE_CURRENT_BINARY_DIR}/generated-src)
174191

README.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,30 @@ git checkout HEAD -- .
6464

6565
### Dependencies
6666

67+
#### FreeBSD
68+
69+
```bash
70+
pkg install -y \
71+
devel/autoconf \
72+
devel/automake \
73+
devel/cmake \
74+
devel/git \
75+
devel/gmake \
76+
devel/nasm \
77+
devel/ninja \
78+
devel/pkgconf \
79+
multimedia/libass \
80+
multimedia/libv4l \
81+
multimedia/libva \
82+
multimedia/v4l_compat \
83+
print/freetype2 \
84+
security/gnutls \
85+
shells/bash \
86+
x11/libx11 \
87+
x11/libxcb \
88+
x11/libXfixes
89+
```
90+
6791
#### Linux
6892

6993
```bash
@@ -205,6 +229,8 @@ Valid options are, 1, 2, and 3. The default is 1.
205229

206230
### Build
207231

232+
ℹ️ On FreeBSD, use `gmake` instead of `make`.
233+
208234
```bash
209235
make -C build
210236
```

cmake/ffmpeg/_main.cmake

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,25 @@ set(AVCODEC_GENERATED_SRC_PATH ${CMAKE_GENERATED_SRC_PATH}/FFmpeg/libavcodec)
55

66
if(WIN32)
77
set(BUILD_FFMPEG_VAAPI OFF)
8+
9+
# We must disable CUDA and NVENC on ARM64 until following issues is resolved
10+
# https://github.com/FFmpeg/FFmpeg/blob/4e5523c98597a417eb43555933b1075d18ec5f8b/configure#L7443
11+
if (${arch} STREQUAL "arm64")
12+
set(BUILD_FFMPEG_NV_CODEC_HEADERS OFF)
13+
endif()
814
elseif(APPLE)
915
set(BUILD_FFMPEG_AMF OFF)
1016
set(BUILD_FFMPEG_MF OFF)
1117
set(BUILD_FFMPEG_NV_CODEC_HEADERS OFF)
1218
set(BUILD_FFMPEG_VAAPI OFF)
19+
elseif(FREEBSD)
20+
set(BUILD_FFMPEG_AMF OFF)
21+
set(BUILD_FFMPEG_MF OFF)
22+
if(${arch} STREQUAL "aarch64")
23+
set(BUILD_FFMPEG_NV_CODEC_HEADERS OFF)
24+
endif()
1325
elseif(UNIX)
14-
# nothing to disable for Linux
26+
set(BUILD_FFMPEG_MF OFF)
1527
endif()
1628

1729
if(BUILD_FFMPEG_AMF)

0 commit comments

Comments
 (0)