From cacadc4df426e42273bcf4ad37758220faf2201f Mon Sep 17 00:00:00 2001 From: ReenigneArcher <42013603+ReenigneArcher@users.noreply.github.com> Date: Mon, 4 Mar 2024 22:15:37 -0500 Subject: [PATCH 01/33] build(linux): ensure pre-compiled arch pkg is not debug build (#2214) --- docker/archlinux.dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/docker/archlinux.dockerfile b/docker/archlinux.dockerfile index 15cb5d23685..bd853ad395d 100644 --- a/docker/archlinux.dockerfile +++ b/docker/archlinux.dockerfile @@ -87,6 +87,7 @@ RUN <<_PKGBUILD set -e namcap -i PKGBUILD makepkg -si --noconfirm +rm -f /build/sunshine/pkg/sunshine-debug*.pkg.tar.zst ls -a _PKGBUILD From 9f94eebd32f148120389ebd3246829ee7e7bd66e Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Mon, 4 Mar 2024 18:43:16 -0600 Subject: [PATCH 02/33] Fix mismatched case and unhandled exception in open_drm_fd_for_cuda_device() --- src/platform/linux/cuda.cpp | 43 ++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/src/platform/linux/cuda.cpp b/src/platform/linux/cuda.cpp index 5b121c70691..33c939243f2 100644 --- a/src/platform/linux/cuda.cpp +++ b/src/platform/linux/cuda.cpp @@ -247,29 +247,38 @@ namespace cuda { // There's no way to directly go from CUDA to a DRM device, so we'll // use sysfs to look up the DRM device name from the PCI ID. - char pci_bus_id[13]; - CU_CHECK(cdf->cuDeviceGetPCIBusId(pci_bus_id, sizeof(pci_bus_id), device), "Couldn't get CUDA device PCI bus ID"); - BOOST_LOG(debug) << "Found CUDA device with PCI bus ID: "sv << pci_bus_id; + std::array pci_bus_id; + CU_CHECK(cdf->cuDeviceGetPCIBusId(pci_bus_id.data(), pci_bus_id.size(), device), "Couldn't get CUDA device PCI bus ID"); + BOOST_LOG(debug) << "Found CUDA device with PCI bus ID: "sv << pci_bus_id.data(); + + // Linux uses lowercase hexadecimal while CUDA uses uppercase + std::transform(pci_bus_id.begin(), pci_bus_id.end(), pci_bus_id.begin(), + [](char c) { return std::tolower(c); }); // Look for the name of the primary node in sysfs - char sysfs_path[PATH_MAX]; - std::snprintf(sysfs_path, sizeof(sysfs_path), "/sys/bus/pci/devices/%s/drm", pci_bus_id); - fs::path sysfs_dir { sysfs_path }; - for (auto &entry : fs::directory_iterator { sysfs_dir }) { - auto file = entry.path().filename(); - auto filestring = file.generic_u8string(); - if (std::string_view { filestring }.substr(0, 4) != "card"sv) { - continue; - } + try { + char sysfs_path[PATH_MAX]; + std::snprintf(sysfs_path, sizeof(sysfs_path), "/sys/bus/pci/devices/%s/drm", pci_bus_id.data()); + fs::path sysfs_dir { sysfs_path }; + for (auto &entry : fs::directory_iterator { sysfs_dir }) { + auto file = entry.path().filename(); + auto filestring = file.generic_u8string(); + if (std::string_view { filestring }.substr(0, 4) != "card"sv) { + continue; + } - BOOST_LOG(debug) << "Found DRM primary node: "sv << filestring; + BOOST_LOG(debug) << "Found DRM primary node: "sv << filestring; - fs::path dri_path { "/dev/dri"sv }; - auto device_path = dri_path / file; - return open(device_path.c_str(), O_RDWR); + fs::path dri_path { "/dev/dri"sv }; + auto device_path = dri_path / file; + return open(device_path.c_str(), O_RDWR); + } + } + catch (const std::filesystem::filesystem_error &err) { + BOOST_LOG(error) << "Failed to read sysfs: "sv << err.what(); } - BOOST_LOG(error) << "Unable to find DRM device with PCI bus ID: "sv << pci_bus_id; + BOOST_LOG(error) << "Unable to find DRM device with PCI bus ID: "sv << pci_bus_id.data(); return -1; } From 4ebc7b5cef0884cae5076a8f79d96a3859bea9e8 Mon Sep 17 00:00:00 2001 From: ReenigneArcher <42013603+ReenigneArcher@users.noreply.github.com> Date: Tue, 5 Mar 2024 08:56:09 -0500 Subject: [PATCH 03/33] build(macos): add build strategy matrix (#2211) --- .github/workflows/CI.yml | 69 ++++++++++++++++++++++++---------- README.rst | 4 +- docs/source/about/setup.rst | 4 +- docs/source/building/macos.rst | 20 ++++++++-- src/main.cpp | 3 ++ 5 files changed, 73 insertions(+), 27 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 60f555c2166..06d5a5e5d02 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -506,11 +506,23 @@ jobs: prerelease: ${{ needs.setup_release.outputs.pre_release }} build_mac: - name: MacOS - runs-on: macos-11 needs: [check_changelog, setup_release] env: BOOST_VERSION: 1.83.0 + strategy: + fail-fast: false # false to test all, true to fail entire job if any fail + matrix: + include: + # https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners/about-github-hosted-runners#standard-github-hosted-runners-for-public-repositories + # while GitHub has larger macOS runners, they are not available for our repos :( + - os_version: "12" + arch: "x86_64" + - os_version: "13" + arch: "x86_64" + - os_version: "14" + arch: "arm64" + name: macOS-${{ matrix.os_version }} ${{ matrix.arch }} + runs-on: macos-${{ matrix.os_version }} steps: - name: Checkout @@ -520,24 +532,32 @@ jobs: - name: Setup Dependencies MacOS run: | + if [[ ${{ matrix.arch }} == "arm64" ]]; then + brew_prefix="/opt/homebrew" + else + brew_prefix="/usr/local" + fi + # install dependencies using homebrew brew install cmake curl miniupnpc node openssl opus pkg-config # fix openssl header not found - # ln -sf /usr/local/opt/openssl/include/openssl /usr/local/include/openssl - - # by installing boost from source, several headers cannot be found... - # the above commented out link only works if boost is installed from homebrew... does not make sense - ln -sf $(find /usr/local/Cellar -type d -name "openssl" -path "*/openssl@3/*/include" | head -n 1) \ - /usr/local/include/openssl + openssl_path=$(find ${brew_prefix}/Cellar -type d -name "openssl" -path "*/openssl@3/*/include" | head -n 1) + echo "OpenSSL path: $openssl_path" + ln -sf $openssl_path ${brew_prefix}/include/openssl + ls -l ${brew_prefix}/include/openssl # fix opus header not found - ln -sf $(find /usr/local/Cellar -type d -name "opus" -path "*/opus/*/include" | head -n 1) \ - /usr/local/include/opus + opus_path=$(find ${brew_prefix}/Cellar -type d -name "opus" -path "*/opus/*/include" | head -n 1) + echo "Opus path: $opus_path" + ln -sf $opus_path ${brew_prefix}/include/opus + ls -l ${brew_prefix}/include/opus # fix miniupnpc header not found - ln -sf $(find /usr/local/Cellar -type d -name "miniupnpc" -path "*/miniupnpc/*/include" | head -n 1) \ - /usr/local/include/miniupnpc + upnp_path=$(find ${brew_prefix}/Cellar -type d -name "miniupnpc" -path "*/miniupnpc/*/include" | head -n 1) + echo "Miniupnpc path: $upnp_path" + ln -sf $upnp_path ${brew_prefix}/include/miniupnpc + ls -l ${brew_prefix}/include/miniupnpc - name: Install Boost # installing boost from homebrew takes 30 minutes in a GitHub runner @@ -594,15 +614,13 @@ jobs: # package cpack -G DragNDrop - mv ./cpack_artifacts/Sunshine.dmg ../artifacts/sunshine.dmg - - # cpack -G Bundle - # mv ./cpack_artifacts/Sunshine.dmg ../artifacts/sunshine-bundle.dmg + mv ./cpack_artifacts/Sunshine.dmg \ + ../artifacts/sunshine-macos-${{ matrix.os_version }}-${{ matrix.arch }}.dmg - name: Upload Artifacts uses: actions/upload-artifact@v4 with: - name: sunshine-macos + name: sunshine-macos-${{ matrix.os_version }}-${{ matrix.arch }} path: artifacts/ - name: Create/Update GitHub Release @@ -620,9 +638,19 @@ jobs: prerelease: ${{ needs.setup_release.outputs.pre_release }} build_mac_port: - name: Macports needs: [check_changelog, setup_release] - runs-on: macos-11 + strategy: + fail-fast: false # false to test all, true to fail entire job if any fail + matrix: + include: + # https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners/about-github-hosted-runners#standard-github-hosted-runners-for-public-repositories + # while GitHub has larger macOS runners, they are not available for our repos :( + - os_version: "12" + release: true + - os_version: "13" + - os_version: "14" + name: Macports (macOS-${{ matrix.os_version }}) + runs-on: macos-${{ matrix.os_version }} steps: - name: Checkout @@ -725,13 +753,14 @@ jobs: echo "::endgroup::" - name: Upload Artifacts + if: ${{ matrix.release == 'true' }} uses: actions/upload-artifact@v4 with: name: sunshine-macports path: artifacts/ - name: Create/Update GitHub Release - if: ${{ needs.setup_release.outputs.create_release == 'true' }} + if: ${{ needs.setup_release.outputs.create_release == 'true' && matrix.release == 'true' }} uses: ncipollo/release-action@v1 with: name: ${{ needs.setup_release.outputs.release_name }} diff --git a/README.rst b/README.rst index fbc78658668..11508d976e3 100644 --- a/README.rst +++ b/README.rst @@ -32,11 +32,11 @@ System Requirements +------------+------------------------------------------------------------+ | OS | Windows: 10+ (Windows Server not supported) | | +------------------------------------------------------------+ -| | macOS: 11.7+ | +| | macOS: 12+ | | +------------------------------------------------------------+ | | Linux/Debian: 11 (bullseye) | | +------------------------------------------------------------+ -| | Linux/Fedora: 37+ | +| | Linux/Fedora: 38+ | | +------------------------------------------------------------+ | | Linux/Ubuntu: 20.04+ (focal) | +------------+------------------------------------------------------------+ diff --git a/docs/source/about/setup.rst b/docs/source/about/setup.rst index 8a280fcf644..2457ccc59e9 100644 --- a/docs/source/about/setup.rst +++ b/docs/source/about/setup.rst @@ -281,14 +281,14 @@ Install .. tab:: macOS - .. important:: Sunshine on macOS is experimental. Gamepads do not work. Other features may not work as expected. + .. important:: Sunshine on macOS is experimental. Gamepads do not work. .. tab:: dmg .. warning:: The `dmg` does not include runtime dependencies. This package is not recommended for most users. No support will be provided! - #. Download the ``sunshine.dmg`` file and install it. + #. Download the ``sunshine--.dmg`` file and install it. Uninstall: .. code-block:: bash diff --git a/docs/source/building/macos.rst b/docs/source/building/macos.rst index c14751c28f8..bf96fb394f9 100644 --- a/docs/source/building/macos.rst +++ b/docs/source/building/macos.rst @@ -20,9 +20,23 @@ Install Requirements .. code-block:: bash brew install boost cmake miniupnpc node opus pkg-config - # if there are issues with an SSL header that is not found: - cd /usr/local/include - ln -s ../opt/openssl/include/openssl . + +If there are issues with an SSL header that is not found: + .. tab:: Intel + + .. code-block:: bash + + pushd /usr/local/include + ln -s ../opt/openssl/include/openssl . + popd + + .. tab:: Apple Silicon + + .. code-block:: bash + + pushd /opt/homebrew/include + ln -s ../opt/openssl/include/openssl . + popd Build ----- diff --git a/src/main.cpp b/src/main.cpp index 5cc28f9f2a2..a3901448680 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -106,8 +106,11 @@ main(int argc, char *argv[]) { setlocale(LC_ALL, ".UTF-8"); #endif +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" // Use UTF-8 conversion for the default C++ locale (used by boost::log) std::locale::global(std::locale(std::locale(), new std::codecvt_utf8)); +#pragma GCC diagnostic pop mail::man = std::make_shared(); From b99a9e92becb5e2b56e0555093d81b8aa8712f6e Mon Sep 17 00:00:00 2001 From: ReenigneArcher <42013603+ReenigneArcher@users.noreply.github.com> Date: Tue, 5 Mar 2024 18:18:17 -0500 Subject: [PATCH 04/33] build(macos): fix publishing of portfile (#2220) --- .github/workflows/CI.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 06d5a5e5d02..c2d97440e22 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -753,14 +753,14 @@ jobs: echo "::endgroup::" - name: Upload Artifacts - if: ${{ matrix.release == 'true' }} + if: ${{ matrix.release }} uses: actions/upload-artifact@v4 with: name: sunshine-macports path: artifacts/ - name: Create/Update GitHub Release - if: ${{ needs.setup_release.outputs.create_release == 'true' && matrix.release == 'true' }} + if: ${{ needs.setup_release.outputs.create_release == 'true' && matrix.release }} uses: ncipollo/release-action@v1 with: name: ${{ needs.setup_release.outputs.release_name }} From 3f215968ad61864063b1a84025e7ce74f6c1e553 Mon Sep 17 00:00:00 2001 From: ReenigneArcher <42013603+ReenigneArcher@users.noreply.github.com> Date: Tue, 5 Mar 2024 23:00:51 -0500 Subject: [PATCH 05/33] fix(config): add missing resolution to default config ui (#2224) --- src_assets/common/assets/web/config.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src_assets/common/assets/web/config.html b/src_assets/common/assets/web/config.html index a072e101ba0..e7d47e4d852 100644 --- a/src_assets/common/assets/web/config.html +++ b/src_assets/common/assets/web/config.html @@ -1234,7 +1234,7 @@

"install_steam_audio_drivers": "enabled", "adapter_name": "", "output_name": "", - "resolutions": "[352x240,480x360,858x480,1280x720,1920x1080,2560x1080,3440x1440,1920x1200,3840x2160,3840x1600]", + "resolutions": "[352x240,480x360,858x480,1280x720,1920x1080,2560x1080,2560x1440,3440x1440,1920x1200,3840x2160,3840x1600]", "fps": "[10,30,60,90,120]", }, }, From 9e299c295dc94ca6f1d813f1b974e40de901f369 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Tue, 5 Mar 2024 22:32:06 -0600 Subject: [PATCH 06/33] Fix predefined FPS values not taking effect --- src/config.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/config.cpp b/src/config.cpp index ba2718aca7f..21562f83487 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -849,6 +849,11 @@ namespace config { std::vector list; list_string_f(vars, name, list); + // check if list is empty, i.e. when the value doesn't exist in the config file + if (list.empty()) { + return; + } + // The framerate list must be cleared before adding values from the file configuration. // If the list is not cleared, then the specified parameters do not affect the behavior of the sunshine server. // That is, if you set only 30 fps in the configuration file, it will not work because by default, during initialization the list includes 10, 30, 60, 90 and 120 fps. From c86a4e112be4d1a396e561619ea78f1d01a407b0 Mon Sep 17 00:00:00 2001 From: detiam <44510779+detiam@users.noreply.github.com> Date: Wed, 6 Mar 2024 23:23:32 +0800 Subject: [PATCH 07/33] Fix wrong path in desktop file (#2223) Co-authored-by: ReenigneArcher <42013603+ReenigneArcher@users.noreply.github.com> --- cmake/packaging/unix.cmake | 2 -- cmake/prep/special_package_configuration.cmake | 2 ++ packaging/linux/flatpak/sunshine.desktop | 4 ++-- packaging/linux/sunshine.desktop | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/cmake/packaging/unix.cmake b/cmake/packaging/unix.cmake index d6a4ae93575..bacbfc910de 100644 --- a/cmake/packaging/unix.cmake +++ b/cmake/packaging/unix.cmake @@ -1,8 +1,6 @@ # unix specific packaging # put anything here that applies to both linux and macos -include(GNUInstallDirs) - # return here if building a macos package if(SUNSHINE_PACKAGE_MACOS) return() diff --git a/cmake/prep/special_package_configuration.cmake b/cmake/prep/special_package_configuration.cmake index 3094c2399a5..a5a780f5563 100644 --- a/cmake/prep/special_package_configuration.cmake +++ b/cmake/prep/special_package_configuration.cmake @@ -3,6 +3,8 @@ if (APPLE) configure_file(packaging/macos/Portfile Portfile @ONLY) endif() elseif (UNIX) + include(GNUInstallDirs) # this needs to be included prior to configuring the desktop files + # configure the .desktop file if(${SUNSHINE_BUILD_APPIMAGE}) configure_file(packaging/linux/AppImage/sunshine.desktop sunshine.desktop @ONLY) diff --git a/packaging/linux/flatpak/sunshine.desktop b/packaging/linux/flatpak/sunshine.desktop index be702701e08..1c5fe13a409 100644 --- a/packaging/linux/flatpak/sunshine.desktop +++ b/packaging/linux/flatpak/sunshine.desktop @@ -12,9 +12,9 @@ Actions=RunInTerminal;KMS; [Desktop Action RunInTerminal] Name=Run in Terminal Icon=application-x-executable -Exec=gio launch @CMAKE_INSTALL_DATAROOTDIR@/applications/sunshine_terminal.desktop +Exec=gio launch @CMAKE_INSTALL_FULL_DATAROOTDIR@/applications/sunshine_terminal.desktop [Desktop Action KMS] Name=Run in Terminal (KMS) Icon=application-x-executable -Exec=gio launch @CMAKE_INSTALL_DATAROOTDIR@/applications/sunshine_kms.desktop +Exec=gio launch @CMAKE_INSTALL_FULL_DATAROOTDIR@/applications/sunshine_kms.desktop diff --git a/packaging/linux/sunshine.desktop b/packaging/linux/sunshine.desktop index b0f2ce327ec..719555301d5 100644 --- a/packaging/linux/sunshine.desktop +++ b/packaging/linux/sunshine.desktop @@ -12,4 +12,4 @@ Actions=RunInTerminal; [Desktop Action RunInTerminal] Name=Run in Terminal Icon=application-x-executable -Exec=gio launch @CMAKE_INSTALL_DATAROOTDIR@/applications/sunshine_terminal.desktop +Exec=gio launch @CMAKE_INSTALL_FULL_DATAROOTDIR@/applications/sunshine_terminal.desktop From 3b3e6818f31858eaa6413c8e832dc803eeb48157 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Tue, 5 Mar 2024 22:57:28 -0600 Subject: [PATCH 08/33] Make debuginfo artifacts harder to confuse with the Windows portable build --- .github/workflows/CI.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index c2d97440e22..6b1eb296b47 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -843,11 +843,15 @@ jobs: - name: Package Windows Debug Info working-directory: build run: | - # save the original binaries with debug info + # use .dbg file extension for binaries to avoid confusion with real packages + Get-ChildItem -File -Recurse | ` + % { Rename-Item -Path $_.PSPath -NewName $_.Name.Replace(".exe",".dbg") } + + # save the binaries with debug info 7z -r ` "-xr!CMakeFiles" ` "-xr!cpack_artifacts" ` - a "../artifacts/sunshine-debuginfo-win32.zip" "*.exe" + a "../artifacts/sunshine-win32-debuginfo.7z" "*.dbg" - name: Upload Artifacts uses: actions/upload-artifact@v4 From 6aeaaf5ec9df4c278c1a8126a2dfbc748d000d76 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Wed, 6 Mar 2024 19:18:12 -0600 Subject: [PATCH 09/33] Fix process tree tracking when the cmd.exe trampoline is used --- src/platform/windows/misc.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/platform/windows/misc.cpp b/src/platform/windows/misc.cpp index 77de69f4cd3..98065e3201a 100644 --- a/src/platform/windows/misc.cpp +++ b/src/platform/windows/misc.cpp @@ -681,10 +681,11 @@ namespace platf { * @param raw_cmd The raw command provided by the user. * @param working_dir The working directory for the new process. * @param token The user token currently being impersonated or `NULL` if running as ourselves. + * @param creation_flags The creation flags for CreateProcess(), which may be modified by this function. * @return A command string suitable for use by CreateProcess(). */ std::wstring - resolve_command_string(const std::string &raw_cmd, const std::wstring &working_dir, HANDLE token) { + resolve_command_string(const std::string &raw_cmd, const std::wstring &working_dir, HANDLE token, DWORD &creation_flags) { std::wstring raw_cmd_w = from_utf8(raw_cmd); // First, convert the given command into parts so we can get the executable/file/URL without parameters @@ -757,8 +758,13 @@ namespace platf { // FIXME: Maybe we can improve this in the future. if (res == HRESULT_FROM_WIN32(ERROR_NO_ASSOCIATION)) { BOOST_LOG(warning) << "Using trampoline to handle target: "sv << raw_cmd; - std::wcscpy(shell_command_string.data(), L"cmd.exe /c start \"\" \"%1\" %*"); + std::wcscpy(shell_command_string.data(), L"cmd.exe /c start \"\" /wait \"%1\" %*"); needs_cmd_escaping = true; + + // We must suppress the console window that would otherwise appear when starting cmd.exe. + creation_flags &= ~CREATE_NEW_CONSOLE; + creation_flags |= CREATE_NO_WINDOW; + res = S_OK; } @@ -951,7 +957,7 @@ namespace platf { // Open the process as the current user account, elevation is handled in the token itself. ec = impersonate_current_user(user_token, [&]() { std::wstring env_block = create_environment_block(cloned_env); - std::wstring wcmd = resolve_command_string(cmd, start_dir, user_token); + std::wstring wcmd = resolve_command_string(cmd, start_dir, user_token, creation_flags); ret = CreateProcessAsUserW(user_token, NULL, (LPWSTR) wcmd.c_str(), @@ -985,7 +991,7 @@ namespace platf { } std::wstring env_block = create_environment_block(cloned_env); - std::wstring wcmd = resolve_command_string(cmd, start_dir, NULL); + std::wstring wcmd = resolve_command_string(cmd, start_dir, NULL, creation_flags); ret = CreateProcessW(NULL, (LPWSTR) wcmd.c_str(), NULL, From 972e5d2b145d2e927f4f94c3dc36b777f9d1b650 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Wed, 6 Mar 2024 19:45:49 -0600 Subject: [PATCH 10/33] Strip quotes out of the working directory path --- src/process.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/process.cpp b/src/process.cpp index 804291577c2..89dc4dc5ae5 100644 --- a/src/process.cpp +++ b/src/process.cpp @@ -664,6 +664,12 @@ namespace proc { if (working_dir) { ctx.working_dir = parse_env_val(this_env, *working_dir); +#ifdef _WIN32 + // The working directory, unlike the command itself, should not be quoted + // when it contains spaces. Unlike POSIX, Windows forbids quotes in paths, + // so we can safely strip them all out here to avoid confusing the user. + boost::erase_all(ctx.working_dir, "\""); +#endif } if (image_path) { From 06c0ed1d1cb5a80c6f0a6fe8d7a3fd8a77580adc Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Wed, 6 Mar 2024 20:54:27 -0600 Subject: [PATCH 11/33] Temporarily add the working directory to our path when starting an app CreateProcess() doesn't search in the child's specified working directory by default. --- src/platform/windows/misc.cpp | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/platform/windows/misc.cpp b/src/platform/windows/misc.cpp index 98065e3201a..e7bb64e52b8 100644 --- a/src/platform/windows/misc.cpp +++ b/src/platform/windows/misc.cpp @@ -933,6 +933,31 @@ namespace platf { // Create a new console for interactive processes and use no console for non-interactive processes creation_flags |= interactive ? CREATE_NEW_CONSOLE : CREATE_NO_WINDOW; + // Find the PATH variable in our environment block using a case-insensitive search + auto sunshine_wenv = boost::this_process::wenvironment(); + std::wstring path_var_name { L"PATH" }; + std::wstring old_path_val; + auto itr = std::find_if(sunshine_wenv.cbegin(), sunshine_wenv.cend(), [&](const auto &e) { return boost::iequals(e.get_name(), path_var_name); }); + if (itr != sunshine_wenv.cend()) { + // Use the existing variable if it exists, since Boost treats these as case-sensitive. + path_var_name = itr->get_name(); + old_path_val = sunshine_wenv[path_var_name].to_string(); + } + + // Temporarily prepend the specified working directory to PATH to ensure CreateProcess() + // will (preferentially) find binaries that reside in the working directory. + sunshine_wenv[path_var_name].assign(start_dir + L";" + old_path_val); + + // Restore the old PATH value for our process when we're done here + auto restore_path = util::fail_guard([&]() { + if (old_path_val.empty()) { + sunshine_wenv[path_var_name].clear(); + } + else { + sunshine_wenv[path_var_name].assign(old_path_val); + } + }); + BOOL ret; if (is_running_as_system()) { // Duplicate the current user's token From f5dd0d4eafbd34a540c77c73c9cab1d05b99b0f8 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Wed, 6 Mar 2024 20:55:00 -0600 Subject: [PATCH 12/33] Update app examples to clarify new command syntax for Windows --- docs/source/about/guides/app_examples.rst | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/source/about/guides/app_examples.rst b/docs/source/about/guides/app_examples.rst index ca834e4a4f2..8bca2bd89f0 100644 --- a/docs/source/about/guides/app_examples.rst +++ b/docs/source/about/guides/app_examples.rst @@ -6,6 +6,8 @@ and applications to Sunshine. .. attention:: Throughout these examples, any fields not shown are left blank. You can enhance your experience by adding an image or a log file (via the ``Output`` field). +.. note:: When a working directory is not specified, it defaults to the folder where the target application resides. + Common Examples --------------- @@ -24,7 +26,7 @@ Steam Big Picture ^^^^^^^^^^^^^^^^^ .. note:: Steam is launched as a detached command because Steam starts with a process that self updates itself and the original - process is killed. Since the original process ends it will not work as a regular command. + process is killed. .. tab:: Linux @@ -51,7 +53,7 @@ Steam Big Picture +----------------------+-----------------------------+ | Application Name | ``Steam Big Picture`` | +----------------------+-----------------------------+ - | Detached Commands | ``steam://open/bigpicture`` | + | Command | ``steam://open/bigpicture`` | +----------------------+-----------------------------+ | Image | ``steam.png`` | +----------------------+-----------------------------+ @@ -59,8 +61,7 @@ Steam Big Picture Epic Game Store game ^^^^^^^^^^^^^^^^^^^^ -.. note:: Using URI method will be the most consistent between various games, but does not allow a game to be launched - using the "Command" and therefore the stream will not end when the game ends. +.. note:: Using URI method will be the most consistent between various games. URI (Epic) """""""""" @@ -70,7 +71,7 @@ URI (Epic) +----------------------+--------------------------------------------------------------------------------------------------------------------------------------------+ | Application Name | ``Surviving Mars`` | +----------------------+--------------------------------------------------------------------------------------------------------------------------------------------+ - | Detached Commands | ``com.epicgames.launcher://apps/d759128018124dcabb1fbee9bb28e178%3A20729b9176c241f0b617c5723e70ec2d%3AOvenbird?action=launch&silent=true`` | + | Command | ``com.epicgames.launcher://apps/d759128018124dcabb1fbee9bb28e178%3A20729b9176c241f0b617c5723e70ec2d%3AOvenbird?action=launch&silent=true`` | +----------------------+--------------------------------------------------------------------------------------------------------------------------------------------+ Binary (Epic w/ working directory) @@ -81,7 +82,7 @@ Binary (Epic w/ working directory) +----------------------+-----------------------------------------------+ | Application Name | ``Surviving Mars`` | +----------------------+-----------------------------------------------+ - | Command | ``cmd /c "MarsEpic.exe"`` | + | Command | ``MarsEpic.exe`` | +----------------------+-----------------------------------------------+ | Working Directory | ``C:\Program Files\Epic Games\SurvivingMars`` | +----------------------+-----------------------------------------------+ @@ -100,8 +101,7 @@ Binary (Epic w/o working directory) Steam game ^^^^^^^^^^ -.. note:: Using URI method will be the most consistent between various games, but does not allow a game to be launched - using the "Command" and therefore the stream will not end when the game ends. +.. note:: Using URI method will be the most consistent between various games. URI (Steam) """"""""""" @@ -127,7 +127,7 @@ URI (Steam) +----------------------+------------------------------+ | Application Name | ``Surviving Mars`` | +----------------------+------------------------------+ - | Detached Commands | ``steam://rungameid/464920`` | + | Command | ``steam://rungameid/464920`` | +----------------------+------------------------------+ Binary (Steam w/ working directory) From 7cdd156bcecda18d83237b7b8ff537ac10a8c0ba Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Thu, 7 Mar 2024 00:59:40 -0600 Subject: [PATCH 13/33] Fix heap corruption with cursor pixel counts that aren't divisible by 8 --- src/platform/windows/display_vram.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/platform/windows/display_vram.cpp b/src/platform/windows/display_vram.cpp index a56869eab40..1baa1282bb9 100644 --- a/src/platform/windows/display_vram.cpp +++ b/src/platform/windows/display_vram.cpp @@ -234,7 +234,7 @@ namespace platf::dxgi { auto xor_mask = std::begin(img_data) + bytes; for (auto x = 0; x < bytes; ++x) { - for (auto c = 7; c >= 0; --c) { + for (auto c = 7; c >= 0 && ((std::uint8_t *) pixel_data) != std::end(cursor_img); --c) { auto bit = 1 << c; auto color_type = ((*and_mask & bit) ? 1 : 0) + ((*xor_mask & bit) ? 2 : 0); @@ -307,7 +307,7 @@ namespace platf::dxgi { auto xor_mask = std::begin(img_data) + bytes; for (auto x = 0; x < bytes; ++x) { - for (auto c = 7; c >= 0; --c) { + for (auto c = 7; c >= 0 && ((std::uint8_t *) pixel_data) != std::end(cursor_img); --c) { auto bit = 1 << c; auto color_type = ((*and_mask & bit) ? 1 : 0) + ((*xor_mask & bit) ? 2 : 0); From ce3b62598317caf605385e1a9061b95edf889196 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Fri, 8 Mar 2024 17:26:43 -0600 Subject: [PATCH 14/33] Fix undefined behavior when computing cursor end pointer --- src/platform/linux/kmsgrab.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/platform/linux/kmsgrab.cpp b/src/platform/linux/kmsgrab.cpp index cd622fa775c..a7a3256d433 100644 --- a/src/platform/linux/kmsgrab.cpp +++ b/src/platform/linux/kmsgrab.cpp @@ -1240,8 +1240,13 @@ namespace platf { auto delta_width = std::min(captured_cursor.src_w, std::max(0, screen_width - cursor_x)) - cursor_delta_x; for (auto y = 0; y < delta_height; ++y) { // Offset into the cursor image to skip drawing the parts of the cursor image that are off screen - auto cursor_begin = (uint32_t *) &captured_cursor.pixels[((y + cursor_delta_y) * captured_cursor.src_w + cursor_delta_x) * 4]; - auto cursor_end = (uint32_t *) &captured_cursor.pixels[((y + cursor_delta_y) * captured_cursor.src_w + delta_width + cursor_delta_x) * 4]; + // + // NB: We must access the elements via the data() function because cursor_end may point to the + // the first element beyond the valid range of the vector. Using vector's [] operator in that + // manner is undefined behavior (and triggers errors when using debug libc++), while doing the + // same with an array is fine. + auto cursor_begin = (uint32_t *) &captured_cursor.pixels.data()[((y + cursor_delta_y) * captured_cursor.src_w + cursor_delta_x) * 4]; + auto cursor_end = (uint32_t *) &captured_cursor.pixels.data()[((y + cursor_delta_y) * captured_cursor.src_w + delta_width + cursor_delta_x) * 4]; auto pixels_begin = &pixels[(y + cursor_y) * (img.row_pitch / img.pixel_pitch) + cursor_x]; From 33e99e1feb02299ac907c12fedf9d8d36cae775c Mon Sep 17 00:00:00 2001 From: ReenigneArcher <42013603+ReenigneArcher@users.noreply.github.com> Date: Sat, 9 Mar 2024 10:47:55 -0500 Subject: [PATCH 15/33] build(macos)!: add homebrew formula and drop dmg (#2222) --- .github/workflows/CI.yml | 155 +++++++----------- CMakeLists.txt | 2 +- cmake/prep/options.cmake | 8 + .../prep/special_package_configuration.cmake | 3 + cmake/targets/common.cmake | 13 +- docs/source/about/setup.rst | 13 +- packaging/macos/sunshine.rb | 62 +++++++ src_assets/macos/misc/uninstall_pkg.sh | 3 + vite.config.js | 17 +- 9 files changed, 162 insertions(+), 114 deletions(-) create mode 100644 packaging/macos/sunshine.rb diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 6b1eb296b47..f2529e7390e 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -505,10 +505,8 @@ jobs: discussionCategory: announcements prerelease: ${{ needs.setup_release.outputs.pre_release }} - build_mac: + build_mac_brew: needs: [check_changelog, setup_release] - env: - BOOST_VERSION: 1.83.0 strategy: fail-fast: false # false to test all, true to fail entire job if any fail matrix: @@ -516,126 +514,87 @@ jobs: # https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners/about-github-hosted-runners#standard-github-hosted-runners-for-public-repositories # while GitHub has larger macOS runners, they are not available for our repos :( - os_version: "12" - arch: "x86_64" + release: true - os_version: "13" - arch: "x86_64" - os_version: "14" - arch: "arm64" - name: macOS-${{ matrix.os_version }} ${{ matrix.arch }} + name: Homebrew (macOS-${{ matrix.os_version }}) runs-on: macos-${{ matrix.os_version }} steps: - name: Checkout uses: actions/checkout@v4 - with: - submodules: recursive - - name: Setup Dependencies MacOS + - name: Setup Dependencies Homebrew + run: | + # install dependencies using homebrew + brew install cmake + + - name: Configure formula run: | - if [[ ${{ matrix.arch }} == "arm64" ]]; then - brew_prefix="/opt/homebrew" + # variables for formula + branch=${GITHUB_HEAD_REF} + + # check the branch variable + if [ -z "$branch" ] + then + echo "This is a PUSH event" + clone_url=${{ github.event.repository.clone_url }} + branch="${{ github.ref_name }}" else - brew_prefix="/usr/local" + echo "This is a PR event" + clone_url=${{ github.event.pull_request.head.repo.clone_url }} + branch="${{ github.event.pull_request.head.ref }}" fi + echo "Branch: ${branch}" + echo "Clone URL: ${clone_url}" - # install dependencies using homebrew - brew install cmake curl miniupnpc node openssl opus pkg-config - - # fix openssl header not found - openssl_path=$(find ${brew_prefix}/Cellar -type d -name "openssl" -path "*/openssl@3/*/include" | head -n 1) - echo "OpenSSL path: $openssl_path" - ln -sf $openssl_path ${brew_prefix}/include/openssl - ls -l ${brew_prefix}/include/openssl - - # fix opus header not found - opus_path=$(find ${brew_prefix}/Cellar -type d -name "opus" -path "*/opus/*/include" | head -n 1) - echo "Opus path: $opus_path" - ln -sf $opus_path ${brew_prefix}/include/opus - ls -l ${brew_prefix}/include/opus - - # fix miniupnpc header not found - upnp_path=$(find ${brew_prefix}/Cellar -type d -name "miniupnpc" -path "*/miniupnpc/*/include" | head -n 1) - echo "Miniupnpc path: $upnp_path" - ln -sf $upnp_path ${brew_prefix}/include/miniupnpc - ls -l ${brew_prefix}/include/miniupnpc - - - name: Install Boost - # installing boost from homebrew takes 30 minutes in a GitHub runner - run: | - export BOOST_ROOT=${HOME}/boost-${BOOST_VERSION} - - # install boost - wget \ - https://github.com/boostorg/boost/releases/download/boost-${BOOST_VERSION}/boost-${BOOST_VERSION}.tar.gz \ - --progress=bar:force:noscroll -q --show-progress - tar xf boost-${BOOST_VERSION}.tar.gz - cd boost-${BOOST_VERSION} - - # libdir should be set by --prefix but isn't - ./bootstrap.sh \ - --prefix=${BOOST_ROOT} \ - --libdir=${BOOST_ROOT}/lib \ - --with-libraries=locale,log,program_options,system,thread - ./b2 headers - ./b2 install \ - --prefix=${BOOST_ROOT} \ - --libdir=${BOOST_ROOT}/lib \ - -j$(sysctl -n hw.ncpu) \ - link=shared,static \ - variant=release \ - cxxflags=-std=c++14 \ - cxxflags=-stdlib=libc++ \ - linkflags=-stdlib=libc++ - - # put boost in cmake prefix path - echo "BOOST_ROOT=${BOOST_ROOT}" >> ${GITHUB_ENV} - - - name: Build MacOS - env: - BRANCH: ${{ github.head_ref || github.ref_name }} - BUILD_VERSION: ${{ needs.check_changelog.outputs.next_version_bare }} - COMMIT: ${{ github.event.pull_request.head.sha || github.sha }} - run: | mkdir build cd build cmake \ - -DBUILD_WERROR=ON \ - -DCMAKE_BUILD_TYPE=Release \ - -DCMAKE_INSTALL_PREFIX=/usr \ - -DSUNSHINE_ASSETS_DIR=local/sunshine/assets \ - -DSUNSHINE_EXECUTABLE_PATH=/usr/bin/sunshine \ + -DGITHUB_BRANCH="${branch}" \ + -DGITHUB_CLONE_URL="${clone_url}" \ + -DSUNSHINE_CONFIGURE_HOMEBREW=ON \ + -DSUNSHINE_CONFIGURE_ONLY=ON \ .. - make -j $(sysctl -n hw.ncpu) + cd .. - - name: Package MacOS - run: | - mkdir -p artifacts - cd build + # copy formula to artifacts + mkdir -p homebrew + cp -f ./build/sunshine.rb ./homebrew/sunshine.rb - # package - cpack -G DragNDrop - mv ./cpack_artifacts/Sunshine.dmg \ - ../artifacts/sunshine-macos-${{ matrix.os_version }}-${{ matrix.arch }}.dmg + # testing + cat ./homebrew/sunshine.rb - name: Upload Artifacts + if: ${{ matrix.release }} uses: actions/upload-artifact@v4 with: - name: sunshine-macos-${{ matrix.os_version }}-${{ matrix.arch }} - path: artifacts/ + name: sunshine-homebrew + path: homebrew/ - - name: Create/Update GitHub Release - if: ${{ needs.setup_release.outputs.create_release == 'true' }} - uses: ncipollo/release-action@v1 + - name: Should Publish Homebrew Formula + id: homebrew_publish + run: | + PUBLISH=false + if [[ \ + "${{ matrix.release }}" == "true" && \ + "${{ github.repository_owner }}" == "LizardByte" && \ + "${{ needs.setup_release.outputs.create_release }}" == "true" && \ + "${{ github.ref }}" == "refs/heads/master" \ + ]]; then + PUBLISH=true + fi + + echo "publish=${PUBLISH}" >> $GITHUB_OUTPUT + + - name: Validate and Publish Homebrew Formula + uses: LizardByte/homebrew-release-action@v2024.309.150158 with: - name: ${{ needs.setup_release.outputs.release_name }} - tag: ${{ needs.setup_release.outputs.release_tag }} - commit: ${{ needs.setup_release.outputs.release_commit }} - artifacts: "*artifacts/*" + formula_file: ${{ github.workspace }}/homebrew/sunshine.rb + git_email: ${{ secrets.GH_BOT_EMAIL }} + git_username: ${{ secrets.GH_BOT_NAME }} + publish: ${{ steps.homebrew_publish.outputs.publish }} token: ${{ secrets.GH_BOT_TOKEN }} - allowUpdates: true - body: ${{ needs.setup_release.outputs.release_body }} - discussionCategory: announcements - prerelease: ${{ needs.setup_release.outputs.pre_release }} build_mac_port: needs: [check_changelog, setup_release] diff --git a/CMakeLists.txt b/CMakeLists.txt index d672c9b8ae8..593d86b82dd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.18) # todo - set version to 0.0.0 once confident in automated versioning project(Sunshine VERSION 0.22.0 - DESCRIPTION "Sunshine is a self-hosted game stream host for Moonlight." + DESCRIPTION "Self-hosted game stream host for Moonlight" HOMEPAGE_URL "https://app.lizardbyte.dev/Sunshine") set(PROJECT_LICENSE "GPL-3.0") diff --git a/cmake/prep/options.cmake b/cmake/prep/options.cmake index 9104320d31d..9a7fca8e5e5 100644 --- a/cmake/prep/options.cmake +++ b/cmake/prep/options.cmake @@ -12,7 +12,15 @@ option(CUDA_INHERIT_COMPILE_OPTIONS "When building CUDA code, inherit compile options from the the main project. You may want to disable this if your IDE throws errors about unknown flags after running cmake." ON) +if(UNIX) + # technically, the homebrew build could be on linux as well... no idea if it would actually work + option(SUNSHINE_BUILD_HOMEBREW + "Enable a Homebrew build." OFF) +endif () + if(APPLE) + option(SUNSHINE_CONFIGURE_HOMEBREW + "Configure macOS Homebrew formula. Recommended to use with SUNSHINE_CONFIGURE_ONLY" OFF) option(SUNSHINE_CONFIGURE_PORTFILE "Configure macOS Portfile. Recommended to use with SUNSHINE_CONFIGURE_ONLY" OFF) option(SUNSHINE_PACKAGE_MACOS diff --git a/cmake/prep/special_package_configuration.cmake b/cmake/prep/special_package_configuration.cmake index a5a780f5563..695b6e443c2 100644 --- a/cmake/prep/special_package_configuration.cmake +++ b/cmake/prep/special_package_configuration.cmake @@ -2,6 +2,9 @@ if (APPLE) if(${SUNSHINE_CONFIGURE_PORTFILE}) configure_file(packaging/macos/Portfile Portfile @ONLY) endif() + if(${SUNSHINE_CONFIGURE_HOMEBREW}) + configure_file(packaging/macos/sunshine.rb sunshine.rb @ONLY) + endif() elseif (UNIX) include(GNUInstallDirs) # this needs to be included prior to configuring the desktop files diff --git a/cmake/targets/common.cmake b/cmake/targets/common.cmake index 3dd629e0cab..9f2ce08240e 100644 --- a/cmake/targets/common.cmake +++ b/cmake/targets/common.cmake @@ -37,8 +37,19 @@ endif() target_compile_options(sunshine PRIVATE $<$:${SUNSHINE_COMPILE_OPTIONS}>;$<$:${SUNSHINE_COMPILE_OPTIONS_CUDA};-std=c++17>) # cmake-lint: disable=C0301 +# Homebrew build fails the vite build if we set these environment variables +if(${SUNSHINE_BUILD_HOMEBREW}) + set(NPM_SOURCE_ASSETS_DIR "") + set(NPM_ASSETS_DIR "") + set(NPM_BUILD_HOMEBREW "true") +else() + set(NPM_SOURCE_ASSETS_DIR ${SUNSHINE_SOURCE_ASSETS_DIR}) + set(NPM_ASSETS_DIR ${CMAKE_BINARY_DIR}) + set(NPM_BUILD_HOMEBREW "") +endif() + #WebUI build add_custom_target(web-ui ALL WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" COMMENT "Installing NPM Dependencies and Building the Web UI" - COMMAND bash -c \"npm install && SUNSHINE_SOURCE_ASSETS_DIR=${SUNSHINE_SOURCE_ASSETS_DIR} SUNSHINE_ASSETS_DIR=${CMAKE_BINARY_DIR} npm run build\") # cmake-lint: disable=C0301 + COMMAND bash -c \"npm install && SUNSHINE_BUILD_HOMEBREW=${NPM_BUILD_HOMEBREW} SUNSHINE_SOURCE_ASSETS_DIR=${NPM_SOURCE_ASSETS_DIR} SUNSHINE_ASSETS_DIR=${NPM_ASSETS_DIR} npm run build\") # cmake-lint: disable=C0301 diff --git a/docs/source/about/setup.rst b/docs/source/about/setup.rst index 2457ccc59e9..53da139875b 100644 --- a/docs/source/about/setup.rst +++ b/docs/source/about/setup.rst @@ -283,18 +283,15 @@ Install .. important:: Sunshine on macOS is experimental. Gamepads do not work. - .. tab:: dmg + .. tab:: Homebrew - .. warning:: The `dmg` does not include runtime dependencies. This package is not recommended for most users. - No support will be provided! + #. Install `Homebrew `__ + #. Update the Homebrew sources and install Sunshine. - #. Download the ``sunshine--.dmg`` file and install it. - - Uninstall: .. code-block:: bash - cd /etc/sunshine/assets - uninstall_pkg.sh + brew tap LizardByte/homebrew + brew install sunshine .. tab:: Portfile diff --git a/packaging/macos/sunshine.rb b/packaging/macos/sunshine.rb new file mode 100644 index 00000000000..e312c99d4d6 --- /dev/null +++ b/packaging/macos/sunshine.rb @@ -0,0 +1,62 @@ +require "language/node" + +class @PROJECT_NAME@ < Formula + desc "@PROJECT_DESCRIPTION@" + homepage "@PROJECT_HOMEPAGE_URL@" + url "@GITHUB_CLONE_URL@", + tag: "@GITHUB_BRANCH@" + version "@PROJECT_VERSION@" + license all_of: ["GPL-3.0-only"] + head "@GITHUB_CLONE_URL@", branch: "nightly" + + depends_on "boost" => :build + depends_on "cmake" => :build + depends_on "pkg-config" => :build + depends_on "curl" + depends_on "miniupnpc" + depends_on "node" + depends_on "openssl" + depends_on "opus" + + def install + args = %W[ + -DBUIld_WERROR=ON + -DCMAKE_INSTALL_PREFIX=#{prefix} + -DOPENSSL_ROOT_DIR=#{Formula["openssl"].opt_prefix} + -DSUNSHINE_ASSETS_DIR=sunshine/assets + -DSUNSHINE_BUILD_HOMEBREW=ON + ] + system "cmake", "-S", ".", "-B", "build", *std_cmake_args, *args + + cd "build" do + system "make", "-j" + system "make", "install" + end + end + + service do + run [opt_bin/"sunshine", "~/.config/sunshine/sunshine.conf"] + end + + def caveats + <<~EOS + Thanks for installing @PROJECT_NAME@! + + To get started, review the documentation at: + https://docs.lizardbyte.dev/projects/sunshine/en/latest/ + + Sunshine can only access microphones on macOS due to system limitations. + To stream system audio use "Soundflower" or "BlackHole". + + Gamepads are not currently supported on macOS. + EOS + end + + test do + # test that the binary runs at all + output = shell_output("#{bin}/sunshine --version").strip + puts output + + # TODO: add unit tests + end +end diff --git a/src_assets/macos/misc/uninstall_pkg.sh b/src_assets/macos/misc/uninstall_pkg.sh index 869f33d2fe6..89e7bbfb278 100644 --- a/src_assets/macos/misc/uninstall_pkg.sh +++ b/src_assets/macos/misc/uninstall_pkg.sh @@ -1,4 +1,7 @@ #!/bin/bash -e + +# note: this file was used to remove files when using the pkg/dmg, it is no longer used, but left for reference + set -e package_name=org.macports.Sunshine diff --git a/vite.config.js b/vite.config.js index a41470e4bf5..8732f1a08c7 100644 --- a/vite.config.js +++ b/vite.config.js @@ -16,13 +16,18 @@ import process from 'process' let assetsSrcPath = 'src_assets/common/assets/web'; let assetsDstPath = 'build/assets/web'; -if (process.env.SUNSHINE_SOURCE_ASSETS_DIR) { - console.log("Using srcdir from Cmake: " + resolve(process.env.SUNSHINE_SOURCE_ASSETS_DIR,"common/assets/web")); - assetsSrcPath = resolve(process.env.SUNSHINE_SOURCE_ASSETS_DIR,"common/assets/web") +if (process.env.SUNSHINE_BUILD_HOMEBREW) { + console.log("Building for homebrew, using default paths") } -if (process.env.SUNSHINE_ASSETS_DIR) { - console.log("Using destdir from Cmake: " + resolve(process.env.SUNSHINE_ASSETS_DIR,"assets/web")); - assetsDstPath = resolve(process.env.SUNSHINE_ASSETS_DIR,"assets/web") +else { + if (process.env.SUNSHINE_SOURCE_ASSETS_DIR) { + console.log("Using srcdir from Cmake: " + resolve(process.env.SUNSHINE_SOURCE_ASSETS_DIR,"common/assets/web")); + assetsSrcPath = resolve(process.env.SUNSHINE_SOURCE_ASSETS_DIR,"common/assets/web") + } + if (process.env.SUNSHINE_ASSETS_DIR) { + console.log("Using destdir from Cmake: " + resolve(process.env.SUNSHINE_ASSETS_DIR,"assets/web")); + assetsDstPath = resolve(process.env.SUNSHINE_ASSETS_DIR,"assets/web") + } } let header = fs.readFileSync(resolve(assetsSrcPath, "template_header.html")) From 9d5b01727efdc03a80f31c46a4c6ca529db5eee7 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Fri, 8 Mar 2024 23:13:27 -0600 Subject: [PATCH 16/33] Replace WMIC-based check for ViGEmBus with a Powershell check This version is simpler and much faster on machines with many installed apps. --- .../windows/misc/gamepad/install-gamepad.bat | 25 ++++++------------- 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/src_assets/windows/misc/gamepad/install-gamepad.bat b/src_assets/windows/misc/gamepad/install-gamepad.bat index cf164cb5109..a31babb93f6 100644 --- a/src_assets/windows/misc/gamepad/install-gamepad.bat +++ b/src_assets/windows/misc/gamepad/install-gamepad.bat @@ -2,28 +2,17 @@ setlocal enabledelayedexpansion rem Check if a compatible version of ViGEmBus is already installed (1.17 or later) -set Version= -for /f "usebackq delims=" %%a in (`wmic product where "name='ViGEm Bus Driver' or name='Nefarius Virtual Gamepad Emulation Bus Driver'" get Version /format:Textvaluelist`) do ( - for /f "delims=" %%# in ("%%a") do set "%%#" -) - -rem Extract Major and Minor versions -for /f "tokens=1,2 delims=." %%a in ("%Version%") do ( - set "MajorVersion=%%a" - set "MinorVersion=%%b" -) - -rem Compare the version to 1.17 -if /i !MajorVersion! gtr 1 goto skip -if /i !MajorVersion! equ 1 ( - if /i !MinorVersion! geq 17 ( - goto skip - ) +rem +rem Note: We use exit code 2 to indicate success because either 0 or 1 may be returned +rem based on the PowerShell version if an exception occurs. +powershell -c Exit $(if ((Get-Item "$env:SystemRoot\System32\drivers\ViGEmBus.sys").VersionInfo.FileVersion -ge [System.Version]"1.17") { 2 } Else { 1 }) +if %ERRORLEVEL% EQU 2 ( + goto skip ) goto continue :skip -echo "The installed version is %Version%, no update needed. Exiting." +echo "The installed version is 1.17 or later, no update needed. Exiting." exit /b 0 :continue From 278567f72d02b528c45c749e8cecfa54d310d55e Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sat, 9 Mar 2024 11:18:39 -0600 Subject: [PATCH 17/33] Move kmsgrab dependencies from optdepends to depends kmsgrab is the most fully featured capture backend for current versions of Sunshine, so it should be built by default. In addition to zero-copy capture and HDR support, it is the *only* capture backend that can handle non-wlroots Wayland capture. --- docker/archlinux.dockerfile | 4 +--- packaging/linux/Arch/PKGBUILD | 6 +++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/docker/archlinux.dockerfile b/docker/archlinux.dockerfile index bd853ad395d..ddb3c28bafb 100644 --- a/docker/archlinux.dockerfile +++ b/docker/archlinux.dockerfile @@ -34,7 +34,7 @@ ENV COMMIT=${COMMIT} SHELL ["/bin/bash", "-o", "pipefail", "-c"] # install dependencies -# cuda, libcap, and libdrm are optional dependencies for PKGBUILD +# cuda is an optional build-time dependency for PKGBUILD RUN <<_DEPS #!/bin/bash set -e @@ -43,8 +43,6 @@ pacman -Syu --disable-download-timeout --needed --noconfirm \ cmake \ cuda \ git \ - libcap \ - libdrm \ namcap _DEPS diff --git a/packaging/linux/Arch/PKGBUILD b/packaging/linux/Arch/PKGBUILD index 4422698263e..dd478080049 100644 --- a/packaging/linux/Arch/PKGBUILD +++ b/packaging/linux/Arch/PKGBUILD @@ -13,6 +13,8 @@ depends=('avahi' 'boost-libs' 'curl' 'libayatana-appindicator' + 'libcap' + 'libdrm' 'libevdev' 'libmfx' 'libnotify' @@ -35,9 +37,7 @@ makedepends=('boost' 'make' 'nodejs' 'npm') -optdepends=('cuda: NvFBC capture support' - 'libcap' - 'libdrm') +optdepends=('cuda: NvFBC capture support') provides=('sunshine') From 74ce047a4b372cd7aa39abdae2f8b12629c3f57d Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sat, 9 Mar 2024 11:24:55 -0600 Subject: [PATCH 18/33] Add optdepends for Intel and AMD hardware encoding --- packaging/linux/Arch/PKGBUILD | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packaging/linux/Arch/PKGBUILD b/packaging/linux/Arch/PKGBUILD index dd478080049..4bdef18d99f 100644 --- a/packaging/linux/Arch/PKGBUILD +++ b/packaging/linux/Arch/PKGBUILD @@ -37,7 +37,9 @@ makedepends=('boost' 'make' 'nodejs' 'npm') -optdepends=('cuda: NvFBC capture support') +optdepends=('cuda: Nvidia GPU encoding support' + 'libva-mesa-driver: AMD GPU encoding support' + 'intel-media-driver: Intel GPU encoding support') provides=('sunshine') From cb4bfaa2f407ac3bdd6a08d4b47bbaf40d8f2f0e Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sat, 9 Mar 2024 11:55:22 -0600 Subject: [PATCH 19/33] Add the .INSTALL script needed for kmsgrab to work This also removes the standalone PKGBUILD artifact because our PKGBUILD has external dependencies now. --- .../prep/special_package_configuration.cmake | 1 + docker/archlinux.dockerfile | 2 +- docs/source/about/setup.rst | 19 ++----------------- packaging/linux/Arch/PKGBUILD | 1 + packaging/linux/Arch/sunshine.install | 12 ++++++++++++ 5 files changed, 17 insertions(+), 18 deletions(-) create mode 100644 packaging/linux/Arch/sunshine.install diff --git a/cmake/prep/special_package_configuration.cmake b/cmake/prep/special_package_configuration.cmake index 695b6e443c2..d04066cdc8a 100644 --- a/cmake/prep/special_package_configuration.cmake +++ b/cmake/prep/special_package_configuration.cmake @@ -29,6 +29,7 @@ elseif (UNIX) # configure the arch linux pkgbuild if(${SUNSHINE_CONFIGURE_PKGBUILD}) configure_file(packaging/linux/Arch/PKGBUILD PKGBUILD @ONLY) + configure_file(packaging/linux/Arch/sunshine.install sunshine.install @ONLY) endif() # configure the flatpak manifest diff --git a/docker/archlinux.dockerfile b/docker/archlinux.dockerfile index ddb3c28bafb..e8cfd93998e 100644 --- a/docker/archlinux.dockerfile +++ b/docker/archlinux.dockerfile @@ -78,6 +78,7 @@ _MAKE WORKDIR /build/sunshine/pkg RUN mv /build/sunshine/build/PKGBUILD . +RUN mv /build/sunshine/build/sunshine.install . # namcap and build PKGBUILD file RUN <<_PKGBUILD @@ -91,7 +92,6 @@ _PKGBUILD FROM scratch as artifacts -COPY --link --from=sunshine-build /build/sunshine/pkg/PKGBUILD /PKGBUILD COPY --link --from=sunshine-build /build/sunshine/pkg/sunshine*.pkg.tar.zst /sunshine.pkg.tar.zst FROM sunshine-base as sunshine diff --git a/docs/source/about/setup.rst b/docs/source/about/setup.rst index 53da139875b..0a68bad8f14 100644 --- a/docs/source/about/setup.rst +++ b/docs/source/about/setup.rst @@ -38,7 +38,6 @@ Install =========================================== ============== ============== ================================ Package CUDA Version Min Driver CUDA Compute Capabilities =========================================== ============== ============== ================================ - PKGBUILD User dependent User dependent User dependent 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 @@ -90,21 +89,7 @@ Install ./sunshine.AppImage --remove - .. tab:: Archlinux PKGBUILD - - #. Open terminal and run the following code. - - .. code-block:: bash - - wget https://github.com/LizardByte/Sunshine/releases/latest/download/PKGBUILD - makepkg -fi - - Uninstall: - .. code-block:: bash - - pacman -R sunshine - - .. tab:: Archlinux pkg + .. tab:: Arch Linux Package #. Open terminal and run the following code. @@ -205,7 +190,7 @@ Install sudo dnf remove sunshine - The `deb`, `rpm`, `Flatpak` and `AppImage` packages should handle these steps automatically. + The `deb`, `rpm`, `zst`, `Flatpak` and `AppImage` packages should handle these steps automatically. Third party packages may not. Sunshine needs access to `uinput` to create mouse and gamepad events. diff --git a/packaging/linux/Arch/PKGBUILD b/packaging/linux/Arch/PKGBUILD index 4bdef18d99f..44a6beb2b2f 100644 --- a/packaging/linux/Arch/PKGBUILD +++ b/packaging/linux/Arch/PKGBUILD @@ -8,6 +8,7 @@ pkgdesc="@PROJECT_DESCRIPTION@" arch=('x86_64' 'aarch64') url=@PROJECT_HOMEPAGE_URL@ license=('GPL3') +install=sunshine.install depends=('avahi' 'boost-libs' diff --git a/packaging/linux/Arch/sunshine.install b/packaging/linux/Arch/sunshine.install new file mode 100644 index 00000000000..4d4a4a45493 --- /dev/null +++ b/packaging/linux/Arch/sunshine.install @@ -0,0 +1,12 @@ +do_setcap() { + setcap cap_sys_admin+p $(readlink -f $(which sunshine)) +} + +post_install() { + do_setcap +} + +post_upgrade() { + do_setcap +} + From bc0a4786f4c403a696482933f9bd9a760cf4f344 Mon Sep 17 00:00:00 2001 From: brycerocky <56776312+brycerocky@users.noreply.github.com> Date: Sun, 10 Mar 2024 15:35:48 -0700 Subject: [PATCH 20/33] Use icon caching for system tray. (#2238) --- src/system_tray.cpp | 2 ++ third-party/tray | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/system_tray.cpp b/src/system_tray.cpp index 39131ba30fe..eb5948a41c1 100644 --- a/src/system_tray.cpp +++ b/src/system_tray.cpp @@ -145,6 +145,8 @@ namespace system_tray { { .text = "Restart", .cb = tray_restart_cb }, { .text = "Quit", .cb = tray_quit_cb }, { .text = nullptr } }, + .iconPathCount = 4, + .allIconPaths = { TRAY_ICON, TRAY_ICON_LOCKED, TRAY_ICON_PLAYING, TRAY_ICON_PAUSING }, }; /** diff --git a/third-party/tray b/third-party/tray index 2bf1c610300..a08c1025c3f 160000 --- a/third-party/tray +++ b/third-party/tray @@ -1 +1 @@ -Subproject commit 2bf1c610300b27f8d8ce87e2f13223fc83efeb42 +Subproject commit a08c1025c3f158d6b6c4b9bcf0ab770291d26896 From a2785baf0aa7202bceecd975b1aa2d8798d2378a Mon Sep 17 00:00:00 2001 From: ReenigneArcher <42013603+ReenigneArcher@users.noreply.github.com> Date: Sun, 10 Mar 2024 22:03:20 -0400 Subject: [PATCH 21/33] fix(linux): automatically migrate config directory (#2240) --- .../linux/flatpak/dev.lizardbyte.sunshine.yml | 1 + src/platform/linux/misc.cpp | 48 +++++++++++++++---- 2 files changed, 41 insertions(+), 8 deletions(-) diff --git a/packaging/linux/flatpak/dev.lizardbyte.sunshine.yml b/packaging/linux/flatpak/dev.lizardbyte.sunshine.yml index a4176d4ea15..1da03310f7a 100644 --- a/packaging/linux/flatpak/dev.lizardbyte.sunshine.yml +++ b/packaging/linux/flatpak/dev.lizardbyte.sunshine.yml @@ -11,6 +11,7 @@ separate-locales: false finish-args: - --device=all # access all devices - --env=PULSE_PROP_media.category=Manager # allow sunshine to manage audio sinks + - --env=SUNSHINE_MIGRATE_CONFIG=1 # migrate config files to the new location - --filesystem=home # need to save files in user's home directory - --share=ipc # required for X11 shared memory extension - --share=network # access network diff --git a/src/platform/linux/misc.cpp b/src/platform/linux/misc.cpp index 0075d4502f8..27b281ac3e0 100644 --- a/src/platform/linux/misc.cpp +++ b/src/platform/linux/misc.cpp @@ -100,22 +100,54 @@ namespace platf { fs::path appdata() { + bool found = false; + bool migrate_config = true; const char *dir; + const char *homedir; + fs::path config_path; + + // Get the home directory + if ((homedir = getenv("HOME")) == nullptr || strlen(homedir) == 0) { + // If HOME is empty or not set, use the current user's home directory + homedir = getpwuid(geteuid())->pw_dir; + } // May be set if running under a systemd service with the ConfigurationDirectory= option set. - if ((dir = getenv("CONFIGURATION_DIRECTORY")) != nullptr) { - return fs::path { dir } / "sunshine"sv; + if ((dir = getenv("CONFIGURATION_DIRECTORY")) != nullptr && strlen(dir) > 0) { + found = true; + config_path = fs::path(dir) / "sunshine"sv; } // Otherwise, follow the XDG base directory specification: // https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html - if ((dir = getenv("XDG_CONFIG_HOME")) != nullptr) { - return fs::path { dir } / "sunshine"sv; - } - if ((dir = getenv("HOME")) == nullptr) { - dir = getpwuid(geteuid())->pw_dir; + if (!found && (dir = getenv("XDG_CONFIG_HOME")) != nullptr && strlen(dir) > 0) { + found = true; + config_path = fs::path(dir) / "sunshine"sv; + } + // As a last resort, use the home directory + if (!found) { + migrate_config = false; + config_path = fs::path(homedir) / ".config/sunshine"sv; + } + + // migrate from the old config location if necessary + if (migrate_config && found && getenv("SUNSHINE_MIGRATE_CONFIG") == "1"sv) { + fs::path old_config_path = fs::path(homedir) / ".config/sunshine"sv; + if (old_config_path != config_path && fs::exists(old_config_path)) { + if (!fs::exists(config_path)) { + BOOST_LOG(info) << "Migrating config from "sv << old_config_path << " to "sv << config_path; + std::error_code ec; + fs::rename(old_config_path, config_path, ec); + if (ec) { + return old_config_path; + } + } + else { + BOOST_LOG(warning) << "Config exists in both "sv << old_config_path << " and "sv << config_path << ", using "sv << config_path << "... it is recommended to remove "sv << old_config_path; + } + } } - return fs::path { dir } / ".config/sunshine"sv; + return config_path; } std::string From 91744960c138772928b602eb0091a082d7f7a508 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Mon, 11 Mar 2024 02:42:25 -0500 Subject: [PATCH 22/33] Avoid broken fallback to cross-adapter NVENC encoding with KMS --- src/platform/linux/kmsgrab.cpp | 21 ++++++++++++++++++++- src/platform/linux/misc.cpp | 6 +++--- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/platform/linux/kmsgrab.cpp b/src/platform/linux/kmsgrab.cpp index a7a3256d433..a567d70314a 100644 --- a/src/platform/linux/kmsgrab.cpp +++ b/src/platform/linux/kmsgrab.cpp @@ -108,6 +108,7 @@ namespace platf { using obj_prop_t = util::safe_ptr; using prop_t = util::safe_ptr; using prop_blob_t = util::safe_ptr; + using version_t = util::safe_ptr; using conn_type_count_t = std::map; @@ -364,6 +365,12 @@ namespace platf { return drmModeGetResources(fd.el); } + bool + is_nvidia() { + version_t ver { drmGetVersion(fd.el) }; + return ver && ver->name && strncmp(ver->name, "nvidia-drm", 10) == 0; + } + bool is_cursor(std::uint32_t plane_id) { auto props = plane_props(plane_id); @@ -604,6 +611,12 @@ namespace platf { continue; } + // Skip non-Nvidia cards if we're looking for CUDA devices + if (mem_type == mem_type_e::cuda && !card.is_nvidia()) { + BOOST_LOG(debug) << file << " is not a CUDA device"sv; + continue; + } + auto end = std::end(card); for (auto plane = std::begin(card); plane != end; ++plane) { // Skip unused planes @@ -1576,7 +1589,7 @@ namespace platf { // A list of names of displays accepted as display_name std::vector - kms_display_names() { + kms_display_names(mem_type_e hwdevice_type) { int count = 0; if (!fs::exists("/dev/dri")) { @@ -1608,6 +1621,12 @@ namespace platf { continue; } + // Skip non-Nvidia cards if we're looking for CUDA devices + if (hwdevice_type == mem_type_e::cuda && !card.is_nvidia()) { + BOOST_LOG(debug) << file << " is not a CUDA device"sv; + continue; + } + auto crtc_to_monitor = kms::map_crtc_to_monitor(card.monitors(conn_type_count)); auto end = std::end(card); diff --git a/src/platform/linux/misc.cpp b/src/platform/linux/misc.cpp index 27b281ac3e0..884c0e9047a 100644 --- a/src/platform/linux/misc.cpp +++ b/src/platform/linux/misc.cpp @@ -766,13 +766,13 @@ namespace platf { #ifdef SUNSHINE_BUILD_DRM std::vector - kms_display_names(); + kms_display_names(mem_type_e hwdevice_type); std::shared_ptr kms_display(mem_type_e hwdevice_type, const std::string &display_name, const video::config_t &config); bool verify_kms() { - return !kms_display_names().empty(); + return !kms_display_names(mem_type_e::unknown).empty(); } #endif @@ -798,7 +798,7 @@ namespace platf { if (sources[source::WAYLAND]) return wl_display_names(); #endif #ifdef SUNSHINE_BUILD_DRM - if (sources[source::KMS]) return kms_display_names(); + if (sources[source::KMS]) return kms_display_names(hwdevice_type); #endif #ifdef SUNSHINE_BUILD_X11 if (sources[source::X11]) return x11_display_names(); From 3117fa57ec53709c665833eabb316441e02207fc Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sun, 10 Mar 2024 19:35:51 -0500 Subject: [PATCH 23/33] Rename 85-sunshine.rules to 60-sunshine.rules This ensures the rules are evaluated before 73-seat-late.rules which enables uaccess tag application for existing logged on users. --- cmake/packaging/linux.cmake | 4 ++-- docs/source/about/setup.rst | 2 +- packaging/linux/AppImage/AppRun | 4 ++-- packaging/linux/flatpak/scripts/additional-install.sh | 4 ++-- packaging/linux/flatpak/scripts/remove-additional-install.sh | 2 +- .../linux/misc/{85-sunshine.rules => 60-sunshine.rules} | 0 6 files changed, 8 insertions(+), 8 deletions(-) rename src_assets/linux/misc/{85-sunshine.rules => 60-sunshine.rules} (100%) diff --git a/cmake/packaging/linux.cmake b/cmake/packaging/linux.cmake index 8563414a40e..499f058c8bd 100644 --- a/cmake/packaging/linux.cmake +++ b/cmake/packaging/linux.cmake @@ -3,7 +3,7 @@ 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" + install(FILES "${SUNSHINE_SOURCE_ASSETS_DIR}/linux/misc/60-sunshine.rules" DESTINATION "${SUNSHINE_ASSETS_DIR}/udev/rules.d") install(FILES "${CMAKE_CURRENT_BINARY_DIR}/sunshine.service" DESTINATION "${SUNSHINE_ASSETS_DIR}/systemd/user") @@ -11,7 +11,7 @@ else() find_package(Systemd) find_package(Udev) - install(FILES "${SUNSHINE_SOURCE_ASSETS_DIR}/linux/misc/85-sunshine.rules" + install(FILES "${SUNSHINE_SOURCE_ASSETS_DIR}/linux/misc/60-sunshine.rules" DESTINATION "${UDEV_RULES_INSTALL_DIR}") install(FILES "${CMAKE_CURRENT_BINARY_DIR}/sunshine.service" DESTINATION "${SYSTEMD_USER_UNIT_INSTALL_DIR}") diff --git a/docs/source/about/setup.rst b/docs/source/about/setup.rst index 0a68bad8f14..89b5830247f 100644 --- a/docs/source/about/setup.rst +++ b/docs/source/about/setup.rst @@ -199,7 +199,7 @@ Install .. code-block:: bash echo 'KERNEL=="uinput", SUBSYSTEM=="misc", OPTIONS+="static_node=uinput", TAG+="uaccess"' | \ - sudo tee /etc/udev/rules.d/85-sunshine.rules + sudo tee /etc/udev/rules.d/60-sunshine.rules #. Optionally, configure autostart service diff --git a/packaging/linux/AppImage/AppRun b/packaging/linux/AppImage/AppRun index ddc5fd38455..4eeaeada97f 100644 --- a/packaging/linux/AppImage/AppRun +++ b/packaging/linux/AppImage/AppRun @@ -46,7 +46,7 @@ echo " function install() { # user input rules # shellcheck disable=SC2002 - cat "$SUNSHINE_SHARE_HERE/udev/rules.d/85-sunshine.rules" | sudo tee /etc/udev/rules.d/85-sunshine.rules + cat "$SUNSHINE_SHARE_HERE/udev/rules.d/60-sunshine.rules" | sudo tee /etc/udev/rules.d/60-sunshine.rules # sunshine service mkdir -p ~/.config/systemd/user @@ -79,7 +79,7 @@ function install() { function remove() { # remove input rules - sudo rm -f /etc/udev/rules.d/85-sunshine.rules + sudo rm -f /etc/udev/rules.d/60-sunshine.rules # remove service sudo rm -f ~/.config/systemd/user/sunshine.service diff --git a/packaging/linux/flatpak/scripts/additional-install.sh b/packaging/linux/flatpak/scripts/additional-install.sh index 8a905b53810..a27db4e09ba 100644 --- a/packaging/linux/flatpak/scripts/additional-install.sh +++ b/packaging/linux/flatpak/scripts/additional-install.sh @@ -7,7 +7,7 @@ echo Sunshine User Service has been installed. echo Use [systemctl --user enable sunshine] once to autostart Sunshine on login. # Udev rule -UDEV=$(cat /app/share/sunshine/udev/rules.d/85-sunshine.rules) +UDEV=$(cat /app/share/sunshine/udev/rules.d/60-sunshine.rules) echo Configuring mouse permission. -flatpak-spawn --host pkexec sh -c "echo '$UDEV' > /etc/udev/rules.d/85-sunshine.rules" +flatpak-spawn --host pkexec sh -c "echo '$UDEV' > /etc/udev/rules.d/60-sunshine.rules" echo Restart computer for mouse permission to take effect. diff --git a/packaging/linux/flatpak/scripts/remove-additional-install.sh b/packaging/linux/flatpak/scripts/remove-additional-install.sh index 6148f62ea1e..0d13baeb62c 100644 --- a/packaging/linux/flatpak/scripts/remove-additional-install.sh +++ b/packaging/linux/flatpak/scripts/remove-additional-install.sh @@ -7,5 +7,5 @@ systemctl --user daemon-reload echo Sunshine User Service has been removed. # Udev rule -flatpak-spawn --host pkexec sh -c "rm /etc/udev/rules.d/85-sunshine.rules" +flatpak-spawn --host pkexec sh -c "rm /etc/udev/rules.d/60-sunshine.rules" echo Mouse permission removed. Restart computer to take effect. diff --git a/src_assets/linux/misc/85-sunshine.rules b/src_assets/linux/misc/60-sunshine.rules similarity index 100% rename from src_assets/linux/misc/85-sunshine.rules rename to src_assets/linux/misc/60-sunshine.rules From 3181d91edf6e1ad958f19626381b5980fc2afabb Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sun, 10 Mar 2024 20:06:59 -0500 Subject: [PATCH 24/33] Apply udev rules to /dev/uinput immediately after installation --- docs/source/about/setup.rst | 5 ++++- packaging/linux/AppImage/AppRun | 21 ++------------------- packaging/linux/Arch/sunshine.install | 8 ++++++++ src_assets/linux/misc/postinst | 7 +++++++ 4 files changed, 21 insertions(+), 20 deletions(-) diff --git a/docs/source/about/setup.rst b/docs/source/about/setup.rst index 89b5830247f..8b803a78215 100644 --- a/docs/source/about/setup.rst +++ b/docs/source/about/setup.rst @@ -195,11 +195,14 @@ Install Sunshine needs access to `uinput` to create mouse and gamepad events. - #. Create `udev` rules. + #. Create and reload `udev` rules for uinput. .. code-block:: bash echo 'KERNEL=="uinput", SUBSYSTEM=="misc", OPTIONS+="static_node=uinput", TAG+="uaccess"' | \ sudo tee /etc/udev/rules.d/60-sunshine.rules + sudo udevadm control --reload-rules + sudo udevadm trigger + sudo modprobe uinput #. Optionally, configure autostart service diff --git a/packaging/linux/AppImage/AppRun b/packaging/linux/AppImage/AppRun index 4eeaeada97f..404704c34d3 100644 --- a/packaging/linux/AppImage/AppRun +++ b/packaging/linux/AppImage/AppRun @@ -47,6 +47,8 @@ function install() { # user input rules # shellcheck disable=SC2002 cat "$SUNSHINE_SHARE_HERE/udev/rules.d/60-sunshine.rules" | sudo tee /etc/udev/rules.d/60-sunshine.rules + sudo udevadm control --reload-rules + sudo udevadm trigger --property-match=DEVNAME=/dev/uinput # sunshine service mkdir -p ~/.config/systemd/user @@ -56,25 +58,6 @@ function install() { # setcap sudo setcap cap_sys_admin+p "$(readlink -f "$SUNSHINE_BIN_HERE")" - - while true - do - read -r -p "This installation requires a reboot. Do you want to reboot NOW? [y/n] " input - - case $input in - [yY][eE][sS]|[yY]) - echo "Yes" - sudo reboot now - ;; - [nN][oO]|[nN]) - echo "No" - break - ;; - *) - echo "Invalid input..." - ;; - esac - done } function remove() { diff --git a/packaging/linux/Arch/sunshine.install b/packaging/linux/Arch/sunshine.install index 4d4a4a45493..a8a700f1f1c 100644 --- a/packaging/linux/Arch/sunshine.install +++ b/packaging/linux/Arch/sunshine.install @@ -2,11 +2,19 @@ do_setcap() { setcap cap_sys_admin+p $(readlink -f $(which sunshine)) } +do_udev_reload() { + udevadm control --reload-rules + udevadm trigger --property-match=DEVNAME=/dev/uinput + modprobe uinput || true +} + post_install() { do_setcap + do_udev_reload } post_upgrade() { do_setcap + do_udev_reload } diff --git a/src_assets/linux/misc/postinst b/src_assets/linux/misc/postinst index 63f0523d867..aab899f94ec 100644 --- a/src_assets/linux/misc/postinst +++ b/src_assets/linux/misc/postinst @@ -6,3 +6,10 @@ if [ -x "$path_to_setcap" ] ; then echo "$path_to_setcap cap_sys_admin+p /usr/bin/sunshine" $path_to_setcap cap_sys_admin+p $(readlink -f /usr/bin/sunshine) fi + +# Trigger udev rule reload for /dev/uinput +path_to_udevadm=$(which udevadm) +if [ -x "$path_to_udevadm" ] ; then + $path_to_udevadm control --reload-rules + $path_to_udevadm trigger --property-match=DEVNAME=/dev/uinput +fi From 97467ea355ea3f39ad1ea568847d85757aa1052b Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sun, 10 Mar 2024 22:06:11 -0500 Subject: [PATCH 25/33] Reorder and reword the KMS setup step --- docs/source/about/setup.rst | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/docs/source/about/setup.rst b/docs/source/about/setup.rst index 8b803a78215..5b1f32937b9 100644 --- a/docs/source/about/setup.rst +++ b/docs/source/about/setup.rst @@ -204,6 +204,22 @@ Install sudo udevadm trigger sudo modprobe uinput + #. Enable permissions for KMS capture. + .. warning:: Capture of most Wayland-based desktop environments will fail unless this step is performed. + + .. note:: ``cap_sys_admin`` may as well be root, except you don't need to be root to run it. It is necessary to + allow Sunshine to use KMS capture. + + **Enable** + .. code-block:: bash + + sudo setcap cap_sys_admin+p $(readlink -f $(which sunshine)) + + **Disable (for Xorg/X11 only)** + .. code-block:: bash + + sudo setcap -r $(readlink -f $(which sunshine)) + #. Optionally, configure autostart service - filename: ``~/.config/systemd/user/sunshine.service`` @@ -248,20 +264,6 @@ Install systemctl --user enable sunshine - #. Additional Setup for KMS - .. note:: ``cap_sys_admin`` may as well be root, except you don't need to be root to run it. It is necessary to - allow Sunshine to use KMS. - - **Enable** - .. code-block:: bash - - sudo setcap cap_sys_admin+p $(readlink -f $(which sunshine)) - - **Disable (for Xorg/X11)** - .. code-block:: bash - - sudo setcap -r $(readlink -f $(which sunshine)) - #. Reboot .. code-block:: bash From e383ab99563e82e54a15e2d4b394e7bc3f0c8bb9 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sun, 10 Mar 2024 22:20:52 -0500 Subject: [PATCH 26/33] Add note to prefer distro packages over Flatpak/AppImage --- docs/source/about/setup.rst | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/source/about/setup.rst b/docs/source/about/setup.rst index 5b1f32937b9..70ed96f57f7 100644 --- a/docs/source/about/setup.rst +++ b/docs/source/about/setup.rst @@ -51,6 +51,8 @@ Install .. tab:: AppImage + .. caution:: Use distro-specific packages instead of the AppImage if they are available. + According to AppImageLint the supported distro matrix of the AppImage is below. - ✔ Debian bullseye @@ -103,7 +105,7 @@ Install pacman -R sunshine - .. tab:: Debian Package + .. tab:: Debian/Ubuntu Package #. Download ``sunshine-{distro}-{distro-version}-{arch}.deb`` and run the following code. @@ -123,6 +125,8 @@ Install .. tab:: Flatpak Package + .. caution:: Use distro-specific packages instead of the Flatpak if they are available. + .. important:: The instructions provided here are for the version supplied in the `latest release`_, which does not necessarily match the version in the Flathub repository! From d8877982ffe4a4fc22dbae3e2776145d6651d92a Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Tue, 12 Mar 2024 18:08:14 -0500 Subject: [PATCH 27/33] Improve KMS debuggability and avoid known broken cases --- src/platform/linux/kmsgrab.cpp | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/src/platform/linux/kmsgrab.cpp b/src/platform/linux/kmsgrab.cpp index a567d70314a..748fc93a967 100644 --- a/src/platform/linux/kmsgrab.cpp +++ b/src/platform/linux/kmsgrab.cpp @@ -15,6 +15,7 @@ #include #include +#include "src/config.h" #include "src/logging.h" #include "src/platform/common.h" #include "src/round_robin.h" @@ -298,6 +299,9 @@ namespace platf { return -1; } + version_t ver { drmGetVersion(fd.el) }; + BOOST_LOG(info) << path << " -> "sv << ((ver && ver->name) ? ver->name : "UNKNOWN"); + // Open the render node for this card to share with libva. // If it fails, we'll just share the primary node instead. char *rendernode_path = drmGetRenderDeviceNameFromFd(fd.el); @@ -316,12 +320,21 @@ namespace platf { } if (drmSetClientCap(fd.el, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1)) { - BOOST_LOG(error) << "Couldn't expose some/all drm planes for card: "sv << path; + BOOST_LOG(error) << "GPU driver doesn't support universal planes: "sv << path; return -1; } if (drmSetClientCap(fd.el, DRM_CLIENT_CAP_ATOMIC, 1)) { - BOOST_LOG(warning) << "Couldn't expose some properties for card: "sv << path; + BOOST_LOG(warning) << "GPU driver doesn't support atomic mode-setting: "sv << path; +#if defined(SUNSHINE_BUILD_X11) + // We won't be able to capture the mouse cursor with KMS on non-atomic drivers, + // so fall back to X11 if it's available and the user didn't explicitly force KMS. + if (window_system == window_system_e::X11 && config::video.capture != "kms") { + BOOST_LOG(info) << "Avoiding KMS capture under X11 due to lack of atomic mode-setting"sv; + return -1; + } +#endif + BOOST_LOG(warning) << "Cursor capture may fail without atomic mode-setting support!"sv; } plane_res.reset(drmModeGetPlaneResources(fd.el)); @@ -640,8 +653,7 @@ namespace platf { } if (!fb->handles[0]) { - BOOST_LOG(error) - << "Couldn't get handle for DRM Framebuffer ["sv << plane->fb_id << "]: Possibly not permitted: do [sudo setcap cap_sys_admin+p sunshine]"sv; + BOOST_LOG(error) << "Couldn't get handle for DRM Framebuffer ["sv << plane->fb_id << "]: Probably not permitted"sv; return -1; } @@ -909,12 +921,14 @@ namespace platf { if (!prop_crtc_w || !prop_crtc_h || !prop_crtc_x || !prop_crtc_y) { BOOST_LOG(error) << "Cursor plane is missing required plane CRTC properties!"sv; + BOOST_LOG(error) << "Atomic mode-setting must be enabled to capture the cursor!"sv; cursor_plane_id = -1; captured_cursor.visible = false; return; } if (!prop_src_x || !prop_src_y || !prop_src_w || !prop_src_h) { BOOST_LOG(error) << "Cursor plane is missing required plane SRC properties!"sv; + BOOST_LOG(error) << "Atomic mode-setting must be enabled to capture the cursor!"sv; cursor_plane_id = -1; captured_cursor.visible = false; return; @@ -1072,8 +1086,7 @@ namespace platf { } if (!fb->handles[0]) { - BOOST_LOG(error) - << "Couldn't get handle for DRM Framebuffer ["sv << plane->fb_id << "]: Possibly not permitted: do [sudo setcap cap_sys_admin+p sunshine]"sv; + BOOST_LOG(error) << "Couldn't get handle for DRM Framebuffer ["sv << plane->fb_id << "]: Probably not permitted"sv; return capture_e::error; } @@ -1647,8 +1660,9 @@ namespace platf { } if (!fb->handles[0]) { - BOOST_LOG(error) - << "Couldn't get handle for DRM Framebuffer ["sv << plane->fb_id << "]: Possibly not permitted: do [sudo setcap cap_sys_admin+p sunshine]"sv; + BOOST_LOG(error) << "Couldn't get handle for DRM Framebuffer ["sv << plane->fb_id << "]: Probably not permitted"sv; + BOOST_LOG((window_system != window_system_e::X11 || config::video.capture == "kms") ? fatal : error) + << "You must run [sudo setcap cap_sys_admin+p $(readlink -f sunshine)] for KMS display capture to work!"sv; break; } From c13a30db7876ad18fecd222f4433ccd11f24d6c5 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Tue, 12 Mar 2024 21:01:49 -0500 Subject: [PATCH 28/33] Allow NVENC to be forced to try capturing non-Nvidia GPUs --- src/platform/linux/kmsgrab.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/platform/linux/kmsgrab.cpp b/src/platform/linux/kmsgrab.cpp index 748fc93a967..d4feb3557d8 100644 --- a/src/platform/linux/kmsgrab.cpp +++ b/src/platform/linux/kmsgrab.cpp @@ -625,9 +625,12 @@ namespace platf { } // Skip non-Nvidia cards if we're looking for CUDA devices + // unless NVENC is selected manually by the user if (mem_type == mem_type_e::cuda && !card.is_nvidia()) { BOOST_LOG(debug) << file << " is not a CUDA device"sv; - continue; + if (config::video.encoder != "nvenc") { + continue; + } } auto end = std::end(card); @@ -1635,9 +1638,15 @@ namespace platf { } // Skip non-Nvidia cards if we're looking for CUDA devices + // unless NVENC is selected manually by the user if (hwdevice_type == mem_type_e::cuda && !card.is_nvidia()) { BOOST_LOG(debug) << file << " is not a CUDA device"sv; - continue; + if (config::video.encoder == "nvenc") { + BOOST_LOG(warning) << "Using NVENC with your display connected to a different GPU may not work properly!"sv; + } + else { + continue; + } } auto crtc_to_monitor = kms::map_crtc_to_monitor(card.monitors(conn_type_count)); From 1859e23cd5be366a38a106b5e9e42149b68f8961 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 13 Mar 2024 09:04:41 -0400 Subject: [PATCH 29/33] build(deps): bump LizardByte/homebrew-release-action from 2024.309.150158 to 2024.311.172824 (#2245) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/CI.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index f2529e7390e..80c309ca052 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -588,7 +588,7 @@ jobs: echo "publish=${PUBLISH}" >> $GITHUB_OUTPUT - name: Validate and Publish Homebrew Formula - uses: LizardByte/homebrew-release-action@v2024.309.150158 + uses: LizardByte/homebrew-release-action@v2024.311.172824 with: formula_file: ${{ github.workspace }}/homebrew/sunshine.rb git_email: ${{ secrets.GH_BOT_EMAIL }} From 0bfad20d4c3d7ffe27b25a9617e601998911e5c4 Mon Sep 17 00:00:00 2001 From: Crashdummy Date: Wed, 13 Mar 2024 14:48:13 +0100 Subject: [PATCH 30/33] fix(Linux/Fedora): re-enable CUDA and bump to 12.4.0 (#2247) --- docker/fedora-38.dockerfile | 42 ++++++++++++++++---------------- docker/fedora-39.dockerfile | 48 ++++++++++++++++++------------------- docs/source/about/setup.rst | 4 ++-- 3 files changed, 45 insertions(+), 49 deletions(-) diff --git a/docker/fedora-38.dockerfile b/docker/fedora-38.dockerfile index 9ba496c5b97..55622ab7070 100644 --- a/docker/fedora-38.dockerfile +++ b/docker/fedora-38.dockerfile @@ -68,28 +68,27 @@ dnf clean all rm -rf /var/cache/yum _DEPS -# todo - enable cuda once it's supported for gcc 13 and fedora 38 ## install cuda -#WORKDIR /build/cuda +WORKDIR /build/cuda ## versions: https://developer.nvidia.com/cuda-toolkit-archive -#ENV CUDA_VERSION="12.0.0" -#ENV CUDA_BUILD="525.60.13" +ENV CUDA_VERSION="12.4.0" +ENV CUDA_BUILD="550.54.14" ## hadolint ignore=SC3010 -#RUN <<_INSTALL_CUDA -##!/bin/bash -#set -e -#cuda_prefix="https://developer.download.nvidia.com/compute/cuda/" -#cuda_suffix="" -#if [[ "${TARGETPLATFORM}" == 'linux/arm64' ]]; then -# cuda_suffix="_sbsa" -#fi -#url="${cuda_prefix}${CUDA_VERSION}/local_installers/cuda_${CUDA_VERSION}_${CUDA_BUILD}_linux${cuda_suffix}.run" -#echo "cuda url: ${url}" -#wget "$url" --progress=bar:force:noscroll -q --show-progress -O ./cuda.run -#chmod a+x ./cuda.run -#./cuda.run --silent --toolkit --toolkitpath=/build/cuda --no-opengl-libs --no-man-page --no-drm -#rm ./cuda.run -#_INSTALL_CUDA +RUN <<_INSTALL_CUDA +#!/bin/bash +set -e +cuda_prefix="https://developer.download.nvidia.com/compute/cuda/" +cuda_suffix="" +if [[ "${TARGETPLATFORM}" == 'linux/arm64' ]]; then + cuda_suffix="_sbsa" +fi +url="${cuda_prefix}${CUDA_VERSION}/local_installers/cuda_${CUDA_VERSION}_${CUDA_BUILD}_linux${cuda_suffix}.run" +echo "cuda url: ${url}" +wget "$url" --progress=bar:force:noscroll -q --show-progress -O ./cuda.run +chmod a+x ./cuda.run +./cuda.run --silent --toolkit --toolkitpath=/build/cuda --no-opengl-libs --no-man-page --no-drm +rm ./cuda.run +_INSTALL_CUDA # copy repository WORKDIR /build/sunshine/ @@ -99,12 +98,11 @@ COPY --link .. . WORKDIR /build/sunshine/build # cmake and cpack -# todo - add cmake argument back in for cuda support "-DCMAKE_CUDA_COMPILER:PATH=/build/cuda/bin/nvcc \" -# todo - re-enable "DSUNSHINE_ENABLE_CUDA" RUN <<_MAKE #!/bin/bash set -e cmake \ + -DCMAKE_CUDA_COMPILER:PATH=/build/cuda/bin/nvcc \ -DBUILD_WERROR=ON \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_INSTALL_PREFIX=/usr \ @@ -113,7 +111,7 @@ cmake \ -DSUNSHINE_ENABLE_WAYLAND=ON \ -DSUNSHINE_ENABLE_X11=ON \ -DSUNSHINE_ENABLE_DRM=ON \ - -DSUNSHINE_ENABLE_CUDA=OFF \ + -DSUNSHINE_ENABLE_CUDA=ON \ /build/sunshine make -j "$(nproc)" cpack -G RPM diff --git a/docker/fedora-39.dockerfile b/docker/fedora-39.dockerfile index e942a8aa916..7bdb4adc216 100644 --- a/docker/fedora-39.dockerfile +++ b/docker/fedora-39.dockerfile @@ -68,28 +68,27 @@ dnf clean all rm -rf /var/cache/yum _DEPS -# todo - enable cuda once it's supported for gcc 13 and fedora 39 -## install cuda -#WORKDIR /build/cuda -## versions: https://developer.nvidia.com/cuda-toolkit-archive -#ENV CUDA_VERSION="12.0.0" -#ENV CUDA_BUILD="525.60.13" -## hadolint ignore=SC3010 -#RUN <<_INSTALL_CUDA -##!/bin/bash -#set -e -#cuda_prefix="https://developer.download.nvidia.com/compute/cuda/" -#cuda_suffix="" -#if [[ "${TARGETPLATFORM}" == 'linux/arm64' ]]; then -# cuda_suffix="_sbsa" -#fi -#url="${cuda_prefix}${CUDA_VERSION}/local_installers/cuda_${CUDA_VERSION}_${CUDA_BUILD}_linux${cuda_suffix}.run" -#echo "cuda url: ${url}" -#wget "$url" --progress=bar:force:noscroll -q --show-progress -O ./cuda.run -#chmod a+x ./cuda.run -#./cuda.run --silent --toolkit --toolkitpath=/build/cuda --no-opengl-libs --no-man-page --no-drm -#rm ./cuda.run -#_INSTALL_CUDA +# install cuda +WORKDIR /build/cuda +# versions: https://developer.nvidia.com/cuda-toolkit-archive +ENV CUDA_VERSION="12.4.0" +ENV CUDA_BUILD="550.54.14" +# hadolint ignore=SC3010 +RUN <<_INSTALL_CUDA +#!/bin/bash +set -e +cuda_prefix="https://developer.download.nvidia.com/compute/cuda/" +cuda_suffix="" +if [[ "${TARGETPLATFORM}" == 'linux/arm64' ]]; then + cuda_suffix="_sbsa" +fi +url="${cuda_prefix}${CUDA_VERSION}/local_installers/cuda_${CUDA_VERSION}_${CUDA_BUILD}_linux${cuda_suffix}.run" +echo "cuda url: ${url}" +wget "$url" --progress=bar:force:noscroll -q --show-progress -O ./cuda.run +chmod a+x ./cuda.run +./cuda.run --silent --toolkit --toolkitpath=/build/cuda --no-opengl-libs --no-man-page --no-drm +rm ./cuda.run +_INSTALL_CUDA # copy repository WORKDIR /build/sunshine/ @@ -99,12 +98,11 @@ COPY --link .. . WORKDIR /build/sunshine/build # cmake and cpack -# todo - add cmake argument back in for cuda support "-DCMAKE_CUDA_COMPILER:PATH=/build/cuda/bin/nvcc \" -# todo - re-enable "DSUNSHINE_ENABLE_CUDA" RUN <<_MAKE #!/bin/bash set -e cmake \ + -DCMAKE_CUDA_COMPILER:PATH=/build/cuda/bin/nvcc \ -DBUILD_WERROR=ON \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_INSTALL_PREFIX=/usr \ @@ -113,7 +111,7 @@ cmake \ -DSUNSHINE_ENABLE_WAYLAND=ON \ -DSUNSHINE_ENABLE_X11=ON \ -DSUNSHINE_ENABLE_DRM=ON \ - -DSUNSHINE_ENABLE_CUDA=OFF \ + -DSUNSHINE_ENABLE_CUDA=ON \ /build/sunshine make -j "$(nproc)" cpack -G RPM diff --git a/docs/source/about/setup.rst b/docs/source/about/setup.rst index 70ed96f57f7..2a2b015ce9c 100644 --- a/docs/source/about/setup.rst +++ b/docs/source/about/setup.rst @@ -43,8 +43,8 @@ Install 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 35;50;52;60;61;62;70;75;80;86;90 - sunshine-fedora-38-{arch}.rpm unavailable unavailable none - sunshine-fedora-39-{arch}.rpm unavailable unavailable none + sunshine-fedora-38-{arch}.rpm 12.4.0 525.60.13 50;52;60;61;62;70;75;80;86;90 + sunshine-fedora-39-{arch}.rpm 12.4.0 525.60.13 50;52;60;61;62;70;75;80;86;90 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 =========================================== ============== ============== ================================ From 3e49e25c63eed5cbc3d9596515ce359603060bdd Mon Sep 17 00:00:00 2001 From: ReenigneArcher <42013603+ReenigneArcher@users.noreply.github.com> Date: Wed, 13 Mar 2024 10:44:31 -0400 Subject: [PATCH 31/33] chore: bump version to v0.22.1 (#2221) Co-authored-by: Cameron Gutman --- CHANGELOG.md | 38 ++++++++++++++++++++++++++++++++++++++ CMakeLists.txt | 2 +- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f8290545da..6ab14e01b8e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,42 @@ # Changelog +## [0.22.1] - 2024-03-13 +**Breaking** +- (ArchLinux) Drop support for standalone PKGBUILD files. Use the binary Arch package or install via AUR instead. +- (macOS) Drop support for experimental dmg package. Use Homebrew or MacPorts instead. + +**Added** +- (macOS) Added Homebrew support + +**Changed** +- (Process/Windows) The working directory is now searched first when the command contains a relative path +- (ArchLinux) The kmsgrab capture backend is now compiled by default to support Wayland capture on non-wlroots-based compositors +- (Capture/Linux) X11 capture is now preferred over kmsgrab for cards that lack atomic modesetting support to ensure cursor capture works +- (Capture/Linux) Kmsgrab will only choose NVENC by default if the display is connected to the Nvidia GPU to avoid possible EGL import failures + +**Fixed** +- (Config) Fix unsupported resolution error with some Moonlight clients +- (Capture/Windows) Fix crash when streaming Ryujinx, Red Alert 2, and other apps that use unusually sized monochrome cursors +- (Capture/Linux) Fix crash in KMS cursor capture when running on Arch-based distros +- (Capture/Linux) Fix crash if CUDA GPU has a PCI ID with hexadecimal digits greater than 9 +- (Process/Windows) Fix starting apps when the working directory is enclosed in quotes +- (Process/Windows) Fix process tree tracking when the app is launched via a cmd.exe trampoline +- (Installer/Windows) Fix slow operation during ViGEmBus installation that may cause the installer to appear stuck +- (Build/macOS) Fix issues building on macOS 13 and 14 +- (Build/Linux) Fix missing install script in the Arch binary package +- (Build/Linux) Fix missing optional dependencies in the Arch binary package +- (Build/Linux) Ensure correct Arch pkg is published to GitHub releases +- (Capture/Linux) Fix mismatched case and unhandled exception in CUDA device lookup +- (Config) Add missing resolution to default config ui +- (Linux) Fix udev rules for uinput access not working until after reboot +- (Linux) Fix wrong path in desktop files +- (Tray) Cache icons to avoid possible DRM issues +- (Linux) Migrate old config files to new location if env SUNSHINE_MIGRATE_CONFIG=1 is set (automatically set for Flatpak) +- (Linux/Fedora) Re-enable CUDA support and bump to 12.4.0 + +**Misc** +- (Build/Windows) Adjust Windows debuginfo artifact to reduce confusion with real release binaries + ## [0.22.0] - 2024-03-03 **Breaking** - (Network) Clients must now be paired with the host before they can use Wake-on-LAN @@ -720,3 +757,4 @@ settings. In v0.17.0, games now run under your user account without elevated pri [0.20.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.20.0 [0.21.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.21.0 [0.22.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.22.0 +[0.22.1]: https://github.com/LizardByte/Sunshine/releases/tag/v0.22.1 diff --git a/CMakeLists.txt b/CMakeLists.txt index 593d86b82dd..fce20cd2bb7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.18) # todo - set this conditionally # todo - set version to 0.0.0 once confident in automated versioning -project(Sunshine VERSION 0.22.0 +project(Sunshine VERSION 0.22.1 DESCRIPTION "Self-hosted game stream host for Moonlight" HOMEPAGE_URL "https://app.lizardbyte.dev/Sunshine") From 22736c4ce92d3a359a96db1cd9107adea5db484f Mon Sep 17 00:00:00 2001 From: ReenigneArcher <42013603+ReenigneArcher@users.noreply.github.com> Date: Wed, 13 Mar 2024 18:05:45 -0400 Subject: [PATCH 32/33] Fix(linux/fedora39) patch system headers so build succeeds with cuda (#2253) Co-authored-by: Cameron Gutman <2695644+cgutman@users.noreply.github.com> --- .gitattributes | 3 +++ docker/fedora-39.dockerfile | 7 +++++++ 2 files changed, 10 insertions(+) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000000..1ccee08a107 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,3 @@ +# ensure dockerfiles are checked out with LF line endings +Dockerfile text eol=lf +*.dockerfile text eol=lf diff --git a/docker/fedora-39.dockerfile b/docker/fedora-39.dockerfile index 7bdb4adc216..20dae39a797 100644 --- a/docker/fedora-39.dockerfile +++ b/docker/fedora-39.dockerfile @@ -81,6 +81,13 @@ cuda_prefix="https://developer.download.nvidia.com/compute/cuda/" cuda_suffix="" if [[ "${TARGETPLATFORM}" == 'linux/arm64' ]]; then cuda_suffix="_sbsa" + + # patch headers https://bugs.launchpad.net/ubuntu/+source/mumax3/+bug/2032624 + sed -i 's/__Float32x4_t/int/g' /usr/include/bits/math-vector.h + sed -i 's/__Float64x2_t/int/g' /usr/include/bits/math-vector.h + sed -i 's/__SVFloat32_t/float/g' /usr/include/bits/math-vector.h + sed -i 's/__SVFloat64_t/float/g' /usr/include/bits/math-vector.h + sed -i 's/__SVBool_t/int/g' /usr/include/bits/math-vector.h fi url="${cuda_prefix}${CUDA_VERSION}/local_installers/cuda_${CUDA_VERSION}_${CUDA_BUILD}_linux${cuda_suffix}.run" echo "cuda url: ${url}" From c43dd2489f217e7ab04a16fc1bf7534cf6266e5f Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Wed, 13 Mar 2024 17:32:04 -0500 Subject: [PATCH 33/33] Don't update tray icon after tray_exit() was called --- CHANGELOG.md | 1 + src/system_tray.cpp | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6ab14e01b8e..d1c67c68c3f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,7 @@ - (Linux) Fix udev rules for uinput access not working until after reboot - (Linux) Fix wrong path in desktop files - (Tray) Cache icons to avoid possible DRM issues +- (Tray) Fix attempt to update tray icon after it was destroyed - (Linux) Migrate old config files to new location if env SUNSHINE_MIGRATE_CONFIG=1 is set (automatically set for Flatpak) - (Linux/Fedora) Re-enable CUDA support and bump to 12.4.0 diff --git a/src/system_tray.cpp b/src/system_tray.cpp index eb5948a41c1..c34c3d75a98 100644 --- a/src/system_tray.cpp +++ b/src/system_tray.cpp @@ -47,6 +47,8 @@ using namespace std::literals; // system_tray namespace namespace system_tray { + static std::atomic tray_initialized = false; + /** * @brief Callback for opening the UI from the system tray. * @param item The tray menu item. @@ -239,6 +241,7 @@ namespace system_tray { BOOST_LOG(info) << "System tray created"sv; } + tray_initialized = true; while (tray_loop(1) == 0) { BOOST_LOG(debug) << "System tray loop"sv; } @@ -275,6 +278,7 @@ namespace system_tray { */ int end_tray() { + tray_initialized = false; tray_exit(); return 0; } @@ -285,6 +289,10 @@ namespace system_tray { */ void update_tray_playing(std::string app_name) { + if (!tray_initialized) { + return; + } + tray.notification_title = NULL; tray.notification_text = NULL; tray.notification_cb = NULL; @@ -307,6 +315,10 @@ namespace system_tray { */ void update_tray_pausing(std::string app_name) { + if (!tray_initialized) { + return; + } + tray.notification_title = NULL; tray.notification_text = NULL; tray.notification_cb = NULL; @@ -329,6 +341,10 @@ namespace system_tray { */ void update_tray_stopped(std::string app_name) { + if (!tray_initialized) { + return; + } + tray.notification_title = NULL; tray.notification_text = NULL; tray.notification_cb = NULL; @@ -350,6 +366,10 @@ namespace system_tray { */ void update_tray_require_pin() { + if (!tray_initialized) { + return; + } + tray.notification_title = NULL; tray.notification_text = NULL; tray.notification_cb = NULL;