Files
cAI/cNLP/CMake/create_library_from_dirs.cmake
T

83 lines
3.7 KiB
CMake
Raw Normal View History

2026-08-10 01:21:15 +08:00
# ==============================================================================
# 宏定义:CREATE_LIBRARY_FROM_DIRS
# 参数 1: TARGET_NAME - 要生成的库的名称
# 参数 2: LIB_TYPE - 库类型(STATIC 或 SHARED
# 参数 3: SOURCE_DIRS - 需要扫描源码的目录列表(分号分隔的字符串)
# 参数 4: EXCLUDE_FILES - 需要额外过滤的文件名列表(分号分隔的字符串,支持正则)
# ==============================================================================
macro(create_library_from_dirs TARGET_NAME LIB_TYPE SOURCE_DIRS EXCLUDE_FILES)
set(ALL_SOURCES "")
add_library(${TARGET_NAME} ${LIB_TYPE} "")
# 1. 遍历传入的每一个目录
foreach(DIR ${SOURCE_DIRS})
# 统一处理相对路径和绝对路径
if(NOT IS_ABSOLUTE "${DIR}")
set(DIR "${CMAKE_CURRENT_SOURCE_DIR}/${DIR}")
endif()
# 检查目录是否存在,防止写错路径导致报错
if(EXISTS "${DIR}")
# 2. 收集当前目录下所有的 .c, .s, .S 文件
file(GLOB ALL_FILES
"${DIR}/*.c"
"${DIR}/*.s"
"${DIR}/*.S"
)
target_include_directories(${TARGET_NAME} PUBLIC ${DIR})
message(STATUS "[${TARGET_NAME}] INCLUDE ${DIR}")
foreach(FILE_PATH ${ALL_FILES})
# 获取纯文件名(例如:Compiler_GNUC.c),方便精准匹配
get_filename_component(FILE_NAME "${FILE_PATH}" NAME)
# 检查是否匹配自定义的排除列表
set(SHOULD_EXCLUDE FALSE)
foreach(EX_PATTERN ${EXCLUDE_FILES})
# 支持完整文件名匹配或正则表达式匹配
if("${FILE_NAME}" STREQUAL "${EX_PATTERN}" OR "${FILE_NAME}" MATCHES "${EX_PATTERN}")
set(SHOULD_EXCLUDE TRUE)
break()
endif()
endforeach()
# 4. 执行过滤判断
if(FILE_PATH MATCHES "\\.t\\.c$")
# 过滤单元测试文件
list(APPEND UNIT_TEST_SOURCES ${FILE_PATH})
elseif(SHOULD_EXCLUDE)
# 过滤用户指定的特定文件
message(STATUS "[${TARGET_NAME}] EXCLUDED specific file: ${FILE_NAME} from target ${TARGET_NAME}")
else()
# 留下的才是有效的库源码
list(APPEND ALL_SOURCES ${FILE_PATH})
endif()
endforeach()
else()
message(WARNING "[${TARGET_NAME}] Directory does not exist: ${DIR}")
endif()
endforeach()
# 4. 确保找到了有效的源代码再创建库
list(LENGTH ALL_SOURCES SOURCE_COUNT)
if(SOURCE_COUNT GREATER 0)
# add_library(${TARGET_NAME} ${LIB_TYPE} ${ALL_SOURCES})
target_sources(${TARGET_NAME} PUBLIC ${ALL_SOURCES})
message(STATUS "[${TARGET_NAME}] Created ${LIB_TYPE} library '${TARGET_NAME}' with ${SOURCE_COUNT} source files.")
foreach (item IN LISTS ALL_SOURCES)
message(STATUS "[${TARGET_NAME}] SOURCE: ${item}")
endforeach ()
else()
message(FATAL_ERROR "No valid source files found for target: ${TARGET_NAME}")
endif()
list(LENGTH UNIT_TEST_SOURCES UNIT_TEST_COUNT)
if(UNIT_TEST_COUNT GREATER 0)
foreach (item IN LISTS UNIT_TEST_SOURCES)
get_filename_component(TestUnit ${item} NAME_WLE)
message(STATUS "[${TARGET_NAME}] TEST: ${TestUnit} - ${item}")
add_executable(${TestUnit} ${item})
target_link_libraries(${TestUnit} PUBLIC ${TARGET_NAME})
endforeach ()
endif ()
endmacro()