# ----------------------------------------------------------------------------------------------------------
# Copyright (c) 2026 Huawei Technologies Co., Ltd.
# This program is free software, you can redistribute it and/or modify it under the terms and conditions of
# CANN Open Software License Agreement Version 2.0 (the "License").
# Please refer to the License for details. You may not use this file except in compliance with the License.
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
# See LICENSE in the root of the software repository for the full text of the License.
# ----------------------------------------------------------------------------------------------------------

cmake_minimum_required(VERSION 3.16)

# ============================================================================
# 架构特定源文件收集逻辑(修复版)
# ============================================================================
# 原理:
#   1. 首先收集所有 .cpp 源文件作为基础源文件
#   2. 根据 ARCH_SPECIFIC_DIRS 过滤掉所有架构特定目录中的文件
#   3. 根据 SOC_ARCH_DIRS 重新添加当前 SOC 对应的架构特定源文件
#
# 修复说明:
#   原方案使用 file(GLOB_RECURSE ... **/*.cpp) 模式无法正确匹配嵌套目录
#   新方案使用路径字符串匹配来正确识别架构特定文件
# ============================================================================

# 收集基础源文件(所有 .cpp 文件)
file(GLOB_RECURSE BASE_SRC_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
message(STATUS "[sparse] Total source files before filtering: ${BASE_SRC_FILES}")

# -------------------------------------------------------------------------------------------------
# 步骤1:过滤掉所有架构特定目录中的文件
#   - ARCH_SPECIFIC_DIRS 在根 CMakeLists.txt 中定义(如 arch35, arch22, arch20)
#   - 使用路径匹配替代 GLOB 模式,确保正确识别嵌套目录中的架构特定文件
# -------------------------------------------------------------------------------------------------
foreach(arch_dir ${ARCH_SPECIFIC_DIRS})
  set(arch_dir_srcs "")
  foreach(src ${BASE_SRC_FILES})
    # 使用字符串匹配检查文件路径是否包含架构目录
    if(src MATCHES "/${arch_dir}/")
      list(APPEND arch_dir_srcs ${src})
    endif()
  endforeach()
  
  if(arch_dir_srcs)
    message(STATUS "[sparse] Filtering out ${arch_dir} sources: ${arch_dir_srcs}")
    foreach(arch_src ${arch_dir_srcs})
      list(REMOVE_ITEM BASE_SRC_FILES ${arch_src})
    endforeach()
  endif()
endforeach()

# -------------------------------------------------------------------------------------------------
# 步骤2:收集当前 SOC 对应的架构特定源文件
#   - SOC_ARCH_DIRS 根据 SOC_VERSION 在根 CMakeLists.txt 中通过 get_soc_arch_dirs() 确定
#   - 例如:ascend910b -> arch22, ascend950 -> arch35, ascend310p -> arch20
# -------------------------------------------------------------------------------------------------
set(ARCH_SRC_FILES "")
if(SOC_ARCH_DIRS)
  message(STATUS "[sparse] SOC_ARCH_DIRS specified, collecting arch-specific sources: ${SOC_ARCH_DIRS}")
  foreach(arch_dir ${SOC_ARCH_DIRS})
    # 收集所有源文件,然后筛选出匹配当前架构目录的文件
    file(GLOB_RECURSE all_srcs ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
    set(arch_dir_srcs "")
    foreach(src ${all_srcs})
      if(src MATCHES "/${arch_dir}/")
        list(APPEND arch_dir_srcs ${src})
      endif()
    endforeach()
    
    if(arch_dir_srcs)
      message(STATUS "[sparse] Adding ${arch_dir} sources: ${arch_dir_srcs}")
      list(APPEND ARCH_SRC_FILES ${arch_dir_srcs})
    else()
      message(WARNING "[sparse] Arch directory '${arch_dir}' specified but no source files found")
    endif()
  endforeach()
else()
  message(STATUS "[sparse] No SOC_ARCH_DIRS specified, using generic implementation only")
endif()

# -------------------------------------------------------------------------------------------------
# 步骤3:合并源文件列表并输出到父作用域
# -------------------------------------------------------------------------------------------------
set(ALL_SPARSE_SRC_FILES "")
list(APPEND ALL_SPARSE_SRC_FILES ${BASE_SRC_FILES} ${ARCH_SRC_FILES})

# 去重(防止同一文件被多次添加)
if(ALL_SPARSE_SRC_FILES)
  list(REMOVE_DUPLICATES ALL_SPARSE_SRC_FILES)
endif()

# 输出统计信息
list(LENGTH BASE_SRC_FILES base_count)
list(LENGTH ARCH_SRC_FILES arch_count)
list(LENGTH ALL_SPARSE_SRC_FILES total_count)
message(STATUS "[sparse] Source file summary: ${base_count} generic + ${arch_count} arch-specific = ${total_count} total")

# 设置父作用域变量
set(ALL_SPARSE_SRC_FILES ${ALL_SPARSE_SRC_FILES} PARENT_SCOPE)