cmake_minimum_required(VERSION 3.16)

project(_slime C CXX)

include(${CMAKE_CURRENT_LIST_DIR}/cmake/utils.cmake)

# Slime options for transfer engine
slime_option(BUILD_RDMA                "Build RDMA"                        ON)


slime_option(USE_CUDA                  "USE in CUDA Platform"             OFF)
slime_option(USE_MACA                  "USE in MACA Platform"             OFF)

slime_option(BUILD_NVLINK              "Build NVLINK"                     OFF)
slime_option(BUILD_ASCEND_DIRECT       "Build Ascend direct transport"    OFF)
slime_option(BUILD_TCP                 "Build TCP transport"               ON)
slime_option(BUILD_TOPO_SYSFS          "Build sysfs topology backend"       ON)
set(BUILD_TOPO_CUDA_DEFAULT OFF)
if(USE_CUDA OR BUILD_NVLINK)
    set(BUILD_TOPO_CUDA_DEFAULT ON)
endif()
slime_option(BUILD_TOPO_CUDA           "Build CUDA topology backend"        ${BUILD_TOPO_CUDA_DEFAULT})

# Slime options for custom python wrapper
slime_option(BUILD_PYTHON              "Build python wrapper"             OFF)

# Slime options for torch plugin
slime_option(BUILD_TORCH_PLUGIN        "Build torch plugin"               OFF)

# Slime options for test
slime_option(BUILD_TEST                "Build test"                       OFF)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(DLSLIME_INSTALL_PATH "lib" CACHE STRING "Library installation directory")
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

if (BUILD_NVLINK)
    # CMake validates CMAKE_CUDA_ARCHITECTURES while enabling the language,
    # so provide a non-empty default before enable_language(CUDA). Honour an
    # explicit -DCMAKE_CUDA_ARCHITECTURES value when the caller supplies one.
    if (NOT DEFINED CMAKE_CUDA_ARCHITECTURES OR CMAKE_CUDA_ARCHITECTURES STREQUAL "")
        set(CMAKE_CUDA_ARCHITECTURES "native" CACHE STRING "CUDA architectures" FORCE)
    endif()
    enable_language(CUDA)
    set(CMAKE_CUDA_STANDARD 17)
    find_package(CUDAToolkit REQUIRED)
    include_directories(${CUDAToolkit_INCLUDE_DIRS})
endif()

if (BUILD_TOPO_CUDA)
    find_package(CUDAToolkit 13.0 REQUIRED)
endif()

if (BUILD_PYTHON)
    set(DLSLIME_INSTALL_PATH "${SKBUILD_PROJECT_NAME}")
    set(DLSLIME_CONFIG_DEST "${DLSLIME_INSTALL_PATH}/share/cmake/dlslime")
else()
    set(DLSLIME_INSTALL_PATH "lib")
    set(DLSLIME_CONFIG_DEST "share/cmake/dlslime")
endif()

if (BUILD_TORCH_PLUGIN)
    include(${CMAKE_CURRENT_LIST_DIR}/cmake/torch.cmake)
endif()

# --- Dependencies ---
# Define NanoInfra root path (for third_party when building from NanoInfra)
include_directories(.)
add_subdirectory(dlslime/csrc)

# Keep the build-tree consumer target available in every transport
# configuration. The installed export provides the same namespaced target.
if(NOT TARGET dlslime::dlslime)
    add_library(dlslime::dlslime ALIAS dlslime)
endif()


if (BUILD_TEST)
    include(CTest)
    add_subdirectory(tests/cpp)
endif (BUILD_TEST)

# --- Installation & Export ---

# 1. Install Headers
install(
    DIRECTORY dlslime/csrc/
    DESTINATION include/dlslime
    FILES_MATCHING PATTERN "*.h" PATTERN "*.hpp"
    PATTERN "python" EXCLUDE  # Exclude python bindings source if present
    PATTERN "topology/sysfs_backend.h" EXCLUDE
    PATTERN "topology/cuda_backend.h" EXCLUDE
)

# 2. Install Targets Export
install(EXPORT dlslimeTargets
    NAMESPACE dlslime::
    DESTINATION ${DLSLIME_CONFIG_DEST}
)

# 3. Generate Config File
include(CMakePackageConfigHelpers)
set(INSTALL_INCLUDE_DIR "include/dlslime")
configure_package_config_file(
    cmake/dlslimeConfig.cmake.in
    "${CMAKE_CURRENT_BINARY_DIR}/dlslimeConfig.cmake"
    INSTALL_DESTINATION ${DLSLIME_CONFIG_DEST}
    PATH_VARS INSTALL_INCLUDE_DIR
)

write_basic_package_version_file(
    "${CMAKE_CURRENT_BINARY_DIR}/dlslimeConfigVersion.cmake"
    VERSION 0.0.2
    COMPATIBILITY AnyNewerVersion
)

install(
    FILES
        "${CMAKE_CURRENT_BINARY_DIR}/dlslimeConfig.cmake"
        "${CMAKE_CURRENT_BINARY_DIR}/dlslimeConfigVersion.cmake"
    DESTINATION ${DLSLIME_CONFIG_DEST}
)
