# Copyright Advanced Micro Devices, Inc., or its affiliates.
# SPDX-License-Identifier: MIT

cmake_minimum_required(VERSION 3.25.2)
project(rocm-libraries LANGUAGES C CXX Fortran ASM)

list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules")

include(CMakeDependentOption)
include(GNUInstallDirs)
include(add_subdirectory_with_message)
include(fetch_rocm_cmake)

# --- Options and cache variables ---
option(ROCM_LIBS_SUPERBUILD "Enable superbuild mode" ON)

set(ROCM_LIBS_ENABLE_COMPONENTS "all"
    CACHE STRING "Semicolon-separated list of components to build (default: 'all')"
)

set(SUPPORTED_COMPONENTS
    # shared
    mxdatagenerator
    rocroller
    # projects
    hipblas-common
    rocprim
    rocrand
)

set(UNSUPPORTED_COMPONENTS
    # shared
    tensile
    # projects
    composablekernel
    hipblas
    hipblaslt
    hipcub
    hipfft
    hiprand
    hipsolver
    hipsparse
    hipsparselt
    miopen
    rocblas
    rocfft
    rocsolver
    rocsparse
    rocthrust
)

# NOTE: This is a temp option to reduce warnings generated by rocm-cmake. However, these warnings
# are reasonable and should be addressed.
option(ROCM_WARN_TOOLCHAIN_VAR "Warn if the toolchain version is not supported" OFF)

option(CMAKE_MESSAGE_CONTEXT_SHOW "Show the context of the message" ON)

# --- Validate options ---
if(NOT ROCM_LIBS_ENABLE_COMPONENTS)
    message(FATAL_ERROR "ROCM_LIBS_ENABLE_COMPONENTS is empty, use 'all' to enable all components")
endif()

if("all" IN_LIST ROCM_LIBS_ENABLE_COMPONENTS)
    set(ROCM_LIBS_ENABLE_COMPONENTS ${SUPPORTED_COMPONENTS})
endif()

message(STATUS "Enabling components:")
foreach(component ${ROCM_LIBS_ENABLE_COMPONENTS})
    if(component IN_LIST SUPPORTED_COMPONENTS)
        message(STATUS "  ${component} (supported)")
    elseif(component IN_LIST UNSUPPORTED_COMPONENTS)
        message(STATUS "  ${component} (unsupported)")
    else()
        message(FATAL_ERROR "Unknown component: ${component}.")
    endif()
endforeach()

# --- Add subdirectories ---
if("mxdatagenerator" IN_LIST ROCM_LIBS_ENABLE_COMPONENTS)
    add_subdirectory_with_message(
        COMPONENT mxdatagenerator
        PREFIX_PATH shared
        EXPECT_TARGET roc::mxDataGenerator
    )
endif()

if("hipblas-common" IN_LIST ROCM_LIBS_ENABLE_COMPONENTS)
    add_subdirectory_with_message(
        COMPONENT hipblas-common
        PREFIX_PATH projects
        EXPECT_TARGET roc::hipblas-common
    )
endif()

if("rocroller" IN_LIST ROCM_LIBS_ENABLE_COMPONENTS)
    # required deps: pip install pytest-cmake
    set(ROCROLLER_ENABLE_FETCH ON)
    add_subdirectory_with_message(
        COMPONENT rocroller
        PREFIX_PATH shared
        EXPECT_TARGET roc::rocroller
    )
endif()

if("rocprim" IN_LIST ROCM_LIBS_ENABLE_COMPONENTS)
    add_subdirectory_with_message(
        COMPONENT rocprim
        PREFIX_PATH projects
        EXPECT_TARGET rocprim
    )
endif()

if("rocrand" IN_LIST ROCM_LIBS_ENABLE_COMPONENTS)
    add_subdirectory_with_message(
        COMPONENT rocrand
        PREFIX_PATH projects
        EXPECT_TARGET rocrand
    )
endif()

# --- Projects not yet configured for superbuild ---
if("tensile" IN_LIST ROCM_LIBS_ENABLE_COMPONENTS)
    message(FATAL_ERROR "tensile is not yet supported in the superbuild")
endif()

if("rocsparse" IN_LIST ROCM_LIBS_ENABLE_COMPONENTS)
    message(FATAL_ERROR "rocsparse is not yet supported in the superbuild")
endif()

if("rocfft" IN_LIST ROCM_LIBS_ENABLE_COMPONENTS)
    message(FATAL_ERROR "rocfft is not yet supported in the superbuild")
endif()

if("hipfft" IN_LIST ROCM_LIBS_ENABLE_COMPONENTS)
    message(FATAL_ERROR "hipfft is not yet supported in the superbuild")
endif()

if("hipsparse" IN_LIST ROCM_LIBS_ENABLE_COMPONENTS)
    message(FATAL_ERROR "hipsparse is not yet supported in the superbuild")
endif()

if("composablekernel" IN_LIST ROCM_LIBS_ENABLE_COMPONENTS)
    message(FATAL_ERROR "composablekernel is not yet supported in the superbuild")
endif()

if("miopen" IN_LIST ROCM_LIBS_ENABLE_COMPONENTS)
    message(FATAL_ERROR "miopen is not yet supported in the superbuild")
endif()

if("hipcub" IN_LIST ROCM_LIBS_ENABLE_COMPONENTS)
    message(FATAL_ERROR "hipcub is not yet supported in the superbuild")
    # NOTE: Currently, hipcub tries to expose the rocm::rocprim target if it isn't already found.
    # This action should be removed so that rocprim is made an explicit dependency where required.
endif()

if("hiprand" IN_LIST ROCM_LIBS_ENABLE_COMPONENTS)
    message(FATAL_ERROR "hiprand is not yet supported in the superbuild")
endif()

if("hipblaslt" IN_LIST ROCM_LIBS_ENABLE_COMPONENTS)
    message(FATAL_ERROR "hipblaslt is not yet supported in the superbuild")
endif()

if("hipblas" IN_LIST ROCM_LIBS_ENABLE_COMPONENTS)
    message(FATAL_ERROR "hipblas is not yet supported in the superbuild")
endif()

if("hipsolver" IN_LIST ROCM_LIBS_ENABLE_COMPONENTS)
    message(FATAL_ERROR "hipsolver is not yet supported in the superbuild")
endif()

if("hipsparselt" IN_LIST ROCM_LIBS_ENABLE_COMPONENTS)
    message(FATAL_ERROR "hipsparselt is not yet supported in the superbuild")
endif()

if("rocblas" IN_LIST ROCM_LIBS_ENABLE_COMPONENTS)
    message(FATAL_ERROR "rocblas is not yet supported in the superbuild")
endif()

if("rocsolver" IN_LIST ROCM_LIBS_ENABLE_COMPONENTS)
    message(FATAL_ERROR "rocsolver is not yet supported in the superbuild")
endif()

if("rocthrust" IN_LIST ROCM_LIBS_ENABLE_COMPONENTS)
    message(FATAL_ERROR "rocthrust is not yet supported in the superbuild")
endif()
