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
4 changes: 2 additions & 2 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@
shallow = true
[submodule "third-party/nxdk"]
path = third-party/nxdk
url = https://github.com/ReenigneArcher/nxdk.git
branch = codex/moonlight-runtime
url = https://github.com/XboxDev/nxdk.git
branch = master
shallow = true
[submodule "third-party/openssl"]
path = third-party/openssl
Expand Down
10 changes: 6 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ if(MOONLIGHT_BUILD_KIND STREQUAL "XBOX")
set(CMAKE_CXX_STANDARD_REQUIRED ON)

option(BUILD_DOCS "Build documentation" OFF)
option(MOONLIGHT_SKIP_NXDK_PREP "Skip nxdk bootstrap during the internal Xbox child configure" OFF)

include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/xbox-build.cmake")
return()
Expand Down Expand Up @@ -72,10 +71,13 @@ endif()
if(BUILD_XBOX)
include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/nxdk.cmake")

moonlight_resolve_nxdk_dir(MOONLIGHT_NXDK_DIR)
moonlight_prepare_nxdk("${MOONLIGHT_NXDK_DIR}" "${CMAKE_BINARY_DIR}/nxdk-bootstrap")
moonlight_resolve_nxdk_dir(source_nxdk_dir)
set(_nxdk_build_dir "${MOONLIGHT_NXDK_BUILD_DIR}")
moonlight_stage_nxdk("${source_nxdk_dir}" "${_nxdk_build_dir}")
moonlight_prepare_nxdk("${_nxdk_build_dir}" "${_nxdk_build_dir}/.moonlight-bootstrap")
moonlight_add_xbox_build(
NXDK_DIR "${MOONLIGHT_NXDK_DIR}"
NXDK_DIR "${_nxdk_build_dir}"
SOURCE_NXDK_DIR "${source_nxdk_dir}"
BINARY_DIR "${CMAKE_BINARY_DIR}/xbox"
)
endif()
8 changes: 3 additions & 5 deletions CMakePresets.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,11 @@
"displayName": "Xbox Release (mingw64)",
"description": "Direct nxdk Xbox configure for IDE/code-model support on Xbox-only sources",
"generator": "Unix Makefiles",
"toolchainFile": "${sourceDir}/third-party/nxdk/share/toolchain-nxdk.cmake",
"toolchainFile": "${sourceDir}/cmake/nxdk-toolchain.cmake",
"binaryDir": "${sourceDir}/cmake-build-xbox-release",
"environment": {
"CHERE_INVOKING": "1",
"MSYSTEM": "MINGW64",
"NXDK_DIR": "${sourceDir}/third-party/nxdk"
"MSYSTEM": "MINGW64"
},
"cacheVariables": {
"BUILD_DOCS": "OFF",
Expand All @@ -55,8 +54,7 @@
"CMAKE_MAKE_PROGRAM": "C:/msys64/usr/bin/make.exe",
"CMAKE_TRY_COMPILE_TARGET_TYPE": "STATIC_LIBRARY",
"MOONLIGHT_BUILD_KIND": "XBOX",
"MOONLIGHT_SKIP_NXDK_PREP": "ON",
"NXDK_DIR": "${sourceDir}/third-party/nxdk"
"MOONLIGHT_NXDK_DIR": "${sourceDir}/third-party/nxdk"
}
},
{
Expand Down
43 changes: 26 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ brew install "${dependencies[@]}"

### Configure

Configure the top-level project with the normal host toolchain. CMake uses the vendored `third-party/nxdk` checkout, bootstraps the required `nxdk` outputs, builds the host-native tests with the standard compiler/linker, and drives the Xbox build through an internal child configure that reuses the stock `nxdk` toolchain.
Configure the top-level project with the normal host toolchain. CMake uses the vendored `third-party/nxdk` checkout, copies its tracked sources and nested submodules into the build directory, bootstraps the required `nxdk` outputs there, builds the host-native tests with the standard compiler/linker, and drives the Xbox build through an internal child configure that reuses the stock `nxdk` toolchain.

For host and Xbox builds, CMake checks whether the compiler supports Clang's `unused-but-set-global` warning. When supported, this warning remains nonfatal for `moonlight-common-c`, whose debug counters are read only by assertions that are disabled in release builds. Other warnings retain the dependency's existing error policy.

Expand Down Expand Up @@ -176,22 +176,31 @@ Coverage should come from this host-native test build instead of the cross-compi

### Dependency compatibility on Xbox

The nxdk submodule tracks `ReenigneArcher/nxdk`'s `codex/moonlight-runtime` branch,
which pins `ReenigneArcher/nxdk-pdclib`'s `codex/descriptor-stdio` branch. Both dependencies
are pinned to specific commits, so recursive checkout includes the required runtime support
without waiting for the upstream nxdk or PDCLib pull requests to merge.

nxdk provides regular-file descriptors shared by POSIX I/O and stdio. Socket descriptors use
a separate range and dispatch to lwIP after network initialization. `gettimeofday()` uses
kernel timestamps with subsecond precision.

The Xbox OpenSSL build disables POSIX descriptor I/O. Pairing uses a custom socket BIO that
leaves socket ownership with the caller. Directory enumeration and path-based `stat()` use
nxdk's working filesystem APIs directly. Stat queries return the native file identity,
64-bit size, and access, write, and metadata-change timestamps; unrepresentable timestamps
report `EOVERFLOW`. Relative paths resolve against nxdk's fixed `D:\` working directory.
FFmpeg builds its original file helpers against nxdk's descriptor APIs using its generic
platform path. Memory mapping and temporary-file creation remain disabled.
The SDK submodule tracks upstream XboxDev/nxdk, including its upstream PDCLib. Moonlight's
Xbox adapters live in `src/_nxdk_compat` and are built by `cmake/nxdk-compat.cmake`.
All SDK libraries, host tools and generated lwIP files are built under the build
directory, including for direct Xbox presets. `cmake/nxdk-toolchain.cmake` prepares
that copy before compiler checks and then loads the stock nxdk toolchain. SDK
revision changes and local edits to tracked SDK files refresh the copy; unrelated
untracked files and existing build products are excluded. `MOONLIGHT_NXDK_DIR`
selects the source checkout; `MOONLIGHT_NXDK_BUILD_DIR` selects the build copy.

The local network target builds upstream lwIP with the streaming receive limits,
socket options and mDNS enabled. The `network/nxdk-network.patch` compatibility
patch is applied with `git apply` to build-directory copies, preserving thread
priorities and safe packet drops on receive-pool exhaustion. The submodule
sources stay unchanged. `nxNetInit` is compiled with the same settings so its
network-interface layout matches lwIP.

The compatibility layer provides real wall-clock, sleep and reentrant string helpers.
FFmpeg's unused POSIX descriptor/file helpers and OpenSSL's optional POSIX directory
and metadata queries fail explicitly with `ENOSYS`. Moonlight's Win32 file APIs,
standard stdio and custom OpenSSL socket BIO continue to handle saved data and pairing.
FFmpeg configure probes still link actual Xbox libraries and the local timing helpers.

OpenSSL disables POSIX descriptor I/O; its socket BIO leaves socket ownership with
the caller. FFmpeg builds its original file helpers through its generic platform
path, with memory mapping and temporary-file creation disabled.

### CLion on Windows

Expand Down
5 changes: 3 additions & 2 deletions cmake/modules/GetOpenSSL.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ if(MOONLIGHT_OPENSSL_PLATFORM STREQUAL "XBOX")
-D_exit=_Exit
-include
"${CMAKE_SOURCE_DIR}/src/_nxdk_compat/openssl_compat.h"
"-I${CMAKE_SOURCE_DIR}/src/_nxdk_compat/include"
"-I${NXDK_DIR}/lib"
"-I${NXDK_DIR}/lib/net"
"-I${NXDK_DIR}/lib/xboxrt/libc_extensions"
Expand Down Expand Up @@ -303,8 +304,8 @@ if(MOONLIGHT_OPENSSL_PLATFORM STREQUAL "XBOX")
DEPENDERS build
DEPENDS
"${CMAKE_SOURCE_DIR}/src/_nxdk_compat/openssl_compat.h"
"${NXDK_DIR}/lib/xboxrt/libc_extensions/dirent.h"
"${NXDK_DIR}/lib/xboxrt/libc_extensions/sys/stat.h"
"${CMAKE_SOURCE_DIR}/src/_nxdk_compat/include/dirent.h"
"${CMAKE_SOURCE_DIR}/src/_nxdk_compat/include/sys/stat.h"
COMMENT "Invalidate OpenSSL objects after nxdk compatibility changes"
LOG ON)
endif()
Expand Down
35 changes: 14 additions & 21 deletions cmake/moonlight-dependencies.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -65,27 +65,24 @@ function(_moonlight_compute_ffmpeg_signature out_var nxdk_dir ffmpeg_source_dir)
set(ffmpeg_cxx_wrapper "${ARGV4}")

_moonlight_get_ffmpeg_revision(ffmpeg_revision "${ffmpeg_source_dir}")
file(READ "${nxdk_dir}/.moonlight-source.signature" nxdk_revision)
file(SHA256 "${ffmpeg_cc_wrapper}" ffmpeg_cc_wrapper_hash)
file(SHA256 "${ffmpeg_cxx_wrapper}" ffmpeg_cxx_wrapper_hash)
file(SHA256 "${nxdk_dir}/lib/xboxrt/libc_extensions/sys/types.h" ffmpeg_nxdk_types_hash)
file(SHA256 "${nxdk_dir}/lib/xboxrt/libc_extensions/sys/time.h" ffmpeg_nxdk_time_hash)
file(SHA256 "${nxdk_dir}/lib/xboxrt/libc_extensions/fcntl.h" ffmpeg_nxdk_fcntl_hash)
file(SHA256 "${nxdk_dir}/lib/xboxrt/libc_extensions/unistd.h" ffmpeg_nxdk_unistd_hash)
file(SHA256 "${nxdk_dir}/lib/xboxrt/libc_extensions/sys/stat.h" ffmpeg_nxdk_stat_hash)
file(SHA256 "${nxdk_dir}/lib/xboxrt/libc_extensions/stdio_ext_.h" ffmpeg_nxdk_stdio_hash)
file(SHA256 "${nxdk_dir}/lib/pdclib/platform/xbox/include/pdclib/_PDCLIB_config.h" ffmpeg_nxdk_pdclib_hash)
file(GLOB_RECURSE compat_inputs CONFIGURE_DEPENDS
"${CMAKE_SOURCE_DIR}/src/_nxdk_compat/*.h"
"${CMAKE_SOURCE_DIR}/src/_nxdk_compat/*.c")
set(compat_hashes)
foreach(input IN LISTS compat_inputs)
file(SHA256 "${input}" input_hash)
list(APPEND compat_hashes "${input}=${input_hash}")
endforeach()
file(SHA256 "${CMAKE_SOURCE_DIR}/cmake/moonlight-dependencies.cmake" ffmpeg_dependency_manifest_hash)

set(signature_inputs
"FFMPEG_REVISION=${ffmpeg_revision}"
"NXDK_DIR=${nxdk_dir}"
"NXDK_TYPES_SHA256=${ffmpeg_nxdk_types_hash}"
"NXDK_TIME_SHA256=${ffmpeg_nxdk_time_hash}"
"NXDK_FCNTL_SHA256=${ffmpeg_nxdk_fcntl_hash}"
"NXDK_UNISTD_SHA256=${ffmpeg_nxdk_unistd_hash}"
"NXDK_STAT_SHA256=${ffmpeg_nxdk_stat_hash}"
"NXDK_STDIO_SHA256=${ffmpeg_nxdk_stdio_hash}"
"NXDK_PDCLIB_SHA256=${ffmpeg_nxdk_pdclib_hash}"
"NXDK_REVISION=${nxdk_revision}"
"COMPAT_SHA256=${compat_hashes}"
"FFMPEG_PROFILE=h264-opus-xbox"
"FFMPEG_TARGET_OS=none"
"FFMPEG_ARCH=x86"
Expand Down Expand Up @@ -165,6 +162,7 @@ function(_moonlight_get_ffmpeg_configure_args out_var)
sh
"${ffmpeg_source_shell_path}/configure"
"--prefix=${ffmpeg_install_shell_path}"
"--extra-ldflags=${MOONLIGHT_NXDK_COMPAT_LIBRARY}"
--enable-cross-compile
--arch=x86
--cpu=i686
Expand Down Expand Up @@ -430,15 +428,9 @@ macro(MOONLIGHT_PREPARE_COMMON_DEPENDENCIES)
set(MOONLIGHT_NXDK_NET_INCLUDE_DIR "${NXDK_DIR}/lib/net")
set(MOONLIGHT_NXDK_LIBC_EXTENSIONS_DIR "${NXDK_DIR}/lib/xboxrt/libc_extensions")
set(MOONLIGHT_NXDK_LWIP_POSIX_COMPAT_DIR "${NXDK_DIR}/lib/net/lwip/src/include/compat/posix")
set(MOONLIGHT_NXDK_LWIP_MDNS_SOURCES
"${NXDK_DIR}/lib/net/lwip/src/apps/mdns/mdns.c"
"${NXDK_DIR}/lib/net/lwip/src/apps/mdns/mdns_domain.c"
"${NXDK_DIR}/lib/net/lwip/src/apps/mdns/mdns_out.c"
)

if(TARGET enet)
target_compile_definitions(enet PRIVATE NXDK)
target_link_libraries(enet PUBLIC NXDK::NXDK NXDK::Net)
target_link_libraries(enet PUBLIC NXDK::NXDK NXDK::Net moonlight_nxdk_compat)
target_include_directories(enet PRIVATE
"${MOONLIGHT_NXDK_NET_INCLUDE_DIR}"
"${MOONLIGHT_NXDK_LIBC_EXTENSIONS_DIR}"
Expand All @@ -448,6 +440,7 @@ macro(MOONLIGHT_PREPARE_COMMON_DEPENDENCIES)

if(TARGET moonlight-common-c)
target_compile_definitions(moonlight-common-c PRIVATE NXDK)
target_link_libraries(moonlight-common-c PUBLIC moonlight_nxdk_compat NXDK::Net)
target_include_directories(moonlight-common-c PRIVATE
"${MOONLIGHT_NXDK_NET_INCLUDE_DIR}"
"${MOONLIGHT_NXDK_LIBC_EXTENSIONS_DIR}"
Expand Down
87 changes: 87 additions & 0 deletions cmake/nxdk-compat.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# Build Moonlight's adapters against unmodified upstream nxdk sources.
include_guard(GLOBAL)

# Apply the network patch to disposable copies, then publish only changed files.
function(_moonlight_patch_nxdk_network port patch_file)
find_package(Git REQUIRED)
set(work "${port}/patch-work")
set(port_files
lib/net/nforceif/include/arch/sys_arch.h
lib/net/nforceif/src/sys_arch.c
lib/net/nvnetdrv/nvnetdrv_lwip.c)
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${patch_file}")
foreach(source IN LISTS port_files)
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${NXDK_DIR}/${source}")
configure_file("${NXDK_DIR}/${source}" "${work}/${source}" COPYONLY)
endforeach()

# An explicit work tree confines git apply to these copies, including when
# the build directory is inside the Moonlight checkout. Normalize CRLF on
# input and write LF so patching is independent of the user's Git settings.
execute_process(
COMMAND "${GIT_EXECUTABLE}" -c core.autocrlf=input "--work-tree=${work}"
apply --whitespace=error "${patch_file}"
WORKING_DIRECTORY "${work}"
RESULT_VARIABLE patch_result
OUTPUT_VARIABLE patch_output
ERROR_VARIABLE patch_error)
if(NOT patch_result EQUAL 0)
message(FATAL_ERROR
"Failed to apply Moonlight's nxdk network patch; review it against the selected SDK.\n"
"${patch_output}${patch_error}")
endif()
foreach(source IN LISTS port_files)
configure_file("${work}/${source}" "${port}/${source}" COPYONLY)
endforeach()
endfunction()

# Build Moonlight's private network port and the runtime used by dependencies.
function(moonlight_prepare_nxdk_compat)
set(compat "${CMAKE_SOURCE_DIR}/src/_nxdk_compat")
set(port "${CMAKE_CURRENT_BINARY_DIR}/nxdk-compat")
_moonlight_patch_nxdk_network("${port}" "${compat}/network/nxdk-network.patch")

# opt.h includes this before defining defaults. Keep nxdk's base settings.
configure_file("${compat}/network/lwipopts.h.in" "${port}/lwipopts.h" @ONLY)

set(LWIP_DIR "${NXDK_DIR}/lib/net/lwip") # cmake-lint: disable=C0103
set(LWIP_EXCLUDE_SLIPIF TRUE) # cmake-lint: disable=C0103
include("${LWIP_DIR}/src/Filelists.cmake")
add_library(moonlight_nxdk_net STATIC
${lwipcore_SRCS} ${lwipcore4_SRCS} ${lwipcore6_SRCS}
${lwipapi_SRCS} ${lwipnetif_SRCS} ${lwipmdns_SRCS}
"${NXDK_DIR}/lib/net/nvnetdrv/nvnetdrv.c"
"${port}/lib/net/nvnetdrv/nvnetdrv_lwip.c"
"${port}/lib/net/nforceif/src/sys_arch.c")
target_compile_definitions(moonlight_nxdk_net PRIVATE RX_BUFF_CNT=PBUF_POOL_SIZE)
target_include_directories(moonlight_nxdk_net BEFORE PUBLIC
"${port}/lib/net/nforceif/include" "${port}" "${compat}/include")
target_include_directories(moonlight_nxdk_net SYSTEM PUBLIC
"${NXDK_DIR}/lib/net/lwip/src/include"
"${NXDK_DIR}/lib/net/nforceif/include"
"${NXDK_DIR}/lib/net/nvnetdrv")

# nxNetInit owns a struct netif: it must use the same mDNS-enabled layout.
# Include it as an object so the stock libnxdk net.obj is never extracted.
add_library(moonlight_nxdk_net_init OBJECT "${NXDK_DIR}/lib/nxdk/net.c")
target_link_libraries(moonlight_nxdk_net_init PRIVATE moonlight_nxdk_net)
get_target_property(sdk_libraries NXDK::NXDK INTERFACE_LINK_LIBRARIES)
list(REMOVE_ITEM sdk_libraries nxdk_net)
set_property(TARGET NXDK::NXDK PROPERTY INTERFACE_LINK_LIBRARIES "${sdk_libraries};moonlight_nxdk_net")
set_property(TARGET NXDK::Net PROPERTY INTERFACE_LINK_LIBRARIES moonlight_nxdk_net)

# FFmpeg configures before ordinary targets build. Build its real timing
# helpers now as well, so configure still links genuine Xbox executables.
moonlight_run_nxdk_command("Compatibility probe object" "${NXDK_DIR}" "${port}"
"${NXDK_DIR}/bin/nxdk-cc" "-I${compat}/include"
-c "${compat}/runtime.c" -o runtime.obj)
moonlight_run_nxdk_command("Compatibility probe archive" "${NXDK_DIR}" "${port}"
llvm-ar rcs compat.lib runtime.obj)
set(MOONLIGHT_NXDK_COMPAT_LIBRARY "${port}/compat.lib" PARENT_SCOPE)
add_library(moonlight_nxdk_compat STATIC "${compat}/runtime.c")
target_include_directories(moonlight_nxdk_compat PUBLIC "${compat}/include")
target_compile_options(moonlight_nxdk_compat INTERFACE
-include "${compat}/include/moonlight_posix.h")
file(GLOB_RECURSE compat_inputs CONFIGURE_DEPENDS "${compat}/*.h" "${compat}/*.c")
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${compat_inputs})
endfunction()
Loading
Loading