Some checks failed
Orchestrator / Commit Message Validation (push) Has been skipped
Orchestrator / Lint (push) Successful in 1m19s
Orchestrator / Windows (x86-64) (push) Failing after 5m16s
Orchestrator / Linux (x86-64) (push) Failing after 13m23s
Orchestrator / Create Release (push) Has been skipped
New CMake preset `cross-win-clangcl` for Ninja Multi-Config on non-Windows hosts. Toolchain: clang-cl (MSVC-ABI), lld-link, xwin SDK/CRT splat. Shader compilation routes through wine fxc.exe with FXC_PATH env forwarding and unix→Windows path translation via `winepath -w`. Plus per-file build fixes (constexpr→const, llvm-rc forward-slash, zlib-ng AVX guard, /RTCsu MSVC-only). third_party/snappy bumped to fabi/sylpheed-crossbuild for the target-aware POSIX-gate header. Produces `xenia_canary.exe` (Debug MSVC) suitable for use as the audit oracle under Wine for xenia-rs work. See docs/CROSS_BUILD_SETUP.md for the full reproduction recipe. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
120 lines
5.0 KiB
CMake
120 lines
5.0 KiB
CMake
# cmake/toolchains/linux-to-win-msvc.cmake
|
|
# Linux host -> Windows MSVC-ABI cross toolchain using clang-cl + lld-link
|
|
# + xwin-supplied Win10 SDK/CRT. Driven by Ninja Multi-Config.
|
|
|
|
set(CMAKE_SYSTEM_NAME Windows)
|
|
set(CMAKE_SYSTEM_PROCESSOR x86_64)
|
|
|
|
if(NOT DEFINED XWIN_DIR)
|
|
if(DEFINED ENV{XWIN_DIR})
|
|
set(XWIN_DIR "$ENV{XWIN_DIR}")
|
|
else()
|
|
set(XWIN_DIR "$ENV{HOME}/.xwin/splat")
|
|
endif()
|
|
endif()
|
|
set(XWIN_DIR "${XWIN_DIR}" CACHE PATH "xwin splat root (contains crt/ and sdk/)")
|
|
|
|
if(NOT EXISTS "${XWIN_DIR}/crt/include")
|
|
message(FATAL_ERROR "XWIN_DIR=${XWIN_DIR} missing crt/include - run xwin splat.")
|
|
endif()
|
|
|
|
set(CMAKE_C_COMPILER clang-cl)
|
|
set(CMAKE_CXX_COMPILER clang-cl)
|
|
set(CMAKE_LINKER lld-link)
|
|
set(CMAKE_RC_COMPILER llvm-rc)
|
|
set(CMAKE_AR llvm-lib)
|
|
set(CMAKE_MT llvm-mt)
|
|
|
|
set(CMAKE_C_COMPILER_TARGET x86_64-pc-windows-msvc)
|
|
set(CMAKE_CXX_COMPILER_TARGET x86_64-pc-windows-msvc)
|
|
|
|
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
|
|
|
|
# Force /MD (release CRT) for every config. xenia's CMakeLists.txt does a
|
|
# `string(REPLACE "/MDd" "/MD" ...)` on CMAKE_CXX_FLAGS_DEBUG, but with
|
|
# clang-cl, the runtime selection comes from CMAKE_MSVC_RUNTIME_LIBRARY
|
|
# (which expands to -MDd in dash form), so the substitution misses.
|
|
# Pinning the policy here avoids the need for non-redistributable debug
|
|
# CRT DLLs (MSVCP140D.dll etc) at runtime, which xwin doesn't ship.
|
|
cmake_policy(SET CMP0091 NEW)
|
|
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreadedDLL")
|
|
|
|
# xwin's default splat is a flat layout (crt/include, sdk/include/{ucrt,um,shared,...}),
|
|
# which clang-cl's /winsysroot does NOT understand. Use explicit -imsvc + -libpath:
|
|
# instead. Re-running `xwin splat --use-winsysroot-style` would also work but
|
|
# requires re-downloading ~600 MB.
|
|
# Use SHELL: prefix so CMake doesn't deduplicate repeated -imsvc tokens.
|
|
add_compile_options(
|
|
"SHELL:-imsvc \"${XWIN_DIR}/crt/include\""
|
|
"SHELL:-imsvc \"${XWIN_DIR}/sdk/include/ucrt\""
|
|
"SHELL:-imsvc \"${XWIN_DIR}/sdk/include/um\""
|
|
"SHELL:-imsvc \"${XWIN_DIR}/sdk/include/shared\""
|
|
"SHELL:-imsvc \"${XWIN_DIR}/sdk/include/winrt\""
|
|
)
|
|
add_link_options(
|
|
"/libpath:${XWIN_DIR}/crt/lib/x86_64"
|
|
"/libpath:${XWIN_DIR}/sdk/lib/ucrt/x86_64"
|
|
"/libpath:${XWIN_DIR}/sdk/lib/um/x86_64"
|
|
)
|
|
# xwin pulls the latest MSVC STL which now hard-asserts Clang >= 19. Our host
|
|
# has Clang 18, which works fine in practice — opt out of the version check.
|
|
# (See yvals_core.h STL1000 in $XWIN_DIR/crt/include.)
|
|
add_compile_definitions(_ALLOW_COMPILER_AND_STL_VERSION_MISMATCH)
|
|
# llvm-rc needs SDK headers explicitly + the resource file's own dir so the
|
|
# RC's relative ICON path (../../../assets/icon/icon.ico) resolves.
|
|
get_filename_component(_toolchain_dir "${CMAKE_CURRENT_LIST_FILE}" DIRECTORY)
|
|
get_filename_component(_xenia_root "${_toolchain_dir}/../.." ABSOLUTE)
|
|
set(CMAKE_RC_FLAGS_INIT
|
|
"/I \"${XWIN_DIR}/sdk/include/um\" /I \"${XWIN_DIR}/sdk/include/shared\" /I \"${_xenia_root}/src/xenia/app\"")
|
|
|
|
# Quiet MSVC-STL false positives and xenia-specific warnings that clang-cl
|
|
# emits but cl.exe doesn't (treated as errors under /WX).
|
|
add_compile_options(
|
|
-Wno-microsoft-include
|
|
-Wno-unused-command-line-argument
|
|
-Wno-ignored-pragma-intrinsic
|
|
-Wno-nonportable-include-path
|
|
-Wno-pragma-pack
|
|
-Wno-tautological-pointer-compare
|
|
-Wno-microsoft-cast
|
|
-Wno-deprecated-declarations
|
|
# These are silenced for native Linux Clang in CMakeLists.txt's else() branch,
|
|
# but the if(MSVC) branch fires under clang-cl and skips them — so re-add.
|
|
-Wno-switch
|
|
-Wno-attributes
|
|
-Wno-deprecated-register
|
|
-Wno-deprecated-volatile
|
|
-Wno-deprecated-enum-enum-conversion
|
|
# cl.exe accepts __pragma(optimize("s",on)); clang-cl only knows the empty
|
|
# argument form. xenia gates XE_MSVC_OPTIMIZE_SMALL on _MSC_VER so the
|
|
# rejected pragma still emits from the clang-cl path. Treat as no-op.
|
|
-Wno-ignored-pragmas
|
|
# xenia decorates several `virtual` methods with XE_FORCEINLINE; clang-cl
|
|
# then complains that the inline body isn't visible in includer TUs
|
|
# (definitions live in command_processor.cc). cl.exe accepts this silently.
|
|
-Wno-undefined-inline
|
|
-Wno-sizeof-pointer-memaccess
|
|
# `'ZM'` (PE magic, stored little-endian as "MZ" in the binary) — cl.exe
|
|
# accepts the multi-char constant silently; clang-cl errors under /WX.
|
|
-Wno-multichar
|
|
)
|
|
# _mm_cvtsi64x_si128 is an MSVC-only alias for the standard _mm_cvtsi64_si128.
|
|
# Used (gated on XE_PLATFORM_WIN32) in xenia/gpu/draw_util.cc.
|
|
add_compile_definitions(_mm_cvtsi64x_si128=_mm_cvtsi64_si128)
|
|
|
|
# Plumb FXC for tools/build/compile_shader_dxbc.py (wine fxc auto-prepend).
|
|
# Use real Win10 SDK fxc.exe 10.x (supports SM 5_1, produces vkd3d-proton-
|
|
# acceptable DXBC).
|
|
if(DEFINED ENV{FXC_PATH})
|
|
set(ENV_FXC "$ENV{FXC_PATH}")
|
|
else()
|
|
set(ENV_FXC "$ENV{HOME}/.local/share/xenia-cross/fxc/fxc.exe")
|
|
endif()
|
|
set(ENV{FXC_PATH} "${ENV_FXC}")
|
|
|
|
set(CMAKE_FIND_ROOT_PATH "${XWIN_DIR}")
|
|
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
|
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
|
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
|
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
|