diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 2b76e22d64c..ca4a69f35a4 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 @@ -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: diff --git a/CMakeLists.txt b/CMakeLists.txt index 3fa910ef5ed..ffbdff0657a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,567 +1,40 @@ 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() +# basic project configuration +include(${CMAKE_MODULE_PATH}/prep/base.cmake) -add_subdirectory(third-party/moonlight-common-c/enet) -add_subdirectory(third-party/Simple-Web-Server) +# set version info for this build +include(${CMAKE_MODULE_PATH}/prep/build_version.cmake) -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) +# cmake build flags +include(${CMAKE_MODULE_PATH}/prep/options.cmake) -find_package(Threads REQUIRED) -find_package(OpenSSL REQUIRED) -find_package(PkgConfig REQUIRED) -pkg_check_modules(CURL REQUIRED libcurl) +# configure special package files, such as sunshine.desktop, Flatpak manifest, Portfile , etc. +include(${CMAKE_MODULE_PATH}/prep/special_package_configuration.cmake) -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) +# Exit if END_BUILD is ON +if(${END_BUILD}) + return() 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") +# project constants +include(${CMAKE_MODULE_PATH}/prep/constants.cmake) - option(SUNSHINE_MACOS_PACKAGE "Should only be used when creating a MACOS package/dmg." OFF) +# load macros +include(${CMAKE_MODULE_PATH}/macros/common.cmake) - link_directories(/opt/local/lib) - link_directories(/usr/local/lib) - ADD_DEFINITIONS(-DBOOST_LOG_DYN_LINK) +# load submodules +include(${CMAKE_MODULE_PATH}/submodules/include_submodules.cmake) - 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}) - - 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}) -else() - add_compile_definitions(SUNSHINE_PLATFORM="linux") - - 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() +# load dependencies +include(${CMAKE_MODULE_PATH}/dependencies/common.cmake) -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}) +# setup compile definitions +include(${CMAKE_MODULE_PATH}/compile_definitions/common.cmake) # Pre-compiled binaries if(WIN32) @@ -631,7 +104,7 @@ if(UNIX) endif() # use relative assets path for AppImage... maybe for all unix -if(${SUNSHINE_CONFIGURE_APPIMAGE}) +if(${SUNSHINE_BUILD_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}") @@ -867,7 +340,7 @@ if(APPLE) set(CPACK_BUNDLE_ICON "${PROJECT_SOURCE_DIR}/sunshine.icns") # set(CPACK_BUNDLE_STARTUP_COMMAND "${INSTALL_RUNTIME_DIR}/sunshine") endif() -if(APPLE AND SUNSHINE_MACOS_PACKAGE) # TODO +if(APPLE AND SUNSHINE_PACKAGE_MACOS) # TODO set(MAC_PREFIX "${CMAKE_PROJECT_NAME}.app/Contents") set(INSTALL_RUNTIME_DIR "${MAC_PREFIX}/MacOS") @@ -899,7 +372,7 @@ elseif(UNIX) else() install(DIRECTORY "${SUNSHINE_SOURCE_ASSETS_DIR}/linux/assets/" DESTINATION "${SUNSHINE_ASSETS_DIR}") - if(${SUNSHINE_CONFIGURE_APPIMAGE} OR ${SUNSHINE_CONFIGURE_FLATPAK}) + 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" diff --git a/cmake/compile_definitions/common.cmake b/cmake/compile_definitions/common.cmake new file mode 100644 index 00000000000..792c12e70dd --- /dev/null +++ b/cmake/compile_definitions/common.cmake @@ -0,0 +1,86 @@ +# 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 + +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}) 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..2d0f9d03584 --- /dev/null +++ b/cmake/compile_definitions/unix.cmake @@ -0,0 +1,2 @@ +# unix specific compile definitions +# put anything here that applies to both linux and macos 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..c8d73046e2b --- /dev/null +++ b/cmake/dependencies/common.cmake @@ -0,0 +1,20 @@ +# 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) + +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..fa7d0f43a5c --- /dev/null +++ b/cmake/macros/common.cmake @@ -0,0 +1,14 @@ +# common macros +# this file will also load 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/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..356beeee77b --- /dev/null +++ b/cmake/submodules/include_submodules.cmake @@ -0,0 +1,13 @@ +# 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) 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/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@"