-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCMakeLists.txt
More file actions
514 lines (455 loc) · 23.9 KB
/
Copy pathCMakeLists.txt
File metadata and controls
514 lines (455 loc) · 23.9 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
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
cmake_minimum_required(VERSION 3.16)
project(BLang LANGUAGES C CXX)
# Platform detection
if(APPLE)
add_compile_definitions(PLATFORM_DARWIN)
elseif(UNIX)
add_compile_definitions(PLATFORM_LINUX)
elseif(WIN32)
add_compile_definitions(PLATFORM_WINDOWS)
endif()
# Optional LLVM integration for code generation
option(BLANG_ENABLE_LLVM "Enable LLVM code generation (auto-detected by default)" ON)
if(NOT BLANG_ENABLE_LLVM)
message(STATUS "LLVM disabled by BLANG_ENABLE_LLVM=OFF -- building in parse-only mode")
set(LLVM_FOUND FALSE)
endif()
if(BLANG_ENABLE_LLVM)
find_package(LLVM CONFIG QUIET)
endif()
if(LLVM_FOUND)
message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
include_directories(${LLVM_INCLUDE_DIRS})
add_definitions(${LLVM_DEFINITIONS})
llvm_map_components_to_libnames(llvm_libs
support
core
irreader
passes
)
else()
message(STATUS "LLVM not found -- building without code generation support")
endif()
# Optional sanitizer instrumentation (opt-in; OFF by default so normal/CI
# non-sanitizer builds are byte-for-byte unchanged). Comma-separated list, e.g.
# cmake -S . -B build-asan -DBLANG_SANITIZE=address,undefined
# Flags are added to BOTH compile and link lines and, because this block precedes
# every target definition, apply uniformly to the compiler (qcc/bcc/lexer) and
# the C runtime libraries. UBSan is made FATAL (-fno-sanitize-recover) so real UB
# fails the build's test run rather than printing and continuing.
set(BLANG_SANITIZE "" CACHE STRING
"Comma-separated sanitizers to instrument with (e.g. address,undefined). Empty = off.")
if(BLANG_SANITIZE)
message(STATUS "Sanitizers enabled: ${BLANG_SANITIZE}")
add_compile_options(-fsanitize=${BLANG_SANITIZE} -fno-sanitize-recover=all
-fno-omit-frame-pointer -g)
add_link_options(-fsanitize=${BLANG_SANITIZE})
endif()
# Lexer test targets
add_executable(lexerTest LexerTest.cpp FileLexer.cpp LexerReader.cpp)
set_target_properties(lexerTest PROPERTIES CXX_STANDARD 17 CXX_STANDARD_REQUIRED ON)
add_executable(lexerTest2 LexerTest2.cpp FileLexer.cpp LexerReader.cpp)
set_target_properties(lexerTest2 PROPERTIES CXX_STANDARD 17 CXX_STANDARD_REQUIRED ON)
# LSP protocol layer (JSON value type + Content-Length framing) and its unit
# test. Compiler-side code — deliberately independent of runtime/blang_json.
add_executable(jsonTest lsp/JsonTest.cpp lsp/Json.cpp lsp/Transport.cpp)
set_target_properties(jsonTest PROPERTIES CXX_STANDARD 17 CXX_STANDARD_REQUIRED ON)
# Compiler FRONTEND sources: lexer, parser, Sema, diagnostics — no driver
# main(), no LLVM. Shared by qcc, the fuzzer, and (soon) the LSP server.
set(BLANG_FRONTEND_SOURCES
QModule.cpp
FileLexer.cpp
LexerReader.cpp
QBlock.cpp
QBreakContinue.cpp
QEnumDefinition.cpp
QExpression.cpp
QFieldAccessExpression.cpp
QForInStatement.cpp
QFunctionDefinition.cpp
QImplBlock.cpp
QMatchExpression.cpp
QProtocolDefinition.cpp
QReturnStatement.cpp
QStatement.cpp
QStructDefinition.cpp
QType.cpp
QVariableDefinition.cpp
QSpawnStatement.cpp
QEventHandler.cpp
QTestBlock.cpp
QAssertStatement.cpp
QQueryExpression.cpp
QLambdaExpression.cpp
BmodEmitter.cpp
LocationDumper.cpp
DiagnosticEngine.cpp
Sema.cpp
Resolver.cpp
FormatString.cpp)
# The qcc driver = frontend + the CLI main.
set(QCC_SOURCES ${BLANG_FRONTEND_SOURCES} qcc.cpp)
# blangd — the BLang language server: the shared frontend + the LSP layer.
# Never compiled with LLVM (diagnostics need parse+sema only), so it builds
# identically in both build modes.
add_executable(blangd
${BLANG_FRONTEND_SOURCES}
lsp/Json.cpp
lsp/Transport.cpp
lsp/Compile.cpp
lsp/AstLocator.cpp
lsp/Server.cpp
lsp/blangd_main.cpp)
set_target_properties(blangd PROPERTIES CXX_STANDARD 17 CXX_STANDARD_REQUIRED ON)
target_include_directories(blangd PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
# modules-v2-graph U1: the frontend (QModule.cpp) computes a module-identity
# digest via SHA-256, so every frontend consumer links blang_sha256.
target_link_libraries(blangd blang_sha256)
# Add LLVM code generation when available
if(LLVM_FOUND)
list(APPEND QCC_SOURCES
CodeGen.cpp CGStatements.cpp CGExpressions.cpp CGTypes.cpp
CGStruct.cpp CGEnum.cpp CGLambda.cpp CGRuntime.cpp CGDebug.cpp)
endif()
add_executable(qcc ${QCC_SOURCES})
# NOTE: JH_VERBOSE_LOGGING is intentionally NOT defined on qcc. It would enable
# logging.h's LOG/TRACE_BEGIN macros, which fprintf compiler-developer trace
# ([TRACE] …, "Saving position", …) to stderr on every parse — incompatible
# with U2's quiet-by-default contract (FR-007 / Gate D). Compiler developers
# who want that trace can build with -DJH_VERBOSE_LOGGING.
set_target_properties(qcc PROPERTIES CXX_STANDARD 17 CXX_STANDARD_REQUIRED ON)
# blang_sqlgen (SQLGen + SchemaMigration) is always needed: codegen uses SQLGen
# and --emit-schema uses SchemaMigration even in parse-only builds.
target_link_libraries(qcc blang_sqlgen)
# modules-v2-graph U1: module-identity digest (SHA-256) in the frontend.
target_link_libraries(qcc blang_sha256)
if(LLVM_FOUND)
target_compile_definitions(qcc PRIVATE BLANG_HAS_LLVM)
target_link_libraries(qcc ${llvm_libs})
endif()
# ---------------------------------------------------------------------------
# Bounded parser fuzzing (libFuzzer) — opt-in, clang-only (U5, REQ-006).
# Configure a dedicated clang build:
# cmake -S . -B build-fuzz -DBLANG_ENABLE_LLVM=OFF -DBLANG_FUZZ=ON \
# -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++
# cmake --build build-fuzz --target fuzz_parse
# Uses the PARSE-ONLY compiler sources (QCC_SOURCES here has no CodeGen because
# the fuzz build sets BLANG_ENABLE_LLVM=OFF) with qcc's main() compiled out.
# ---------------------------------------------------------------------------
option(BLANG_FUZZ "Build the libFuzzer parser target fuzz_parse (requires clang)" OFF)
if(BLANG_FUZZ)
if(NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang")
message(FATAL_ERROR "BLANG_FUZZ requires clang (libFuzzer). Reconfigure with -DCMAKE_CXX_COMPILER=clang++.")
endif()
# Frontend-only: no qcc.cpp, so no conditional-main tricks are needed
# (libFuzzer supplies its own main).
add_executable(fuzz_parse ${BLANG_FRONTEND_SOURCES} fuzz/fuzz_parse.cpp)
set_target_properties(fuzz_parse PROPERTIES CXX_STANDARD 17 CXX_STANDARD_REQUIRED ON)
target_include_directories(fuzz_parse PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
target_compile_options(fuzz_parse PRIVATE -fsanitize=fuzzer,address -fno-omit-frame-pointer -g)
target_link_options(fuzz_parse PRIVATE -fsanitize=fuzzer,address)
# modules-v2-graph U1: the frontend (QModule.cpp) computes a module-identity
# digest via SHA-256, so fuzz_parse — built from BLANG_FRONTEND_SOURCES — must
# link blang_sha256, exactly as qcc and blangd do. Unconditional: needed in the
# parse-only fuzz config (BLANG_ENABLE_LLVM=OFF) too.
target_link_libraries(fuzz_parse blang_sha256)
if(LLVM_FOUND)
# The parser needs no LLVM; keep fuzz_parse lean. (Normally the fuzz build
# is configured BLANG_ENABLE_LLVM=OFF so this branch is not taken.)
target_compile_definitions(fuzz_parse PRIVATE BLANG_HAS_LLVM)
target_link_libraries(fuzz_parse ${llvm_libs} blang_sqlgen)
endif()
endif()
# BLang runtime library (ARC, thread pool, channels, async)
add_library(blang_runtime STATIC runtime/blang_runtime.c)
set_target_properties(blang_runtime PROPERTIES C_STANDARD 11 C_STANDARD_REQUIRED ON)
target_include_directories(blang_runtime PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/runtime)
find_package(Threads REQUIRED)
target_link_libraries(blang_runtime Threads::Threads)
# Also build a standalone .o for linking into BLang programs via bcc
add_library(blang_runtime_obj OBJECT runtime/blang_runtime.c)
set_target_properties(blang_runtime_obj PROPERTIES C_STANDARD 11 C_STANDARD_REQUIRED ON POSITION_INDEPENDENT_CODE ON)
target_include_directories(blang_runtime_obj PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/runtime)
# BLang string runtime library
add_library(blang_string STATIC runtime/blang_string.c)
set_target_properties(blang_string PROPERTIES C_STANDARD 11 C_STANDARD_REQUIRED ON)
target_include_directories(blang_string PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/runtime)
# BLang array runtime library
add_library(blang_array STATIC runtime/blang_array.c)
set_target_properties(blang_array PROPERTIES C_STANDARD 11 C_STANDARD_REQUIRED ON)
target_include_directories(blang_array PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/runtime)
# BLang buffer runtime library (byte buffer for I/O)
add_library(blang_buffer STATIC runtime/blang_buffer.c)
set_target_properties(blang_buffer PROPERTIES C_STANDARD 11 C_STANDARD_REQUIRED ON)
target_include_directories(blang_buffer PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/runtime)
# BLang JSON runtime library
add_library(blang_json STATIC runtime/blang_json.c)
set_target_properties(blang_json PROPERTIES C_STANDARD 11 C_STANDARD_REQUIRED ON)
target_include_directories(blang_json PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/runtime)
# BLang networking runtime library (TCP sockets + poll-based Selector)
add_library(blang_net STATIC runtime/blang_net.c)
set_target_properties(blang_net PROPERTIES C_STANDARD 11 C_STANDARD_REQUIRED ON)
target_include_directories(blang_net PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/runtime)
target_link_libraries(blang_net blang_string blang_buffer)
# BLang filesystem runtime library (file I/O + directory ops)
add_library(blang_fs STATIC runtime/blang_fs.c)
set_target_properties(blang_fs PROPERTIES C_STANDARD 11 C_STANDARD_REQUIRED ON)
target_include_directories(blang_fs PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/runtime)
target_link_libraries(blang_fs blang_string blang_buffer blang_array)
# BLang sys runtime library (argc/argv capture for sys.args)
add_library(blang_sys STATIC runtime/blang_sys.c)
set_target_properties(blang_sys PROPERTIES C_STANDARD 11 C_STANDARD_REQUIRED ON)
target_include_directories(blang_sys PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/runtime)
target_link_libraries(blang_sys blang_string blang_array)
# BLang native stdlib modules (U4): math (libm), time, random, env. Each is an
# import-gated static lib (linked unconditionally by bcc; the linker drops it
# when unreferenced — import-gating happens at the .b combine layer via
# kKnownOrder, not at link).
add_library(blang_math STATIC runtime/blang_math.c)
set_target_properties(blang_math PROPERTIES C_STANDARD 11 C_STANDARD_REQUIRED ON)
target_include_directories(blang_math PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/runtime)
target_link_libraries(blang_math m)
add_library(blang_time STATIC runtime/blang_time.c)
set_target_properties(blang_time PROPERTIES C_STANDARD 11 C_STANDARD_REQUIRED ON)
target_include_directories(blang_time PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/runtime)
add_library(blang_random STATIC runtime/blang_random.c)
set_target_properties(blang_random PROPERTIES C_STANDARD 11 C_STANDARD_REQUIRED ON)
target_include_directories(blang_random PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/runtime)
add_library(blang_env STATIC runtime/blang_env.c)
set_target_properties(blang_env PROPERTIES C_STANDARD 11 C_STANDARD_REQUIRED ON)
target_include_directories(blang_env PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/runtime)
target_link_libraries(blang_env blang_string)
# BLang hash module (U5): FNV-1a over string bytes, backs the hashed Map/Set in
# stdlib/collections.b. Import-gated like the other stdlib .a's.
add_library(blang_hash STATIC runtime/blang_hash.c)
set_target_properties(blang_hash PROPERTIES C_STANDARD 11 C_STANDARD_REQUIRED ON)
target_include_directories(blang_hash PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/runtime)
target_link_libraries(blang_hash blang_string)
# BLang test-runner driver (behind `bcc test`): fork-isolated test dispatch.
add_library(blang_testrunner STATIC runtime/blang_testrunner.c)
set_target_properties(blang_testrunner PROPERTIES C_STANDARD 11 C_STANDARD_REQUIRED ON)
target_include_directories(blang_testrunner PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/runtime)
# BLang database runtime library
add_library(blang_db STATIC runtime/blang_db.c)
set_target_properties(blang_db PROPERTIES C_STANDARD 11 C_STANDARD_REQUIRED ON)
target_include_directories(blang_db PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/runtime)
# Check for libuv (event loop for async/await)
find_package(PkgConfig QUIET)
if(PkgConfig_FOUND)
pkg_check_modules(LIBUV QUIET libuv)
endif()
if(LIBUV_FOUND)
message(STATUS "Found libuv: ${LIBUV_VERSION}")
target_compile_definitions(blang_runtime PRIVATE BLANG_HAS_LIBUV)
target_compile_definitions(blang_runtime_obj PRIVATE BLANG_HAS_LIBUV)
target_include_directories(blang_runtime PRIVATE ${LIBUV_INCLUDE_DIRS})
target_include_directories(blang_runtime_obj PRIVATE ${LIBUV_INCLUDE_DIRS})
target_link_libraries(blang_runtime ${LIBUV_LIBRARIES})
else()
message(STATUS "libuv not found -- async/await will use pthread fallback")
endif()
# Check for SQLite3
if(PkgConfig_FOUND)
pkg_check_modules(SQLITE3 QUIET sqlite3)
endif()
if(SQLITE3_FOUND)
message(STATUS "Found SQLite3: ${SQLITE3_VERSION}")
target_compile_definitions(blang_db PRIVATE BLANG_HAS_SQLITE)
target_include_directories(blang_db PRIVATE ${SQLITE3_INCLUDE_DIRS})
target_link_libraries(blang_db ${SQLITE3_LIBRARIES})
else()
message(STATUS "SQLite3 not found -- database runtime will use stubs")
endif()
# Check for libpq (PostgreSQL backend)
if(PkgConfig_FOUND)
pkg_check_modules(LIBPQ QUIET libpq)
endif()
if(LIBPQ_FOUND)
message(STATUS "Found libpq: ${LIBPQ_VERSION}")
target_compile_definitions(blang_db PRIVATE BLANG_HAS_POSTGRES)
target_include_directories(blang_db PRIVATE ${LIBPQ_INCLUDE_DIRS})
target_link_libraries(blang_db ${LIBPQ_LIBRARIES})
else()
message(STATUS "libpq not found -- PostgreSQL backend disabled")
endif()
# SHA-256 library (standalone C, used by BuildCache)
add_library(blang_sha256 STATIC sha256.c)
set_target_properties(blang_sha256 PROPERTIES C_STANDARD 11 C_STANDARD_REQUIRED ON)
# Build cache (artifact caching for incremental builds)
add_library(blang_buildcache STATIC BuildCache.cpp)
set_target_properties(blang_buildcache PROPERTIES CXX_STANDARD 17 CXX_STANDARD_REQUIRED ON)
target_link_libraries(blang_buildcache blang_sha256)
# SQL generation and schema migration (C++ library for qcc/bcc)
add_library(blang_sqlgen STATIC SQLGen.cpp SchemaMigration.cpp)
set_target_properties(blang_sqlgen PROPERTIES CXX_STANDARD 17 CXX_STANDARD_REQUIRED ON)
target_include_directories(blang_sqlgen PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
# bcc - BLang compiler driver (orchestrates qcc -> llc -> cc pipeline)
add_executable(bcc bcc.cpp ProjectConfig.cpp BuildCache.cpp sha256.c)
set_target_properties(bcc PROPERTIES CXX_STANDARD 17 CXX_STANDARD_REQUIRED ON)
# Bake tool paths into bcc at build time so it works regardless of runtime PATH/arch
target_compile_definitions(bcc PRIVATE BCC_CC_PATH="${CMAKE_C_COMPILER}")
target_compile_definitions(bcc PRIVATE BCC_HOST_ARCH="${CMAKE_SYSTEM_PROCESSOR}")
target_compile_definitions(bcc PRIVATE BCC_RUNTIME_LIB="${CMAKE_BINARY_DIR}/libblang_runtime.a")
target_compile_definitions(bcc PRIVATE BCC_STRING_LIB="${CMAKE_BINARY_DIR}/libblang_string.a")
target_compile_definitions(bcc PRIVATE BCC_ARRAY_LIB="${CMAKE_BINARY_DIR}/libblang_array.a")
target_compile_definitions(bcc PRIVATE BCC_BUFFER_LIB="${CMAKE_BINARY_DIR}/libblang_buffer.a")
target_compile_definitions(bcc PRIVATE BCC_JSON_LIB="${CMAKE_BINARY_DIR}/libblang_json.a")
target_compile_definitions(bcc PRIVATE BCC_NET_LIB="${CMAKE_BINARY_DIR}/libblang_net.a")
target_compile_definitions(bcc PRIVATE BCC_FS_LIB="${CMAKE_BINARY_DIR}/libblang_fs.a")
target_compile_definitions(bcc PRIVATE BCC_SYS_LIB="${CMAKE_BINARY_DIR}/libblang_sys.a")
target_compile_definitions(bcc PRIVATE BCC_MATH_LIB="${CMAKE_BINARY_DIR}/libblang_math.a")
target_compile_definitions(bcc PRIVATE BCC_TIME_LIB="${CMAKE_BINARY_DIR}/libblang_time.a")
target_compile_definitions(bcc PRIVATE BCC_RANDOM_LIB="${CMAKE_BINARY_DIR}/libblang_random.a")
target_compile_definitions(bcc PRIVATE BCC_ENV_LIB="${CMAKE_BINARY_DIR}/libblang_env.a")
target_compile_definitions(bcc PRIVATE BCC_HASH_LIB="${CMAKE_BINARY_DIR}/libblang_hash.a")
target_compile_definitions(bcc PRIVATE BCC_TESTRUNNER_LIB="${CMAKE_BINARY_DIR}/libblang_testrunner.a")
# Ensure the test-runner driver lib is built before bcc links against it via `bcc test`.
add_dependencies(bcc blang_testrunner)
target_compile_definitions(bcc PRIVATE BCC_DB_LIB="${CMAKE_BINARY_DIR}/libblang_db.a")
# Linker flags for the DB backend(s) (e.g. -lsqlite3, -lpq) baked into bcc so
# final binaries that use the DB runtime link the right system libraries.
set(BCC_DB_LDFLAGS_LIST "")
if(SQLITE3_FOUND)
list(APPEND BCC_DB_LDFLAGS_LIST ${SQLITE3_LDFLAGS})
endif()
if(LIBPQ_FOUND)
list(APPEND BCC_DB_LDFLAGS_LIST ${LIBPQ_LDFLAGS})
endif()
string(REPLACE ";" " " BCC_DB_LDFLAGS_STR "${BCC_DB_LDFLAGS_LIST}")
target_compile_definitions(bcc PRIVATE BCC_DB_LINKFLAGS="${BCC_DB_LDFLAGS_STR}")
# bcc runs schema migrations in-process (SchemaMigration) and applies them
# against the database (blang_db + SQLite backend).
target_link_libraries(bcc blang_sqlgen blang_db)
message(STATUS "bcc: C compiler = ${CMAKE_C_COMPILER}")
message(STATUS "bcc: host arch = ${CMAKE_SYSTEM_PROCESSOR}")
# Copy stdlib .b files alongside executables so bcc can resolve `import` to the
# matching stdlib/<name>.b at compile time. Globs all modules so new ones are
# picked up automatically.
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/stdlib)
file(GLOB STDLIB_FILES ${CMAKE_CURRENT_SOURCE_DIR}/stdlib/*.b)
foreach(stdlib_file ${STDLIB_FILES})
get_filename_component(stdlib_name ${stdlib_file} NAME)
configure_file(${stdlib_file} ${CMAKE_BINARY_DIR}/stdlib/${stdlib_name} COPYONLY)
endforeach()
if(LIBUV_FOUND)
target_compile_definitions(bcc PRIVATE BCC_HAS_LIBUV)
endif()
if(LLVM_FOUND)
find_program(LLC_EXECUTABLE NAMES llc-18 llc HINTS ${LLVM_TOOLS_BINARY_DIR} NO_DEFAULT_PATH)
if(NOT LLC_EXECUTABLE)
find_program(LLC_EXECUTABLE NAMES llc-18 llc HINTS ${LLVM_TOOLS_BINARY_DIR})
endif()
if(LLC_EXECUTABLE)
message(STATUS "bcc: llc = ${LLC_EXECUTABLE}")
target_compile_definitions(bcc PRIVATE BCC_LLC_PATH="${LLC_EXECUTABLE}")
endif()
endif()
# ---------------------------------------------------------------------------
# Runtime C unit tests (CTest). Dependency-free assert harness in runtime/tests/
# (test_util.h). One add_test() per behavior so `ctest -N` reports each case.
# These build in every configuration, so a BLANG_SANITIZE build (build-asan)
# runs them under ASan/UBSan automatically.
# ---------------------------------------------------------------------------
enable_testing()
# modules-v2-graph U4: the standalone Resolver component's tests (no LLVM).
# ResolverTest — exercises the resolver INDEPENDENT of any driver (DC4).
# ResolverReuseTest — builds the resolver as lsp/Compile.cpp does and asserts a
# fixture resolves identically to the qcc path (DC5); also
# calls the real lsp::compileDocument entry point.
add_executable(resolverTest ResolverTest.cpp ${BLANG_FRONTEND_SOURCES})
set_target_properties(resolverTest PROPERTIES CXX_STANDARD 17 CXX_STANDARD_REQUIRED ON)
target_include_directories(resolverTest PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(resolverTest blang_sqlgen blang_sha256)
add_test(NAME resolver_component COMMAND resolverTest)
add_executable(resolverReuseTest ResolverReuseTest.cpp lsp/Compile.cpp ${BLANG_FRONTEND_SOURCES})
set_target_properties(resolverReuseTest PROPERTIES CXX_STANDARD 17 CXX_STANDARD_REQUIRED ON)
target_include_directories(resolverReuseTest PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(resolverReuseTest blang_sqlgen blang_sha256)
add_test(NAME resolver_reuse COMMAND resolverReuseTest)
add_executable(test_array runtime/tests/test_array.c)
target_link_libraries(test_array blang_array blang_string)
set_target_properties(test_array PROPERTIES C_STANDARD 11 C_STANDARD_REQUIRED ON)
add_executable(test_string runtime/tests/test_string.c)
target_link_libraries(test_string blang_string blang_array)
set_target_properties(test_string PROPERTIES C_STANDARD 11 C_STANDARD_REQUIRED ON)
add_executable(test_buffer runtime/tests/test_buffer.c)
target_link_libraries(test_buffer blang_buffer blang_array blang_string)
set_target_properties(test_buffer PROPERTIES C_STANDARD 11 C_STANDARD_REQUIRED ON)
add_executable(test_json runtime/tests/test_json.c)
target_link_libraries(test_json blang_json)
set_target_properties(test_json PROPERTIES C_STANDARD 11 C_STANDARD_REQUIRED ON)
add_executable(test_fs runtime/tests/test_fs.c)
target_link_libraries(test_fs blang_fs blang_buffer blang_array blang_string)
set_target_properties(test_fs PROPERTIES C_STANDARD 11 C_STANDARD_REQUIRED ON)
add_executable(test_net runtime/tests/test_net.c)
target_link_libraries(test_net blang_net blang_runtime blang_string blang_buffer blang_array Threads::Threads)
set_target_properties(test_net PROPERTIES C_STANDARD 11 C_STANDARD_REQUIRED ON)
# Native stdlib module unit tests (U4).
add_executable(test_math runtime/tests/test_math.c)
target_link_libraries(test_math blang_math m)
set_target_properties(test_math PROPERTIES C_STANDARD 11 C_STANDARD_REQUIRED ON)
add_executable(test_time runtime/tests/test_time.c)
target_link_libraries(test_time blang_time)
set_target_properties(test_time PROPERTIES C_STANDARD 11 C_STANDARD_REQUIRED ON)
add_executable(test_random runtime/tests/test_random.c)
target_link_libraries(test_random blang_random)
set_target_properties(test_random PROPERTIES C_STANDARD 11 C_STANDARD_REQUIRED ON)
add_executable(test_env runtime/tests/test_env.c)
target_link_libraries(test_env blang_env blang_string blang_array)
set_target_properties(test_env PROPERTIES C_STANDARD 11 C_STANDARD_REQUIRED ON)
add_executable(test_hash runtime/tests/test_hash.c)
target_link_libraries(test_hash blang_hash blang_string blang_array)
set_target_properties(test_hash PROPERTIES C_STANDARD 11 C_STANDARD_REQUIRED ON)
# One add_test per case (name must match the case table in each test_*.c).
set(ARRAY_CASES create_empty push_length get set pop pop_empty insert_remove concat clear grow get_oob set_oob get_null)
set(STRING_CASES create_len empty equals concat substring to_upper to_lower trim contains starts_ends index_of compare to_int replace char_at_oob)
set(BUFFER_CASES create append_byte from_string append_string get_set to_string slice index_of clear get_oob)
set(JSON_CASES decode_int decode_string decode_bool decode_error object_roundtrip array_build object_get_missing)
set(FS_CASES write_read seek size remove mkdir_list)
set(NET_CASES connect_refused connect_bad_host selector_lifecycle close_invalid)
set(MATH_CASES sqrt pow trig log_exp floor_ceil fabs abs_int)
set(TIME_CASES now_positive millis_ge_seconds monotonic_nondecreasing)
set(RANDOM_CASES seeded_sequence seed_reproducible int_range_bounds int_range_empty float01_bounds)
set(ENV_CASES get_hit get_miss has_true has_false)
set(HASH_CASES deterministic distinct nonnegative empty_string)
foreach(c ${ARRAY_CASES})
add_test(NAME array_${c} COMMAND test_array ${c})
endforeach()
foreach(c ${STRING_CASES})
add_test(NAME string_${c} COMMAND test_string ${c})
endforeach()
foreach(c ${BUFFER_CASES})
add_test(NAME buffer_${c} COMMAND test_buffer ${c})
endforeach()
foreach(c ${JSON_CASES})
add_test(NAME json_${c} COMMAND test_json ${c})
endforeach()
foreach(c ${FS_CASES})
add_test(NAME fs_${c} COMMAND test_fs ${c})
endforeach()
foreach(c ${NET_CASES})
add_test(NAME net_${c} COMMAND test_net ${c})
endforeach()
foreach(c ${MATH_CASES})
add_test(NAME math_${c} COMMAND test_math ${c})
endforeach()
foreach(c ${TIME_CASES})
add_test(NAME time_${c} COMMAND test_time ${c})
endforeach()
foreach(c ${RANDOM_CASES})
add_test(NAME random_${c} COMMAND test_random ${c})
endforeach()
foreach(c ${ENV_CASES})
add_test(NAME env_${c} COMMAND test_env ${c})
endforeach()
foreach(c ${HASH_CASES})
add_test(NAME hash_${c} COMMAND test_hash ${c})
endforeach()
# LSP protocol-layer unit test (single binary, internal check table).
add_test(NAME lsp_json COMMAND jsonTest)
# Build-cache key unit test (modules-v2-exports U2, done-condition 7): proves the
# .bmod format version participates in the cache key, so a format bump
# invalidates every warm entry rather than serving a stale interface.
add_executable(buildCacheTest BuildCacheTest.cpp BuildCache.cpp sha256.c)
set_target_properties(buildCacheTest PROPERTIES CXX_STANDARD 17 CXX_STANDARD_REQUIRED ON)
add_test(NAME build_cache_key COMMAND buildCacheTest)