cmake_minimum_required(VERSION 3.20)

# Xbox Kernel Replacement Layer
# Replaces 147 Xbox kernel imports with Win32 equivalents.
# Memory layout, file I/O, threading, synchronization, crypto, HAL.

set(KERNEL_SOURCES
    kernel_path.c
    kernel_pool.c
    kernel_rtl.c
    kernel_memory.c
    kernel_file.c
    kernel_thread.c
    kernel_sync.c
    kernel_hal.c
    kernel_xbox.c
    kernel_ob.c
    kernel_io.c
    kernel_crypto.c
    kernel_thunks.c
    kernel_bridge.c
    gil_stats.c
    guest_vmem.c
    xbox_memory_layout.c
    icall_feedback.c
    recomp_trace.c
    nv2a_pb_scan.c
    nv2a_pb_exec.c
    xbe_variant.c
)

if(WIN32)
    # Every host thread's native stack in a watchdog snapshot (no gdb there).
    list(APPEND KERNEL_SOURCES ../platform/win32_stacks.c)
endif()

add_library(xbox_kernel STATIC ${KERNEL_SOURCES})

# The device-model side of the kernel: interrupt lines and the contiguous
# arena's bus range. Its own library so xbox_apu and xbox_usb can link it
# without the bridge (see xbox_devbus.c).
add_library(xbox_devbus STATIC xbox_devbus.c)
target_include_directories(xbox_devbus PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(xbox_devbus PUBLIC platform)
target_link_libraries(xbox_kernel PUBLIC xbox_devbus)

# See src/platform/CMakeLists.txt: resolve src/ relative to this file, not via
# CMAKE_SOURCE_DIR, which is the consuming project's root under add_subdirectory().
get_filename_component(XBOXRECOMP_SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/.." ABSOLUTE)

target_include_directories(xbox_kernel PUBLIC
    ${CMAKE_CURRENT_SOURCE_DIR}
    ${XBOXRECOMP_SRC_DIR}
)

if(WIN32)
    # platform is an INTERFACE target on Windows: it contributes the src/
    # include path that "platform/xbox_winnt.h" resolves against.
    target_link_libraries(xbox_kernel PUBLIC platform kernel32 bcrypt)
else()
    # Linux: platform layer (POSIX host primitives) + OpenSSL for crypto.
    # The crypto (kernel_crypto.c) is portable C; nothing calls OpenSSL. It
    # stays linked on desktop for compatibility and is skipped on the Switch,
    # which has no OpenSSL package.
    if(NINTENDO_SWITCH OR ANDROID)
        target_link_libraries(xbox_kernel PUBLIC platform)
    else()
        find_package(OpenSSL REQUIRED)
        target_link_libraries(xbox_kernel PUBLIC platform OpenSSL::Crypto)
    endif()
endif()

if(MSVC)
    target_compile_options(xbox_kernel PRIVATE /W4 /WX- /O2 /GS- /Gy)
    target_compile_definitions(xbox_kernel PRIVATE _CRT_SECURE_NO_WARNINGS)
else()
    target_compile_options(xbox_kernel PRIVATE -Wall -Wextra -Wno-unused-parameter -O2)
endif()

target_compile_definitions(xbox_kernel PRIVATE $<$<CONFIG:Debug>:_DEBUG>)
