Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .github/workflows/ci-windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,11 @@ jobs:
# Clean up
Remove-Item -Path doxygen-setup.exe

- name: Setup dotnet # needed for wix
uses: actions/setup-dotnet@baa11fbfe1d6520db94683bd5c7a3818018e4309 # v5.1.0
with:
dotnet-version: '10.x'

- name: Setup python
id: setup-python
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
Expand Down Expand Up @@ -176,12 +181,19 @@ jobs:

# package
cpack -G NSIS
cpack -G WIX
cpack -G ZIP

# move
mv ./cpack_artifacts/Sunshine.exe ../artifacts/Sunshine-${{ matrix.name }}-installer.exe
mv ./cpack_artifacts/Sunshine.msi ../artifacts/Sunshine-${{ matrix.name }}-installer.msi
mv ./cpack_artifacts/Sunshine.zip ../artifacts/Sunshine-${{ matrix.name }}-portable.zip

- name: Debug wix
if: always()
shell: msys2 {0}
run: cat ./build/cpack_artifacts/_CPack_Packages/win64/WIX/wix.log || true

- name: Run tests
id: test
shell: msys2 {0}
Expand Down
95 changes: 94 additions & 1 deletion cmake/packaging/windows_wix.cmake
Original file line number Diff line number Diff line change
@@ -1,4 +1,97 @@
# WIX Packaging
# see options at: https://cmake.org/cmake/help/latest/cpack_gen/wix.html

# TODO: Replace nsis with wix
# find dotnet
find_program(DOTNET_EXECUTABLE dotnet HINTS "C:/Program Files/dotnet")

if(NOT DOTNET_EXECUTABLE)
message(WARNING "Dotnet executable not found, skipping WiX packaging.")
return()
endif()

set(CPACK_WIX_VERSION 4)
set(WIX_VERSION 4.0.4)
set(WIX_UI_VERSION 4.0.4) # extension versioning is independent of the WiX version
set(WIX_BUILD_PARENT_DIRECTORY "${CMAKE_BINARY_DIR}/wix_packaging")
set(WIX_BUILD_DIRECTORY "${CPACK_PACKAGE_DIRECTORY}/_CPack_Packages/win64/WIX")

# Download and install WiX tools locally in the build directory
set(WIX_TOOL_PATH "${CMAKE_BINARY_DIR}/.wix")
file(MAKE_DIRECTORY ${WIX_TOOL_PATH})

# Install WiX locally using dotnet
execute_process(
COMMAND ${DOTNET_EXECUTABLE} tool install --tool-path ${WIX_TOOL_PATH} wix --version ${WIX_VERSION}
ERROR_VARIABLE WIX_INSTALL_OUTPUT
RESULT_VARIABLE WIX_INSTALL_RESULT
)

if(NOT WIX_INSTALL_RESULT EQUAL 0)
message(FATAL_ERROR "Failed to install WiX tools locally.
WiX packaging may not work correctly, error: ${WIX_INSTALL_OUTPUT}")
endif()

# Install WiX UI Extension
execute_process(
COMMAND "${WIX_TOOL_PATH}/wix" extension add WixToolset.UI.wixext/${WIX_UI_VERSION}
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
ERROR_VARIABLE WIX_UI_INSTALL_OUTPUT
RESULT_VARIABLE WIX_UI_INSTALL_RESULT
)

if(NOT WIX_UI_INSTALL_RESULT EQUAL 0)
message(FATAL_ERROR "Failed to install WiX UI extension, error: ${WIX_UI_INSTALL_OUTPUT}")
endif()

# Install WiX Util Extension
execute_process(
COMMAND "${WIX_TOOL_PATH}/wix" extension add WixToolset.Util.wixext/${WIX_UI_VERSION}
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
ERROR_VARIABLE WIX_UTIL_INSTALL_OUTPUT
RESULT_VARIABLE WIX_UTIL_INSTALL_RESULT
)

if(NOT WIX_UTIL_INSTALL_RESULT EQUAL 0)
message(FATAL_ERROR "Failed to install WiX Util extension, error: ${WIX_UTIL_INSTALL_OUTPUT}")
endif()

# Set WiX-specific variables
set(CPACK_WIX_ROOT "${WIX_TOOL_PATH}")
set(CPACK_WIX_UPGRADE_GUID "512A3D1B-BE16-401B-A0D1-59BBA3942FB8")

# Installer metadata
set(CPACK_WIX_HELP_LINK "https://docs.lizardbyte.dev/projects/sunshine/latest/md_docs_2getting__started.html")
set(CPACK_WIX_PRODUCT_ICON "${SUNSHINE_ICON_PATH}")
set(CPACK_WIX_PRODUCT_URL "${CMAKE_PROJECT_HOMEPAGE_URL}")
set(CPACK_WIX_PROGRAM_MENU_FOLDER "LizardByte")

set(CPACK_WIX_EXTENSIONS
"WixToolset.UI.wixext"
"WixToolset.Util.wixext"
)

message(STATUS "cpack package directory: ${CPACK_PACKAGE_DIRECTORY}")

# copy custom wxs files to the build directory
file(COPY "${CMAKE_CURRENT_LIST_DIR}/wix_resources/"
DESTINATION "${WIX_BUILD_PARENT_DIRECTORY}/")

set(CPACK_WIX_EXTRA_SOURCES
"${WIX_BUILD_PARENT_DIRECTORY}/sunshine-installer.wxs"
)
set(CPACK_WIX_PATCH_FILE
"${WIX_BUILD_PARENT_DIRECTORY}/patch.xml"
)

# Copy root LICENSE and rename to have .txt extension
file(COPY "${CMAKE_SOURCE_DIR}/LICENSE"
DESTINATION "${CMAKE_BINARY_DIR}")
file(RENAME "${CMAKE_BINARY_DIR}/LICENSE" "${CMAKE_BINARY_DIR}/LICENSE.txt")
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_BINARY_DIR}/LICENSE.txt") # cpack will covert this to an RTF if it is txt

# https://cmake.org/cmake/help/latest/cpack_gen/wix.html#variable:CPACK_WIX_ARCHITECTURE
if(CMAKE_SYSTEM_PROCESSOR MATCHES "ARM64")
set(CPACK_WIX_ARCHITECTURE "arm64")
else()
set(CPACK_WIX_ARCHITECTURE "x64")
endif()
5 changes: 5 additions & 0 deletions cmake/packaging/wix_resources/patch.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<CPackWiXPatch>
<CPackWiXFragment Id="CM_G_Core">
<FeatureRef Id="RunSunshineInstallScripts"/>
</CPackWiXFragment>
</CPackWiXPatch>
83 changes: 83 additions & 0 deletions cmake/packaging/wix_resources/sunshine-installer.wxs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"
xmlns:util="http://wixtoolset.org/schemas/v4/wxs/util">
<Fragment>
<StandardDirectory Id="ProgramMenuFolder">
<Component Id="ApplicationShortcutRoot" Guid="*">
<Shortcut Id="ApplicationStartMenuShortcutRoot"
Name="Sunshine"
Description="Sunshine Game Stream Host"
Target="[INSTALL_ROOT]sunshine.exe"
Arguments="--shortcut"
WorkingDirectory="INSTALL_ROOT"/>
<RegistryValue Root="HKCU" Key="Software\LizardByte\Sunshine" Name="installed_root" Type="integer" Value="1" KeyPath="yes"/>
</Component>
<Directory Id="ProgramMenuSubfolder" Name="LizardByte">
<Directory Id="ProgramMenuSunshineFolder" Name="Sunshine">
<Component Id="ApplicationShortcut" Guid="*">
<Shortcut Id="ApplicationStartMenuShortcut"
Name="Sunshine"
Description="Sunshine Game Stream Host"
Target="[INSTALL_ROOT]sunshine.exe"
Arguments="--shortcut"
WorkingDirectory="INSTALL_ROOT"/>
<RemoveFolder Id="CleanUpShortCut" Directory="ProgramMenuSunshineFolder" On="uninstall"/>
<RemoveFolder Id="CleanUpShortCutParent" Directory="ProgramMenuSubfolder" On="uninstall"/>
<RegistryValue Root="HKCU" Key="Software\LizardByte\Sunshine" Name="installed" Type="integer" Value="1" KeyPath="yes"/>
</Component>
<Component Id="DocumentationShortcut" Guid="*">
<util:InternetShortcut Id="DocumentationLink"
Name="Sunshine Documentation"
Target="https://docs.lizardbyte.dev/projects/sunshine"
Type="url"/>
<RemoveFolder Id="CleanUpDocsShortCut" Directory="ProgramMenuSunshineFolder" On="uninstall"/>
<RegistryValue Root="HKCU" Key="Software\LizardByte\Sunshine" Name="docs_shortcut" Type="integer" Value="1" KeyPath="yes"/>
</Component>
<Component Id="WebsiteShortcut" Guid="*">
<util:InternetShortcut Id="WebsiteLink"
Name="LizardByte Web Site"
Target="https://app.lizardbyte.dev"
Type="url"/>
<RemoveFolder Id="CleanUpWebsiteShortCut" Directory="ProgramMenuSunshineFolder" On="uninstall"/>
<RegistryValue Root="HKCU" Key="Software\LizardByte\Sunshine" Name="website_shortcut" Type="integer" Value="1" KeyPath="yes"/>
</Component>
<Component Id="SupportShortcut" Guid="*">
<util:InternetShortcut Id="SupportLink"
Name="LizardByte Support"
Target="https://app.lizardbyte.dev/support"
Type="url"/>
<RemoveFolder Id="CleanUpSupportShortCut" Directory="ProgramMenuSunshineFolder" On="uninstall"/>
<RegistryValue Root="HKCU" Key="Software\LizardByte\Sunshine" Name="support_shortcut" Type="integer" Value="1" KeyPath="yes"/>
</Component>
</Directory>
</Directory>
</StandardDirectory>

<!-- Install: Run sunshine-setup.ps1 with -Action install, add -Silent if UILevel <= 3 (silent/basic UI) -->
<CustomAction Id="CA_SunshineInstall" Directory="INSTALL_ROOT" ExeCommand="powershell.exe -NoProfile -ExecutionPolicy Bypass -File &quot;[INSTALL_ROOT]scripts\sunshine-setup.ps1&quot; -Action install" Execute="deferred" Return="ignore" Impersonate="no" />
<CustomAction Id="CA_SunshineInstallSilent" Directory="INSTALL_ROOT" ExeCommand="powershell.exe -WindowStyle Hidden -NoProfile -ExecutionPolicy Bypass -File &quot;[INSTALL_ROOT]scripts\sunshine-setup.ps1&quot; -Action install -Silent" Execute="deferred" Return="ignore" Impersonate="no" />

<!-- Uninstall: Run sunshine-setup.ps1 with -Action uninstall, add -Silent if UILevel <= 3 (silent/basic UI) -->
<CustomAction Id="CA_SunshineUninstall" Directory="INSTALL_ROOT" ExeCommand="powershell.exe -NoProfile -ExecutionPolicy Bypass -File &quot;[INSTALL_ROOT]scripts\sunshine-setup.ps1&quot; -Action uninstall" Execute="deferred" Return="ignore" Impersonate="no" />
<CustomAction Id="CA_SunshineUninstallSilent" Directory="INSTALL_ROOT" ExeCommand="powershell.exe -WindowStyle Hidden -NoProfile -ExecutionPolicy Bypass -File &quot;[INSTALL_ROOT]scripts\sunshine-setup.ps1&quot; -Action uninstall -Silent" Execute="deferred" Return="ignore" Impersonate="no" />

<InstallExecuteSequence>
<!-- Run installation script after files are installed -->
<!-- UILevel > 3 means Full UI (interactive), UILevel <= 3 means Silent/Basic UI -->
<Custom Action="CA_SunshineInstall" After="InstallFiles" Condition="NOT Installed AND UILevel &gt; 3" />
<Custom Action="CA_SunshineInstallSilent" After="InstallFiles" Condition="NOT Installed AND UILevel &lt;= 3" />

<!-- Run uninstallation script before files are removed -->
<Custom Action="CA_SunshineUninstall" Before="RemoveFiles" Condition="REMOVE=&quot;ALL&quot; AND UILevel &gt; 3" />
<Custom Action="CA_SunshineUninstallSilent" Before="RemoveFiles" Condition="REMOVE=&quot;ALL&quot; AND UILevel &lt;= 3" />
</InstallExecuteSequence>

<!-- We need this in order to actually run our custom actions, but let's hide it -->
<Feature Id="RunSunshineInstallScripts" Title="Run Sunshine Installation Scripts" Level="1" Display="hidden">
<ComponentRef Id="ApplicationShortcutRoot" />
<ComponentRef Id="ApplicationShortcut" />
<ComponentRef Id="DocumentationShortcut" />
<ComponentRef Id="WebsiteShortcut" />
<ComponentRef Id="SupportShortcut" />
</Feature>
</Fragment>
</Wix>
4 changes: 2 additions & 2 deletions cmake/prep/build_version.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,11 @@ else()
if(NOT GIT_DESCRIBE_ERROR_CODE)
MESSAGE("Sunshine Branch: ${GIT_DESCRIBE_BRANCH}")
if(NOT GIT_DESCRIBE_BRANCH STREQUAL "master")
set(PROJECT_VERSION ${PROJECT_VERSION}.${GIT_DESCRIBE_VERSION})
set(PROJECT_VERSION ${PROJECT_VERSION}-${GIT_DESCRIBE_VERSION})
MESSAGE("Sunshine Version: ${GIT_DESCRIBE_VERSION}")
endif()
if(GIT_IS_DIRTY)
set(PROJECT_VERSION ${PROJECT_VERSION}.dirty)
set(PROJECT_VERSION ${PROJECT_VERSION}-dirty)
MESSAGE("Git tree is dirty!")
endif()
else()
Expand Down
7 changes: 6 additions & 1 deletion docs/building.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,8 @@ dependencies=(
pacman -S "${dependencies[@]}"
```

To create a WiX installer, you also need to install [.NET](https://dotnet.microsoft.com/download).

### Clone
Ensure [git](https://git-scm.com) is installed on your system, then clone the repository using the following command:

Expand Down Expand Up @@ -198,9 +200,12 @@ ninja -C build
```}
}}
@tab{Windows | @tabs{
@tab{Installer | ```bash
@tab{NSIS Installer | ```bash
cpack -G NSIS --config ./build/CPackConfig.cmake
```}
@tab{WiX Installer | ```bash
cpack -G WIX --config ./build/CPackConfig.cmake
```}
@tab{Portable | ```bash
cpack -G ZIP --config ./build/CPackConfig.cmake
```}
Expand Down
6 changes: 6 additions & 0 deletions docs/getting_started.md
Original file line number Diff line number Diff line change
Expand Up @@ -331,14 +331,20 @@ brew uninstall sunshine

#### Installer (recommended)

> [!CAUTION]
> The msi installer is preferred moving forward. Before using a different type of installer, you should manually
> uninstall the previous installation.
1. Download and install
[Sunshine-Windows-AMD64-installer.msi](https://github.com/LizardByte/Sunshine/releases/latest/download/Sunshine-Windows-AMD64-installer.msi)
[Sunshine-Windows-AMD64-installer.exe](https://github.com/LizardByte/Sunshine/releases/latest/download/Sunshine-Windows-AMD64-installer.exe)

> [!TIP]
> Installer logs can be found in the following locations.<br>
> | File | log paths |
> | ---- | --------- |
> | .exe | `%%PROGRAMFILES%/Sunshine/install.log`<br>`%%TEMP%/Sunshine/logs/install/` |
> | .msi | `%%TEMP%/Sunshine/logs/install/` |
> [!CAUTION]
> You should carefully select or unselect the options you want to install. Do not blindly install or
Expand Down
Loading