diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 2b76e22d64c..fe222e5528f 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -59,7 +59,7 @@ jobs: - name: Check CMakeLists.txt Version run: | - version=$(grep -o -E '^project\(Sunshine VERSION [0-9]+\.[0-9]+\.[0-9]+' CMakeLists.txt | \ + version=$(grep -o -E '^project\(Sunshine VERSION [0-9]+\.[0-9]+\.[0-9]+' ./cmake/prep/base.cmake | \ grep -o -E '[0-9]+\.[0-9]+\.[0-9]+') echo "cmakelists_version=${version}" >> $GITHUB_ENV @@ -264,7 +264,7 @@ jobs: prerelease: ${{ needs.setup_release.outputs.pre_release }} build_linux: - name: Linux + name: Linux ${{ matrix.type }} runs-on: ubuntu-${{ matrix.dist }} needs: [check_changelog, setup_release] strategy: @@ -272,7 +272,7 @@ jobs: matrix: include: # package these differently - type: appimage - EXTRA_ARGS: '-DSUNSHINE_CONFIGURE_APPIMAGE=ON' + EXTRA_ARGS: '-DSUNSHINE_BUILD_APPIMAGE=ON' dist: 20.04 steps: @@ -406,6 +406,7 @@ jobs: make -j ${nproc} - name: Package Linux - CPACK + # todo - this is no longer used if: ${{ matrix.type == 'cpack' }} working-directory: build run: | @@ -418,13 +419,13 @@ jobs: fi - name: Set AppImage Version - if: ${{ matrix.type == 'appimage' && ( needs.check_changelog.outputs.next_version_bare != needs.check_changelog.outputs.last_version ) }} # yamllint disable-line rule:line-length + if: ${{ matrix.type == 'AppImage' && ( needs.check_changelog.outputs.next_version_bare != needs.check_changelog.outputs.last_version ) }} # yamllint disable-line rule:line-length run: | version=${{ needs.check_changelog.outputs.next_version_bare }} echo "VERSION=${version}" >> $GITHUB_ENV - name: Package Linux - AppImage - if: ${{ matrix.type == 'appimage' }} + if: ${{ matrix.type == 'AppImage' }} working-directory: build run: | # install sunshine to the DESTDIR @@ -460,7 +461,7 @@ jobs: chmod +x ../artifacts/sunshine.AppImage - name: Verify AppImage - if: ${{ matrix.type == 'appimage' }} + if: ${{ matrix.type == 'AppImage' }} run: | wget https://github.com/TheAssassin/appimagelint/releases/download/continuous/appimagelint-x86_64.AppImage chmod +x appimagelint-x86_64.AppImage diff --git a/CMakeLists.txt b/CMakeLists.txt index 3fa910ef5ed..eb6fb6821b8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,974 +1,43 @@ cmake_minimum_required(VERSION 3.18) # `CMAKE_CUDA_ARCHITECTURES` requires 3.18 -# todo - set version to 0.0.0 once confident in automated versioning -project(Sunshine VERSION 0.20.0 - DESCRIPTION "Sunshine is a self-hosted game stream host for Moonlight." - HOMEPAGE_URL "https://app.lizardbyte.dev") - -set(PROJECT_LONG_DESCRIPTION "Offering low latency, cloud gaming server capabilities with support for AMD, Intel, \ -and Nvidia GPUs for hardware encoding. Software encoding is also available. You can connect to Sunshine from any \ -Moonlight client on a variety of devices. A web UI is provided to allow configuration, and client pairing, from \ -your favorite web browser. Pair from the local server or any mobile device.") - -# Check if env vars are defined before attempting to access them, variables will be defined even if blank -if((DEFINED ENV{BRANCH}) AND (DEFINED ENV{BUILD_VERSION}) AND (DEFINED ENV{COMMIT})) # cmake-lint: disable=W0106 - if(($ENV{BRANCH} STREQUAL "master") AND (NOT $ENV{BUILD_VERSION} STREQUAL "")) - # If BRANCH is "master" and BUILD_VERSION is not empty, then we are building a master branch - MESSAGE("Got from CI master branch and version $ENV{BUILD_VERSION}") - set(PROJECT_VERSION $ENV{BUILD_VERSION}) - elseif((DEFINED ENV{BRANCH}) AND (DEFINED ENV{COMMIT})) - # If BRANCH is set but not BUILD_VERSION we are building nightly, we gather only the commit hash - MESSAGE("Got from CI $ENV{BRANCH} branch and commit $ENV{COMMIT}") - set(PROJECT_VERSION ${PROJECT_VERSION}.$ENV{COMMIT}) - endif() -# Generate Sunshine Version based of the git tag -# https://github.com/nocnokneo/cmake-git-versioning-example/blob/master/LICENSE -else() - find_package(Git) - if(GIT_EXECUTABLE) - MESSAGE("${CMAKE_CURRENT_SOURCE_DIR}") - get_filename_component(SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY) - #Get current Branch - execute_process( - COMMAND ${GIT_EXECUTABLE} rev-parse --abbrev-ref HEAD - #WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} - OUTPUT_VARIABLE GIT_DESCRIBE_BRANCH - RESULT_VARIABLE GIT_DESCRIBE_ERROR_CODE - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - # Gather current commit - execute_process( - COMMAND ${GIT_EXECUTABLE} rev-parse --short HEAD - #WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} - OUTPUT_VARIABLE GIT_DESCRIBE_VERSION - RESULT_VARIABLE GIT_DESCRIBE_ERROR_CODE - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - # Check if Dirty - execute_process( - COMMAND ${GIT_EXECUTABLE} diff --quiet --exit-code - #WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} - RESULT_VARIABLE GIT_IS_DIRTY - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - if(NOT GIT_DESCRIBE_ERROR_CODE) - MESSAGE("Sunshine Branch: ${GIT_DESCRIBE_BRANCH}") - if(NOT GIT_DESCRIBE_BRANCH STREQUAL "master") - set(PROJECT_VERSION ${PROJECT_VERSION}.${GIT_DESCRIBE_VERSION}) - MESSAGE("Sunshine Version: ${GIT_DESCRIBE_VERSION}") - endif() - if(GIT_IS_DIRTY) - set(PROJECT_VERSION ${PROJECT_VERSION}.dirty) - MESSAGE("Git tree is dirty!") - endif() - else() - MESSAGE(ERROR ": Got git error while fetching tags: ${GIT_DESCRIBE_ERROR_CODE}") - endif() - else() - MESSAGE(WARNING ": Git not found, cannot find git version") - endif() -endif() - -option(SUNSHINE_CONFIGURE_APPIMAGE "Configuration specific for AppImage." OFF) -option(SUNSHINE_CONFIGURE_AUR "Configure files required for AUR." OFF) -option(SUNSHINE_CONFIGURE_FLATPAK_MAN "Configure manifest file required for Flatpak build." OFF) -option(SUNSHINE_CONFIGURE_FLATPAK "Configuration specific for Flatpak." OFF) -option(SUNSHINE_CONFIGURE_PORTFILE "Configure macOS Portfile." OFF) -option(SUNSHINE_CONFIGURE_ONLY "Configure special files only, then exit." OFF) - -if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) - message(STATUS "Setting build type to 'Release' as none was specified.") - set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build." FORCE) -endif() - -if(${SUNSHINE_CONFIGURE_APPIMAGE}) - configure_file(packaging/linux/sunshine.desktop sunshine.desktop @ONLY) -elseif(${SUNSHINE_CONFIGURE_AUR}) - configure_file(packaging/linux/aur/PKGBUILD PKGBUILD @ONLY) -elseif(${SUNSHINE_CONFIGURE_FLATPAK_MAN}) - configure_file(packaging/linux/flatpak/dev.lizardbyte.sunshine.yml dev.lizardbyte.sunshine.yml @ONLY) -elseif(${SUNSHINE_CONFIGURE_PORTFILE}) - configure_file(packaging/macos/Portfile Portfile @ONLY) -endif() - -# return if configure only is set -if(${SUNSHINE_CONFIGURE_ONLY}) - return() -endif() - +# set the module path, used for includes set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) -set(SUNSHINE_SOURCE_ASSETS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src_assets") - -if(APPLE) - # ADD_FRAMEWORK: args = `fwname`, `appname` - macro(ADD_FRAMEWORK fwname appname) - find_library(FRAMEWORK_${fwname} - NAMES ${fwname} - PATHS ${CMAKE_OSX_SYSROOT}/System/Library - PATH_SUFFIXES Frameworks - NO_DEFAULT_PATH) - if( ${FRAMEWORK_${fwname}} STREQUAL FRAMEWORK_${fwname}-NOTFOUND) - MESSAGE(ERROR ": Framework ${fwname} not found") - else() - TARGET_LINK_LIBRARIES(${appname} "${FRAMEWORK_${fwname}}/${fwname}") - MESSAGE(STATUS "Framework ${fwname} found at ${FRAMEWORK_${fwname}}") - endif() - endmacro(ADD_FRAMEWORK) -endif() - -add_subdirectory(third-party/moonlight-common-c/enet) -add_subdirectory(third-party/Simple-Web-Server) - -set(UPNPC_BUILD_SHARED OFF CACHE BOOL "no shared libraries") -set(UPNPC_BUILD_TESTS OFF CACHE BOOL "Don't build tests for miniupnpc") -set(UPNPC_BUILD_SAMPLE OFF CACHE BOOL "Don't build samples for miniupnpc") -set(UPNPC_NO_INSTALL ON CACHE BOOL "Don't install any libraries build for miniupnpc") -add_subdirectory(third-party/miniupnp/miniupnpc) -include_directories(SYSTEM third-party/miniupnp/miniupnpc/include) - -find_package(Threads REQUIRED) -find_package(OpenSSL REQUIRED) -find_package(PkgConfig REQUIRED) -pkg_check_modules(CURL REQUIRED libcurl) - -if(WIN32) - set(Boost_USE_STATIC_LIBS ON) # cmake-lint: disable=C0103 - # 1.82.0+ is required for boost::json::value::set_at_pointer() support - find_package(Boost 1.82.0 COMPONENTS locale log filesystem program_options json REQUIRED) -else() - find_package(Boost COMPONENTS locale log filesystem program_options REQUIRED) -endif() - -list(APPEND SUNSHINE_COMPILE_OPTIONS -Wall -Wno-sign-compare) - -# enable system tray, we will disable this later if we cannot find the required package config on linux -set(SUNSHINE_TRAY 1) - -if(WIN32) - enable_language(RC) - set(CMAKE_RC_COMPILER windres) - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static") - - add_definitions(-DCURL_STATICLIB) - include_directories(SYSTEM ${CURL_STATIC_INCLUDE_DIRS}) - link_directories(${CURL_STATIC_LIBRARY_DIRS}) - - add_compile_definitions(SUNSHINE_PLATFORM="windows") - add_subdirectory(tools) # This is temporary, only tools for Windows are needed, for now - - include_directories(SYSTEM third-party/nvapi-open-source-sdk) - file(GLOB NVPREFS_FILES CONFIGURE_DEPENDS - "third-party/nvapi-open-source-sdk/*.h" - "src/platform/windows/nvprefs/*.cpp" - "src/platform/windows/nvprefs/*.h") - - include_directories(SYSTEM third-party/ViGEmClient/include) - - if(NOT DEFINED SUNSHINE_ICON_PATH) - set(SUNSHINE_ICON_PATH "${CMAKE_CURRENT_SOURCE_DIR}/sunshine.ico") - endif() - configure_file(src/platform/windows/windows.rs.in windows.rc @ONLY) - set(PLATFORM_TARGET_FILES - "${CMAKE_CURRENT_BINARY_DIR}/windows.rc" - src/platform/windows/publish.cpp - src/platform/windows/misc.h - src/platform/windows/misc.cpp - src/platform/windows/input.cpp - src/platform/windows/display.h - src/platform/windows/display_base.cpp - src/platform/windows/display_vram.cpp - src/platform/windows/display_ram.cpp - src/platform/windows/audio.cpp - third-party/tray/tray_windows.c - third-party/ViGEmClient/src/ViGEmClient.cpp - third-party/ViGEmClient/include/ViGEm/Client.h - third-party/ViGEmClient/include/ViGEm/Common.h - third-party/ViGEmClient/include/ViGEm/Util.h - third-party/ViGEmClient/include/ViGEm/km/BusShared.h - ${NVPREFS_FILES}) - - set(OPENSSL_LIBRARIES - libssl.a - libcrypto.a) - - list(PREPEND PLATFORM_LIBRARIES - libstdc++.a - libwinpthread.a - libssp.a - ksuser - wsock32 - ws2_32 - d3d11 dxgi D3DCompiler - setupapi - dwmapi - userenv - synchronization.lib - avrt - ${CURL_STATIC_LIBRARIES}) - - set_source_files_properties(third-party/ViGEmClient/src/ViGEmClient.cpp - PROPERTIES COMPILE_DEFINITIONS "UNICODE=1;ERROR_INVALID_DEVICE_OBJECT_PARAMETER=650") - set_source_files_properties(third-party/ViGEmClient/src/ViGEmClient.cpp - PROPERTIES COMPILE_FLAGS "-Wno-unknown-pragmas -Wno-misleading-indentation -Wno-class-memaccess") -elseif(APPLE) - add_compile_definitions(SUNSHINE_PLATFORM="macos") - - option(SUNSHINE_MACOS_PACKAGE "Should only be used when creating a MACOS package/dmg." OFF) - - link_directories(/opt/local/lib) - link_directories(/usr/local/lib) - ADD_DEFINITIONS(-DBOOST_LOG_DYN_LINK) - FIND_LIBRARY(APP_SERVICES_LIBRARY ApplicationServices ) - FIND_LIBRARY(AV_FOUNDATION_LIBRARY AVFoundation ) - FIND_LIBRARY(COCOA Cocoa REQUIRED ) # tray icon - FIND_LIBRARY(CORE_MEDIA_LIBRARY CoreMedia ) - FIND_LIBRARY(CORE_VIDEO_LIBRARY CoreVideo ) - FIND_LIBRARY(VIDEO_TOOLBOX_LIBRARY VideoToolbox ) - FIND_LIBRARY(FOUNDATION_LIBRARY Foundation ) - list(APPEND SUNSHINE_EXTERNAL_LIBRARIES - ${APP_SERVICES_LIBRARY} - ${AV_FOUNDATION_LIBRARY} - ${COCOA} - ${CORE_MEDIA_LIBRARY} - ${CORE_VIDEO_LIBRARY} - ${VIDEO_TOOLBOX_LIBRARY} - ${FOUNDATION_LIBRARY}) +# basic project configuration +include(${CMAKE_MODULE_PATH}/prep/base.cmake) - set(PLATFORM_INCLUDE_DIRS - ${Boost_INCLUDE_DIR}) +# set version info for this build +include(${CMAKE_MODULE_PATH}/prep/build_version.cmake) - set(APPLE_PLIST_FILE ${SUNSHINE_SOURCE_ASSETS_DIR}/macos/assets/Info.plist) +# cmake build flags +include(${CMAKE_MODULE_PATH}/prep/options.cmake) - set(PLATFORM_TARGET_FILES - src/platform/macos/av_audio.h - src/platform/macos/av_audio.m - src/platform/macos/av_img_t.h - src/platform/macos/av_video.h - src/platform/macos/av_video.m - src/platform/macos/display.mm - src/platform/macos/input.cpp - src/platform/macos/microphone.mm - src/platform/macos/misc.mm - src/platform/macos/misc.h - src/platform/macos/nv12_zero_device.cpp - src/platform/macos/nv12_zero_device.h - src/platform/macos/publish.cpp - third-party/TPCircularBuffer/TPCircularBuffer.c - third-party/TPCircularBuffer/TPCircularBuffer.h - third-party/tray/tray_darwin.m - ${APPLE_PLIST_FILE}) -else() - add_compile_definitions(SUNSHINE_PLATFORM="linux") +# configure special package files, such as sunshine.desktop, Flatpak manifest, Portfile , etc. +include(${CMAKE_MODULE_PATH}/prep/special_package_configuration.cmake) - option(SUNSHINE_ENABLE_DRM "Enable KMS grab if available" ON) - option(SUNSHINE_ENABLE_X11 "Enable X11 grab if available" ON) - option(SUNSHINE_ENABLE_WAYLAND "Enable building wayland specific code" ON) - option(SUNSHINE_ENABLE_CUDA "Enable cuda specific code" ON) - option(SUNSHINE_ENABLE_TRAY "Enable tray icon" ON) - - if(${SUNSHINE_ENABLE_X11}) - find_package(X11) - else() - set(X11_FOUND OFF) - endif() - - set(CUDA_FOUND OFF) - if(${SUNSHINE_ENABLE_CUDA}) - include(CheckLanguage) - check_language(CUDA) - - if(CMAKE_CUDA_COMPILER) - set(CUDA_FOUND ON) - enable_language(CUDA) - - message(STATUS "CUDA Compiler Version: ${CMAKE_CUDA_COMPILER_VERSION}") - set(CMAKE_CUDA_ARCHITECTURES "") - - # https://tech.amikelive.com/node-930/cuda-compatibility-of-nvidia-display-gpu-drivers/ - if(CMAKE_CUDA_COMPILER_VERSION VERSION_LESS 6.5) - list(APPEND CMAKE_CUDA_ARCHITECTURES 10) - # set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} -gencode arch=compute_10,code=sm_10") - elseif(CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL 6.5) - list(APPEND CMAKE_CUDA_ARCHITECTURES 50 52) - # set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} -gencode arch=compute_50,code=sm_50") - # set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} -gencode arch=compute_52,code=sm_52") - endif() - - if(CMAKE_CUDA_COMPILER_VERSION VERSION_LESS 7.0) - list(APPEND CMAKE_CUDA_ARCHITECTURES 11) - # set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} -gencode arch=compute_11,code=sm_11") - elseif(CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER 7.6) - list(APPEND CMAKE_CUDA_ARCHITECTURES 60 61 62) - # set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} -gencode arch=compute_60,code=sm_60") - # set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} -gencode arch=compute_61,code=sm_61") - # set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} -gencode arch=compute_62,code=sm_62") - endif() - - if(CMAKE_CUDA_COMPILER_VERSION VERSION_LESS 9.0) - list(APPEND CMAKE_CUDA_ARCHITECTURES 20) - # set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} -gencode arch=compute_20,code=sm_20") - elseif(CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL 9.0) - list(APPEND CMAKE_CUDA_ARCHITECTURES 70) - # set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} -gencode arch=compute_70,code=sm_70") - endif() - - if(CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL 10.0) - list(APPEND CMAKE_CUDA_ARCHITECTURES 75) - # set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} -gencode arch=compute_75,code=sm_75") - endif() - - if(CMAKE_CUDA_COMPILER_VERSION VERSION_LESS 11.0) - list(APPEND CMAKE_CUDA_ARCHITECTURES 30) - # set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} -gencode arch=compute_30,code=sm_30") - elseif(CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL 11.0) - list(APPEND CMAKE_CUDA_ARCHITECTURES 80) - # set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} -gencode arch=compute_80,code=sm_80") - endif() - - if(CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL 11.1) - list(APPEND CMAKE_CUDA_ARCHITECTURES 86) - # set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} -gencode arch=compute_86,code=sm_86") - endif() - - if(CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL 11.8) - list(APPEND CMAKE_CUDA_ARCHITECTURES 90) - # set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} -gencode arch=compute_90,code=sm_90") - endif() - - if(CMAKE_CUDA_COMPILER_VERSION VERSION_LESS 12.0) - list(APPEND CMAKE_CUDA_ARCHITECTURES 35) - # set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} -gencode arch=compute_35,code=sm_35") - endif() - - # message(STATUS "CUDA NVCC Flags: ${CUDA_NVCC_FLAGS}") - message(STATUS "CUDA Architectures: ${CMAKE_CUDA_ARCHITECTURES}") - endif() - endif() - if(${SUNSHINE_ENABLE_DRM}) - find_package(LIBDRM) - find_package(LIBCAP) - else() - set(LIBDRM_FOUND OFF) - set(LIBCAP_FOUND OFF) - endif() - if(${SUNSHINE_ENABLE_WAYLAND}) - find_package(Wayland) - else() - set(WAYLAND_FOUND OFF) - endif() - - if(X11_FOUND) - add_compile_definitions(SUNSHINE_BUILD_X11) - include_directories(SYSTEM ${X11_INCLUDE_DIR}) - list(APPEND PLATFORM_LIBRARIES ${X11_LIBRARIES}) - list(APPEND PLATFORM_TARGET_FILES src/platform/linux/x11grab.cpp) - endif() - - if(CUDA_FOUND) - include_directories(SYSTEM third-party/nvfbc) - list(APPEND PLATFORM_TARGET_FILES - src/platform/linux/cuda.cu - src/platform/linux/cuda.cpp - third-party/nvfbc/NvFBC.h) - - add_compile_definitions(SUNSHINE_BUILD_CUDA) - endif() - - if(LIBDRM_FOUND AND LIBCAP_FOUND) - add_compile_definitions(SUNSHINE_BUILD_DRM) - include_directories(SYSTEM ${LIBDRM_INCLUDE_DIRS} ${LIBCAP_INCLUDE_DIRS}) - list(APPEND PLATFORM_LIBRARIES ${LIBDRM_LIBRARIES} ${LIBCAP_LIBRARIES}) - list(APPEND PLATFORM_TARGET_FILES src/platform/linux/kmsgrab.cpp) - list(APPEND SUNSHINE_DEFINITIONS EGL_NO_X11=1) - elseif(LIBDRM_FOUND) - message(WARNING "Found libdrm, yet there is no libcap") - elseif(LIBDRM_FOUND) - message(WARNING "Found libcap, yet there is no libdrm") - endif() - - if(WAYLAND_FOUND) - add_compile_definitions(SUNSHINE_BUILD_WAYLAND) - # GEN_WAYLAND: args = `filename` - macro(GEN_WAYLAND filename) - file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/generated-src) - - message("wayland-scanner private-code \ -${CMAKE_SOURCE_DIR}/third-party/wayland-protocols/${filename}.xml \ -${CMAKE_BINARY_DIR}/generated-src/${filename}.c") - message("wayland-scanner client-header \ -${CMAKE_SOURCE_DIR}/third-party/wayland-protocols/${filename}.xml \ -${CMAKE_BINARY_DIR}/generated-src/${filename}.h") - execute_process( - COMMAND wayland-scanner private-code - ${CMAKE_SOURCE_DIR}/third-party/wayland-protocols/${filename}.xml - ${CMAKE_BINARY_DIR}/generated-src/${filename}.c - COMMAND wayland-scanner client-header - ${CMAKE_SOURCE_DIR}/third-party/wayland-protocols/${filename}.xml - ${CMAKE_BINARY_DIR}/generated-src/${filename}.h - - RESULT_VARIABLE EXIT_INT - ) - - if(NOT ${EXIT_INT} EQUAL 0) - message(FATAL_ERROR "wayland-scanner failed") - endif() - - list(APPEND PLATFORM_TARGET_FILES - ${CMAKE_BINARY_DIR}/generated-src/${filename}.c - ${CMAKE_BINARY_DIR}/generated-src/${filename}.h) - endmacro() - - GEN_WAYLAND(xdg-output-unstable-v1) - GEN_WAYLAND(wlr-export-dmabuf-unstable-v1) - - include_directories( - SYSTEM - ${WAYLAND_INCLUDE_DIRS} - ${CMAKE_BINARY_DIR}/generated-src - ) - - list(APPEND PLATFORM_LIBRARIES ${WAYLAND_LIBRARIES}) - list(APPEND PLATFORM_TARGET_FILES - src/platform/linux/wlgrab.cpp - src/platform/linux/wayland.cpp) - endif() - if(NOT ${X11_FOUND} AND NOT (${LIBDRM_FOUND} AND ${LIBCAP_FOUND}) AND NOT ${WAYLAND_FOUND}) - message(FATAL_ERROR "Couldn't find either x11, wayland, cuda or (libdrm and libcap)") - endif() - - # tray icon - if(${SUNSHINE_ENABLE_TRAY}) - pkg_check_modules(APPINDICATOR appindicator3-0.1) - if(NOT APPINDICATOR_FOUND) - message(WARNING "Couldn't find appindicator, disabling tray icon") - set(SUNSHINE_TRAY 0) - else() - include_directories(SYSTEM ${APPINDICATOR_INCLUDE_DIRS}) - link_directories(${APPINDICATOR_LIBRARY_DIRS}) - - list(APPEND PLATFORM_TARGET_FILES third-party/tray/tray_linux.c) - list(APPEND SUNSHINE_EXTERNAL_LIBRARIES ${APPINDICATOR_LIBRARIES}) - endif() - else() - set(SUNSHINE_TRAY 0) - endif() - - list(APPEND PLATFORM_TARGET_FILES - src/platform/linux/publish.cpp - src/platform/linux/vaapi.h - src/platform/linux/vaapi.cpp - src/platform/linux/cuda.h - src/platform/linux/graphics.h - src/platform/linux/graphics.cpp - src/platform/linux/misc.h - src/platform/linux/misc.cpp - src/platform/linux/audio.cpp - src/platform/linux/input.cpp - src/platform/linux/x11grab.h - src/platform/linux/wayland.h - third-party/glad/src/egl.c - third-party/glad/src/gl.c - third-party/glad/include/EGL/eglplatform.h - third-party/glad/include/KHR/khrplatform.h - third-party/glad/include/glad/gl.h - third-party/glad/include/glad/egl.h) - - list(APPEND PLATFORM_LIBRARIES - Boost::dynamic_linking - dl - evdev - numa - pulse - pulse-simple) - - include_directories( - SYSTEM - /usr/include/libevdev-1.0 - third-party/nv-codec-headers/include - third-party/glad/include) - - if(NOT DEFINED SUNSHINE_EXECUTABLE_PATH) - set(SUNSHINE_EXECUTABLE_PATH "sunshine") - endif() - configure_file(sunshine.service.in sunshine.service @ONLY) -endif() - -include_directories(SYSTEM third-party/nv-codec-headers/include) -file(GLOB NVENC_SOURCES CONFIGURE_DEPENDS "src/nvenc/*.cpp" "src/nvenc/*.h") -list(APPEND PLATFORM_TARGET_FILES ${NVENC_SOURCES}) - -configure_file(src/version.h.in version.h @ONLY) -include_directories(${CMAKE_CURRENT_BINARY_DIR}) - -set(SUNSHINE_TARGET_FILES - third-party/nanors/rs.c - third-party/nanors/rs.h - third-party/moonlight-common-c/src/Input.h - third-party/moonlight-common-c/src/Rtsp.h - third-party/moonlight-common-c/src/RtspParser.c - third-party/moonlight-common-c/src/Video.h - third-party/tray/tray.h - src/upnp.cpp - src/upnp.h - src/cbs.cpp - src/utility.h - src/uuid.h - src/config.h - src/config.cpp - src/main.cpp - src/main.h - src/crypto.cpp - src/crypto.h - src/nvhttp.cpp - src/nvhttp.h - src/httpcommon.cpp - src/httpcommon.h - src/confighttp.cpp - src/confighttp.h - src/rtsp.cpp - src/rtsp.h - src/stream.cpp - src/stream.h - src/video.cpp - src/video.h - src/video_colorspace.cpp - src/video_colorspace.h - src/input.cpp - src/input.h - src/audio.cpp - src/audio.h - src/platform/common.h - src/process.cpp - src/process.h - src/network.cpp - src/network.h - src/move_by_copy.h - src/system_tray.cpp - src/system_tray.h - src/task_pool.h - src/thread_pool.h - src/thread_safe.h - src/sync.h - src/round_robin.h - src/stat_trackers.h - src/stat_trackers.cpp - ${PLATFORM_TARGET_FILES}) - -set_source_files_properties(src/upnp.cpp PROPERTIES COMPILE_FLAGS -Wno-pedantic) - -set_source_files_properties(third-party/nanors/rs.c - PROPERTIES COMPILE_FLAGS "-include deps/obl/autoshim.h -ftree-vectorize") - -list(APPEND SUNSHINE_DEFINITIONS SUNSHINE_TRAY=${SUNSHINE_TRAY}) - -# Pre-compiled binaries -if(WIN32) - set(FFMPEG_PREPARED_BINARIES "${CMAKE_CURRENT_SOURCE_DIR}/third-party/ffmpeg-windows-x86_64") - set(FFMPEG_PLATFORM_LIBRARIES mfplat ole32 strmiids mfuuid mfx) -elseif(APPLE) - if (CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64") - set(FFMPEG_PREPARED_BINARIES "${CMAKE_CURRENT_SOURCE_DIR}/third-party/ffmpeg-macos-aarch64") - else() - set(FFMPEG_PREPARED_BINARIES "${CMAKE_CURRENT_SOURCE_DIR}/third-party/ffmpeg-macos-x86_64") - endif() -else() - set(FFMPEG_PLATFORM_LIBRARIES va va-drm va-x11 vdpau X11) - if (CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64") - set(FFMPEG_PREPARED_BINARIES "${CMAKE_CURRENT_SOURCE_DIR}/third-party/ffmpeg-linux-aarch64") - else() - set(FFMPEG_PREPARED_BINARIES "${CMAKE_CURRENT_SOURCE_DIR}/third-party/ffmpeg-linux-x86_64") - list(APPEND FFMPEG_PLATFORM_LIBRARIES mfx) - set(CPACK_DEB_PLATFORM_PACKAGE_DEPENDS "libmfx1,") - set(CPACK_RPM_PLATFORM_PACKAGE_REQUIRES "intel-mediasdk >= 22.3.0,") - endif() -endif() -set(FFMPEG_INCLUDE_DIRS - ${FFMPEG_PREPARED_BINARIES}/include) -if(EXISTS ${FFMPEG_PREPARED_BINARIES}/lib/libhdr10plus.a) - set(HDR10_PLUS_LIBRARY - ${FFMPEG_PREPARED_BINARIES}/lib/libhdr10plus.a) -endif() -set(FFMPEG_LIBRARIES - ${FFMPEG_PREPARED_BINARIES}/lib/libavcodec.a - ${FFMPEG_PREPARED_BINARIES}/lib/libavutil.a - ${FFMPEG_PREPARED_BINARIES}/lib/libcbs.a - ${FFMPEG_PREPARED_BINARIES}/lib/libSvtAv1Enc.a - ${FFMPEG_PREPARED_BINARIES}/lib/libswscale.a - ${FFMPEG_PREPARED_BINARIES}/lib/libx264.a - ${FFMPEG_PREPARED_BINARIES}/lib/libx265.a - ${HDR10_PLUS_LIBRARY} - ${FFMPEG_PLATFORM_LIBRARIES}) - -include_directories(${CMAKE_CURRENT_SOURCE_DIR}) - -include_directories( - SYSTEM - ${CMAKE_CURRENT_SOURCE_DIR}/third-party - ${CMAKE_CURRENT_SOURCE_DIR}/third-party/moonlight-common-c/enet/include - ${CMAKE_CURRENT_SOURCE_DIR}/third-party/nanors - ${CMAKE_CURRENT_SOURCE_DIR}/third-party/nanors/deps/obl - ${FFMPEG_INCLUDE_DIRS} - ${PLATFORM_INCLUDE_DIRS} -) - -string(TOUPPER "x${CMAKE_BUILD_TYPE}" BUILD_TYPE) -if("${BUILD_TYPE}" STREQUAL "XDEBUG") - if(WIN32) - set_source_files_properties(src/nvhttp.cpp PROPERTIES COMPILE_FLAGS -O2) - endif() -else() - add_definitions(-DNDEBUG) -endif() - -# setup assets directory -if(NOT SUNSHINE_ASSETS_DIR) - set(SUNSHINE_ASSETS_DIR "assets") -endif() -if(UNIX) - set(SUNSHINE_ASSETS_DIR "${CMAKE_INSTALL_PREFIX}/${SUNSHINE_ASSETS_DIR}") -endif() - -# use relative assets path for AppImage... maybe for all unix -if(${SUNSHINE_CONFIGURE_APPIMAGE}) - string(REPLACE "${CMAKE_INSTALL_PREFIX}" ".${CMAKE_INSTALL_PREFIX}" SUNSHINE_ASSETS_DIR_DEF ${SUNSHINE_ASSETS_DIR}) -else() - set(SUNSHINE_ASSETS_DIR_DEF "${SUNSHINE_ASSETS_DIR}") -endif() -list(APPEND SUNSHINE_DEFINITIONS SUNSHINE_ASSETS_DIR="${SUNSHINE_ASSETS_DIR_DEF}") - -list(APPEND SUNSHINE_EXTERNAL_LIBRARIES - libminiupnpc-static - ${CMAKE_THREAD_LIBS_INIT} - enet - opus - ${FFMPEG_LIBRARIES} - ${Boost_LIBRARIES} - ${OPENSSL_LIBRARIES} - ${CURL_LIBRARIES} - ${PLATFORM_LIBRARIES}) - -if(NOT WIN32) - list(APPEND SUNSHINE_EXTERNAL_LIBRARIES Boost::log) -endif() - -add_executable(sunshine ${SUNSHINE_TARGET_FILES}) - -if(WIN32) - set_target_properties(sunshine PROPERTIES LINK_SEARCH_START_STATIC 1) - set(CMAKE_FIND_LIBRARY_SUFFIXES ".dll") - find_library(ZLIB ZLIB1) - list(APPEND SUNSHINE_EXTERNAL_LIBRARIES - Wtsapi32.lib) -endif() - -target_link_libraries(sunshine ${SUNSHINE_EXTERNAL_LIBRARIES} ${EXTRA_LIBS}) -target_compile_definitions(sunshine PUBLIC ${SUNSHINE_DEFINITIONS}) -set_target_properties(sunshine PROPERTIES CXX_STANDARD 17 - VERSION ${PROJECT_VERSION} - SOVERSION ${PROJECT_VERSION_MAJOR}) - -if(NOT DEFINED CMAKE_CUDA_STANDARD) - set(CMAKE_CUDA_STANDARD 17) - set(CMAKE_CUDA_STANDARD_REQUIRED ON) -endif() - -if(APPLE) - target_link_options(sunshine PRIVATE LINKER:-sectcreate,__TEXT,__info_plist,${APPLE_PLIST_FILE}) - # Tell linker to dynamically load these symbols at runtime, in case they're unavailable: - target_link_options(sunshine PRIVATE -Wl,-U,_CGPreflightScreenCaptureAccess -Wl,-U,_CGRequestScreenCaptureAccess) -endif() - -foreach(flag IN LISTS SUNSHINE_COMPILE_OPTIONS) - list(APPEND SUNSHINE_COMPILE_OPTIONS_CUDA "$<$:--compiler-options=${flag}>") -endforeach() - -target_compile_options(sunshine PRIVATE $<$:${SUNSHINE_COMPILE_OPTIONS}>;$<$:${SUNSHINE_COMPILE_OPTIONS_CUDA};-std=c++17>) # cmake-lint: disable=C0301 - -# CPACK / Packaging - -# Common options -set(CPACK_PACKAGE_NAME "Sunshine") -set(CPACK_PACKAGE_VENDOR "LizardByte") -set(CPACK_PACKAGE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/cpack_artifacts) -set(CPACK_PACKAGE_CONTACT "https://app.lizardbyte.dev") -set(CPACK_DEBIAN_PACKAGE_MAINTAINER "https://github.com/LizardByte") -set(CPACK_PACKAGE_DESCRIPTION ${CMAKE_PROJECT_DESCRIPTION}) -set(CPACK_PACKAGE_HOMEPAGE_URL ${CMAKE_PROJECT_HOMEPAGE_URL}) -set(CPACK_RESOURCE_FILE_LICENSE ${PROJECT_SOURCE_DIR}/LICENSE) -set(CPACK_PACKAGE_ICON ${PROJECT_SOURCE_DIR}/sunshine.png) -set(CPACK_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME}") -set(CPACK_STRIP_FILES YES) - -# install npm modules -install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/node_modules" - DESTINATION "${SUNSHINE_ASSETS_DIR}/web") - -# Platform specific options -if(WIN32) # see options at: https://cmake.org/cmake/help/latest/cpack_gen/nsis.html - install(TARGETS sunshine RUNTIME DESTINATION "." COMPONENT application) - - # Hardening: include zlib1.dll (loaded via LoadLibrary() in openssl's libcrypto.a) - install(FILES "${ZLIB}" DESTINATION "." COMPONENT application) - - # Adding tools - install(TARGETS dxgi-info RUNTIME DESTINATION "tools" COMPONENT dxgi) - install(TARGETS audio-info RUNTIME DESTINATION "tools" COMPONENT audio) - - # Mandatory tools - install(TARGETS ddprobe RUNTIME DESTINATION "tools" COMPONENT application) - install(TARGETS sunshinesvc RUNTIME DESTINATION "tools" COMPONENT application) - - # Mandatory scripts - install(DIRECTORY "${SUNSHINE_SOURCE_ASSETS_DIR}/windows/misc/service/" - DESTINATION "scripts" - COMPONENT assets) - install(DIRECTORY "${SUNSHINE_SOURCE_ASSETS_DIR}/windows/misc/migration/" - DESTINATION "scripts" - COMPONENT assets) - - # Configurable options for the service - install(DIRECTORY "${SUNSHINE_SOURCE_ASSETS_DIR}/windows/misc/autostart/" - DESTINATION "scripts" - COMPONENT autostart) - - # scripts - install(DIRECTORY "${SUNSHINE_SOURCE_ASSETS_DIR}/windows/misc/firewall/" - DESTINATION "scripts" - COMPONENT firewall) - install(DIRECTORY "${SUNSHINE_SOURCE_ASSETS_DIR}/windows/misc/vigembus/" - DESTINATION "scripts" - COMPONENT vigembus) - - # Sunshine assets - install(DIRECTORY "${SUNSHINE_SOURCE_ASSETS_DIR}/common/assets/" - DESTINATION "${SUNSHINE_ASSETS_DIR}" - COMPONENT assets) - install(DIRECTORY "${SUNSHINE_SOURCE_ASSETS_DIR}/windows/assets/" - DESTINATION "${SUNSHINE_ASSETS_DIR}" - COMPONENT assets) - - # set(CPACK_NSIS_MUI_HEADERIMAGE "") # TODO: image should be 150x57 bmp - set(CPACK_PACKAGE_ICON "${CMAKE_CURRENT_SOURCE_DIR}\\\\sunshine.ico") - set(CPACK_NSIS_INSTALLED_ICON_NAME "${PROJECT__DIR}\\\\${PROJECT_EXE}") - # The name of the directory that will be created in C:/Program files/ - set(CPACK_PACKAGE_INSTALL_DIRECTORY "${CPACK_PACKAGE_NAME}") - - # Extra install commands - # Restores permissions on the install directory - # Migrates config files from the root into the new config folder - # Install service - SET(CPACK_NSIS_EXTRA_INSTALL_COMMANDS - "${CPACK_NSIS_EXTRA_INSTALL_COMMANDS} - IfSilent +2 0 - ExecShell 'open' 'https://sunshinestream.readthedocs.io/' - nsExec::ExecToLog 'icacls \\\"$INSTDIR\\\" /reset' - nsExec::ExecToLog '\\\"$INSTDIR\\\\scripts\\\\migrate-config.bat\\\"' - nsExec::ExecToLog '\\\"$INSTDIR\\\\scripts\\\\add-firewall-rule.bat\\\"' - nsExec::ExecToLog '\\\"$INSTDIR\\\\scripts\\\\install-service.bat\\\"' - nsExec::ExecToLog '\\\"$INSTDIR\\\\scripts\\\\install-vigembus.bat\\\"' - nsExec::ExecToLog '\\\"$INSTDIR\\\\scripts\\\\autostart-service.bat\\\"' - NoController: - ") - - # Extra uninstall commands - # Uninstall service - set(CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS - "${CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS} - nsExec::ExecToLog '\\\"$INSTDIR\\\\scripts\\\\delete-firewall-rule.bat\\\"' - nsExec::ExecToLog '\\\"$INSTDIR\\\\scripts\\\\uninstall-service.bat\\\"' - nsExec::ExecToLog '\\\"$INSTDIR\\\\sunshine.exe\\\" --restore-nvprefs-undo' - MessageBox MB_YESNO|MB_ICONQUESTION \ - 'Do you want to remove ViGEmBus)?' \ - /SD IDNO IDNO NoVigem - nsExec::ExecToLog '\\\"$INSTDIR\\\\scripts\\\\uninstall-vigembus.bat\\\"'; skipped if no - NoVigem: - MessageBox MB_YESNO|MB_ICONQUESTION \ - 'Do you want to remove $INSTDIR (this includes the configuration, cover images, and settings)?' \ - /SD IDNO IDNO NoDelete - RMDir /r \\\"$INSTDIR\\\"; skipped if no - NoDelete: - ") - - # Adding an option for the start menu - set(CPACK_NSIS_MODIFY_PATH "OFF") - set(CPACK_NSIS_EXECUTABLES_DIRECTORY ".") - # This will be shown on the installed apps Windows settings - set(CPACK_NSIS_INSTALLED_ICON_NAME "${CMAKE_PROJECT_NAME}.exe") - set(CPACK_NSIS_CREATE_ICONS_EXTRA - "${CPACK_NSIS_CREATE_ICONS_EXTRA} - CreateShortCut '\$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\${CMAKE_PROJECT_NAME}.lnk' \ - '\$INSTDIR\\\\${CMAKE_PROJECT_NAME}.exe' '--shortcut' - ") - set(CPACK_NSIS_DELETE_ICONS_EXTRA - "${CPACK_NSIS_DELETE_ICONS_EXTRA} - Delete '\$SMPROGRAMS\\\\$MUI_TEMP\\\\${CMAKE_PROJECT_NAME}.lnk' - ") - - # Checking for previous installed versions - set(CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL "ON") - - set(CPACK_NSIS_HELP_LINK "https://sunshinestream.readthedocs.io/about/installation.html") - set(CPACK_NSIS_URL_INFO_ABOUT "${CMAKE_PROJECT_HOMEPAGE_URL}") - set(CPACK_NSIS_CONTACT "${CMAKE_PROJECT_HOMEPAGE_URL}/support") - - set(CPACK_NSIS_MENU_LINKS - "https://sunshinestream.readthedocs.io" "Sunshine documentation" - "https://app.lizardbyte.dev" "LizardByte Web Site" - "https://app.lizardbyte.dev/support" "LizardByte Support") - set(CPACK_NSIS_MANIFEST_DPI_AWARE true) - - # Setting components groups and dependencies - set(CPACK_COMPONENT_GROUP_CORE_EXPANDED true) - - # sunshine binary - set(CPACK_COMPONENT_APPLICATION_DISPLAY_NAME "${CMAKE_PROJECT_NAME}") - set(CPACK_COMPONENT_APPLICATION_DESCRIPTION "${CMAKE_PROJECT_NAME} main application and required components.") - set(CPACK_COMPONENT_APPLICATION_GROUP "Core") - set(CPACK_COMPONENT_APPLICATION_REQUIRED true) - set(CPACK_COMPONENT_APPLICATION_DEPENDS assets) - - # service auto-start script - set(CPACK_COMPONENT_AUTOSTART_DISPLAY_NAME "Launch on Startup") - set(CPACK_COMPONENT_AUTOSTART_DESCRIPTION "If enabled, launches Sunshine automatically on system startup.") - set(CPACK_COMPONENT_AUTOSTART_GROUP "Core") - - # assets - set(CPACK_COMPONENT_ASSETS_DISPLAY_NAME "Required Assets") - set(CPACK_COMPONENT_ASSETS_DESCRIPTION "Shaders, default box art, and web UI.") - set(CPACK_COMPONENT_ASSETS_GROUP "Core") - set(CPACK_COMPONENT_ASSETS_REQUIRED true) - - # audio tool - set(CPACK_COMPONENT_AUDIO_DISPLAY_NAME "audio-info") - set(CPACK_COMPONENT_AUDIO_DESCRIPTION "CLI tool providing information about sound devices.") - set(CPACK_COMPONENT_AUDIO_GROUP "Tools") - - # display tool - set(CPACK_COMPONENT_DXGI_DISPLAY_NAME "dxgi-info") - set(CPACK_COMPONENT_DXGI_DESCRIPTION "CLI tool providing information about graphics cards and displays.") - set(CPACK_COMPONENT_DXGI_GROUP "Tools") - - # firewall scripts - set(CPACK_COMPONENT_FIREWALL_DISPLAY_NAME "Add Firewall Exclusions") - set(CPACK_COMPONENT_FIREWALL_DESCRIPTION "Scripts to enable or disable firewall rules.") - set(CPACK_COMPONENT_FIREWALL_GROUP "Scripts") - - # vigembus scripts - set(CPACK_COMPONENT_VIGEMBUS_DISPLAY_NAME "Virtual Gamepad Support") - set(CPACK_COMPONENT_VIGEMBUS_DESCRIPTION "Scripts to install and uninstall ViGEmBus for virtual gamepad support.") - set(CPACK_COMPONENT_VIGEMBUS_GROUP "Scripts") -endif() -if(APPLE) - # TODO: bundle doesn't produce a valid .app use cpack -G DragNDrop - set(CPACK_BUNDLE_NAME "${CMAKE_PROJECT_NAME}") - set(CPACK_BUNDLE_PLIST "${APPLE_PLIST_FILE}") - set(CPACK_BUNDLE_ICON "${PROJECT_SOURCE_DIR}/sunshine.icns") - # set(CPACK_BUNDLE_STARTUP_COMMAND "${INSTALL_RUNTIME_DIR}/sunshine") +# Exit if END_BUILD is ON +if(${END_BUILD}) + return() endif() -if(APPLE AND SUNSHINE_MACOS_PACKAGE) # TODO - set(MAC_PREFIX "${CMAKE_PROJECT_NAME}.app/Contents") - set(INSTALL_RUNTIME_DIR "${MAC_PREFIX}/MacOS") - - install(DIRECTORY "${SUNSHINE_SOURCE_ASSETS_DIR}/common/assets/" - DESTINATION "${SUNSHINE_ASSETS_DIR}") - install(DIRECTORY "${SUNSHINE_SOURCE_ASSETS_DIR}/macos/assets/" - DESTINATION "${SUNSHINE_ASSETS_DIR}") - install(TARGETS sunshine - BUNDLE DESTINATION . COMPONENT Runtime - RUNTIME DESTINATION ${INSTALL_RUNTIME_DIR} COMPONENT Runtime) -elseif(UNIX) - # Installation destination dir - set(CPACK_SET_DESTDIR true) - if(NOT CMAKE_INSTALL_PREFIX) - set(CMAKE_INSTALL_PREFIX "/usr/share/sunshine") - endif() +# project constants +include(${CMAKE_MODULE_PATH}/prep/constants.cmake) - install(TARGETS sunshine RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}") +# load macros +include(${CMAKE_MODULE_PATH}/macros/common.cmake) - install(DIRECTORY "${SUNSHINE_SOURCE_ASSETS_DIR}/common/assets/" - DESTINATION "${SUNSHINE_ASSETS_DIR}") +# load submodules +include(${CMAKE_MODULE_PATH}/submodules/include_submodules.cmake) - if(APPLE) - install(DIRECTORY "${SUNSHINE_SOURCE_ASSETS_DIR}/macos/assets/" - DESTINATION "${SUNSHINE_ASSETS_DIR}") - install(FILES "${SUNSHINE_SOURCE_ASSETS_DIR}/macos/misc/uninstall_pkg.sh" - DESTINATION "${SUNSHINE_ASSETS_DIR}") - else() - install(DIRECTORY "${SUNSHINE_SOURCE_ASSETS_DIR}/linux/assets/" - DESTINATION "${SUNSHINE_ASSETS_DIR}") - if(${SUNSHINE_CONFIGURE_APPIMAGE} OR ${SUNSHINE_CONFIGURE_FLATPAK}) - install(FILES "${SUNSHINE_SOURCE_ASSETS_DIR}/linux/misc/85-sunshine.rules" - DESTINATION "${SUNSHINE_ASSETS_DIR}/udev/rules.d") - install(FILES "${CMAKE_CURRENT_BINARY_DIR}/sunshine.service" - DESTINATION "${SUNSHINE_ASSETS_DIR}/systemd/user") - else() - install(FILES "${SUNSHINE_SOURCE_ASSETS_DIR}/linux/misc/85-sunshine.rules" - DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/udev/rules.d") - install(FILES "${CMAKE_CURRENT_BINARY_DIR}/sunshine.service" - DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/systemd/user") - endif() +# load dependencies +include(${CMAKE_MODULE_PATH}/dependencies/common.cmake) - # 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") +# setup compile definitions +include(${CMAKE_MODULE_PATH}/compile_definitions/common.cmake) - # Dependencies - set(CPACK_DEB_COMPONENT_INSTALL ON) - set(CPACK_DEBIAN_PACKAGE_DEPENDS "\ - ${CPACK_DEB_PLATFORM_PACKAGE_DEPENDS} \ - libboost-filesystem${Boost_VERSION}, \ - libboost-locale${Boost_VERSION}, \ - libboost-log${Boost_VERSION}, \ - libboost-program-options${Boost_VERSION}, \ - libcap2, \ - libcurl4, \ - libdrm2, \ - libevdev2, \ - libnuma1, \ - libopus0, \ - libpulse0, \ - libva2, \ - libva-drm2, \ - libvdpau1, \ - libwayland-client0, \ - libx11-6, \ - openssl | libssl3") - set(CPACK_RPM_PACKAGE_REQUIRES "\ - ${CPACK_RPM_PLATFORM_PACKAGE_REQUIRES} \ - boost-filesystem >= ${Boost_VERSION}, \ - boost-locale >= ${Boost_VERSION}, \ - boost-log >= ${Boost_VERSION}, \ - boost-program-options >= ${Boost_VERSION}, \ - libcap >= 2.22, \ - libcurl >= 7.0, \ - libdrm >= 2.4.97, \ - libevdev >= 1.5.6, \ - libopusenc >= 0.2.1, \ - libva >= 2.14.0, \ - libvdpau >= 1.5, \ - libwayland-client >= 1.20.0, \ - libX11 >= 1.7.3.1, \ - numactl-libs >= 2.0.14, \ - openssl >= 3.0.2, \ - pulseaudio-libs >= 10.0") - # This should automatically figure out dependencies, doesn't work with the current config - set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS OFF) - - if(${SUNSHINE_TRAY} STREQUAL 1) - install(FILES "${CMAKE_SOURCE_DIR}/sunshine.svg" - DESTINATION "${CMAKE_INSTALL_PREFIX}/share/icons") - - set(CPACK_DEBIAN_PACKAGE_DEPENDS "\ - ${CPACK_DEBIAN_PACKAGE_DEPENDS}, \ - libappindicator3-1") - set(CPACK_RPM_PACKAGE_REQUIRES "\ - ${CPACK_RPM_PACKAGE_REQUIRES}, \ - libappindicator-gtk3 >= 12.10.0") - endif() - endif() -endif() +# target definitions +include(${CMAKE_MODULE_PATH}/targets/common.cmake) -include(CPack) +# packaging +include(${CMAKE_MODULE_PATH}/packaging/common.cmake) diff --git a/cmake/compile_definitions/common.cmake b/cmake/compile_definitions/common.cmake new file mode 100644 index 00000000000..f1a95fd0e3c --- /dev/null +++ b/cmake/compile_definitions/common.cmake @@ -0,0 +1,119 @@ +# common compile definitions +# this file will also load platform specific definitions + +list(APPEND SUNSHINE_COMPILE_OPTIONS -Wall -Wno-sign-compare) +# Wall - enable all warnings +# Wno-sign-compare - disable warnings for signed/unsigned comparisons + +# platform specific compile definitions +if(WIN32) + include(${CMAKE_MODULE_PATH}/compile_definitions/windows.cmake) +elseif(UNIX) + include(${CMAKE_MODULE_PATH}/compile_definitions/unix.cmake) + + if(APPLE) + include(${CMAKE_MODULE_PATH}/compile_definitions/macos.cmake) + else() + include(${CMAKE_MODULE_PATH}/compile_definitions/linux.cmake) + endif() +endif() + +include_directories(SYSTEM third-party/nv-codec-headers/include) +file(GLOB NVENC_SOURCES CONFIGURE_DEPENDS "src/nvenc/*.cpp" "src/nvenc/*.h") +list(APPEND PLATFORM_TARGET_FILES ${NVENC_SOURCES}) + +configure_file(src/version.h.in version.h @ONLY) +include_directories(${CMAKE_CURRENT_BINARY_DIR}) + +set(SUNSHINE_TARGET_FILES + third-party/nanors/rs.c + third-party/nanors/rs.h + third-party/moonlight-common-c/src/Input.h + third-party/moonlight-common-c/src/Rtsp.h + third-party/moonlight-common-c/src/RtspParser.c + third-party/moonlight-common-c/src/Video.h + third-party/tray/tray.h + src/upnp.cpp + src/upnp.h + src/cbs.cpp + src/utility.h + src/uuid.h + src/config.h + src/config.cpp + src/main.cpp + src/main.h + src/crypto.cpp + src/crypto.h + src/nvhttp.cpp + src/nvhttp.h + src/httpcommon.cpp + src/httpcommon.h + src/confighttp.cpp + src/confighttp.h + src/rtsp.cpp + src/rtsp.h + src/stream.cpp + src/stream.h + src/video.cpp + src/video.h + src/video_colorspace.cpp + src/video_colorspace.h + src/input.cpp + src/input.h + src/audio.cpp + src/audio.h + src/platform/common.h + src/process.cpp + src/process.h + src/network.cpp + src/network.h + src/move_by_copy.h + src/system_tray.cpp + src/system_tray.h + src/task_pool.h + src/thread_pool.h + src/thread_safe.h + src/sync.h + src/round_robin.h + src/stat_trackers.h + src/stat_trackers.cpp + ${PLATFORM_TARGET_FILES}) + +set_source_files_properties(src/upnp.cpp PROPERTIES COMPILE_FLAGS -Wno-pedantic) + +set_source_files_properties(third-party/nanors/rs.c + PROPERTIES COMPILE_FLAGS "-include deps/obl/autoshim.h -ftree-vectorize") + +list(APPEND SUNSHINE_DEFINITIONS SUNSHINE_TRAY=${SUNSHINE_TRAY}) + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +include_directories( + SYSTEM + ${CMAKE_CURRENT_SOURCE_DIR}/third-party + ${CMAKE_CURRENT_SOURCE_DIR}/third-party/moonlight-common-c/enet/include + ${CMAKE_CURRENT_SOURCE_DIR}/third-party/nanors + ${CMAKE_CURRENT_SOURCE_DIR}/third-party/nanors/deps/obl + ${FFMPEG_INCLUDE_DIRS} + ${PLATFORM_INCLUDE_DIRS} +) + +string(TOUPPER "x${CMAKE_BUILD_TYPE}" BUILD_TYPE) +if("${BUILD_TYPE}" STREQUAL "XDEBUG") + if(WIN32) + set_source_files_properties(src/nvhttp.cpp PROPERTIES COMPILE_FLAGS -O2) + endif() +else() + add_definitions(-DNDEBUG) +endif() + +list(APPEND SUNSHINE_EXTERNAL_LIBRARIES + libminiupnpc-static + ${CMAKE_THREAD_LIBS_INIT} + enet + opus + ${FFMPEG_LIBRARIES} + ${Boost_LIBRARIES} + ${OPENSSL_LIBRARIES} + ${CURL_LIBRARIES} + ${PLATFORM_LIBRARIES}) diff --git a/cmake/compile_definitions/linux.cmake b/cmake/compile_definitions/linux.cmake new file mode 100644 index 00000000000..ce19f55d8ba --- /dev/null +++ b/cmake/compile_definitions/linux.cmake @@ -0,0 +1,207 @@ +# linux specific compile definitions + +add_compile_definitions(SUNSHINE_PLATFORM="linux") + +if(NOT DEFINED SUNSHINE_EXECUTABLE_PATH) + set(SUNSHINE_EXECUTABLE_PATH "sunshine") +endif() + +# cuda +set(CUDA_FOUND OFF) +if(${SUNSHINE_ENABLE_CUDA}) + include(CheckLanguage) + check_language(CUDA) + + if(CMAKE_CUDA_COMPILER) + set(CUDA_FOUND ON) + enable_language(CUDA) + + message(STATUS "CUDA Compiler Version: ${CMAKE_CUDA_COMPILER_VERSION}") + set(CMAKE_CUDA_ARCHITECTURES "") + + # https://tech.amikelive.com/node-930/cuda-compatibility-of-nvidia-display-gpu-drivers/ + if(CMAKE_CUDA_COMPILER_VERSION VERSION_LESS 6.5) + list(APPEND CMAKE_CUDA_ARCHITECTURES 10) + # set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} -gencode arch=compute_10,code=sm_10") + elseif(CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL 6.5) + list(APPEND CMAKE_CUDA_ARCHITECTURES 50 52) + # set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} -gencode arch=compute_50,code=sm_50") + # set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} -gencode arch=compute_52,code=sm_52") + endif() + + if(CMAKE_CUDA_COMPILER_VERSION VERSION_LESS 7.0) + list(APPEND CMAKE_CUDA_ARCHITECTURES 11) + # set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} -gencode arch=compute_11,code=sm_11") + elseif(CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER 7.6) + list(APPEND CMAKE_CUDA_ARCHITECTURES 60 61 62) + # set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} -gencode arch=compute_60,code=sm_60") + # set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} -gencode arch=compute_61,code=sm_61") + # set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} -gencode arch=compute_62,code=sm_62") + endif() + + if(CMAKE_CUDA_COMPILER_VERSION VERSION_LESS 9.0) + list(APPEND CMAKE_CUDA_ARCHITECTURES 20) + # set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} -gencode arch=compute_20,code=sm_20") + elseif(CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL 9.0) + list(APPEND CMAKE_CUDA_ARCHITECTURES 70) + # set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} -gencode arch=compute_70,code=sm_70") + endif() + + if(CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL 10.0) + list(APPEND CMAKE_CUDA_ARCHITECTURES 75) + # set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} -gencode arch=compute_75,code=sm_75") + endif() + + if(CMAKE_CUDA_COMPILER_VERSION VERSION_LESS 11.0) + list(APPEND CMAKE_CUDA_ARCHITECTURES 30) + # set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} -gencode arch=compute_30,code=sm_30") + elseif(CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL 11.0) + list(APPEND CMAKE_CUDA_ARCHITECTURES 80) + # set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} -gencode arch=compute_80,code=sm_80") + endif() + + if(CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL 11.1) + list(APPEND CMAKE_CUDA_ARCHITECTURES 86) + # set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} -gencode arch=compute_86,code=sm_86") + endif() + + if(CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL 11.8) + list(APPEND CMAKE_CUDA_ARCHITECTURES 90) + # set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} -gencode arch=compute_90,code=sm_90") + endif() + + if(CMAKE_CUDA_COMPILER_VERSION VERSION_LESS 12.0) + list(APPEND CMAKE_CUDA_ARCHITECTURES 35) + # set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} -gencode arch=compute_35,code=sm_35") + endif() + + # sort the architectures + list(SORT CMAKE_CUDA_ARCHITECTURES COMPARE NATURAL) + + # message(STATUS "CUDA NVCC Flags: ${CUDA_NVCC_FLAGS}") + message(STATUS "CUDA Architectures: ${CMAKE_CUDA_ARCHITECTURES}") + endif() +endif() +if(CUDA_FOUND) + include_directories(SYSTEM third-party/nvfbc) + list(APPEND PLATFORM_TARGET_FILES + src/platform/linux/cuda.cu + src/platform/linux/cuda.cpp + third-party/nvfbc/NvFBC.h) + + add_compile_definitions(SUNSHINE_BUILD_CUDA) +endif() + +# drm +if(${SUNSHINE_ENABLE_DRM}) + find_package(LIBDRM) + find_package(LIBCAP) +else() + set(LIBDRM_FOUND OFF) + set(LIBCAP_FOUND OFF) +endif() +if(LIBDRM_FOUND AND LIBCAP_FOUND) + add_compile_definitions(SUNSHINE_BUILD_DRM) + include_directories(SYSTEM ${LIBDRM_INCLUDE_DIRS} ${LIBCAP_INCLUDE_DIRS}) + list(APPEND PLATFORM_LIBRARIES ${LIBDRM_LIBRARIES} ${LIBCAP_LIBRARIES}) + list(APPEND PLATFORM_TARGET_FILES src/platform/linux/kmsgrab.cpp) + list(APPEND SUNSHINE_DEFINITIONS EGL_NO_X11=1) +elseif(LIBDRM_FOUND) + message(WARNING "Found libdrm, yet there is no libcap") +elseif(LIBDRM_FOUND) + message(WARNING "Found libcap, yet there is no libdrm") +endif() + +# wayland +if(${SUNSHINE_ENABLE_WAYLAND}) + find_package(Wayland) +else() + set(WAYLAND_FOUND OFF) +endif() +if(WAYLAND_FOUND) + add_compile_definitions(SUNSHINE_BUILD_WAYLAND) + + GEN_WAYLAND(xdg-output-unstable-v1) + GEN_WAYLAND(wlr-export-dmabuf-unstable-v1) + + include_directories( + SYSTEM + ${WAYLAND_INCLUDE_DIRS} + ${CMAKE_BINARY_DIR}/generated-src + ) + + list(APPEND PLATFORM_LIBRARIES ${WAYLAND_LIBRARIES}) + list(APPEND PLATFORM_TARGET_FILES + src/platform/linux/wlgrab.cpp + src/platform/linux/wayland.cpp) +endif() + +# x11 +if(${SUNSHINE_ENABLE_X11}) + find_package(X11) +else() + set(X11_FOUND OFF) +endif() +if(X11_FOUND) + add_compile_definitions(SUNSHINE_BUILD_X11) + include_directories(SYSTEM ${X11_INCLUDE_DIR}) + list(APPEND PLATFORM_LIBRARIES ${X11_LIBRARIES}) + list(APPEND PLATFORM_TARGET_FILES src/platform/linux/x11grab.cpp) +endif() + +if(NOT ${CUDA_FOUND} AND NOT ${WAYLAND_FOUND} AND NOT ${X11_FOUND} AND NOT (${LIBDRM_FOUND} AND ${LIBCAP_FOUND})) + message(FATAL_ERROR "Couldn't find either x11, wayland, cuda or (libdrm and libcap)") +endif() + +# tray icon +if(${SUNSHINE_ENABLE_TRAY}) + pkg_check_modules(APPINDICATOR appindicator3-0.1) + if(NOT APPINDICATOR_FOUND) + message(WARNING "Couldn't find appindicator, disabling tray icon") + set(SUNSHINE_TRAY 0) + else() + include_directories(SYSTEM ${APPINDICATOR_INCLUDE_DIRS}) + link_directories(${APPINDICATOR_LIBRARY_DIRS}) + + list(APPEND PLATFORM_TARGET_FILES third-party/tray/tray_linux.c) + list(APPEND SUNSHINE_EXTERNAL_LIBRARIES ${APPINDICATOR_LIBRARIES}) + endif() +else() + set(SUNSHINE_TRAY 0) +endif() + +list(APPEND PLATFORM_TARGET_FILES + src/platform/linux/publish.cpp + src/platform/linux/vaapi.h + src/platform/linux/vaapi.cpp + src/platform/linux/cuda.h + src/platform/linux/graphics.h + src/platform/linux/graphics.cpp + src/platform/linux/misc.h + src/platform/linux/misc.cpp + src/platform/linux/audio.cpp + src/platform/linux/input.cpp + src/platform/linux/x11grab.h + src/platform/linux/wayland.h + third-party/glad/src/egl.c + third-party/glad/src/gl.c + third-party/glad/include/EGL/eglplatform.h + third-party/glad/include/KHR/khrplatform.h + third-party/glad/include/glad/gl.h + third-party/glad/include/glad/egl.h) + +list(APPEND PLATFORM_LIBRARIES + Boost::dynamic_linking + dl + evdev + numa + pulse + pulse-simple) + +include_directories( + SYSTEM + /usr/include/libevdev-1.0 + third-party/nv-codec-headers/include + third-party/glad/include) + +configure_file(sunshine.service.in sunshine.service @ONLY) diff --git a/cmake/compile_definitions/macos.cmake b/cmake/compile_definitions/macos.cmake new file mode 100644 index 00000000000..83fa9ae3053 --- /dev/null +++ b/cmake/compile_definitions/macos.cmake @@ -0,0 +1,48 @@ +# macos specific compile definitions + +add_compile_definitions(SUNSHINE_PLATFORM="macos") + +link_directories(/opt/local/lib) +link_directories(/usr/local/lib) +ADD_DEFINITIONS(-DBOOST_LOG_DYN_LINK) + +FIND_LIBRARY(APP_SERVICES_LIBRARY ApplicationServices) +FIND_LIBRARY(AV_FOUNDATION_LIBRARY AVFoundation) +FIND_LIBRARY(COCOA Cocoa REQUIRED) # tray icon +FIND_LIBRARY(CORE_MEDIA_LIBRARY CoreMedia) +FIND_LIBRARY(CORE_VIDEO_LIBRARY CoreVideo) +FIND_LIBRARY(FOUNDATION_LIBRARY Foundation) +FIND_LIBRARY(VIDEO_TOOLBOX_LIBRARY VideoToolbox) + +list(APPEND SUNSHINE_EXTERNAL_LIBRARIES + ${APP_SERVICES_LIBRARY} + ${AV_FOUNDATION_LIBRARY} + ${COCOA} + ${CORE_MEDIA_LIBRARY} + ${CORE_VIDEO_LIBRARY} + ${VIDEO_TOOLBOX_LIBRARY} + ${FOUNDATION_LIBRARY}) + +set(PLATFORM_INCLUDE_DIRS + ${Boost_INCLUDE_DIR}) + +set(APPLE_PLIST_FILE ${SUNSHINE_SOURCE_ASSETS_DIR}/macos/assets/Info.plist) + +set(PLATFORM_TARGET_FILES + src/platform/macos/av_audio.h + src/platform/macos/av_audio.m + src/platform/macos/av_img_t.h + src/platform/macos/av_video.h + src/platform/macos/av_video.m + src/platform/macos/display.mm + src/platform/macos/input.cpp + src/platform/macos/microphone.mm + src/platform/macos/misc.mm + src/platform/macos/misc.h + src/platform/macos/nv12_zero_device.cpp + src/platform/macos/nv12_zero_device.h + src/platform/macos/publish.cpp + third-party/TPCircularBuffer/TPCircularBuffer.c + third-party/TPCircularBuffer/TPCircularBuffer.h + third-party/tray/tray_darwin.m + ${APPLE_PLIST_FILE}) diff --git a/cmake/compile_definitions/unix.cmake b/cmake/compile_definitions/unix.cmake new file mode 100644 index 00000000000..a69ebbffd09 --- /dev/null +++ b/cmake/compile_definitions/unix.cmake @@ -0,0 +1,4 @@ +# unix specific compile definitions +# put anything here that applies to both linux and macos + +list(APPEND SUNSHINE_EXTERNAL_LIBRARIES Boost::log) diff --git a/cmake/compile_definitions/windows.cmake b/cmake/compile_definitions/windows.cmake new file mode 100644 index 00000000000..acfcaa5bdcf --- /dev/null +++ b/cmake/compile_definitions/windows.cmake @@ -0,0 +1,74 @@ +# windows specific compile definitions + +add_compile_definitions(SUNSHINE_PLATFORM="windows") + +enable_language(RC) +set(CMAKE_RC_COMPILER windres) +set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static") + +# curl +add_definitions(-DCURL_STATICLIB) +include_directories(SYSTEM ${CURL_STATIC_INCLUDE_DIRS}) +link_directories(${CURL_STATIC_LIBRARY_DIRS}) + +# extra tools/binaries for audio/display devices +add_subdirectory(tools) # todo - this is temporary, only tools for Windows are needed, for now + +# nvidia +include_directories(SYSTEM third-party/nvapi-open-source-sdk) +file(GLOB NVPREFS_FILES CONFIGURE_DEPENDS + "third-party/nvapi-open-source-sdk/*.h" + "src/platform/windows/nvprefs/*.cpp" + "src/platform/windows/nvprefs/*.h") + +# vigem +include_directories(SYSTEM third-party/ViGEmClient/include) +set_source_files_properties(third-party/ViGEmClient/src/ViGEmClient.cpp + PROPERTIES COMPILE_DEFINITIONS "UNICODE=1;ERROR_INVALID_DEVICE_OBJECT_PARAMETER=650") +set_source_files_properties(third-party/ViGEmClient/src/ViGEmClient.cpp + PROPERTIES COMPILE_FLAGS "-Wno-unknown-pragmas -Wno-misleading-indentation -Wno-class-memaccess") + +# sunshine icon +if(NOT DEFINED SUNSHINE_ICON_PATH) + set(SUNSHINE_ICON_PATH "${CMAKE_CURRENT_SOURCE_DIR}/sunshine.ico") +endif() + +configure_file(src/platform/windows/windows.rs.in windows.rc @ONLY) + +set(PLATFORM_TARGET_FILES + "${CMAKE_CURRENT_BINARY_DIR}/windows.rc" + src/platform/windows/publish.cpp + src/platform/windows/misc.h + src/platform/windows/misc.cpp + src/platform/windows/input.cpp + src/platform/windows/display.h + src/platform/windows/display_base.cpp + src/platform/windows/display_vram.cpp + src/platform/windows/display_ram.cpp + src/platform/windows/audio.cpp + third-party/tray/tray_windows.c + third-party/ViGEmClient/src/ViGEmClient.cpp + third-party/ViGEmClient/include/ViGEm/Client.h + third-party/ViGEmClient/include/ViGEm/Common.h + third-party/ViGEmClient/include/ViGEm/Util.h + third-party/ViGEmClient/include/ViGEm/km/BusShared.h + ${NVPREFS_FILES}) + +set(OPENSSL_LIBRARIES + libssl.a + libcrypto.a) + +list(PREPEND PLATFORM_LIBRARIES + libstdc++.a + libwinpthread.a + libssp.a + ksuser + wsock32 + ws2_32 + d3d11 dxgi D3DCompiler + setupapi + dwmapi + userenv + synchronization.lib + avrt + ${CURL_STATIC_LIBRARIES}) diff --git a/cmake/dependencies/common.cmake b/cmake/dependencies/common.cmake new file mode 100644 index 00000000000..b5458ebd9e8 --- /dev/null +++ b/cmake/dependencies/common.cmake @@ -0,0 +1,21 @@ +# load common dependencies +# this file will also load platform specific dependencies + +# common dependencies +find_package(Threads REQUIRED) +find_package(OpenSSL REQUIRED) +find_package(PkgConfig REQUIRED) +pkg_check_modules(CURL REQUIRED libcurl) + +# platform specific dependencies +if(WIN32) + include(${CMAKE_MODULE_PATH}/dependencies/windows.cmake) +elseif(UNIX) + include(${CMAKE_MODULE_PATH}/dependencies/unix.cmake) + + if(APPLE) + include(${CMAKE_MODULE_PATH}/dependencies/macos.cmake) + else() + include(${CMAKE_MODULE_PATH}/dependencies/linux.cmake) + endif() +endif() diff --git a/cmake/dependencies/linux.cmake b/cmake/dependencies/linux.cmake new file mode 100644 index 00000000000..8022b9dfea0 --- /dev/null +++ b/cmake/dependencies/linux.cmake @@ -0,0 +1 @@ +# linux specific dependencies diff --git a/cmake/dependencies/macos.cmake b/cmake/dependencies/macos.cmake new file mode 100644 index 00000000000..c419a20831d --- /dev/null +++ b/cmake/dependencies/macos.cmake @@ -0,0 +1 @@ +# macos specific dependencies diff --git a/cmake/dependencies/unix.cmake b/cmake/dependencies/unix.cmake new file mode 100644 index 00000000000..5b13bf60403 --- /dev/null +++ b/cmake/dependencies/unix.cmake @@ -0,0 +1,4 @@ +# unix specific dependencies +# put anything here that applies to both linux and macos + +find_package(Boost COMPONENTS locale log filesystem program_options REQUIRED) diff --git a/cmake/dependencies/windows.cmake b/cmake/dependencies/windows.cmake new file mode 100644 index 00000000000..3ce9a9da234 --- /dev/null +++ b/cmake/dependencies/windows.cmake @@ -0,0 +1,6 @@ +# windows specific dependencies + +set(Boost_USE_STATIC_LIBS ON) # cmake-lint: disable=C0103 +# Boost >= 1.82.0 is required for boost::json::value::set_at_pointer() support +# todo - are we actually using json? I think this was attempted to be used in a PR, but we ended up not using json +find_package(Boost 1.82.0 COMPONENTS locale log filesystem program_options json REQUIRED) diff --git a/cmake/macros/common.cmake b/cmake/macros/common.cmake new file mode 100644 index 00000000000..24592355fbb --- /dev/null +++ b/cmake/macros/common.cmake @@ -0,0 +1,15 @@ +# common macros +# this file will also load platform specific macros + +# platform specific macros +if(WIN32) + include(${CMAKE_MODULE_PATH}/macros/windows.cmake) +elseif(UNIX) + include(${CMAKE_MODULE_PATH}/macros/unix.cmake) + + if(APPLE) + include(${CMAKE_MODULE_PATH}/macros/macos.cmake) + else() + include(${CMAKE_MODULE_PATH}/macros/linux.cmake) + endif() +endif() diff --git a/cmake/macros/linux.cmake b/cmake/macros/linux.cmake new file mode 100644 index 00000000000..fea94fe870a --- /dev/null +++ b/cmake/macros/linux.cmake @@ -0,0 +1,31 @@ +# linux specific macros + +# GEN_WAYLAND: args = `filename` +macro(GEN_WAYLAND filename) + file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/generated-src) + + message("wayland-scanner private-code \ +${CMAKE_SOURCE_DIR}/third-party/wayland-protocols/${filename}.xml \ +${CMAKE_BINARY_DIR}/generated-src/${filename}.c") + message("wayland-scanner client-header \ +${CMAKE_SOURCE_DIR}/third-party/wayland-protocols/${filename}.xml \ +${CMAKE_BINARY_DIR}/generated-src/${filename}.h") + execute_process( + COMMAND wayland-scanner private-code + ${CMAKE_SOURCE_DIR}/third-party/wayland-protocols/${filename}.xml + ${CMAKE_BINARY_DIR}/generated-src/${filename}.c + COMMAND wayland-scanner client-header + ${CMAKE_SOURCE_DIR}/third-party/wayland-protocols/${filename}.xml + ${CMAKE_BINARY_DIR}/generated-src/${filename}.h + + RESULT_VARIABLE EXIT_INT + ) + + if(NOT ${EXIT_INT} EQUAL 0) + message(FATAL_ERROR "wayland-scanner failed") + endif() + + list(APPEND PLATFORM_TARGET_FILES + ${CMAKE_BINARY_DIR}/generated-src/${filename}.c + ${CMAKE_BINARY_DIR}/generated-src/${filename}.h) +endmacro() diff --git a/cmake/macros/macos.cmake b/cmake/macros/macos.cmake new file mode 100644 index 00000000000..a4d963db4a5 --- /dev/null +++ b/cmake/macros/macos.cmake @@ -0,0 +1,17 @@ +# macos specific macros + +# todo - is this macro actually used? +# ADD_FRAMEWORK: args = `fwname`, `appname` +macro(ADD_FRAMEWORK fwname appname) + find_library(FRAMEWORK_${fwname} + NAMES ${fwname} + PATHS ${CMAKE_OSX_SYSROOT}/System/Library + PATH_SUFFIXES Frameworks + NO_DEFAULT_PATH) + if( ${FRAMEWORK_${fwname}} STREQUAL FRAMEWORK_${fwname}-NOTFOUND) + MESSAGE(ERROR ": Framework ${fwname} not found") + else() + TARGET_LINK_LIBRARIES(${appname} "${FRAMEWORK_${fwname}}/${fwname}") + MESSAGE(STATUS "Framework ${fwname} found at ${FRAMEWORK_${fwname}}") + endif() +endmacro(ADD_FRAMEWORK) diff --git a/cmake/macros/unix.cmake b/cmake/macros/unix.cmake new file mode 100644 index 00000000000..3fb68ed4c26 --- /dev/null +++ b/cmake/macros/unix.cmake @@ -0,0 +1,2 @@ +# unix specific macros +# put anything here that applies to both linux and macos diff --git a/cmake/macros/windows.cmake b/cmake/macros/windows.cmake new file mode 100644 index 00000000000..9cc0e46f2e0 --- /dev/null +++ b/cmake/macros/windows.cmake @@ -0,0 +1 @@ +# windows specific macros diff --git a/cmake/packaging/common.cmake b/cmake/packaging/common.cmake new file mode 100644 index 00000000000..6e0abf7e5cc --- /dev/null +++ b/cmake/packaging/common.cmake @@ -0,0 +1,42 @@ +# common packaging + +# setup assets directory +if(NOT SUNSHINE_ASSETS_DIR) + set(SUNSHINE_ASSETS_DIR "assets") +endif() + +# common cpack options +set(CPACK_PACKAGE_NAME ${CMAKE_PROJECT_NAME}) +set(CPACK_PACKAGE_VENDOR "LizardByte") +set(CPACK_PACKAGE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/cpack_artifacts) +set(CPACK_PACKAGE_CONTACT "https://app.lizardbyte.dev") +set(CPACK_PACKAGE_DESCRIPTION ${CMAKE_PROJECT_DESCRIPTION}) +set(CPACK_PACKAGE_HOMEPAGE_URL ${CMAKE_PROJECT_HOMEPAGE_URL}) +set(CPACK_RESOURCE_FILE_LICENSE ${PROJECT_SOURCE_DIR}/LICENSE) +set(CPACK_PACKAGE_ICON ${PROJECT_SOURCE_DIR}/sunshine.png) +set(CPACK_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME}") +set(CPACK_STRIP_FILES YES) + +# install npm modules +install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/node_modules" + DESTINATION "${SUNSHINE_ASSETS_DIR}/web") + +# platform specific packaging +if(WIN32) + include(${CMAKE_MODULE_PATH}/packaging/windows.cmake) +elseif(UNIX) + include(${CMAKE_MODULE_PATH}/packaging/unix.cmake) + + if(APPLE) + include(${CMAKE_MODULE_PATH}/packaging/macos.cmake) + else() + include(${CMAKE_MODULE_PATH}/packaging/linux.cmake) + endif() +endif() + +if(NOT SUNSHINE_ASSETS_DIR_DEF) + set(SUNSHINE_ASSETS_DIR_DEF "${SUNSHINE_ASSETS_DIR}") +endif() +list(APPEND SUNSHINE_DEFINITIONS SUNSHINE_ASSETS_DIR="${SUNSHINE_ASSETS_DIR_DEF}") + +include(CPack) diff --git a/cmake/packaging/linux.cmake b/cmake/packaging/linux.cmake new file mode 100644 index 00000000000..2af89545579 --- /dev/null +++ b/cmake/packaging/linux.cmake @@ -0,0 +1,81 @@ +# linux specific packaging + +# AppImage +if(${SUNSHINE_BUILD_APPIMAGE}) + # use relative assets path for AppImage + string(REPLACE "${CMAKE_INSTALL_PREFIX}" ".${CMAKE_INSTALL_PREFIX}" SUNSHINE_ASSETS_DIR_DEF ${SUNSHINE_ASSETS_DIR}) +endif() + +install(DIRECTORY "${SUNSHINE_SOURCE_ASSETS_DIR}/linux/assets/" + DESTINATION "${SUNSHINE_ASSETS_DIR}") +if(${SUNSHINE_BUILD_APPIMAGE} OR ${SUNSHINE_BUILD_FLATPAK}) + install(FILES "${SUNSHINE_SOURCE_ASSETS_DIR}/linux/misc/85-sunshine.rules" + DESTINATION "${SUNSHINE_ASSETS_DIR}/udev/rules.d") + install(FILES "${CMAKE_CURRENT_BINARY_DIR}/sunshine.service" + DESTINATION "${SUNSHINE_ASSETS_DIR}/systemd/user") +else() + install(FILES "${SUNSHINE_SOURCE_ASSETS_DIR}/linux/misc/85-sunshine.rules" + DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/udev/rules.d") + install(FILES "${CMAKE_CURRENT_BINARY_DIR}/sunshine.service" + DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/systemd/user") +endif() + +# 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") + +# Dependencies +set(CPACK_DEB_COMPONENT_INSTALL ON) +set(CPACK_DEBIAN_PACKAGE_DEPENDS "\ + ${CPACK_DEB_PLATFORM_PACKAGE_DEPENDS} \ + libboost-filesystem${Boost_VERSION}, \ + libboost-locale${Boost_VERSION}, \ + libboost-log${Boost_VERSION}, \ + libboost-program-options${Boost_VERSION}, \ + libcap2, \ + libcurl4, \ + libdrm2, \ + libevdev2, \ + libnuma1, \ + libopus0, \ + libpulse0, \ + libva2, \ + libva-drm2, \ + libvdpau1, \ + libwayland-client0, \ + libx11-6, \ + openssl | libssl3") +set(CPACK_RPM_PACKAGE_REQUIRES "\ + ${CPACK_RPM_PLATFORM_PACKAGE_REQUIRES} \ + boost-filesystem >= ${Boost_VERSION}, \ + boost-locale >= ${Boost_VERSION}, \ + boost-log >= ${Boost_VERSION}, \ + boost-program-options >= ${Boost_VERSION}, \ + libcap >= 2.22, \ + libcurl >= 7.0, \ + libdrm >= 2.4.97, \ + libevdev >= 1.5.6, \ + libopusenc >= 0.2.1, \ + libva >= 2.14.0, \ + libvdpau >= 1.5, \ + libwayland-client >= 1.20.0, \ + libX11 >= 1.7.3.1, \ + numactl-libs >= 2.0.14, \ + openssl >= 3.0.2, \ + pulseaudio-libs >= 10.0") + +# This should automatically figure out dependencies, doesn't work with the current config +set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS OFF) + +# tray icon +if(${SUNSHINE_TRAY} STREQUAL 1) + install(FILES "${CMAKE_SOURCE_DIR}/sunshine.svg" + DESTINATION "${CMAKE_INSTALL_PREFIX}/share/icons") + + set(CPACK_DEBIAN_PACKAGE_DEPENDS "\ + ${CPACK_DEBIAN_PACKAGE_DEPENDS}, \ + libappindicator3-1") + set(CPACK_RPM_PACKAGE_REQUIRES "\ + ${CPACK_RPM_PACKAGE_REQUIRES}, \ + libappindicator-gtk3 >= 12.10.0") +endif() diff --git a/cmake/packaging/macos.cmake b/cmake/packaging/macos.cmake new file mode 100644 index 00000000000..2b173393bbf --- /dev/null +++ b/cmake/packaging/macos.cmake @@ -0,0 +1,26 @@ +# macos specific packaging + +# todo - bundle doesn't produce a valid .app use cpack -G DragNDrop +set(CPACK_BUNDLE_NAME "${CMAKE_PROJECT_NAME}") +set(CPACK_BUNDLE_PLIST "${APPLE_PLIST_FILE}") +set(CPACK_BUNDLE_ICON "${PROJECT_SOURCE_DIR}/sunshine.icns") +# set(CPACK_BUNDLE_STARTUP_COMMAND "${INSTALL_RUNTIME_DIR}/sunshine") + +if(SUNSHINE_PACKAGE_MACOS) # todo + set(MAC_PREFIX "${CMAKE_PROJECT_NAME}.app/Contents") + set(INSTALL_RUNTIME_DIR "${MAC_PREFIX}/MacOS") + + install(DIRECTORY "${SUNSHINE_SOURCE_ASSETS_DIR}/common/assets/" + DESTINATION "${SUNSHINE_ASSETS_DIR}") + install(DIRECTORY "${SUNSHINE_SOURCE_ASSETS_DIR}/macos/assets/" + DESTINATION "${SUNSHINE_ASSETS_DIR}") + + install(TARGETS sunshine + BUNDLE DESTINATION . COMPONENT Runtime + RUNTIME DESTINATION ${INSTALL_RUNTIME_DIR} COMPONENT Runtime) +else() + install(DIRECTORY "${SUNSHINE_SOURCE_ASSETS_DIR}/macos/assets/" + DESTINATION "${SUNSHINE_ASSETS_DIR}") + install(FILES "${SUNSHINE_SOURCE_ASSETS_DIR}/macos/misc/uninstall_pkg.sh" + DESTINATION "${SUNSHINE_ASSETS_DIR}") +endif() diff --git a/cmake/packaging/unix.cmake b/cmake/packaging/unix.cmake new file mode 100644 index 00000000000..3e9e244ca31 --- /dev/null +++ b/cmake/packaging/unix.cmake @@ -0,0 +1,23 @@ +# unix specific packaging +# put anything here that applies to both linux and macos + +# add install prefix to assets path if not already there +if(NOT SUNSHINE_ASSETS_DIR MATCHES "^${CMAKE_INSTALL_PREFIX}") + set(SUNSHINE_ASSETS_DIR "${CMAKE_INSTALL_PREFIX}/${SUNSHINE_ASSETS_DIR}") +endif() + +# return here if building a macos package +if(SUNSHINE_PACKAGE_MACOS) + return() +endif() + +# Installation destination dir +set(CPACK_SET_DESTDIR true) +if(NOT CMAKE_INSTALL_PREFIX) + set(CMAKE_INSTALL_PREFIX "/usr/share/sunshine") +endif() + +install(TARGETS sunshine RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}") + +install(DIRECTORY "${SUNSHINE_SOURCE_ASSETS_DIR}/common/assets/" + DESTINATION "${SUNSHINE_ASSETS_DIR}") diff --git a/cmake/packaging/windows.cmake b/cmake/packaging/windows.cmake new file mode 100644 index 00000000000..78f0a0e32c0 --- /dev/null +++ b/cmake/packaging/windows.cmake @@ -0,0 +1,155 @@ +# windows specific packaging + +# see options at: https://cmake.org/cmake/help/latest/cpack_gen/nsis.html +install(TARGETS sunshine RUNTIME DESTINATION "." COMPONENT application) + +# Hardening: include zlib1.dll (loaded via LoadLibrary() in openssl's libcrypto.a) +install(FILES "${ZLIB}" DESTINATION "." COMPONENT application) + +# Adding tools +install(TARGETS dxgi-info RUNTIME DESTINATION "tools" COMPONENT dxgi) +install(TARGETS audio-info RUNTIME DESTINATION "tools" COMPONENT audio) + +# Mandatory tools +install(TARGETS ddprobe RUNTIME DESTINATION "tools" COMPONENT application) +install(TARGETS sunshinesvc RUNTIME DESTINATION "tools" COMPONENT application) + +# Mandatory scripts +install(DIRECTORY "${SUNSHINE_SOURCE_ASSETS_DIR}/windows/misc/service/" + DESTINATION "scripts" + COMPONENT assets) +install(DIRECTORY "${SUNSHINE_SOURCE_ASSETS_DIR}/windows/misc/migration/" + DESTINATION "scripts" + COMPONENT assets) + +# Configurable options for the service +install(DIRECTORY "${SUNSHINE_SOURCE_ASSETS_DIR}/windows/misc/autostart/" + DESTINATION "scripts" + COMPONENT autostart) + +# scripts +install(DIRECTORY "${SUNSHINE_SOURCE_ASSETS_DIR}/windows/misc/firewall/" + DESTINATION "scripts" + COMPONENT firewall) +install(DIRECTORY "${SUNSHINE_SOURCE_ASSETS_DIR}/windows/misc/vigembus/" + DESTINATION "scripts" + COMPONENT vigembus) + +# Sunshine assets +install(DIRECTORY "${SUNSHINE_SOURCE_ASSETS_DIR}/common/assets/" + DESTINATION "${SUNSHINE_ASSETS_DIR}" + COMPONENT assets) +install(DIRECTORY "${SUNSHINE_SOURCE_ASSETS_DIR}/windows/assets/" + DESTINATION "${SUNSHINE_ASSETS_DIR}" + COMPONENT assets) + +# set(CPACK_NSIS_MUI_HEADERIMAGE "") # TODO: image should be 150x57 bmp +set(CPACK_PACKAGE_ICON "${CMAKE_CURRENT_SOURCE_DIR}\\\\sunshine.ico") +set(CPACK_NSIS_INSTALLED_ICON_NAME "${PROJECT__DIR}\\\\${PROJECT_EXE}") +# The name of the directory that will be created in C:/Program files/ +set(CPACK_PACKAGE_INSTALL_DIRECTORY "${CPACK_PACKAGE_NAME}") + +# Extra install commands +# Restores permissions on the install directory +# Migrates config files from the root into the new config folder +# Install service +SET(CPACK_NSIS_EXTRA_INSTALL_COMMANDS + "${CPACK_NSIS_EXTRA_INSTALL_COMMANDS} + IfSilent +2 0 + ExecShell 'open' 'https://sunshinestream.readthedocs.io/' + nsExec::ExecToLog 'icacls \\\"$INSTDIR\\\" /reset' + nsExec::ExecToLog '\\\"$INSTDIR\\\\scripts\\\\migrate-config.bat\\\"' + nsExec::ExecToLog '\\\"$INSTDIR\\\\scripts\\\\add-firewall-rule.bat\\\"' + nsExec::ExecToLog '\\\"$INSTDIR\\\\scripts\\\\install-service.bat\\\"' + nsExec::ExecToLog '\\\"$INSTDIR\\\\scripts\\\\install-vigembus.bat\\\"' + nsExec::ExecToLog '\\\"$INSTDIR\\\\scripts\\\\autostart-service.bat\\\"' + NoController: + ") + +# Extra uninstall commands +# Uninstall service +set(CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS + "${CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS} + nsExec::ExecToLog '\\\"$INSTDIR\\\\scripts\\\\delete-firewall-rule.bat\\\"' + nsExec::ExecToLog '\\\"$INSTDIR\\\\scripts\\\\uninstall-service.bat\\\"' + nsExec::ExecToLog '\\\"$INSTDIR\\\\sunshine.exe\\\" --restore-nvprefs-undo' + MessageBox MB_YESNO|MB_ICONQUESTION \ + 'Do you want to remove ViGEmBus)?' \ + /SD IDNO IDNO NoVigem + nsExec::ExecToLog '\\\"$INSTDIR\\\\scripts\\\\uninstall-vigembus.bat\\\"'; skipped if no + NoVigem: + MessageBox MB_YESNO|MB_ICONQUESTION \ + 'Do you want to remove $INSTDIR (this includes the configuration, cover images, and settings)?' \ + /SD IDNO IDNO NoDelete + RMDir /r \\\"$INSTDIR\\\"; skipped if no + NoDelete: + ") + +# Adding an option for the start menu +set(CPACK_NSIS_MODIFY_PATH "OFF") +set(CPACK_NSIS_EXECUTABLES_DIRECTORY ".") +# This will be shown on the installed apps Windows settings +set(CPACK_NSIS_INSTALLED_ICON_NAME "${CMAKE_PROJECT_NAME}.exe") +set(CPACK_NSIS_CREATE_ICONS_EXTRA + "${CPACK_NSIS_CREATE_ICONS_EXTRA} + CreateShortCut '\$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\${CMAKE_PROJECT_NAME}.lnk' \ + '\$INSTDIR\\\\${CMAKE_PROJECT_NAME}.exe' '--shortcut' + ") +set(CPACK_NSIS_DELETE_ICONS_EXTRA + "${CPACK_NSIS_DELETE_ICONS_EXTRA} + Delete '\$SMPROGRAMS\\\\$MUI_TEMP\\\\${CMAKE_PROJECT_NAME}.lnk' + ") + +# Checking for previous installed versions +set(CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL "ON") + +set(CPACK_NSIS_HELP_LINK "https://sunshinestream.readthedocs.io/about/installation.html") +set(CPACK_NSIS_URL_INFO_ABOUT "${CMAKE_PROJECT_HOMEPAGE_URL}") +set(CPACK_NSIS_CONTACT "${CMAKE_PROJECT_HOMEPAGE_URL}/support") + +set(CPACK_NSIS_MENU_LINKS + "https://sunshinestream.readthedocs.io" "Sunshine documentation" + "https://app.lizardbyte.dev" "LizardByte Web Site" + "https://app.lizardbyte.dev/support" "LizardByte Support") +set(CPACK_NSIS_MANIFEST_DPI_AWARE true) + +# Setting components groups and dependencies +set(CPACK_COMPONENT_GROUP_CORE_EXPANDED true) + +# sunshine binary +set(CPACK_COMPONENT_APPLICATION_DISPLAY_NAME "${CMAKE_PROJECT_NAME}") +set(CPACK_COMPONENT_APPLICATION_DESCRIPTION "${CMAKE_PROJECT_NAME} main application and required components.") +set(CPACK_COMPONENT_APPLICATION_GROUP "Core") +set(CPACK_COMPONENT_APPLICATION_REQUIRED true) +set(CPACK_COMPONENT_APPLICATION_DEPENDS assets) + +# service auto-start script +set(CPACK_COMPONENT_AUTOSTART_DISPLAY_NAME "Launch on Startup") +set(CPACK_COMPONENT_AUTOSTART_DESCRIPTION "If enabled, launches Sunshine automatically on system startup.") +set(CPACK_COMPONENT_AUTOSTART_GROUP "Core") + +# assets +set(CPACK_COMPONENT_ASSETS_DISPLAY_NAME "Required Assets") +set(CPACK_COMPONENT_ASSETS_DESCRIPTION "Shaders, default box art, and web UI.") +set(CPACK_COMPONENT_ASSETS_GROUP "Core") +set(CPACK_COMPONENT_ASSETS_REQUIRED true) + +# audio tool +set(CPACK_COMPONENT_AUDIO_DISPLAY_NAME "audio-info") +set(CPACK_COMPONENT_AUDIO_DESCRIPTION "CLI tool providing information about sound devices.") +set(CPACK_COMPONENT_AUDIO_GROUP "Tools") + +# display tool +set(CPACK_COMPONENT_DXGI_DISPLAY_NAME "dxgi-info") +set(CPACK_COMPONENT_DXGI_DESCRIPTION "CLI tool providing information about graphics cards and displays.") +set(CPACK_COMPONENT_DXGI_GROUP "Tools") + +# firewall scripts +set(CPACK_COMPONENT_FIREWALL_DISPLAY_NAME "Add Firewall Exclusions") +set(CPACK_COMPONENT_FIREWALL_DESCRIPTION "Scripts to enable or disable firewall rules.") +set(CPACK_COMPONENT_FIREWALL_GROUP "Scripts") + +# vigembus scripts +set(CPACK_COMPONENT_VIGEMBUS_DISPLAY_NAME "Virtual Gamepad Support") +set(CPACK_COMPONENT_VIGEMBUS_DESCRIPTION "Scripts to install and uninstall ViGEmBus for virtual gamepad support.") +set(CPACK_COMPONENT_VIGEMBUS_GROUP "Scripts") diff --git a/cmake/prep/base.cmake b/cmake/prep/base.cmake new file mode 100644 index 00000000000..c909b12735f --- /dev/null +++ b/cmake/prep/base.cmake @@ -0,0 +1,14 @@ +# todo - set version to 0.0.0 once confident in automated versioning +project(Sunshine VERSION 0.20.0 + DESCRIPTION "Sunshine is a self-hosted game stream host for Moonlight." + HOMEPAGE_URL "https://app.lizardbyte.dev/Sunshine") + +set(PROJECT_LONG_DESCRIPTION "Offering low latency, cloud gaming server capabilities with support for AMD, Intel, \ +and Nvidia GPUs for hardware encoding. Software encoding is also available. You can connect to Sunshine from any \ +Moonlight client on a variety of devices. A web UI is provided to allow configuration, and client pairing, from \ +your favorite web browser. Pair from the local server or any mobile device.") + +if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + message(STATUS "Setting build type to 'Release' as none was specified.") + set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build." FORCE) +endif() diff --git a/cmake/prep/build_version.cmake b/cmake/prep/build_version.cmake new file mode 100644 index 00000000000..49f85f9b585 --- /dev/null +++ b/cmake/prep/build_version.cmake @@ -0,0 +1,58 @@ +# Check if env vars are defined before attempting to access them, variables will be defined even if blank +if((DEFINED ENV{BRANCH}) AND (DEFINED ENV{BUILD_VERSION}) AND (DEFINED ENV{COMMIT})) # cmake-lint: disable=W0106 + if(($ENV{BRANCH} STREQUAL "master") AND (NOT $ENV{BUILD_VERSION} STREQUAL "")) + # If BRANCH is "master" and BUILD_VERSION is not empty, then we are building a master branch + MESSAGE("Got from CI master branch and version $ENV{BUILD_VERSION}") + set(PROJECT_VERSION $ENV{BUILD_VERSION}) + elseif((DEFINED ENV{BRANCH}) AND (DEFINED ENV{COMMIT})) + # If BRANCH is set but not BUILD_VERSION we are building nightly, we gather only the commit hash + MESSAGE("Got from CI $ENV{BRANCH} branch and commit $ENV{COMMIT}") + set(PROJECT_VERSION ${PROJECT_VERSION}.$ENV{COMMIT}) + endif() + # Generate Sunshine Version based of the git tag + # https://github.com/nocnokneo/cmake-git-versioning-example/blob/master/LICENSE +else() + find_package(Git) + if(GIT_EXECUTABLE) + MESSAGE("${CMAKE_CURRENT_SOURCE_DIR}") + get_filename_component(SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY) + #Get current Branch + execute_process( + COMMAND ${GIT_EXECUTABLE} rev-parse --abbrev-ref HEAD + #WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + OUTPUT_VARIABLE GIT_DESCRIBE_BRANCH + RESULT_VARIABLE GIT_DESCRIBE_ERROR_CODE + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + # Gather current commit + execute_process( + COMMAND ${GIT_EXECUTABLE} rev-parse --short HEAD + #WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + OUTPUT_VARIABLE GIT_DESCRIBE_VERSION + RESULT_VARIABLE GIT_DESCRIBE_ERROR_CODE + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + # Check if Dirty + execute_process( + COMMAND ${GIT_EXECUTABLE} diff --quiet --exit-code + #WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + RESULT_VARIABLE GIT_IS_DIRTY + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + if(NOT GIT_DESCRIBE_ERROR_CODE) + MESSAGE("Sunshine Branch: ${GIT_DESCRIBE_BRANCH}") + if(NOT GIT_DESCRIBE_BRANCH STREQUAL "master") + set(PROJECT_VERSION ${PROJECT_VERSION}.${GIT_DESCRIBE_VERSION}) + MESSAGE("Sunshine Version: ${GIT_DESCRIBE_VERSION}") + endif() + if(GIT_IS_DIRTY) + set(PROJECT_VERSION ${PROJECT_VERSION}.dirty) + MESSAGE("Git tree is dirty!") + endif() + else() + MESSAGE(ERROR ": Got git error while fetching tags: ${GIT_DESCRIBE_ERROR_CODE}") + endif() + else() + MESSAGE(WARNING ": Git not found, cannot find git version") + endif() +endif() diff --git a/cmake/prep/constants.cmake b/cmake/prep/constants.cmake new file mode 100644 index 00000000000..4f7a9e48aeb --- /dev/null +++ b/cmake/prep/constants.cmake @@ -0,0 +1,5 @@ +# source assets will be installed from this directory +set(SUNSHINE_SOURCE_ASSETS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src_assets") + +# enable system tray, we will disable this later if we cannot find the required package config on linux +set(SUNSHINE_TRAY 1) diff --git a/cmake/prep/options.cmake b/cmake/prep/options.cmake new file mode 100644 index 00000000000..7e909dd282a --- /dev/null +++ b/cmake/prep/options.cmake @@ -0,0 +1,20 @@ +# if this option is set, the build will exit after configuring special package configuration files +option(SUNSHINE_CONFIGURE_ONLY "Configure special files only, then exit." OFF) + +option(SUNSHINE_ENABLE_TRAY "Enable tray icon." ON) + +if (APPLE) + option(SUNSHINE_CONFIGURE_PORTFILE "Configure macOS Portfile." OFF) + option(SUNSHINE_PACKAGE_MACOS "Should only be used when creating a MACOS package/dmg." OFF) +elseif (UNIX) # Linux + option(SUNSHINE_BUILD_APPIMAGE "Enable an AppImage build." OFF) + option(SUNSHINE_BUILD_FLATPAK "Enable a Flatpak build." OFF) + option(SUNSHINE_CONFIGURE_PKGBUILD "Configure files required for AUR." OFF) + option(SUNSHINE_CONFIGURE_FLATPAK_MAN "Configure manifest file required for Flatpak build." OFF) + + # Linux capture methods + option(SUNSHINE_ENABLE_CUDA "Enable cuda specific code." ON) + option(SUNSHINE_ENABLE_DRM "Enable KMS grab if available." ON) + option(SUNSHINE_ENABLE_WAYLAND "Enable building wayland specific code." ON) + option(SUNSHINE_ENABLE_X11 "Enable X11 grab if available." ON) +endif () diff --git a/cmake/prep/special_package_configuration.cmake b/cmake/prep/special_package_configuration.cmake new file mode 100644 index 00000000000..4df53e5cf3d --- /dev/null +++ b/cmake/prep/special_package_configuration.cmake @@ -0,0 +1,27 @@ +if (APPLE) + if(${SUNSHINE_CONFIGURE_PORTFILE}) + configure_file(packaging/macos/Portfile Portfile @ONLY) + endif() +elseif (UNIX) + # configure the .desktop file + configure_file(packaging/linux/sunshine.desktop sunshine.desktop @ONLY) + + # configure the arch linux pkgbuild + if(${SUNSHINE_CONFIGURE_PKGBUILD}) + configure_file(packaging/linux/Arch/PKGBUILD PKGBUILD @ONLY) + endif() + + # configure the flatpak manifest + if(${SUNSHINE_CONFIGURE_FLATPAK_MAN}) + configure_file(packaging/linux/flatpak/dev.lizardbyte.sunshine.yml dev.lizardbyte.sunshine.yml @ONLY) + endif() +endif() + +# return if configure only is set +if(${SUNSHINE_CONFIGURE_ONLY}) + # message + message(STATUS "SUNSHINE_CONFIGURE_ONLY: ON, exiting...") + set(END_BUILD ON) +else() + set(END_BUILD OFF) +endif() diff --git a/cmake/submodules/include_submodules.cmake b/cmake/submodules/include_submodules.cmake new file mode 100644 index 00000000000..456f5c380a7 --- /dev/null +++ b/cmake/submodules/include_submodules.cmake @@ -0,0 +1,62 @@ +# moonlight common library +add_subdirectory(third-party/moonlight-common-c/enet) + +# web server +add_subdirectory(third-party/Simple-Web-Server) + +# miniupnp +set(UPNPC_BUILD_SHARED OFF CACHE BOOL "No shared libraries") +set(UPNPC_BUILD_TESTS OFF CACHE BOOL "Don't build tests for miniupnpc") +set(UPNPC_BUILD_SAMPLE OFF CACHE BOOL "Don't build samples for miniupnpc") +set(UPNPC_NO_INSTALL ON CACHE BOOL "Don't install any libraries build for miniupnpc") +add_subdirectory(third-party/miniupnp/miniupnpc) +include_directories(SYSTEM third-party/miniupnp/miniupnpc/include) + +# ffmpeg pre-compiled binaries +if(WIN32) + if(NOT CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64") + message(FATAL_ERROR "Unsupported system processor:" ${CMAKE_SYSTEM_PROCESSOR}) + endif() + set(FFMPEG_PLATFORM_LIBRARIES mfplat ole32 strmiids mfuuid mfx) + set(FFMPEG_PREPARED_BINARIES "${CMAKE_CURRENT_SOURCE_DIR}/third-party/ffmpeg-windows-x86_64") +elseif(APPLE) + if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64") + set(FFMPEG_PREPARED_BINARIES "${CMAKE_CURRENT_SOURCE_DIR}/third-party/ffmpeg-macos-x86_64") + elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64") + set(FFMPEG_PREPARED_BINARIES "${CMAKE_CURRENT_SOURCE_DIR}/third-party/ffmpeg-macos-aarch64") + elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "powerpc") + message(FATAL_ERROR "PowerPC is not supported on macOS") + else() + message(FATAL_ERROR "Unsupported system processor:" ${CMAKE_SYSTEM_PROCESSOR}) + endif() +elseif(UNIX) + set(FFMPEG_PLATFORM_LIBRARIES va va-drm va-x11 vdpau X11) + if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64") + list(APPEND FFMPEG_PLATFORM_LIBRARIES mfx) + set(FFMPEG_PREPARED_BINARIES "${CMAKE_CURRENT_SOURCE_DIR}/third-party/ffmpeg-linux-x86_64") + set(CPACK_DEB_PLATFORM_PACKAGE_DEPENDS "libmfx1,") + set(CPACK_RPM_PLATFORM_PACKAGE_REQUIRES "intel-mediasdk >= 22.3.0,") + elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64") + set(FFMPEG_PREPARED_BINARIES "${CMAKE_CURRENT_SOURCE_DIR}/third-party/ffmpeg-linux-aarch64") + elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "ppc64le" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "ppc64") + set(FFMPEG_PREPARED_BINARIES "${CMAKE_CURRENT_SOURCE_DIR}/third-party/ffmpeg-linux-powerpc64le") + else() + message(FATAL_ERROR "Unsupported system processor:" ${CMAKE_SYSTEM_PROCESSOR}) + endif() +endif() +set(FFMPEG_INCLUDE_DIRS + ${FFMPEG_PREPARED_BINARIES}/include) +if(EXISTS ${FFMPEG_PREPARED_BINARIES}/lib/libhdr10plus.a) + set(HDR10_PLUS_LIBRARY + ${FFMPEG_PREPARED_BINARIES}/lib/libhdr10plus.a) +endif() +set(FFMPEG_LIBRARIES + ${FFMPEG_PREPARED_BINARIES}/lib/libavcodec.a + ${FFMPEG_PREPARED_BINARIES}/lib/libavutil.a + ${FFMPEG_PREPARED_BINARIES}/lib/libcbs.a + ${FFMPEG_PREPARED_BINARIES}/lib/libSvtAv1Enc.a + ${FFMPEG_PREPARED_BINARIES}/lib/libswscale.a + ${FFMPEG_PREPARED_BINARIES}/lib/libx264.a + ${FFMPEG_PREPARED_BINARIES}/lib/libx265.a + ${HDR10_PLUS_LIBRARY} + ${FFMPEG_PLATFORM_LIBRARIES}) diff --git a/cmake/targets/common.cmake b/cmake/targets/common.cmake new file mode 100644 index 00000000000..8feb42c0031 --- /dev/null +++ b/cmake/targets/common.cmake @@ -0,0 +1,34 @@ +# common target definitions +# this file will also load platform specific macros + +add_executable(sunshine ${SUNSHINE_TARGET_FILES}) + +if(WIN32) + include(${CMAKE_MODULE_PATH}/targets/windows.cmake) +elseif(UNIX) + include(${CMAKE_MODULE_PATH}/targets/unix.cmake) + + if(APPLE) + include(${CMAKE_MODULE_PATH}/targets/macos.cmake) + else() + include(${CMAKE_MODULE_PATH}/targets/linux.cmake) + endif() +endif() + +# todo - is this necessary? ... for anything except linux? +if(NOT DEFINED CMAKE_CUDA_STANDARD) + set(CMAKE_CUDA_STANDARD 17) + set(CMAKE_CUDA_STANDARD_REQUIRED ON) +endif() + +target_link_libraries(sunshine ${SUNSHINE_EXTERNAL_LIBRARIES} ${EXTRA_LIBS}) +target_compile_definitions(sunshine PUBLIC ${SUNSHINE_DEFINITIONS}) +set_target_properties(sunshine PROPERTIES CXX_STANDARD 17 + VERSION ${PROJECT_VERSION} + SOVERSION ${PROJECT_VERSION_MAJOR}) + +foreach(flag IN LISTS SUNSHINE_COMPILE_OPTIONS) + list(APPEND SUNSHINE_COMPILE_OPTIONS_CUDA "$<$:--compiler-options=${flag}>") +endforeach() + +target_compile_options(sunshine PRIVATE $<$:${SUNSHINE_COMPILE_OPTIONS}>;$<$:${SUNSHINE_COMPILE_OPTIONS_CUDA};-std=c++17>) # cmake-lint: disable=C0301 diff --git a/cmake/targets/linux.cmake b/cmake/targets/linux.cmake new file mode 100644 index 00000000000..fa1f33c0752 --- /dev/null +++ b/cmake/targets/linux.cmake @@ -0,0 +1 @@ +# linux specific target definitions diff --git a/cmake/targets/macos.cmake b/cmake/targets/macos.cmake new file mode 100644 index 00000000000..065b85c5d87 --- /dev/null +++ b/cmake/targets/macos.cmake @@ -0,0 +1,4 @@ +# macos specific target definitions +target_link_options(sunshine PRIVATE LINKER:-sectcreate,__TEXT,__info_plist,${APPLE_PLIST_FILE}) +# Tell linker to dynamically load these symbols at runtime, in case they're unavailable: +target_link_options(sunshine PRIVATE -Wl,-U,_CGPreflightScreenCaptureAccess -Wl,-U,_CGRequestScreenCaptureAccess) diff --git a/cmake/targets/unix.cmake b/cmake/targets/unix.cmake new file mode 100644 index 00000000000..047a0b3d381 --- /dev/null +++ b/cmake/targets/unix.cmake @@ -0,0 +1,2 @@ +# unix specific target definitions +# put anything here that applies to both linux and macos diff --git a/cmake/targets/windows.cmake b/cmake/targets/windows.cmake new file mode 100644 index 00000000000..341d7c2e74e --- /dev/null +++ b/cmake/targets/windows.cmake @@ -0,0 +1,6 @@ +# windows specific target definitions +set_target_properties(sunshine PROPERTIES LINK_SEARCH_START_STATIC 1) +set(CMAKE_FIND_LIBRARY_SUFFIXES ".dll") +find_library(ZLIB ZLIB1) +list(APPEND SUNSHINE_EXTERNAL_LIBRARIES + Wtsapi32.lib) diff --git a/docker/archlinux.dockerfile b/docker/archlinux.dockerfile index ce087274caf..8750b9527e1 100644 --- a/docker/archlinux.dockerfile +++ b/docker/archlinux.dockerfile @@ -68,7 +68,7 @@ else sub_version="" fi cmake \ - -DSUNSHINE_CONFIGURE_AUR=ON \ + -DSUNSHINE_CONFIGURE_PKGBUILD=ON \ -DSUNSHINE_SUB_VERSION="${sub_version}" \ -DGITHUB_CLONE_URL="${CLONE_URL}" \ -DGITHUB_COMMIT="${COMMIT}" \ diff --git a/docs/source/about/installation.rst b/docs/source/about/installation.rst index 86262e8fa9f..3d20a020b30 100644 --- a/docs/source/about/installation.rst +++ b/docs/source/about/installation.rst @@ -36,15 +36,15 @@ CUDA is used for NVFBC capture. Package CUDA Version Min Driver CUDA Compute Capabilities =========================================== ============== ============== ================================ PKGBUILD User dependent User dependent User dependent - sunshine.AppImage 11.8.0 450.80.02 50;52;60;61;62;70;75;80;86;90;35 - sunshine.pkg.tar.zst 11.8.0 450.80.02 50;52;60;61;62;70;75;80;86;90;35 + sunshine.AppImage 11.8.0 450.80.02 35;50;52;60;61;62;70;75;80;86;90 + sunshine.pkg.tar.zst 11.8.0 450.80.02 35;50;52;60;61;62;70;75;80;86;90 sunshine_{arch}.flatpak 12.0.0 525.60.13 50;52;60;61;62;70;75;80;86;90 sunshine-debian-bookworm-{arch}.deb 12.0.0 525.60.13 50;52;60;61;62;70;75;80;86;90 - sunshine-debian-bullseye-{arch}.deb 11.8.0 450.80.02 50;52;60;61;62;70;75;80;86;90;35 + sunshine-debian-bullseye-{arch}.deb 11.8.0 450.80.02 35;50;52;60;61;62;70;75;80;86;90 sunshine-fedora-37-{arch}.rpm 12.0.0 525.60.13 50;52;60;61;62;70;75;80;86;90 sunshine-fedora-38-{arch}.rpm unavailable unavailable none - sunshine-ubuntu-20.04-{arch}.deb 11.8.0 450.80.02 50;52;60;61;62;70;75;80;86;90;35 - sunshine-ubuntu-22.04-{arch}.deb 11.8.0 450.80.02 50;52;60;61;62;70;75;80;86;90;35 + sunshine-ubuntu-20.04-{arch}.deb 11.8.0 450.80.02 35;50;52;60;61;62;70;75;80;86;90 + sunshine-ubuntu-22.04-{arch}.deb 11.8.0 450.80.02 35;50;52;60;61;62;70;75;80;86;90 =========================================== ============== ============== ================================ AppImage diff --git a/docs/source/conf.py b/docs/source/conf.py index e581783865f..b5e7131a107 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -27,7 +27,7 @@ author = 'ReenigneArcher' # The full version, including alpha/beta/rc tags -with open(os.path.join(root_dir, 'CMakeLists.txt'), 'r') as f: +with open(os.path.join(root_dir, 'cmake', 'prep', 'base.cmake'), 'r') as f: version = re.search(r"project\(Sunshine VERSION ((\d+)\.(\d+)\.(\d+))", str(f.read())).group(1) """ To use cmake method for obtaining version instead of regex, diff --git a/packaging/linux/aur/PKGBUILD b/packaging/linux/Arch/PKGBUILD similarity index 100% rename from packaging/linux/aur/PKGBUILD rename to packaging/linux/Arch/PKGBUILD diff --git a/packaging/linux/flatpak/dev.lizardbyte.sunshine.yml b/packaging/linux/flatpak/dev.lizardbyte.sunshine.yml index 403c6db01d4..35f9a52c245 100644 --- a/packaging/linux/flatpak/dev.lizardbyte.sunshine.yml +++ b/packaging/linux/flatpak/dev.lizardbyte.sunshine.yml @@ -223,7 +223,7 @@ modules: - -DSUNSHINE_ENABLE_X11=ON - -DSUNSHINE_ENABLE_DRM=ON - -DSUNSHINE_ENABLE_CUDA=ON - - -DSUNSHINE_CONFIGURE_FLATPAK=ON + - -DSUNSHINE_BUILD_FLATPAK=ON sources: - type: git url: "@GITHUB_CLONE_URL@"