Files
cKit/CMakeLists.txt
2026-09-07 21:37:10 +08:00

100 lines
4.0 KiB
CMake

cmake_minimum_required(VERSION 3.20)
get_filename_component(MY_PROJECT_NAME ${CMAKE_CURRENT_LIST_DIR} NAME)
project(${MY_PROJECT_NAME} C ASM)
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)
# ==============================================================================
# 🎯 宏:add_project_modules_with_tests
# ==============================================================================
macro(add_project_modules_with_tests OUT_APP_SOURCES OUT_TEST_FILES_LIST)
foreach(MODULE_DIR ${ARGN})
if(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${MODULE_DIR}")
message(STATUS "[Module Found]: ${MODULE_DIR}")
# 自动将该目录加入全局头文件包含路径
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/${MODULE_DIR}")
# 1. 搜集该目录下所有的 C/C++ 源文件
file(GLOB ALL_MODULE_FILES
"${CMAKE_CURRENT_SOURCE_DIR}/${MODULE_DIR}/*.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/${MODULE_DIR}/*.cc"
"${CMAKE_CURRENT_SOURCE_DIR}/${MODULE_DIR}/*.c"
"${CMAKE_CURRENT_SOURCE_DIR}/${MODULE_DIR}/*.s"
"${CMAKE_CURRENT_SOURCE_DIR}/${MODULE_DIR}/*.S"
)
# 2. 分离出测试文件 (*.t.cpp 或 *.t.c)
foreach(FILE_PATH ${ALL_MODULE_FILES})
# 匹配以 .t.cpp, .t.cc, .t.c 结尾的文件
if(FILE_PATH MATCHES "\\.t\\.(cpp|cc|c)$")
list(APPEND ${OUT_TEST_FILES_LIST} ${FILE_PATH})
message("\tTestUnit: ${FILE_PATH}")
else()
# 剩下的才是主程序的源代码
list(APPEND ${OUT_APP_SOURCES} ${FILE_PATH})
message("\tSource: ${FILE_PATH}")
endif()
endforeach()
else()
message(WARNING "[Module Warning]: Directory '${MODULE_DIR}' does not exist!")
endif()
endforeach()
endmacro()
# ==============================================================================
# 🚀 使用宏收集目标目录
# ==============================================================================
# 初始化一个空变量用于存放所有源码
set(SOURCES "")
set(TEST_SOURCES "")
configure_file(c_Config.h.in c_Config.h @ONLY)
# 调用宏:第一个参数是接收源码的变量,后面跟上您所有的子目录
add_project_modules_with_tests(SOURCES TEST_SOURCES
Base
Foundation
Graph
Math
Memory
Search
Sort
String
Context
)
#foreach (item ${SOURCES})
# message(STATUS "[${MY_PROJECT_NAME}] SOURCE: ${item}")
#endforeach ()
add_library(${MY_PROJECT_NAME} ${SOURCES})
target_include_directories(${MY_PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_BINARY_DIR})
if(WIN32)
target_link_libraries(${MY_PROJECT_NAME} PUBLIC ws2_32)
endif()
# ==============================================================================
# 🧪 自动生成并注册单元测试
# ==============================================================================
foreach(TEST_FILE ${TEST_SOURCES})
# 获取文件名(不含路径),例如 "C:/project/Math/matrix.t.cpp" -> "matrix.t.cpp"
get_filename_component(TEST_NAME_WE ${TEST_FILE} NAME_WE)
# 构造测试可执行文件的名称,例如 "test_matrix"
set(TEST_EXE_NAME "test_${TEST_NAME_WE}")
# 编译此测试程序:测试程序 = 测试源文件 + 主程序除main外的所有依赖
# 注意:如果您的主程序包含 main.cpp,建议将 main.cpp 从 ${APP_SOURCES} 中剥离,
# 或者在这里只链接需要的源文件,防止出现多个 main 函数冲突。
# add_executable(${TEST_EXE_NAME} ${TEST_FILE} ${APP_SOURCES})
add_executable(${TEST_EXE_NAME} ${TEST_FILE})
target_link_libraries(${TEST_EXE_NAME} PRIVATE ${MY_PROJECT_NAME})
# 将其注册到 CMake 的 ctest 测试集中
add_test(NAME ${TEST_EXE_NAME} COMMAND ${TEST_EXE_NAME})
message(STATUS "[Test Registered]: ${TEST_EXE_NAME}")
endforeach()