Skip to content
Open
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
7 changes: 7 additions & 0 deletions cmake/compile_definitions/macos.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,18 @@ list(APPEND SUNSHINE_EXTERNAL_LIBRARIES
${CORE_MEDIA_LIBRARY}
${CORE_VIDEO_LIBRARY}
${FOUNDATION_LIBRARY}
${IOKIT_LIBRARY}
${VIDEO_TOOLBOX_LIBRARY})

set(APPLE_PLIST_TEMPLATE "${SUNSHINE_SOURCE_ASSETS_DIR}/macos/build/Info.plist.in")
set(APPLE_PLIST_FILE "${CMAKE_BINARY_DIR}/Info.plist")
configure_file("${APPLE_PLIST_TEMPLATE}" "${APPLE_PLIST_FILE}" @ONLY)

# Code-signing entitlements (used by the .app codesign step in
# cmake/packaging/macos.cmake). Grants com.apple.hid.manager.user-access-device
# for the virtual HID gamepad in src/platform/macos/input.cpp.
set(APPLE_ENTITLEMENTS_FILE "${SUNSHINE_SOURCE_ASSETS_DIR}/macos/build/sunshine.entitlements")

set(PLATFORM_TARGET_FILES
"${CMAKE_SOURCE_DIR}/src/platform/macos/av_audio.h"
"${CMAKE_SOURCE_DIR}/src/platform/macos/av_audio.mm"
Expand All @@ -49,6 +55,7 @@ set(PLATFORM_TARGET_FILES
"${CMAKE_SOURCE_DIR}/src/platform/macos/av_video.m"
"${CMAKE_SOURCE_DIR}/src/platform/macos/display.mm"
"${CMAKE_SOURCE_DIR}/src/platform/macos/input.cpp"
"${CMAKE_SOURCE_DIR}/src/platform/macos/input_gamepad.h"
"${CMAKE_SOURCE_DIR}/src/platform/macos/microphone.mm"
"${CMAKE_SOURCE_DIR}/src/platform/macos/misc.mm"
"${CMAKE_SOURCE_DIR}/src/platform/macos/misc.h"
Expand Down
1 change: 1 addition & 0 deletions cmake/dependencies/macos.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ FIND_LIBRARY(CORE_AUDIO_LIBRARY CoreAudio)
FIND_LIBRARY(CORE_MEDIA_LIBRARY CoreMedia)
FIND_LIBRARY(CORE_VIDEO_LIBRARY CoreVideo)
FIND_LIBRARY(FOUNDATION_LIBRARY Foundation)
FIND_LIBRARY(IOKIT_LIBRARY IOKit)
FIND_LIBRARY(VIDEO_TOOLBOX_LIBRARY VideoToolbox)

if(SUNSHINE_ENABLE_TRAY)
Expand Down
7 changes: 6 additions & 1 deletion cmake/packaging/macos.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,14 @@ else()
endforeach()
endif()

# Sign the app last
# Sign the app last. The --entitlements file grants
# com.apple.hid.manager.user-access-device, required by the virtual
# HID gamepad (src/platform/macos/input.cpp). This is an Apple-
# restricted entitlement: the signing identity must be authorized for
# it by Apple, or notarization/AMFI will reject the build.
execute_process(COMMAND /usr/bin/codesign --verbose=2
--sign \"${APPLE_CODESIGN_IDENTITY}\" \"\${_app}\"
--entitlements \"${APPLE_ENTITLEMENTS_FILE}\"
--force --timestamp --options=runtime
RESULT_VARIABLE rc3
)
Expand Down
50 changes: 50 additions & 0 deletions docs/building.md
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,56 @@ ninja -C build
}}
}

### macOS code signing & entitlements
The macOS virtual gamepad publishes a virtual HID device via `IOHIDUserDeviceCreate`,
which requires the `com.apple.hid.manager.user-access-device` entitlement. Builds that
don't carry it (Homebrew, unsigned PR/CI builds) still run normally — `IOHIDUserDeviceCreate`
fails, the gamepad is simply unavailable, and the rest of Sunshine is unaffected. AMFI only
terminates Sunshine when a build *declares* this restricted entitlement under a signature
that isn't authorized to use it (see below).

The entitlements are defined in `src_assets/macos/build/sunshine.entitlements` and are
applied automatically when the `.app` is signed (when `SHOULD_SIGN=true`).

This is an Apple-**restricted** entitlement, which has two consequences:

- **Official / distributed builds:** the Developer ID signing identity must be authorized
by Apple for this entitlement, otherwise notarization (and AMFI at runtime) will reject
the build.
- **Local development (ad-hoc signed) builds:** ad-hoc signatures are not trusted to carry
restricted entitlements, so AMFI will still kill the process. To test the gamepad locally,
first sign the built `.app` with the entitlements:
```bash
codesign --force --deep --sign - \
--entitlements src_assets/macos/build/sunshine.entitlements \
./build/Sunshine.app
```
Then relax AMFI enforcement so the ad-hoc binary is allowed to use the restricted
entitlement. AMFI is controlled by the `amfi_get_out_of_my_way=0x1` boot argument (there is
no `csrutil` switch for it), and setting boot arguments requires SIP to be disabled. **This
weakens system security and is intended for development machines only.**

- **Intel:** boot into Recovery (⌘-R), open Terminal, then:
```bash
csrutil disable
nvram boot-args="amfi_get_out_of_my_way=0x1"
```
Reboot back into macOS.
- **Apple Silicon:** boot into Recovery (hold the power button), set the startup disk to
*Reduced Security* with *"Allow user management of kernel extensions"* via Startup Security
Utility, then from a Recovery Terminal:
```bash
csrutil disable
bputil -k # follow the prompts to allow boot-args
nvram boot-args="amfi_get_out_of_my_way=0x1"
```
Reboot back into macOS. (Exact steps vary by macOS version — consult Apple's current
Startup Security Utility documentation.)

When you are done developing, **revert these changes**: clear the boot argument
(`sudo nvram -d boot-args`) and re-enable SIP from Recovery with `csrutil enable` (and
restore *Full Security* on Apple Silicon).

### Remote Build
It may be beneficial to build remotely in some cases. This will enable easier building on different operating systems.

Expand Down
3 changes: 0 additions & 3 deletions docs/getting_started.md
Original file line number Diff line number Diff line change
Expand Up @@ -305,9 +305,6 @@ brew uninstall sunshine

### macOS

> [!IMPORTANT]
> Sunshine on macOS is experimental. Gamepads do not work.

#### DMG

##### Install
Expand Down
2 changes: 1 addition & 1 deletion gh-pages-template/_data/features.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
Use nearly any controller on your Moonlight client!
<br><small><ul>
<li>Nintendo Switch emulation is only available on Linux.</li>
<li>Gamepad emulation is not currently supported on macOS.</li>
<li>On macOS, only a generic gamepad is emulated, since an Xbox gamepad cannot be properly emulated on it.</li>
</ul></small>

- title: "Configurable"
Expand Down
Loading