build: add freebsd support

This commit is contained in:
ReenigneArcher 2025-07-04 20:16:38 -04:00
parent 8372c37046
commit d3a73d47c9
No known key found for this signature in database
GPG Key ID: 362B4EC0ADC98755
26 changed files with 527 additions and 29 deletions

256
.github/workflows/ci-freebsd.yml vendored Normal file
View File

@ -0,0 +1,256 @@
---
name: CI-FreeBSD
permissions:
contents: read
on:
workflow_call:
inputs:
release_commit:
required: true
type: string
release_version:
required: true
type: string
env:
FREEBSD_CLANG_VERSION: 19
jobs:
setup-matrix:
name: Setup Build Matrix
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.generate-matrix.outputs.matrix }}
steps:
- name: Generate Matrix
id: generate-matrix
shell: bash
run: |
# Base matrix with amd64 build
matrix='{
"include": [
{
"bsd_release": "14.3",
"arch": "x86_64",
"cmake_processor": "amd64",
"runner": "ubuntu-latest"
}
]
}'
# Add aarch64 build only if not a pull request event
if [[ "${{ github.event_name }}" != "pull_request" ]]; then
matrix=$(echo "$matrix" | jq '.include += [{
"bsd_release": "14.3",
"arch": "aarch64",
"cmake_processor": "aarch64",
"runner": "ubuntu-latest"
}]')
fi
# Use heredoc for multiline JSON output
{
echo "matrix<<EOF"
echo "$matrix"
echo "EOF"
} >> "${GITHUB_OUTPUT}"
echo "Generated matrix:"
echo "$matrix" | jq .
build_freebsd:
name: ${{ matrix.cmake_processor }}-${{ matrix.bsd_release }}
runs-on: ubuntu-latest
needs: setup-matrix
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.setup-matrix.outputs.matrix) }}
steps:
- name: Checkout
uses: actions/checkout@v5
with:
submodules: recursive
- name: Get Processor Count
id: processor_count
shell: bash
run: |
PROCESSOR_COUNT=$(nproc)
echo "PROCESSOR_COUNT=${PROCESSOR_COUNT}" >> "${GITHUB_OUTPUT}"
echo "PROCESSOR_COUNT: $PROCESSOR_COUNT"
- name: Setup FreeBSD
uses: vmactions/freebsd-vm@v1.2.3
with:
arch: ${{ matrix.arch }}
cpu: ${{ steps.processor_count.outputs.PROCESSOR_COUNT }}
# TODO: there is no libcap for freebsd... we need graphics/libdrm if we find a way to use libcap
# TODO: docs are off because doxygen is too old: https://www.freshports.org/devel/doxygen/ must be >= 1.10
prepare: |
set -e
pkg update
pkg upgrade -y
pkg install -y \
audio/opus \
audio/pulseaudio \
devel/cmake-core \
devel/evdev-proto \
devel/git \
devel/libayatana-appindicator \
devel/libevdev \
devel/libnotify \
devel/llvm${{ env.FREEBSD_CLANG_VERSION }} \
devel/ninja \
devel/pkgconf \
ftp/curl \
graphics/libdrm \
graphics/wayland \
lang/python312 \
multimedia/libva \
net/miniupnpc \
ports-mgmt/pkg \
security/openssl \
shells/bash \
www/npm \
x11/libX11 \
x11/libxcb \
x11/libXfixes \
x11/libXrandr \
x11/libXtst \
x11-servers/xorg-server
# create symlink for shebang bash compatibility
ln -s /usr/local/bin/bash /bin/bash
# setup python
ln -s /usr/local/bin/python3.12 /usr/local/bin/python
python -m ensurepip
release: ${{ matrix.bsd_release }}
run: |
set -e
# install gcvor
python -m pip install gcovr
# fix git safe.directory issues
git config --global --add safe.directory "*"
sync: nfs
- name: Configure
env:
BRANCH: ${{ github.head_ref || github.ref_name }}
BUILD_VERSION: ${{ inputs.release_version }}
COMMIT: ${{ inputs.release_commit }}
shell: freebsd {0}
run: |
set -e
cd "${GITHUB_WORKSPACE}"
export BRANCH="${BRANCH}"
export BUILD_VERSION="${BUILD_VERSION}"
export COMMIT="${COMMIT}"
cc_path="$(which clang${{ env.FREEBSD_CLANG_VERSION }})"
cxx_path="$(which clang++${{ env.FREEBSD_CLANG_VERSION }})"
export CC="${cc_path}"
export CXX="${cxx_path}"
mkdir -p build
cmake \
-B build \
-G Ninja \
-S . \
-DBUILD_DOCS=OFF \
-DBUILD_WERROR=OFF \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=/usr/local \
-DSUNSHINE_ASSETS_DIR=share/assets \
-DSUNSHINE_EXECUTABLE_PATH=/usr/local/bin/sunshine \
-DSUNSHINE_ENABLE_CUDA=OFF \
-DSUNSHINE_ENABLE_DRM=OFF \
-DSUNSHINE_ENABLE_WAYLAND=ON \
-DSUNSHINE_ENABLE_X11=ON \
-DSUNSHINE_PUBLISHER_NAME='${{ github.repository_owner }}' \
-DSUNSHINE_PUBLISHER_WEBSITE='https://app.lizardbyte.dev' \
-DSUNSHINE_PUBLISHER_ISSUE_URL='https://app.lizardbyte.dev/support'
- name: Build
shell: freebsd {0}
run: |
set -e
cd "${GITHUB_WORKSPACE}"
ninja -C build
- name: Package
shell: freebsd {0}
run: |
set -e
cd "${GITHUB_WORKSPACE}"
mkdir -p artifacts
cd build
cpack -G FREEBSD
# move compiled files to artifacts
mv ./cpack_artifacts/Sunshine.pkg \
../artifacts/Sunshine-FreeBSD-${{ matrix.bsd_release }}-${{ matrix.cmake_processor }}.pkg
- name: Debug +MANIFEST
if: always()
shell: bash
working-directory: build/cpack_artifacts
run: cat ./_CPack_Packages/FreeBSD/FREEBSD/Sunshine/+MANIFEST
- name: Test
id: test
shell: freebsd {0}
run: |
set -e
cd "${GITHUB_WORKSPACE}/build/tests"
export DISPLAY=:1
Xvfb ${DISPLAY} -screen 0 1024x768x24 &
XVFB_PID=$!
./test_sunshine --gtest_color=yes --gtest_output=xml:test_results.xml
kill ${XVFB_PID}
- name: Generate gcov report
id: test_report
# any except canceled or skipped
if: >-
always() &&
(steps.test.outcome == 'success' || steps.test.outcome == 'failure')
shell: freebsd {0}
run: |
cd "${GITHUB_WORKSPACE}/build"
python -m gcovr . -r ../src \
--exclude-noncode-lines \
--exclude-throw-branches \
--exclude-unreachable-branches \
--verbose \
--xml-pretty \
-o coverage.xml
- name: Upload coverage artifact
if: >-
always() &&
(steps.test_report.outcome == 'success')
uses: actions/upload-artifact@v4
with:
name: coverage-FreeBSD-${{ matrix.bsd_release }}-${{ matrix.cmake_processor }}
path: |
build/coverage.xml
build/tests/test_results.xml
if-no-files-found: error
- name: Upload Artifacts
uses: actions/upload-artifact@v4
with:
name: build-FreeBSD-${{ matrix.bsd_release }}-${{ matrix.cmake_processor }}
path: artifacts/
if-no-files-found: error

View File

@ -69,6 +69,14 @@ jobs:
GH_BOT_TOKEN: ${{ secrets.GH_BOT_TOKEN }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
build-freebsd:
name: FreeBSD
needs: release-setup
uses: ./.github/workflows/ci-freebsd.yml
with:
release_commit: ${{ needs.release-setup.outputs.release_commit }}
release_version: ${{ needs.release-setup.outputs.release_version }}
build-homebrew:
name: Homebrew
needs: release-setup
@ -128,6 +136,7 @@ jobs:
!cancelled() &&
startsWith(github.repository, 'LizardByte/')
needs:
- build-freebsd
- build-linux
- build-linux-flatpak
- build-homebrew
@ -137,29 +146,53 @@ jobs:
fail-fast: false
matrix:
include:
- name: FreeBSD-14.3-amd64
coverage: true
pr: true
- name: FreeBSD-14.3-aarch64
coverage: true
pr: false
- name: Linux-AppImage
coverage: true
pr: true
- name: Homebrew-macos-14
coverage: false
pr: true
- name: Homebrew-macos-15
coverage: false
pr: true
- name: Homebrew-macos-26
coverage: false
pr: true
- name: Homebrew-ubuntu-latest
coverage: false
pr: true
- name: Windows-AMD64
coverage: true
pr: true
steps:
- name: Should run
id: should_run
run: |
if [ ${{ github.event_name }} != 'pull_request' ] || [ ${{ matrix.pr }} == 'true' ]; then
echo "SHOULD_RUN=true" >> "${GITHUB_OUTPUT}"
else
echo "SHOULD_RUN=false" >> "${GITHUB_OUTPUT}"
fi
- name: Checkout
if: steps.should_run.outputs.SHOULD_RUN == 'true'
uses: actions/checkout@v5
- name: Download coverage artifact
if: steps.should_run.outputs.SHOULD_RUN == 'true'
uses: actions/download-artifact@v5
with:
name: coverage-${{ matrix.name }}
path: _coverage
- name: Upload test results
if: steps.should_run.outputs.SHOULD_RUN == 'true'
uses: codecov/test-results-action@v1
with:
disable_search: true
@ -170,8 +203,8 @@ jobs:
verbose: true
- name: Upload coverage
if: steps.should_run.outputs.SHOULD_RUN == 'true' && matrix.coverage != false
uses: codecov/codecov-action@v5
if: matrix.coverage != false
with:
disable_search: true
fail_ci_if_error: true
@ -188,6 +221,7 @@ jobs:
needs:
- release-setup
- build-docker
- build-freebsd
- build-linux
- build-linux-flatpak
- build-homebrew

View File

@ -24,6 +24,10 @@ if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build." FORCE)
endif()
if(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
set(FREEBSD ON)
endif()
# set the module path, used for includes
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")

View File

@ -1,6 +1,10 @@
# linux specific compile definitions
if(FREEBSD)
add_compile_definitions(SUNSHINE_PLATFORM="freebsd")
else()
add_compile_definitions(SUNSHINE_PLATFORM="linux")
endif()
# AppImage
if(${SUNSHINE_BUILD_APPIMAGE})
@ -211,6 +215,9 @@ endif()
# These need to be set before adding the inputtino subdirectory in order for them to be picked up
set(LIBEVDEV_CUSTOM_INCLUDE_DIR "${EVDEV_INCLUDE_DIR}")
set(LIBEVDEV_CUSTOM_LIBRARY "${EVDEV_LIBRARY}")
if(FREEBSD)
set(USE_UHID OFF)
endif()
add_subdirectory("${CMAKE_SOURCE_DIR}/third-party/inputtino")
list(APPEND SUNSHINE_EXTERNAL_LIBRARIES inputtino::libinputtino)

View File

@ -30,6 +30,9 @@ include_directories(SYSTEM ${MINIUPNP_INCLUDE_DIRS})
if(NOT DEFINED FFMPEG_PREPARED_BINARIES)
if(WIN32)
set(FFMPEG_PLATFORM_LIBRARIES mfplat ole32 strmiids mfuuid vpl)
elseif(FREEBSD)
# numa is not available on FreeBSD
set(FFMPEG_PLATFORM_LIBRARIES va va-drm va-x11 X11)
elseif(UNIX AND NOT APPLE)
set(FFMPEG_PLATFORM_LIBRARIES numa va va-drm va-x11 X11)
endif()

View File

@ -34,6 +34,14 @@ else()
endif()
endif()
# RPM specific
set(CPACK_RPM_PACKAGE_LICENSE "GPLv3")
# FreeBSD specific
set(CPACK_FREEBSD_PACKAGE_MAINTAINER "${CPACK_PACKAGE_VENDOR}")
set(CPACK_FREEBSD_PACKAGE_ORIGIN "misc/${CPACK_PACKAGE_NAME}")
set(CPACK_FREEBSD_PACKAGE_LICENSE "GPLv3")
# Post install
set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${SUNSHINE_SOURCE_ASSETS_DIR}/linux/misc/postinst")
set(CPACK_RPM_POST_INSTALL_SCRIPT_FILE "${SUNSHINE_SOURCE_ASSETS_DIR}/linux/misc/postinst")
@ -77,6 +85,15 @@ set(CPACK_RPM_PACKAGE_REQUIRES "\
openssl >= 3.0.2, \
pulseaudio-libs >= 10.0, \
which >= 2.21")
list(APPEND CPACK_FREEBSD_PACKAGE_DEPS
audio/opus
ftp/curl
devel/libevdev
net/avahi
x11/libX11
net/miniupnpc
security/openssl
)
if(NOT BOOST_USE_STATIC)
set(CPACK_DEBIAN_PACKAGE_DEPENDS "\
@ -91,6 +108,9 @@ if(NOT BOOST_USE_STATIC)
boost-locale >= ${Boost_VERSION}, \
boost-log >= ${Boost_VERSION}, \
boost-program-options >= ${Boost_VERSION}")
list(APPEND CPACK_FREEBSD_PACKAGE_DEPS
devel/boost-libs
)
endif()
# This should automatically figure out dependencies, doesn't work with the current config
@ -141,6 +161,10 @@ if(${SUNSHINE_TRAY} STREQUAL 1)
set(CPACK_RPM_PACKAGE_REQUIRES "\
${CPACK_RPM_PACKAGE_REQUIRES}, \
libappindicator-gtk3 >= 12.10.0")
list(APPEND CPACK_FREEBSD_PACKAGE_DEPS
devel/libayatana-appindicator
devel/libnotify
)
endif()
# desktop file

View File

@ -26,6 +26,14 @@ and applications to Sunshine.
> process is killed.
@tabs{
@tab{FreeBSD | <!-- -->
\| Field \| Value \|
\|------------------------------\|------------------------------------------------------\|
\| Application Name \| @code{}Steam Big Picture@endcode \|
\| Command Preporations -> Undo \| @code{}setsid steam steam://close/bigpicture@endcode \|
\| Detached Commands \| @code{}setsid steam steam://open/bigpicture@endcode \|
\| Image \| @code{}steam.png@endcode \|
}
@tab{Linux | <!-- -->
\| Field \| Value \|
\|------------------------------\|------------------------------------------------------\|
@ -97,6 +105,12 @@ and applications to Sunshine.
#### URI
@tabs{
@tab{FreeBSD | <!-- -->
\| Field \| Value \|
\|-------------------\|------------------------------------------------------\|
\| Application Name \| @code{}Surviving Mars@endcode \|
\| Detached Commands \| @code{}setsid steam steam://rungameid/464920@endcode \|
}
@tab{Linux | <!-- -->
\| Field \| Value \|
\|-------------------\|------------------------------------------------------\|
@ -119,6 +133,13 @@ and applications to Sunshine.
#### Binary (w/ working directory
@tabs{
@tab{FreeBSD | <!-- -->
\| Field \| Value \|
\|-------------------\|--------------------------------------------------------------\|
\| Application Name \| @code{}Surviving Mars@endcode \|
\| Command \| @code{}MarsSteam@endcode \|
\| Working Directory \| @code{}~/.steam/steam/SteamApps/common/Survivng Mars@endcode \|
}
@tab{Linux | <!-- -->
\| Field \| Value \|
\|-------------------\|--------------------------------------------------------------\|
@ -144,6 +165,12 @@ and applications to Sunshine.
#### Binary (w/o working directory)
@tabs{
@tab{FreeBSD | <!-- -->
\| Field \| Value \|
\|-------------------\|------------------------------------------------------------------------\|
\| Application Name \| @code{}Surviving Mars@endcode \|
\| Command \| @code{}~/.steam/steam/SteamApps/common/Survivng Mars/MarsSteam@endcode \|
}
@tab{Linux | <!-- -->
\| Field \| Value \|
\|-------------------\|------------------------------------------------------------------------\|

View File

@ -14,6 +14,39 @@ It is recommended to use one of the following compilers:
### Dependencies
#### FreeBSD
> [!CAUTION]
> Sunshine support for FreeBSD is experimental and may be incomplete or not work as expected
##### Install dependencies
```sh
pkg install -y \
audio/opus \
audio/pulseaudio \
devel/cmake \
devel/evdev-proto \
devel/git \
devel/libayatana-appindicator \
devel/libevdev \
devel/libnotify \
devel/ninja \
devel/pkgconf \
ftp/curl \
graphics/libdrm \
graphics/wayland \
multimedia/libva \
net/miniupnpc \
ports-mgmt/pkg \
security/openssl \
shells/bash \
www/npm \
x11/libX11 \
x11/libxcb \
x11/libXfixes \
x11/libXrandr \
x11/libXtst
```
#### Linux
Dependencies vary depending on the distribution. You can reference our
[linux_build.sh](https://github.com/LizardByte/Sunshine/blob/master/scripts/linux_build.sh) script for a list of
@ -135,6 +168,11 @@ ninja -C build
### Package
@tabs{
@tab{FreeBSD | @tabs{
@tab{pkg | ```bash
cpack -G FREEBSD --config ./build/CPackConfig.cmake
```}
}}
@tab{Linux | @tabs{
@tab{deb | ```bash
cpack -G DEB --config ./build/CPackConfig.cmake

View File

@ -26,6 +26,7 @@ location by modifying the configuration file.
| OS | Location |
|---------|-------------------------------------------------|
| Docker | @code{}/config@endcode |
| FreeBSD | @code{}~/.config/sunshine@endcode |
| Linux | @code{}~/.config/sunshine@endcode |
| macOS | @code{}~/.config/sunshine@endcode |
| Windows | @code{}%ProgramFiles%\\Sunshine\\config@endcode |
@ -339,12 +340,12 @@ editing the `conf` file in a text editor. Use the examples as reference.
<tr>
<td>ds5</td>
<td>DualShock 5 controller (PS5)
@note{This option applies to Linux only.}</td>
@note{This option applies to FreeBSD and Linux only.}</td>
</tr>
<tr>
<td>switch</td>
<td>Switch Pro controller
@note{This option applies to Linux only.}</td>
@note{This option applies to FreeBSD and Linux only.}</td>
</tr>
<tr>
<td>x360</td>
@ -354,7 +355,7 @@ editing the `conf` file in a text editor. Use the examples as reference.
<tr>
<td>xone</td>
<td>Xbox One controller
@note{This option applies to Linux only.}</td>
@note{This option applies to FreeBSD and Linux only.}</td>
</tr>
</table>
@ -735,14 +736,14 @@ editing the `conf` file in a text editor. Use the examples as reference.
@tip{To find the name of the audio sink follow these instructions.
<br>
<br>
**Linux + pulseaudio:**
**FreeBSD/Linux + pulseaudio:**
<br>
@code{}
pacmd list-sinks | grep "name:"
@endcode
<br>
<br>
**Linux + pipewire:**
**FreeBSD/Linux + pipewire:**
<br>
@code{}
pactl info | grep Source
@ -776,7 +777,7 @@ editing the `conf` file in a text editor. Use the examples as reference.
<td colspan="2">Sunshine will select the default audio device.</td>
</tr>
<tr>
<td>Example (Linux)</td>
<td>Example (FreeBSD/Linux)</td>
<td colspan="2">@code{}
audio_sink = alsa_output.pci-0000_09_00.3.analog-stereo
@endcode</td>
@ -883,7 +884,7 @@ editing the `conf` file in a text editor. Use the examples as reference.
@tip{To find the appropriate values follow these instructions.
<br>
<br>
**Linux + VA-API:**
**FreeBSD/Linux + VA-API:**
<br>
Unlike with *amdvce* and *nvenc*, it doesn't matter if video encoding is done on a different GPU.
@code{}
@ -913,7 +914,7 @@ editing the `conf` file in a text editor. Use the examples as reference.
<td colspan="2">Sunshine will select the default video card.</td>
</tr>
<tr>
<td>Example (Linux)</td>
<td>Example (FreeBSD/Linux)</td>
<td colspan="2">@code{}
adapter_name = /dev/dri/renderD128
@endcode</td>
@ -936,7 +937,7 @@ editing the `conf` file in a text editor. Use the examples as reference.
@tip{To find the appropriate values follow these instructions.
<br>
<br>
**Linux:**
**FreeBSD/Linux:**
<br>
During Sunshine startup, you should see the list of detected displays:
@code{}
@ -1021,7 +1022,7 @@ editing the `conf` file in a text editor. Use the examples as reference.
<td colspan="2">Sunshine will select the default display.</td>
</tr>
<tr>
<td>Example (Linux)</td>
<td>Example (FreeBSD/Linux)</td>
<td colspan="2">@code{}
output_name = 0
@endcode</td>
@ -2034,7 +2035,7 @@ editing the `conf` file in a text editor. Use the examples as reference.
<tr>
<td>x11</td>
<td>Uses XCB. This is the slowest and most CPU intensive so should be avoided if possible.
@note{Applies to Linux only.}</td>
@note{Applies to FreeBSD and Linux only.}</td>
</tr>
<tr>
<td>ddx</td>
@ -2083,7 +2084,7 @@ editing the `conf` file in a text editor. Use the examples as reference.
</tr>
<tr>
<td>vaapi</td>
<td>Use Linux VA-API (AMD, Intel)</td>
<td>Use VA-API (AMD, Intel)</td>
</tr>
<tr>
<td>software</td>

View File

@ -8,7 +8,7 @@ and release artifacts may be missing when merging changes on a faster cadence.
## Binaries
Binaries of Sunshine are created for each release. They are available for Linux, macOS, and Windows.
Binaries of Sunshine are created for each release. They are available for FreeBSD, Linux, macOS, and Windows.
Binaries can be found in the [latest release][latest-release].
> [!NOTE]
@ -28,7 +28,27 @@ and [ghcr.io](https://github.com/orgs/LizardByte/packages?repo_name=sunshine).
See [Docker](../DOCKER_README.md) for more information.
### FreeBSD
#### Install
1. Download the appropriate package for your architecture
| Architecture | Package |
|---------------|----------------------------------------------------------------------------------------------------------------------------------------|
| amd64/x86_64 | [Sunshine-FreeBSD-14.3-amd64.pkg](https://github.com/LizardByte/Sunshine/releases/latest/download/Sunshine-FreeBSD-14.3-amd64.pkg) |
| arm64/aarch64 | [Sunshine-FreeBSD-14.3-aarch64.pkg](https://github.com/LizardByte/Sunshine/releases/latest/download/Sunshine-FreeBSD-14.3-aarch64.pkg) |
2. Open terminal and run the following command.
```sh
sudo pkg install ./Sunshine-FreeBSD-14.3-{arch}.pkg
```
##### Uninstall
```sh
sudo pkg delete Sunshine
```
### Linux
**CUDA Compatibility**
CUDA is used for NVFBC capture.
@ -522,6 +542,12 @@ All shortcuts start with `Ctrl+Alt+Shift`, just like Moonlight.
* The "Desktop" app works the same as any other application except it has no commands. It does not start an application,
instead it simply starts a stream. If you removed it and would like to get it back, just add a new application with
the name "Desktop" and "desktop.png" as the image path.
* The FreeBSD version of Sunshine is missing some features that are present on Linux.
The following are known limitations.
* Only X11 and Wayland capture are supported
* DualSense5 emulation is limited due to missing uhid features
* For the Linux flatpak you must prepend commands with `flatpak-spawn --host`.
* If inputs (mouse, keyboard, gamepads...) aren't working after connecting, add the user running sunshine to the `input` group.

View File

@ -35,6 +35,30 @@
#include "src/platform/common.h"
#include "vaapi.h"
#ifdef __FreeBSD__
#include <netinet/in.h>
#include <sys/socket.h>
// Define constants that are missing in FreeBSD
#ifndef IP_PKTINFO // packet info for IPv4
#define IP_PKTINFO IP_RECVDSTADDR
#endif
#ifndef SOL_IP // socket level for IPv4
#define SOL_IP IPPROTO_IP
#endif
#ifndef SOL_IPV6 // socket level for IPv6
#define SOL_IPV6 IPPROTO_IPV6
#endif
#ifndef SO_PRIORITY // socket option for priority, disabled for FreeBSD
#define SO_PRIORITY -1
#endif
// Define in_pktinfo structure for IPv4 packet info
struct in_pktinfo {
struct in_addr ipi_addr;
struct in_addr ipi_spec_dst;
int ipi_ifindex;
};
#endif
#ifdef __GNUC__
#define SUNSHINE_GNUC_EXTENSION __extension__
#else
@ -507,8 +531,8 @@ namespace platf {
{
// If GSO is not supported, use sendmmsg() instead.
struct mmsghdr msgs[send_info.block_count];
struct iovec iovs[send_info.block_count * (send_info.headers ? 2 : 1)];
std::vector<struct mmsghdr> msgs(send_info.block_count);
std::vector<struct iovec> iovs(send_info.block_count * (send_info.headers ? 2 : 1));
int iov_idx = 0;
for (size_t i = 0; i < send_info.block_count; i++) {
msgs[i].msg_len = 0;
@ -753,6 +777,10 @@ namespace platf {
// reset SO_PRIORITY back to 0.
//
// 6 is the highest priority that can be used without SYS_CAP_ADMIN.
#ifdef __FreeBSD__
// FreeBSD doesn't support SO_PRIORITY, so we skip this
BOOST_LOG(debug) << "SO_PRIORITY not supported on FreeBSD, skipping traffic priority setting";
#else
int priority = data_type == qos_data_type_e::audio ? 6 : 5;
if (setsockopt(sockfd, SOL_SOCKET, SO_PRIORITY, &priority, sizeof(priority)) == 0) {
// Reset SO_PRIORITY to 0 when QoS is disabled
@ -760,6 +788,7 @@ namespace platf {
} else {
BOOST_LOG(error) << "Failed to set SO_PRIORITY: "sv << errno;
}
#endif
return std::make_unique<qos_t>(sockfd, reset_options);
}

View File

@ -13,7 +13,7 @@
#define TRAY_ICON_PLAYING WEB_DIR "images/sunshine-playing.ico"
#define TRAY_ICON_PAUSING WEB_DIR "images/sunshine-pausing.ico"
#define TRAY_ICON_LOCKED WEB_DIR "images/sunshine-locked.ico"
#elif defined(__linux__) || defined(linux) || defined(__linux)
#elif defined(__linux__) || defined(linux) || defined(__linux) || defined(__FreeBSD__)
#define TRAY_ICON SUNSHINE_TRAY_PREFIX "-tray"
#define TRAY_ICON_PLAYING SUNSHINE_TRAY_PREFIX "-playing"
#define TRAY_ICON_PAUSING SUNSHINE_TRAY_PREFIX "-pausing"

View File

@ -897,7 +897,7 @@ namespace video {
H264_ONLY | PARALLEL_ENCODING | ALWAYS_REPROBE | YUV444_SUPPORT
};
#ifdef __linux__
#if defined(__linux__) || defined(linux) || defined(__linux) || defined(__FreeBSD__)
encoder_t vaapi {
"vaapi"sv,
std::make_unique<encoder_platform_formats_avcodec>(
@ -1032,7 +1032,7 @@ namespace video {
&quicksync,
&amdvce,
#endif
#ifdef __linux__
#if defined(__linux__) || defined(linux) || defined(__linux) || defined(__FreeBSD__)
&vaapi,
#endif
#ifdef __APPLE__

View File

@ -221,7 +221,7 @@ namespace video {
extern encoder_t quicksync;
#endif
#ifdef __linux__
#if defined(__linux__) || defined(linux) || defined(__linux) || defined(__FreeBSD__)
extern encoder_t vaapi;
#endif

View File

@ -12,6 +12,10 @@ const props = defineProps({
<slot name="windows"></slot>
</template>
<template v-if="$slots.freebsd && platform === 'freebsd'">
<slot name="freebsd"></slot>
</template>
<template v-if="$slots.linux && platform === 'linux'">
<slot name="linux"></slot>
</template>

View File

@ -331,7 +331,7 @@
<div class="form-text" v-if="platform === 'windows'"><b>{{ $t('apps.env_qres_example') }}</b>
<pre>cmd /C &lt;{{ $t('apps.env_qres_path') }}&gt;\QRes.exe /X:%SUNSHINE_CLIENT_WIDTH% /Y:%SUNSHINE_CLIENT_HEIGHT% /R:%SUNSHINE_CLIENT_FPS%</pre>
</div>
<div class="form-text" v-else-if="platform === 'linux'"><b>{{ $t('apps.env_xrandr_example') }}</b>
<div class="form-text" v-else-if="platform === 'freebsd' || platform === 'linux'"><b>{{ $t('apps.env_xrandr_example') }}</b>
<pre>sh -c "xrandr --output HDMI-1 --mode \"${SUNSHINE_CLIENT_WIDTH}x${SUNSHINE_CLIENT_HEIGHT}\" --rate ${SUNSHINE_CLIENT_FPS}"</pre>
</div>
<div class="form-text" v-else-if="platform === 'macos'"><b>{{ $t('apps.env_displayplacer_example') }}</b>

View File

@ -305,7 +305,7 @@
return el.id !== "vt" && el.id !== "vaapi";
});
}
if (this.platform === "linux") {
if (this.platform === "freebsd" || this.platform === "linux") {
this.tabs = this.tabs.filter((el) => {
return el.id !== "amd" && el.id !== "qsv" && el.id !== "vt";
});

View File

@ -64,6 +64,10 @@ const config = ref(props.config)
<select id="capture" class="form-select" v-model="config.capture">
<option value="">{{ $t('_common.autodetect') }}</option>
<PlatformLayout :platform="platform">
<template #freebsd>
<option value="wlr">wlroots</option>
<option value="x11">X11</option>
</template>
<template #linux>
<option value="nvfbc">NvFBC</option>
<option value="wlr">wlroots</option>
@ -90,6 +94,9 @@ const config = ref(props.config)
<option value="quicksync">Intel QuickSync</option>
<option value="amdvce">AMD AMF/VCE</option>
</template>
<template #freebsd>
<option value="vaapi">VA-API</option>
</template>
<template #linux>
<option value="nvenc">NVIDIA NVENC</option>
<option value="vaapi">VA-API</option>

View File

@ -30,6 +30,10 @@ const config = ref(props.config)
<template #windows>
<pre>tools\audio-info.exe</pre>
</template>
<template #freebsd>
<pre>pacmd list-sinks | grep "name:"</pre>
<pre>pactl info | grep Source</pre>
</template>
<template #linux>
<pre>pacmd list-sinks | grep "name:"</pre>
<pre>pactl info | grep Source</pre>

View File

@ -28,6 +28,12 @@ const config = ref(props.config)
<option value="auto">{{ $t('_common.auto') }}</option>
<PlatformLayout :platform="platform">
<template #freebsd>
<option value="ds5">{{ $t("config.gamepad_ds5") }}</option>
<option value="switch">{{ $t("config.gamepad_switch") }}</option>
<option value="xone">{{ $t("config.gamepad_xone") }}</option>
</template>
<template #linux>
<option value="ds5">{{ $t("config.gamepad_ds5") }}</option>
<option value="switch">{{ $t("config.gamepad_switch") }}</option>

View File

@ -23,6 +23,16 @@ const config = ref(props.config)
{{ $t('config.adapter_name_desc_windows') }}<br>
<pre>tools\dxgi-info.exe</pre>
</template>
<template #freebsd>
{{ $t('config.adapter_name_desc_linux_1') }}<br>
<pre>ls /dev/dri/renderD* # {{ $t('config.adapter_name_desc_linux_2') }}</pre>
<pre>
vainfo --display drm --device /dev/dri/renderD129 | \
grep -E "((VAProfileH264High|VAProfileHEVCMain|VAProfileHEVCMain10).*VAEntrypointEncSlice)|Driver version"
</pre>
{{ $t('config.adapter_name_desc_linux_3') }}<br>
<i>VAProfileH264High : VAEntrypointEncSlice</i>
</template>
<template #linux>
{{ $t('config.adapter_name_desc_linux_1') }}<br>
<pre>ls /dev/dri/renderD* # {{ $t('config.adapter_name_desc_linux_2') }}</pre>

View File

@ -241,6 +241,8 @@ function addRemappingEntry() {
</div>
</div>
</template>
<template #freebsd>
</template>
<template #linux>
</template>
<template #macos>

View File

@ -30,6 +30,16 @@ const outputNamePlaceholder = (props.platform === 'windows') ? '{de9bb7e2-186e-5
<b>&nbsp;&nbsp;}</b>
</pre>
</template>
<template #freebsd>
<pre style="white-space: pre-line;">
Info: Detecting displays
Info: Detected display: DVI-D-0 (id: 0) connected: false
Info: Detected display: HDMI-0 (id: 1) connected: true
Info: Detected display: DP-0 (id: 2) connected: true
Info: Detected display: DP-1 (id: 3) connected: false
Info: Detected display: DVI-D-1 (id: 4) connected: false
</pre>
</template>
<template #linux>
<pre style="white-space: pre-line;">
Info: Detecting displays

View File

@ -126,6 +126,12 @@ namespace test_utils {
#define IS_MACOS false
#endif
#ifdef __FreeBSD__
#define IS_FREEBSD true
#else
#define IS_FREEBSD false
#endif
struct PlatformTestSuite: testing::Test {
static void SetUpTestSuite() {
ASSERT_FALSE(platf_deinit);

View File

@ -13,7 +13,7 @@ struct MouseHIDTest: PlatformTestSuite, testing::WithParamInterface<util::point_
// the alternative `platf::abs_mouse` method seem to work better during tests,
// but I'm not sure about real work
GTEST_SKIP() << "TODO Windows";
#elif __linux__
#elif defined(__linux__) || defined(__FreeBSD__)
// TODO: Inputtino waiting https://github.com/games-on-whales/inputtino/issues/6 is resolved.
GTEST_SKIP() << "TODO Inputtino";
#endif
@ -88,7 +88,7 @@ TEST_P(MouseHIDTest, AbsMoveInputTest) {
65535,
65535
};
#elif __linux__
#elif defined(__linux__) || defined(__FreeBSD__)
platf::touch_port_t abs_port {
0,
0,

View File

@ -32,7 +32,7 @@ INSTANTIATE_TEST_SUITE_P(
&video::amdvce,
&video::quicksync,
#endif
#ifdef __linux__
#if defined(__linux__) || defined(__FreeBSD__)
&video::vaapi,
#endif
#ifdef __APPLE__