Follow-up from #5511, where @martona asked for these to be filed separately since they are not caused by that PR. The code involved is current master (c48e50e). I hit them building #5511's branch and @martona's macos-latency branch, whose CMake files differ from master only by the ScreenCaptureKit framework and the source list; item 2 was re-run today against that build. They affect the .app that a plain cmake + ninja build leaves in the build tree, which cmake/targets/macos.cmake populates on purpose "for local runs".
Environment: macOS 26.7 on Apple M4, Apple clang 21.0.0, CMake 4.4.3, Ninja 1.13.2, Homebrew Boost 1.92.0, icu4c 78.3, Qt 6.11.2. Configured with cmake -B build -G Ninja -S . -DCMAKE_BUILD_TYPE=Release -DBUILD_DOCS=OFF.
1. The web UI can be missing from the bundle (build race)
The bundle's resources are copied by a POST_BUILD step on sunshine (cmake/targets/macos.cmake#L18-L22), which copies ${CMAKE_BINARY_DIR}/assets. That directory's web UI is written by web-ui, a separate ALL target (cmake/targets/common.cmake#L91). No add_dependencies links the two, so Ninja is free to link sunshine and run the copy before web-ui has written anything.
Seen on two fresh builds. On #5511's branch the copy ran 13 seconds before the web UI finished, and the bundle got 1 of 82 web files and no index.html, so the configuration UI served a blank page. On macos-latency the bundle got no web directory at all, against 75 files in build/assets/web. It is intermittent, so a rebuild can look fine.
Suggested fix: add_dependencies(sunshine web-ui) in the .app branch.
2. apps.json is not in the build-tree bundle, and Sunshine then exits with status 0
The same POST_BUILD step copies only ${CMAKE_BINARY_DIR}/assets. The macOS-specific assets, apps.json among them, are copied into the build tree only in the Homebrew branch (cmake/packaging/macos.cmake#L8) and otherwise only at install time (#L54).
On a first run, with no apps.json at file_apps yet, src/config.cpp#L1784-L1785 copies it from the bundle and the copy throws. Reproduced today with a fresh state directory:
Failed to apply config: filesystem error: in copy_file: No such file or directory ["<state>/apps.json"] ["../Resources/assets/apps.json"]
Two things make this harder to diagnose than it needs to be:
- The process exits with status 0, because the parse failure shares
return 0 with the non-error early exits (src/main.cpp#L253-L255). A supervisor or a script sees a clean exit.
- The message only reaches stdout: the log file is initialised after the config parse (#L257), so
sunshine.log is never created.
Suggested fix: have the POST_BUILD step also copy ${SUNSHINE_SOURCE_ASSETS_DIR}/macos/assets/ into the bundle's Resources/assets, as the install step does. Returning a non-zero status on a config failure would be a separate, small improvement.
3. Homebrew Boost fails to link: library 'icudata' not found
Since #5730 the build accepts any system Boost at or above the minimum instead of fetching one. With Homebrew's Boost 1.92, boost_locale brings icudata, icui18n and icuuc onto the link line by name, but Homebrew's icu4c is keg-only, so its lib directory is not in MACOS_LINK_DIRECTORIES (cmake/compile_definitions/macos.cmake#L13-L14). The final link fails:
ld: library 'icudata' not found
Workaround: configure with -DCMAKE_EXE_LINKER_FLAGS="-L$(brew --prefix icu4c)/lib". Separately, docs/building.md lists icu4c as "Optional, if boost is not installed", which is now the opposite of what happens when Boost is installed.
Suggested fix: add the icu4c prefix to the macOS link directories when it exists, or resolve ICU with find_package(ICU).
A correction to my #5511 report
Section 4 there said the built .app only runs from Contents/MacOS because SUNSHINE_ASSETS_DIR is relative to the working directory. That was wrong: on macOS main.cpp anchors the working directory to the executable's folder at startup (since #4759). I retested by starting the binary from another directory, and the web UI is served exactly as from Contents/MacOS. What I saw at the time was item 2 above, not a working-directory problem.
Follow-up from #5511, where @martona asked for these to be filed separately since they are not caused by that PR. The code involved is current master (c48e50e). I hit them building #5511's branch and @martona's
macos-latencybranch, whose CMake files differ from master only by the ScreenCaptureKit framework and the source list; item 2 was re-run today against that build. They affect the.appthat a plaincmake+ninjabuild leaves in the build tree, whichcmake/targets/macos.cmakepopulates on purpose "for local runs".Environment: macOS 26.7 on Apple M4, Apple clang 21.0.0, CMake 4.4.3, Ninja 1.13.2, Homebrew Boost 1.92.0, icu4c 78.3, Qt 6.11.2. Configured with
cmake -B build -G Ninja -S . -DCMAKE_BUILD_TYPE=Release -DBUILD_DOCS=OFF.1. The web UI can be missing from the bundle (build race)
The bundle's resources are copied by a
POST_BUILDstep onsunshine(cmake/targets/macos.cmake#L18-L22), which copies${CMAKE_BINARY_DIR}/assets. That directory's web UI is written byweb-ui, a separateALLtarget (cmake/targets/common.cmake#L91). Noadd_dependencieslinks the two, so Ninja is free to linksunshineand run the copy beforeweb-uihas written anything.Seen on two fresh builds. On #5511's branch the copy ran 13 seconds before the web UI finished, and the bundle got 1 of 82 web files and no
index.html, so the configuration UI served a blank page. Onmacos-latencythe bundle got nowebdirectory at all, against 75 files inbuild/assets/web. It is intermittent, so a rebuild can look fine.Suggested fix:
add_dependencies(sunshine web-ui)in the.appbranch.2.
apps.jsonis not in the build-tree bundle, and Sunshine then exits with status 0The same
POST_BUILDstep copies only${CMAKE_BINARY_DIR}/assets. The macOS-specific assets,apps.jsonamong them, are copied into the build tree only in the Homebrew branch (cmake/packaging/macos.cmake#L8) and otherwise only at install time (#L54).On a first run, with no
apps.jsonatfile_appsyet, src/config.cpp#L1784-L1785 copies it from the bundle and the copy throws. Reproduced today with a fresh state directory:Two things make this harder to diagnose than it needs to be:
return 0with the non-error early exits (src/main.cpp#L253-L255). A supervisor or a script sees a clean exit.sunshine.logis never created.Suggested fix: have the
POST_BUILDstep also copy${SUNSHINE_SOURCE_ASSETS_DIR}/macos/assets/into the bundle'sResources/assets, as the install step does. Returning a non-zero status on a config failure would be a separate, small improvement.3. Homebrew Boost fails to link:
library 'icudata' not foundSince #5730 the build accepts any system Boost at or above the minimum instead of fetching one. With Homebrew's Boost 1.92,
boost_localebringsicudata,icui18nandicuuconto the link line by name, but Homebrew'sicu4cis keg-only, so itslibdirectory is not inMACOS_LINK_DIRECTORIES(cmake/compile_definitions/macos.cmake#L13-L14). The final link fails:Workaround: configure with
-DCMAKE_EXE_LINKER_FLAGS="-L$(brew --prefix icu4c)/lib". Separately,docs/building.mdlistsicu4cas "Optional, if boost is not installed", which is now the opposite of what happens when Boost is installed.Suggested fix: add the
icu4cprefix to the macOS link directories when it exists, or resolve ICU withfind_package(ICU).A correction to my #5511 report
Section 4 there said the built
.apponly runs fromContents/MacOSbecauseSUNSHINE_ASSETS_DIRis relative to the working directory. That was wrong: on macOSmain.cppanchors the working directory to the executable's folder at startup (since #4759). I retested by starting the binary from another directory, and the web UI is served exactly as fromContents/MacOS. What I saw at the time was item 2 above, not a working-directory problem.