build: add freebsd support (#4049)

This commit is contained in:
David Lane
2025-11-11 23:46:11 -05:00
committed by GitHub
parent 2dbe837ebc
commit 1d6d916b7a
31 changed files with 1055 additions and 39 deletions

View File

@ -1,6 +1,10 @@
# linux specific compile definitions
add_compile_definitions(SUNSHINE_PLATFORM="linux")
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

@ -0,0 +1,138 @@
# FreeBSD post-build script to fix +POST_INSTALL and +PRE_DEINSTALL scripts
# in the generated .pkg file.
#
# This script runs AFTER CPack creates the .pkg file. We need to:
# 1. Extract the .pkg file (which is a tar.xz archive)
# 2. Add our install/deinstall scripts to the root
# 3. Remove script entries from the +MANIFEST files section
# 4. Repack the .pkg file using pkg-static
if(NOT CPACK_GENERATOR STREQUAL "FREEBSD")
return()
endif()
message(STATUS "FreeBSD post-build: Processing install/deinstall scripts")
# Get script paths from the list we set
if(NOT DEFINED CPACK_FREEBSD_PACKAGE_SCRIPTS)
message(FATAL_ERROR "FreeBSD post-build: CPACK_FREEBSD_PACKAGE_SCRIPTS not defined")
endif()
list(LENGTH CPACK_FREEBSD_PACKAGE_SCRIPTS _script_count)
if(_script_count EQUAL 0)
message(FATAL_ERROR "FreeBSD post-build: CPACK_FREEBSD_PACKAGE_SCRIPTS is empty")
endif()
# Find the package file in CPACK_TOPLEVEL_DIRECTORY
file(GLOB _pkg_files "${CPACK_TOPLEVEL_DIRECTORY}/*.pkg")
if(NOT _pkg_files)
message(FATAL_ERROR "FreeBSD post-build: No .pkg file found in ${CPACK_TOPLEVEL_DIRECTORY}")
endif()
list(GET _pkg_files 0 _pkg_file)
message(STATUS "FreeBSD post-build: Found package: ${_pkg_file}")
# Create a temporary directory for extraction
get_filename_component(_pkg_dir "${_pkg_file}" DIRECTORY)
set(_tmp_dir "${_pkg_dir}/pkg_repack_tmp")
file(REMOVE_RECURSE "${_tmp_dir}")
file(MAKE_DIRECTORY "${_tmp_dir}")
# Extract the package using tar (pkg files are tar.xz archives)
message(STATUS "FreeBSD post-build: Extracting package...")
find_program(TAR_EXECUTABLE tar REQUIRED)
find_program(PKG_STATIC_EXECUTABLE pkg-static REQUIRED)
execute_process(
COMMAND ${TAR_EXECUTABLE} -xf ${_pkg_file} --no-same-owner --numeric-owner
WORKING_DIRECTORY "${_tmp_dir}"
RESULT_VARIABLE _extract_result
ERROR_VARIABLE _extract_error
)
if(NOT _extract_result EQUAL 0)
message(FATAL_ERROR "FreeBSD post-build: Failed to extract package: ${_extract_error}")
endif()
# Debug: Check what was extracted
file(GLOB_RECURSE _extracted_files RELATIVE "${_tmp_dir}" "${_tmp_dir}/*")
list(LENGTH _extracted_files _file_count)
message(STATUS "FreeBSD post-build: Extracted ${_file_count} files")
# Copy the install/deinstall scripts to the extracted package root
message(STATUS "FreeBSD post-build: Adding install/deinstall scripts...")
foreach(script_path ${CPACK_FREEBSD_PACKAGE_SCRIPTS})
if(EXISTS "${script_path}")
get_filename_component(_script_name "${script_path}" NAME)
file(COPY "${script_path}"
DESTINATION "${_tmp_dir}/"
FILE_PERMISSIONS
OWNER_READ OWNER_WRITE OWNER_EXECUTE
GROUP_READ GROUP_EXECUTE
WORLD_READ WORLD_EXECUTE)
message(STATUS " Added: ${_script_name}")
else()
message(FATAL_ERROR "FreeBSD post-build: Script not found: ${script_path}")
endif()
endforeach()
# Repack the package using pkg-static create
message(STATUS "FreeBSD post-build: Repacking package...")
# Debug: Verify files before repacking
file(GLOB_RECURSE _files_before_repack RELATIVE "${_tmp_dir}" "${_tmp_dir}/*")
list(LENGTH _files_before_repack _count_before_repack)
message(STATUS "FreeBSD post-build: About to repack ${_count_before_repack} files")
# Debug: Check directory structure
if(EXISTS "${_tmp_dir}/usr")
message(STATUS "FreeBSD post-build: Found usr directory in extracted package")
file(GLOB_RECURSE _usr_files RELATIVE "${_tmp_dir}/usr" "${_tmp_dir}/usr/*")
list(LENGTH _usr_files _usr_file_count)
message(STATUS "FreeBSD post-build: usr directory contains ${_usr_file_count} files")
endif()
# Create metadata directory separate from rootdir
set(_metadata_dir "${_tmp_dir}/metadata")
file(MAKE_DIRECTORY "${_metadata_dir}")
# Move manifest and scripts to metadata directory
file(GLOB _metadata_files "${_tmp_dir}/+*")
foreach(meta_file ${_metadata_files})
get_filename_component(_meta_name "${meta_file}" NAME)
file(RENAME "${meta_file}" "${_metadata_dir}/${_meta_name}")
message(STATUS "FreeBSD post-build: Moved ${_meta_name} to metadata directory")
endforeach()
# Use pkg-static create to rebuild the package
# pkg create -r rootdir -m manifestdir -o outdir
# The rootdir should contain the actual files (usr/local/...)
# The manifestdir should contain +MANIFEST and install scripts
execute_process(
COMMAND ${PKG_STATIC_EXECUTABLE} create -r ${_tmp_dir} -m ${_metadata_dir} -o ${_pkg_dir}
RESULT_VARIABLE _pack_result
OUTPUT_VARIABLE _pack_output
ERROR_VARIABLE _pack_error
)
if(NOT _pack_result EQUAL 0)
message(FATAL_ERROR "FreeBSD post-build: Failed to repack package: ${_pack_error}")
endif()
# Find the generated package file (pkg create generates its own name based on manifest)
file(GLOB _new_pkg_files "${_pkg_dir}/Sunshine-*.pkg")
if(NOT _new_pkg_files)
message(FATAL_ERROR "FreeBSD post-build: pkg-static create succeeded but no package file was generated")
endif()
list(GET _new_pkg_files 0 _generated_pkg)
# Replace the original package with the newly created one
file(REMOVE "${_pkg_file}")
file(RENAME "${_generated_pkg}" "${_pkg_file}")
message(STATUS "FreeBSD post-build: Successfully processed package")
# Clean up
file(REMOVE_RECURSE "${_tmp_dir}")

View File

@ -34,10 +34,34 @@ 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")
# FreeBSD post install/deinstall scripts
if(FREEBSD)
# Note: CPack's FreeBSD generator does NOT natively support install/deinstall scripts
# like CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA or CPACK_RPM_POST_INSTALL_SCRIPT_FILE.
# This is a known limitation of the CPack FREEBSD generator.
#
# Workaround: Use CPACK_POST_BUILD_SCRIPTS to extract the generated .pkg file,
# add the install/deinstall scripts, and repack the package. This ensures they are
# recognized as package control scripts rather than installed files.
set(CPACK_FREEBSD_PACKAGE_SCRIPTS
"${SUNSHINE_SOURCE_ASSETS_DIR}/bsd/misc/+POST_INSTALL"
"${SUNSHINE_SOURCE_ASSETS_DIR}/bsd/misc/+PRE_DEINSTALL"
)
list(APPEND CPACK_POST_BUILD_SCRIPTS "${CMAKE_MODULE_PATH}/packaging/freebsd_custom_cpack.cmake")
endif()
# Apply setcap for RPM
# https://github.com/coreos/rpm-ostree/discussions/5036#discussioncomment-10291071
set(CPACK_RPM_USER_FILELIST "%caps(cap_sys_admin+p) ${SUNSHINE_EXECUTABLE_PATH}")
@ -77,6 +101,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 +124,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 on packages
@ -142,6 +178,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