83 lines
3.7 KiB
CMake
83 lines
3.7 KiB
CMake
# ==============================================================================
|
||
# 宏定义: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() |