From 392499294a96c3221b126c231134a66278385695 Mon Sep 17 00:00:00 2001 From: ReenigneArcher <42013603+ReenigneArcher@users.noreply.github.com> Date: Sat, 24 May 2025 11:07:36 -0400 Subject: [PATCH] build(windows): add arm64 build --- .github/workflows/CI.yml | 119 +++++++++++++++--------- cmake/compile_definitions/windows.cmake | 7 +- cmake/dependencies/windows.cmake | 14 +-- docs/building.md | 48 ++++++---- docs/getting_started.md | 20 +++- src/platform/windows/display_base.cpp | 10 +- 6 files changed, 146 insertions(+), 72 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index e1171a27179..36909240908 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -740,9 +740,26 @@ jobs: validate: false build_win: - name: Windows + name: ${{ matrix.name }} needs: setup_release - runs-on: windows-2019 + runs-on: ${{ matrix.os }} + defaults: + run: + shell: msys2 {0} + strategy: + fail-fast: false + matrix: + include: + - name: Windows-AMD64 + os: windows-2019 + arch: x86_64 + msystem: ucrt64 + toolchain: ucrt-x86_64 + - name: Windows-ARM64 + os: windows-11-arm + arch: aarch64 + msystem: clangarm64 + toolchain: clang-aarch64 steps: - name: Checkout uses: actions/checkout@v4 @@ -752,6 +769,7 @@ jobs: - name: Prepare tests id: prepare-tests if: false # todo: DirectX11 is not available, so even software encoder fails + shell: pwsh run: | # function to download and extract a zip file function DownloadAndExtract { @@ -854,63 +872,80 @@ jobs: Get-Content -Path monitor_list.txt - name: Setup Dependencies Windows - # if a dependency needs to be pinned, see https://github.com/LizardByte/build-deps/pull/186 uses: msys2/setup-msys2@v2 with: - msystem: ucrt64 + msystem: ${{ matrix.msystem }} update: true - install: >- - wget - name: Update Windows dependencies env: - gcc_version: "14.2.0-3" - shell: msys2 {0} + MSYSTEM: ${{ matrix.msystem }} + TOOLCHAIN: ${{ matrix.toolchain }} run: | - broken_deps=( - "mingw-w64-ucrt-x86_64-gcc" - "mingw-w64-ucrt-x86_64-gcc-libs" + # variables + declare -A pinned_deps + if [[ ${MSYSTEM} == "ucrt64" ]]; then + pinned_deps["mingw-w64-${TOOLCHAIN}-gcc"]="14.2.0-3" + pinned_deps["mingw-w64-${TOOLCHAIN}-gcc-libs"]="14.2.0-3" + fi + + dependencies=( + "git" + "mingw-w64-${TOOLCHAIN}-cmake" + "mingw-w64-${TOOLCHAIN}-cppwinrt" + "mingw-w64-${TOOLCHAIN}-curl-winssl" + "mingw-w64-${TOOLCHAIN}-graphviz" + "mingw-w64-${TOOLCHAIN}-miniupnpc" + "mingw-w64-${TOOLCHAIN}-nlohmann-json" + "mingw-w64-${TOOLCHAIN}-nodejs" + "mingw-w64-${TOOLCHAIN}-onevpl" + "mingw-w64-${TOOLCHAIN}-openssl" + "mingw-w64-${TOOLCHAIN}-opus" + "mingw-w64-${TOOLCHAIN}-toolchain" ) + if [[ ${MSYSTEM} == "ucrt64" ]]; then + dependencies+=( + "mingw-w64-${TOOLCHAIN}-MinHook" + "mingw-w64-${TOOLCHAIN}-nsis" # TODO: how to create an arm64 installer? + ) + fi + + # do not modify below this line + + ignore_packages=() tarballs="" - for dep in "${broken_deps[@]}"; do - tarball="${dep}-${gcc_version}-any.pkg.tar.zst" + for pkg in "${!pinned_deps[@]}"; do + ignore_packages+=("${pkg}") + version="${pinned_deps[$pkg]}" + tarball="${pkg}-${version}-any.pkg.tar.zst" # download and install working version - wget https://repo.msys2.org/mingw/ucrt64/${tarball} + wget "https://repo.msys2.org/mingw/${MSYSTEM}/${tarball}" tarballs="${tarballs} ${tarball}" done - # install broken dependencies + # Create the ignore string for pacman + ignore_list=$(IFS=,; echo "${ignore_packages[*]}") + + # install pinned dependencies if [ -n "$tarballs" ]; then pacman -U --noconfirm ${tarballs} fi - # install dependencies - dependencies=( - "git" - "mingw-w64-ucrt-x86_64-cmake" - "mingw-w64-ucrt-x86_64-cppwinrt" - "mingw-w64-ucrt-x86_64-curl-winssl" - "mingw-w64-ucrt-x86_64-graphviz" - "mingw-w64-ucrt-x86_64-MinHook" - "mingw-w64-ucrt-x86_64-miniupnpc" - "mingw-w64-ucrt-x86_64-nlohmann-json" - "mingw-w64-ucrt-x86_64-nodejs" - "mingw-w64-ucrt-x86_64-nsis" - "mingw-w64-ucrt-x86_64-onevpl" - "mingw-w64-ucrt-x86_64-openssl" - "mingw-w64-ucrt-x86_64-opus" - "mingw-w64-ucrt-x86_64-toolchain" - ) - - pacman -Syu --noconfirm --ignore="$(IFS=,; echo "${broken_deps[*]}")" "${dependencies[@]}" + # Only add --ignore if we have packages to ignore + if [ -n "$ignore_list" ]; then + pacman -Syu --noconfirm --ignore="${ignore_list}" "${dependencies[@]}" + else + pacman -Syu --noconfirm "${dependencies[@]}" + fi - name: Install Doxygen # GCC compiled doxygen has issues when running graphviz env: DOXYGEN_VERSION: "1.11.0" + shell: pwsh run: | # Set version variables $doxy_ver = $env:DOXYGEN_VERSION @@ -940,7 +975,6 @@ jobs: - name: Python Path id: python-path - shell: msys2 {0} run: | # replace backslashes with double backslashes python_path=$(echo "${{ steps.setup-python.outputs.python-path }}" | sed 's/\\/\\\\/g') @@ -950,7 +984,6 @@ jobs: echo "python-path=${python_path}" >> $GITHUB_OUTPUT - name: Build Windows - shell: msys2 {0} env: BRANCH: ${{ github.head_ref || github.ref_name }} BUILD_VERSION: ${{ needs.setup_release.outputs.release_tag }} @@ -971,7 +1004,6 @@ jobs: ninja -C build - name: Package Windows - shell: msys2 {0} run: | mkdir -p artifacts cd build @@ -981,12 +1013,11 @@ jobs: cpack -G ZIP # move - mv ./cpack_artifacts/Sunshine.exe ../artifacts/sunshine-windows-installer.exe - mv ./cpack_artifacts/Sunshine.zip ../artifacts/sunshine-windows-portable.zip + mv ./cpack_artifacts/Sunshine.exe ../artifacts/Sunshine-${{ matrix.os }}-installer.exe + mv ./cpack_artifacts/Sunshine.zip ../artifacts/Sunshine-${{ matrix.os }}-portable.zip - name: Run tests id: test - shell: msys2 {0} working-directory: build/tests run: | ./test_sunshine.exe --gtest_color=yes --gtest_output=xml:test_results.xml @@ -995,7 +1026,6 @@ jobs: id: test_report # any except canceled or skipped if: always() && (steps.test.outcome == 'success' || steps.test.outcome == 'failure') - shell: msys2 {0} working-directory: build run: | ${{ steps.python-path.outputs.python-path }} -m pip install gcovr @@ -1018,7 +1048,7 @@ jobs: disable_search: true fail_ci_if_error: true files: ./build/tests/test_results.xml - flags: ${{ runner.os }} + flags: ${{ matrix.name }} handle_no_reports_found: true token: ${{ secrets.CODECOV_TOKEN }} verbose: true @@ -1034,11 +1064,12 @@ jobs: disable_search: true fail_ci_if_error: true files: ./build/coverage.xml - flags: ${{ runner.os }} + flags: ${{ matrix.name }} token: ${{ secrets.CODECOV_TOKEN }} verbose: true - name: Package Windows Debug Info + shell: pwsh working-directory: build run: | # use .dbg file extension for binaries to avoid confusion with real packages @@ -1049,7 +1080,7 @@ jobs: 7z -r ` "-xr!CMakeFiles" ` "-xr!cpack_artifacts" ` - a "../artifacts/sunshine-win32-debuginfo.7z" "*.dbg" + a "../artifacts/${{ matrix.name }}-debuginfo.7z" "*.dbg" - name: Upload Artifacts uses: actions/upload-artifact@v4 diff --git a/cmake/compile_definitions/windows.cmake b/cmake/compile_definitions/windows.cmake index a3009be0aa4..6b21276195e 100644 --- a/cmake/compile_definitions/windows.cmake +++ b/cmake/compile_definitions/windows.cmake @@ -75,7 +75,6 @@ list(PREPEND PLATFORM_LIBRARIES libssp.a libstdc++.a libwinpthread.a - minhook::minhook ntdll setupapi shlwapi @@ -85,6 +84,12 @@ list(PREPEND PLATFORM_LIBRARIES wsock32 ) +if(CMAKE_SYSTEM_PROCESSOR MATCHES "AMD64") + list(APPEND PLATFORM_LIBRARIES + minhook::minhook + ) +endif() + if(SUNSHINE_ENABLE_TRAY) list(APPEND PLATFORM_TARGET_FILES "${CMAKE_SOURCE_DIR}/third-party/tray/src/tray_windows.c") diff --git a/cmake/dependencies/windows.cmake b/cmake/dependencies/windows.cmake index 3faad7dfd41..3527418bd17 100644 --- a/cmake/dependencies/windows.cmake +++ b/cmake/dependencies/windows.cmake @@ -1,9 +1,11 @@ # windows specific dependencies -# Make sure MinHook is installed -find_library(MINHOOK_LIBRARY libMinHook.a REQUIRED) -find_path(MINHOOK_INCLUDE_DIR MinHook.h PATH_SUFFIXES include REQUIRED) +if(CMAKE_SYSTEM_PROCESSOR MATCHES "AMD64") + # Make sure MinHook is installed + find_library(MINHOOK_LIBRARY libMinHook.a REQUIRED) + find_path(MINHOOK_INCLUDE_DIR MinHook.h PATH_SUFFIXES include REQUIRED) -add_library(minhook::minhook STATIC IMPORTED) -set_property(TARGET minhook::minhook PROPERTY IMPORTED_LOCATION ${MINHOOK_LIBRARY}) -target_include_directories(minhook::minhook INTERFACE ${MINHOOK_INCLUDE_DIR}) + add_library(minhook::minhook STATIC IMPORTED) + set_property(TARGET minhook::minhook PROPERTY IMPORTED_LOCATION ${MINHOOK_LIBRARY}) + target_include_directories(minhook::minhook INTERFACE ${MINHOOK_INCLUDE_DIR}) +endif() diff --git a/docs/building.md b/docs/building.md index b7f5d402601..a9278dda196 100644 --- a/docs/building.md +++ b/docs/building.md @@ -72,33 +72,49 @@ sudo port install "${dependencies[@]}" ``` #### Windows -First you need to install [MSYS2](https://www.msys2.org), then startup "MSYS2 UCRT64" and execute the following -commands. +First you need to install [MSYS2](https://www.msys2.org). + +For AMD64 startup "MSYS2 UCRT64", or for ARM64 startup "MSYS2 CLANGARM64", then execute the following commands. ##### Update all packages ```bash pacman -Syu ``` +##### Set toolchain variable +For UCRT64: +```bash +export TOOLCHAIN="ucrt64-x86_64" +``` + +For CLANGARM64: +```bash +export TOOLCHAIN="clang-aarch64" +``` + ##### Install dependencies ```bash dependencies=( "git" - "mingw-w64-ucrt-x86_64-boost" # Optional - "mingw-w64-ucrt-x86_64-cmake" - "mingw-w64-ucrt-x86_64-cppwinrt" - "mingw-w64-ucrt-x86_64-curl-winssl" - "mingw-w64-ucrt-x86_64-doxygen" # Optional, for docs... better to install official Doxygen - "mingw-w64-ucrt-x86_64-graphviz" # Optional, for docs - "mingw-w64-ucrt-x86_64-MinHook" - "mingw-w64-ucrt-x86_64-miniupnpc" - "mingw-w64-ucrt-x86_64-nodejs" - "mingw-w64-ucrt-x86_64-nsis" - "mingw-w64-ucrt-x86_64-onevpl" - "mingw-w64-ucrt-x86_64-openssl" - "mingw-w64-ucrt-x86_64-opus" - "mingw-w64-ucrt-x86_64-toolchain" + "mingw-w64-${TOOLCHAIN}-boost" # Optional + "mingw-w64-${TOOLCHAIN}-cmake" + "mingw-w64-${TOOLCHAIN}-cppwinrt" + "mingw-w64-${TOOLCHAIN}-curl-winssl" + "mingw-w64-${TOOLCHAIN}-doxygen" # Optional, for docs... better to install official Doxygen + "mingw-w64-${TOOLCHAIN}-graphviz" # Optional, for docs + "mingw-w64-${TOOLCHAIN}-miniupnpc" + "mingw-w64-${TOOLCHAIN}-nodejs" + "mingw-w64-${TOOLCHAIN}-onevpl" + "mingw-w64-${TOOLCHAIN}-openssl" + "mingw-w64-${TOOLCHAIN}-opus" + "mingw-w64-${TOOLCHAIN}-toolchain" ) +if [[ ${MSYSTEM} == "ucrt64" ]]; then + dependencies+=( + "mingw-w64-${TOOLCHAIN}-MinHook" + "mingw-w64-${TOOLCHAIN}-nsis" # TODO: how to create an arm64 installer? + ) +fi pacman -S "${dependencies[@]}" ``` diff --git a/docs/getting_started.md b/docs/getting_started.md index 88f40844533..2c18128b561 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -280,10 +280,17 @@ brew uninstall sunshine ### Windows +Sunshine now supports ARM64 on Windows; however this should be considered experimental. This version does not properly +support GPU scheduling. + #### Installer (recommended) -1. Download and install - [sunshine-windows-installer.exe](https://github.com/LizardByte/Sunshine/releases/latest/download/sunshine-windows-installer.exe) +1. Download and install based on your architecture: + + | Architecture | Installer | + |-----------------------|----------------------------------------------------------------------------------------------------------------------------------------------| + | AMD64/x64 (Intel/AMD) | [Sunshine-Windows-AMD64-installer.exe](https://github.com/LizardByte/Sunshine/releases/latest/download/Sunshine-Windows-AMD64-installer.exe) | + | ARM64 | [Sunshine-Windows-ARM64-installer.exe](https://github.com/LizardByte/Sunshine/releases/latest/download/Sunshine-Windows-ARM64-installer.exe) | @attention{You should carefully select or unselect the options you want to install. Do not blindly install or enable features.} @@ -296,8 +303,13 @@ overflow menu. Different versions of Windows may provide slightly different step @warning{By using this package instead of the installer, performance will be reduced. This package is not recommended for most users. No support will be provided!} -1. Download and extract - [sunshine-windows-portable.zip](https://github.com/LizardByte/Sunshine/releases/latest/download/sunshine-windows-portable.zip) +1. Download and extract based on your architecture: + + | Architecture | Installer | + |-----------------------|--------------------------------------------------------------------------------------------------------------------------------------------| + | AMD64/x64 (Intel/AMD) | [Sunshine-Windows-AMD64-portable.exe](https://github.com/LizardByte/Sunshine/releases/latest/download/Sunshine-Windows-AMD64-portable.zip) | + | ARM64 | [Sunshine-Windows-ARM64-portable.exe](https://github.com/LizardByte/Sunshine/releases/latest/download/Sunshine-Windows-ARM64-portable.zip) | + 2. Open command prompt as administrator 3. Firewall rules diff --git a/src/platform/windows/display_base.cpp b/src/platform/windows/display_base.cpp index 6698566207f..adec636f0f9 100644 --- a/src/platform/windows/display_base.cpp +++ b/src/platform/windows/display_base.cpp @@ -12,7 +12,11 @@ // lib includes #include #include -#include + +// conditional includes +#if defined(__x86_64__) || defined(__amd64__) + #include +#endif // We have to include boost/process/v1.hpp before display.h due to WinSock.h, // but that prevents the definition of NTSTATUS so we must define it ourself. @@ -407,6 +411,7 @@ namespace platf::dxgi { return false; } +#if defined(__x86_64__) || defined(__amd64__) /** * @brief Hook for NtGdiDdDDIGetCachedHybridQueryValue() from win32u.dll. * @param gpuPreference A pointer to the location where the preference will be written. @@ -425,6 +430,7 @@ namespace platf::dxgi { return STATUS_INVALID_PARAMETER; } } +#endif int display_base_t::init(const ::video::config_t &config, const std::string &display_name) { std::once_flag windows_cpp_once_flag; @@ -444,12 +450,14 @@ namespace platf::dxgi { FreeLibrary(user32); } +#if defined(__x86_64__) || defined(__amd64__) { // We aren't calling MH_Uninitialize(), but that's okay because this hook lasts for the life of the process MH_Initialize(); MH_CreateHookApi(L"win32u.dll", "NtGdiDdDDIGetCachedHybridQueryValue", (void *) NtGdiDdDDIGetCachedHybridQueryValueHook, nullptr); MH_EnableHook(MH_ALL_HOOKS); } +#endif }); // Get rectangle of full desktop for absolute mouse coordinates