Skip to content

macOS: build-tree .app is incomplete (web UI race, no apps.json) and Homebrew Boost fails to link ICU #5787

Closed

Description

@Optimiza

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.

Activity

  1. ReenigneArcher commented on Sep 24, 2026

    @ReenigneArcher
    Member

    When you static link boost, you need to then link against icu4c. If you use the system boost then you don't.

  2. Optimiza commented on Sep 25, 2026

    @Optimiza
    Author

    Thanks, confirmed. The ICU link comes from the static default: BOOST_USE_STATIC is ON (cmake/prep/options.cmake#L29), and Homebrew's static boost_locale config names icudata, icui18n and icuuc bare, while icu4c is keg-only. Configuring the same tree with -DBOOST_USE_STATIC=OFF and no linker flag builds and links: the link line has no -licu*, and otool -L shows the binary loading Homebrew's Boost dylibs, which reference ICU by absolute path. So item 3 is not a defect in the system Boost path; I'm withdrawing it.

    What still reads the other way is docs/building.md#L123, which lists icu4c as "Optional, if boost is not installed". With the static default it is needed when Boost is installed. Either that comment, or a note that Homebrew users can pass -DBOOST_USE_STATIC=OFF, would have saved me the detour.

    Items 1 and 2 still stand on current master (05350c05): nothing orders web-ui before the POST_BUILD copy in cmake/targets/macos.cmake#L18-L22, and the macOS assets, apps.json among them, reach the build tree only in the Homebrew branch of cmake/packaging/macos.cmake#L3-L9.

    A note on how this is written: I run these tests automated with an AI assistant, and I use it to write in English and to carry the log lines over without copying them by hand. The runs, the verdicts and the decision to post are mine.

  3. ReenigneArcher commented on Sep 25, 2026

    @ReenigneArcher
    Member

    Homebrew didn't used to provide static boost, they only recently started doing this.

    Anyway, everything is working in all our ci homebrew builds and dmg builds. You can submit a PR to address these issues if you want, but I don't really feel like having a conversation with an LLM inside of GitHub issues.

  4. Optimiza commented on Sep 25, 2026

    @Optimiza
    Author

    Okay, understood. I'll continue working on the other thing, and I'll leave this up to you. It's something that came to me while I was working on the video problems, and I thought it would be useful for you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions