-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathCMakeLists.txt
More file actions
430 lines (395 loc) · 13 KB
/
Copy pathCMakeLists.txt
File metadata and controls
430 lines (395 loc) · 13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
cmake_minimum_required(VERSION 3.16)
project(coco VERSION 2.2.0 LANGUAGES C ASM)
# 编译选项
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -O2")
# 覆盖率选项
option(COCO_ENABLE_COVERAGE "Enable code coverage" OFF)
if(COCO_ENABLE_COVERAGE)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --coverage -fprofile-arcs -ftest-coverage")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --coverage")
endif()
# AddressSanitizer
option(COCO_ENABLE_ASAN "Enable AddressSanitizer" OFF)
if(COCO_ENABLE_ASAN)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -fno-omit-frame-pointer -g")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address")
message(STATUS "AddressSanitizer enabled")
endif()
# ThreadSanitizer
option(COCO_ENABLE_TSAN "Enable ThreadSanitizer" OFF)
if(COCO_ENABLE_TSAN)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=thread -fno-omit-frame-pointer -g")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=thread")
message(STATUS "ThreadSanitizer enabled")
endif()
# UndefinedBehaviorSanitizer
option(COCO_ENABLE_UBSAN "Enable UndefinedBehaviorSanitizer" OFF)
if(COCO_ENABLE_UBSAN)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=undefined -fno-omit-frame-pointer -g")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=undefined")
message(STATUS "UndefinedBehaviorSanitizer enabled")
endif()
# Valgrind memory check option (runs tests under valgrind)
option(COCO_ENABLE_VALGRIND "Run tests under Valgrind memcheck" OFF)
if(COCO_ENABLE_VALGRIND)
find_program(VALGRIND_PATH valgrind)
if(VALGRIND_PATH)
set(CTEST_MEMORYCHECK_COMMAND "${VALGRIND_PATH}")
set(CMAKE_CTEST_COMMAND "${CMAKE_CTEST_COMMAND} --leak-check=full --error-exitcode=1")
message(STATUS "Valgrind memory check enabled: ${VALGRIND_PATH}")
else()
message(WARNING "valgrind not found. Memory check will not be available.")
endif()
endif()
# 平台检测
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
set(PLATFORM "linux")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_COCO_PLATFORM_LINUX")
elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
set(PLATFORM "macos")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_COCO_PLATFORM_MACOS")
elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows")
set(PLATFORM "windows")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_COCO_PLATFORM_WINDOWS")
endif()
# 架构检测
if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|AMD64")
set(ARCH "x86_64")
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "arm64|aarch64")
set(ARCH "arm64")
endif()
# 源文件
set(CORE_SOURCES
src/core/coro.c
src/core/context.c
src/core/context_api.c
src/core/context_coro.c
src/core/stack_common.c
src/core/stack.c
src/core/signal.c
src/core/stack_pool.c
src/core/stack_pool_multi.c
src/core/stack_pool_mt.c
src/core/cancel.c
src/core/coro_go.c
src/core/stack_map.c
src/core/frame_walker.c
src/core/stack_grow.c
src/core/safety.c
src/core/preempt.c
src/core/hot_stack.c
src/core/version.c
src/core/cls.c
src/core/trace.c
src/core/debug.c
src/sched/global_sched.c
src/sched/runq.c
src/sched/sched.c
src/sched/sched_stats.c
)
set(PLATFORM_SOURCES
src/platform/coco_thread.c
src/platform/coco_mutex.c
src/platform/coco_cond.c
src/platform/abi_detect.c
src/platform/time.c
)
set(TIMER_SOURCES
src/timer/timer_wheel.c
)
set(CHANNEL_SOURCES
src/channel/channel.c
src/channel/channel_mt.c
)
set(IO_SOURCES
src/io/event_loop.c
src/io/fd_table.c
src/io/netpoller_mt.c
)
# 平台特定源文件
if(PLATFORM STREQUAL "linux")
list(APPEND IO_SOURCES src/io/poll_linux.c)
list(APPEND IO_SOURCES src/io/poll_iouring.c)
list(APPEND PLATFORM_SOURCES src/platform/linux/preempt.c)
if(ARCH STREQUAL "x86_64")
list(APPEND PLATFORM_ASM src/platform/linux/ctx_x86_64.S)
elseif(ARCH STREQUAL "arm64")
list(APPEND PLATFORM_ASM src/platform/linux/ctx_arm64.S)
endif()
# 检查 liburing
find_library(LIBURING NAMES uring)
if(LIBURING)
message(STATUS "Found liburing: ${LIBURING}")
else()
message(WARNING "liburing not found. io_uring support will be disabled.")
endif()
elseif(PLATFORM STREQUAL "macos")
list(APPEND IO_SOURCES src/io/poll_macos.c)
list(APPEND PLATFORM_SOURCES src/platform/macos/preempt.c)
if(ARCH STREQUAL "x86_64")
list(APPEND PLATFORM_ASM src/platform/macos/ctx_x86_64.S)
elseif(ARCH STREQUAL "arm64")
list(APPEND PLATFORM_ASM src/platform/macos/ctx_arm64.S)
elseif(ARCH STREQUAL "universal")
# macOS Universal Binary 支持
set(CMAKE_OSX_ARCHITECTURES "x86_64;arm64")
list(APPEND PLATFORM_ASM
src/platform/macos/ctx_x86_64.S
src/platform/macos/ctx_arm64.S
)
endif()
elseif(PLATFORM STREQUAL "windows")
list(APPEND IO_SOURCES src/io/poll_windows.c)
list(APPEND IO_SOURCES src/io/batch_io_fallback.c)
list(APPEND PLATFORM_SOURCES src/platform/windows/preempt.c)
if(ARCH STREQUAL "x86_64")
list(APPEND PLATFORM_ASM src/platform/windows/ctx_x86_64.S)
elseif(ARCH STREQUAL "arm64")
list(APPEND PLATFORM_ASM src/platform/windows/ctx_arm64.S)
endif()
elseif(PLATFORM STREQUAL "macos")
list(APPEND IO_SOURCES src/io/poll_macos.c)
list(APPEND IO_SOURCES src/io/batch_io_fallback.c)
list(APPEND PLATFORM_SOURCES src/platform/macos/preempt.c)
if(ARCH STREQUAL "x86_64")
list(APPEND PLATFORM_ASM src/platform/macos/ctx_x86_64.S)
elseif(ARCH STREQUAL "arm64")
list(APPEND PLATFORM_ASM src/platform/macos/ctx_arm64.S)
elseif(ARCH STREQUAL "universal")
set(CMAKE_OSX_ARCHITECTURES "x86_64;arm64")
list(APPEND PLATFORM_ASM
src/platform/macos/ctx_x86_64.S
src/platform/macos/ctx_arm64.S
)
endif()
endif()
# Build shared library option
option(COCO_BUILD_SHARED "Build shared library" OFF)
if(COCO_BUILD_SHARED)
add_library(coco SHARED
${CORE_SOURCES}
${PLATFORM_SOURCES}
${TIMER_SOURCES}
${CHANNEL_SOURCES}
${IO_SOURCES}
${PLATFORM_ASM}
)
target_compile_definitions(coco PUBLIC COCO_BUILD_SHARED)
else()
add_library(coco STATIC
${CORE_SOURCES}
${PLATFORM_SOURCES}
${TIMER_SOURCES}
${CHANNEL_SOURCES}
${IO_SOURCES}
${PLATFORM_ASM}
)
endif()
target_include_directories(coco PUBLIC include)
target_include_directories(coco PRIVATE src)
# Symbol visibility for shared library
if(NOT WIN32)
target_compile_options(coco PRIVATE -fvisibility=hidden)
endif()
target_compile_definitions(coco PRIVATE COCO_BUILDING)
# Linux: 链接 liburing (如果可用)
if(PLATFORM STREQUAL "linux" AND LIBURING)
target_link_libraries(coco ${LIBURING})
endif()
# Windows: 链接 ws2_32 (Winsock2)
if(WIN32)
target_link_libraries(coco PRIVATE ws2_32)
endif()
# 测试
option(COCO_BUILD_TESTS "Build tests" ON)
if(COCO_BUILD_TESTS)
enable_testing()
# 单元测试 (通用)
set(UNIT_TESTS
test_coro
test_channel
test_timer
test_io
test_stack
test_stack_overflow
test_cancel
test_fd_table
test_iouring
test_io_backend
test_batch_io
test_io_options
test_syscall_count
test_event_loop
test_aging
test_lifecycle
test_priority
test_signal
test_exit
test_sleep
test_aging_trigger
test_stack_pool_multi
test_stack_pool_mt
test_global_sched
test_runq
test_sched
test_channel_mt
test_netpoller_mt
test_context_api
test_context_coro
test_platform_abstraction
test_sched_stats
test_sched_reinit
test_sched_balanced
test_coco_go
test_context_value
test_frame_walker
test_global_sched_mt
test_stack_shrink
test_channel_select
test_stack_growth
test_preempt
test_preempt_block
test_fairness
test_preempt_channel
test_preempt_sched
test_long_running
test_safety
test_stack_map
test_cls
test_trace
test_debug
test_stack_grow
stress_coro_count
stress_channel_burst
stress_channel_mt_burst
stress_timer_wheel
stress_io_thunder
stress_mt_scaling
test_hot_stack
test_shared_stack_stress
test_coro_guard
)
# 平台特定测试
if(PLATFORM STREQUAL "macos")
list(APPEND UNIT_TESTS test_poll_macos)
endif()
foreach(test_name ${UNIT_TESTS})
add_executable(${test_name} tests/unit/${test_name}.c)
target_link_libraries(${test_name} coco)
add_test(NAME ${test_name} COMMAND ${test_name})
endforeach()
# ARM64 上下文测试
if(ARCH STREQUAL "arm64")
add_executable(test_ctx_arm64 tests/unit/ctx/test_ctx_arm64.c)
target_include_directories(test_ctx_arm64 PRIVATE ${CMAKE_SOURCE_DIR}/src)
target_link_libraries(test_ctx_arm64 coco)
add_test(NAME test_ctx_arm64 COMMAND test_ctx_arm64)
endif()
# x86-64 上下文 callee-saved 寄存器完整性测试
if(ARCH STREQUAL "x86_64")
add_executable(test_ctx_x86_64 tests/unit/test_ctx_x86_64.c tests/unit/ctx/regs_x86_64.S)
target_include_directories(test_ctx_x86_64 PRIVATE ${CMAKE_SOURCE_DIR}/src)
target_link_libraries(test_ctx_x86_64 coco)
add_test(NAME test_ctx_x86_64 COMMAND test_ctx_x86_64)
target_compile_options(test_ctx_x86_64 PRIVATE -fomit-frame-pointer)
endif()
# 基准测试
set(BENCH_TESTS
bench_switch
bench_channel
bench_io
bench_io_backend
bench_preempt
bench_stack
bench_hot_stack
bench_mt_sched
bench_hot_cold_switch
)
foreach(bench_name ${BENCH_TESTS})
add_executable(${bench_name} tests/benchmark/${bench_name}.c)
target_link_libraries(${bench_name} coco)
endforeach()
# 整合测试 (运行所有单元测试)
add_executable(test_all tests/unit/test_all.c)
target_link_libraries(test_all coco)
endif()
# 示例
option(COCO_BUILD_EXAMPLES "Build examples" ON)
if(COCO_BUILD_EXAMPLES)
set(EXAMPLES
basic
echo_server
pipeline
memory_test
timer
select
priority
cancel
join_exit
preemption
fan_out
sched_run_once
multithread
http_static
http_static_mt
hot_stack
dynamic_stack
context_api
)
foreach(example_name ${EXAMPLES})
add_executable(${example_name} examples/${example_name}.c)
target_link_libraries(${example_name} coco)
endforeach()
endif()
# 覆盖率目标
if(COCO_BUILD_TESTS AND COCO_ENABLE_COVERAGE)
find_program(LCOV_PATH lcov)
find_program(GENHTML_PATH genhtml)
if(LCOV_PATH AND GENHTML_PATH)
add_custom_target(coverage
# 清理旧的覆盖率数据
COMMAND ${CMAKE_COMMAND} -E remove -f coverage.base coverage.test coverage.total coverage.cleaned.info
# 初始化基准数据
COMMAND ${LCOV_PATH} --capture --initial --directory . --output-file coverage.base
# 运行测试
COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure
# 捕获测试覆盖率数据
COMMAND ${LCOV_PATH} --capture --directory . --output-file coverage.test
# 合并基准和测试数据
COMMAND ${LCOV_PATH} --add-tracefile coverage.base --add-tracefile coverage.test --output-file coverage.total
# 过滤系统头文件和测试文件
COMMAND ${LCOV_PATH} --remove coverage.total '/usr/*' '/opt/homebrew/*' '*/tests/*' '*/examples/*' --output-file coverage.cleaned.info --ignore-errors unused
# 生成 HTML 报告
COMMAND ${GENHTML_PATH} coverage.cleaned.info --output-directory coverage_report
# 输出摘要
COMMAND ${LCOV_PATH} --summary coverage.cleaned.info
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMENT "Generating code coverage report..."
)
add_custom_command(TARGET coverage POST_BUILD
COMMAND ${CMAKE_COMMAND} -E echo "Coverage report generated in: ${CMAKE_BINARY_DIR}/coverage_report/"
)
else()
message(WARNING "lcov or genhtml not found. Coverage target will not be available.")
endif()
endif()
# 安装规则
include(GNUInstallDirs)
install(TARGETS coco
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
install(FILES include/coco.h
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
install(FILES include/coco_safety.h
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
OPTIONAL
)
# pkg-config file
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/coco.pc.in
${CMAKE_CURRENT_BINARY_DIR}/coco.pc @ONLY)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/coco.pc
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)