-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathCMakeLists.txt
More file actions
6014 lines (5406 loc) · 254 KB
/
CMakeLists.txt
File metadata and controls
6014 lines (5406 loc) · 254 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
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
cmake_minimum_required(VERSION 3.20)
# When building directly from the cmake/ subdirectory (e.g. cmake -S cmake),
# THEMIS_ROOT_DIR is not yet set. Default it to the parent of this file.
if(NOT THEMIS_ROOT_DIR)
get_filename_component(THEMIS_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/.." ABSOLUTE)
endif()
# VERSION ist Single-Source-of-Truth: zwingend aus Datei lesen
if(NOT EXISTS "${THEMIS_ROOT_DIR}/VERSION")
message(FATAL_ERROR "VERSION file not found at project root. Please create and set semantic version (e.g., 1.2.3).")
endif()
file(READ "${THEMIS_ROOT_DIR}/VERSION" _ver)
string(STRIP "${_ver}" _ver)
# Accept semantic versions with optional pre-release/build suffixes, but sanitize for CMake's project(VERSION)
if(NOT _ver MATCHES "^[0-9]+\\.[0-9]+\\.[0-9]+(.*)?$")
message(FATAL_ERROR "Invalid VERSION content: '${_ver}'. Expected semantic version like 1.2.3")
endif()
# Extract numeric MAJOR.MINOR.PATCH for CMake's version field
string(REGEX MATCH "^[0-9]+\\.[0-9]+\\.[0-9]+" _ver_numeric "${_ver}")
if(NOT _ver_numeric)
message(FATAL_ERROR "Failed to parse numeric version from '${_ver}'")
endif()
project(Themis VERSION ${_ver_numeric} LANGUAGES CXX)
# Make project version available to all translation units
add_compile_definitions(THEMIS_VERSION_STRING="${_ver}")
# Include modular build configuration (post-v1.3.0 feature)
# See docs/architecture/MODULARIZATION_PLAN.md for details
include(${CMAKE_CURRENT_SOURCE_DIR}/ModularBuild.cmake)
# C++20 Standard
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
# Runtime library for static linking on Windows
if(MSVC AND VCPKG_TARGET_TRIPLET MATCHES "static")
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>" CACHE STRING "" FORCE)
endif()
# Enable CUDA if requested
if(THEMIS_ENABLE_CUDA)
enable_language(CUDA)
set(CMAKE_CUDA_STANDARD 17)
set(CMAKE_CUDA_STANDARD_REQUIRED ON)
endif()
# Export compile commands for IDE support
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
# vcpkg integration
if(DEFINED ENV{VCPKG_ROOT})
set(CMAKE_TOOLCHAIN_FILE "$ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake"
CACHE STRING "Vcpkg toolchain file")
endif()
# Prefer CONFIG packages (vcpkg) over FindXXX modules
set(CMAKE_FIND_PACKAGE_PREFER_CONFIG ON)
# Dependencies
find_package(OpenSSL CONFIG)
if(NOT OpenSSL_FOUND)
find_package(OpenSSL REQUIRED)
endif()
# zlib (required for SAML HTTP-Redirect binding DEFLATE compression)
find_package(ZLIB REQUIRED)
# Make CURL optional: some environments (CI/dev) may not have dev package installed.
# If found, create CURL::libcurl target; otherwise provide a fallback and continue.
find_package(CURL CONFIG)
if(NOT CURL_FOUND)
find_package(CURL)
endif()
if(NOT CURL_FOUND)
message(WARNING "CURL package not found; building without libcurl. Some features may be disabled.")
endif()
# Office document support (DOCX/XLSX/PPTX)
# Find libzip (needed for both Office and Archive processing)
find_package(libzip CONFIG)
if(NOT libzip_FOUND)
find_package(libzip)
endif()
if(libzip_FOUND)
message(STATUS "libzip found - Archive processing available")
else()
message(WARNING "libzip not found - Install with: vcpkg install libzip")
message(WARNING "Archive processing will not be available")
endif()
# pugixml is used by SAML/XML parsing and Office processing.
find_package(pugixml CONFIG)
if(NOT pugixml_FOUND)
find_package(pugixml)
endif()
# Office support requires both libzip and pugixml
if(THEMIS_ENABLE_OFFICE)
if(libzip_FOUND AND pugixml_FOUND)
message(STATUS "Office support enabled - libzip and pugixml found")
add_compile_definitions(THEMIS_ENABLE_OFFICE)
else()
if(NOT pugixml_FOUND)
message(WARNING "pugixml not found - Install with: vcpkg install pugixml")
endif()
message(WARNING "Disabling Office support due to missing dependencies")
set(THEMIS_ENABLE_OFFICE OFF CACHE BOOL "Office support disabled - missing dependencies" FORCE)
endif()
endif()
# PDF support requires poppler-cpp
if(THEMIS_ENABLE_PDF)
find_package(Poppler CONFIG COMPONENTS cpp QUIET)
if(NOT Poppler_FOUND)
find_package(Poppler COMPONENTS cpp QUIET)
endif()
if(Poppler_FOUND)
message(STATUS "PDF support enabled - poppler-cpp found")
add_compile_definitions(THEMIS_ENABLE_PDF)
else()
message(WARNING "poppler-cpp not found - Install with: vcpkg install poppler")
message(WARNING "Disabling PDF layout preservation due to missing dependencies")
set(THEMIS_ENABLE_PDF OFF CACHE BOOL "PDF support disabled - missing poppler-cpp" FORCE)
endif()
endif()
# OCR support requires libtesseract + leptonica
if(THEMIS_ENABLE_OCR)
find_package(Tesseract CONFIG QUIET)
if(NOT Tesseract_FOUND)
find_package(Tesseract QUIET)
endif()
if(Tesseract_FOUND)
message(STATUS "OCR support enabled - libtesseract found")
add_compile_definitions(THEMIS_ENABLE_OCR)
else()
message(WARNING "libtesseract not found - Install with: vcpkg install tesseract")
message(WARNING "Disabling OCR support due to missing dependencies")
set(THEMIS_ENABLE_OCR OFF CACHE BOOL "OCR support disabled - missing libtesseract" FORCE)
endif()
endif()
# FFmpeg support for video processing (optional)
# Priority: 1) Local Submodule, 2) vcpkg, 3) System
find_package(FFmpeg CONFIG QUIET)
if(NOT FFmpeg_FOUND)
find_package(FFmpeg QUIET)
endif()
# If not found, try building from local submodule
if(NOT FFmpeg_FOUND AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/../ffmpeg/CMakeLists.txt")
message(STATUS "Found FFmpeg submodule - building from source")
set(FFMPEG_ENABLE_SMALL ON CACHE BOOL "Build small FFmpeg" FORCE)
set(FFMPEG_ENABLE_OPTIMIZED_BUILD ON CACHE BOOL "Build optimized FFmpeg" FORCE)
# Note: FFmpeg might not have CMakeLists directly; requires configure + make wrapper
# For now, mark as found if directory exists
set(FFmpeg_FOUND TRUE)
set(FFMPEG_SUBMODULE_BUILD ON)
message(STATUS "FFmpeg submodule found at: ${CMAKE_CURRENT_SOURCE_DIR}/../ffmpeg")
endif()
if(FFmpeg_FOUND)
if(FFMPEG_SUBMODULE_BUILD)
message(STATUS "FFmpeg will be built from submodule")
else()
message(STATUS "Found FFmpeg: ${FFmpeg_DIR}")
endif()
set(FFMPEG_FOUND TRUE)
else()
message(STATUS "FFmpeg not found - attempting to build from submodule or install with: vcpkg install ffmpeg")
set(FFMPEG_FOUND FALSE)
endif()
# Build options
option(THEMIS_BUILD_TESTS "Build unit tests" ON)
option(THEMIS_BUILD_BENCHMARKS "Build performance benchmarks" ON)
# GPU and LLM defaults (can be overridden via -D flags)
# GPU acceleration includes FAISS, OpenBLAS, LAPACK via vcpkg
if(NOT DEFINED THEMIS_ENABLE_GPU)
set(THEMIS_ENABLE_GPU ON CACHE BOOL "Enable GPU acceleration for vector search (default ON)" )
endif()
if(NOT DEFINED THEMIS_ENABLE_LLM)
set(THEMIS_ENABLE_LLM ON CACHE BOOL "Enable LLM plugin support with llama.cpp (default ON)" )
endif()
option(THEMIS_ENABLE_TRACING "Enable OpenTelemetry distributed tracing" ON)
option(THEMIS_ENABLE_ASAN "Enable AddressSanitizer for debugging" OFF)
option(THEMIS_STRICT_BUILD "Treat warnings as errors" OFF)
option(THEMIS_ENABLE_AVX2 "Enable AVX2/FMA for SIMD kernels in Release builds (MSVC)" ON)
option(THEMIS_QNAP_BUILD "Build for QNAP NAS with baseline x86-64 (no AVX)" OFF)
option(THEMIS_ENABLE_HSM_REAL "Enable real PKCS#11 HSM provider (fallback to stub if OFF)" OFF)
option(THEMIS_STATIC_BUILD "Build fully static binary for maximum portability (e.g., QNAP)" OFF)
option(THEMIS_CORE_SHARED "Build themis_core as a shared library (DLL/.so) instead of static" OFF)
option(THEMIS_ENABLE_CONTENT_PROCESSORS "Include content processors (audio/image/video/geo/cad) in core" OFF)
# For QNAP or fully static builds, force static core library
if(THEMIS_QNAP_BUILD OR THEMIS_STATIC_BUILD)
set(THEMIS_CORE_SHARED OFF CACHE BOOL "Force static core for QNAP/static builds" FORCE)
# FORCE STATIC BUILD FOR WINDOWS (LNK1189 Export Limit Workaround - v1.3.0+)
set(THEMIS_CORE_SHARED OFF CACHE BOOL "Force static core to avoid Windows DLL export limit (LNK1189)" FORCE)
endif()
# Note: THEMIS_ENABLE_LLM is now set above as FORCE ON (Core Feature)
# Community Edition: LLM is a core feature (llama.cpp Embedding, Similarity, Inference)
# Enterprise/Hyperscaler: Advanced LLM features (Fine-Tuning, Model Management) available as add-on module
# Voice Assistant Support (v1.4.0+) - Enterprise Feature
# Requires: Whisper.cpp (STT), Piper TTS (TTS), llama.cpp (LLM)
option(THEMIS_ENABLE_VOICE_ASSISTANT "Enable Voice Assistant with STT/TTS/LLM (v1.4.0+)" OFF)
option(THEMIS_ENABLE_WHISPER "Enable Whisper.cpp for Speech-to-Text" OFF)
option(THEMIS_ENABLE_PIPER_TTS "Enable Piper TTS for Text-to-Speech" OFF)
option(THEMIS_ENABLE_RNNOISE "Enable RNNoise deep-learning noise suppression" OFF)
# Hardware acceleration backend options
option(THEMIS_ENABLE_CUDA "Enable NVIDIA CUDA acceleration" OFF)
option(THEMIS_ENABLE_HIP "Enable AMD HIP acceleration" OFF)
option(THEMIS_ENABLE_NCCL "Enable NCCL for NVIDIA multi-GPU (v2.5+)" OFF)
option(THEMIS_ENABLE_RCCL "Enable RCCL for AMD multi-GPU (v2.5+)" OFF)
# cuVS/RAFT GPU-accelerated ANN (Approximate Nearest Neighbor) search.
# Requires THEMIS_ENABLE_CUDA=ON and the cuVS/RAFT CMake package to be
# installed (e.g. via conda: `conda install -c rapidsai cuvs`).
# When OFF the CPU brute-force fallback in GPUQueryAccelerator::annSearch()
# is used unconditionally.
if(THEMIS_ENABLE_CUDA)
option(THEMIS_ENABLE_CUVS "Enable cuVS/RAFT GPU-accelerated ANN search (requires CUDA)" OFF)
else()
set(THEMIS_ENABLE_CUVS OFF CACHE BOOL
"cuVS/RAFT ANN search (requires THEMIS_ENABLE_CUDA=ON)" FORCE)
endif()
# Geospatial Processing (P2 - v1.4.0+)
# Enables GDAL integration for Shapefile and GeoTIFF support
option(THEMIS_ENABLE_GDAL "Enable GDAL integration for geospatial data processing" OFF)
# Geospatial CUDA kernel dispatch (v2.1.0+)
# Enables real CUDA kernels for batch point-in-polygon and Haversine distance in
# the geo GPU backend. Requires THEMIS_ENABLE_CUDA=ON and CMAKE_CUDA_COMPILER.
# Default OFF so CPU-only builds are unaffected.
if(THEMIS_ENABLE_CUDA AND CMAKE_CUDA_COMPILER)
option(THEMIS_GEO_CUDA "Enable CUDA kernel dispatch in geo GPU backend" ON)
else()
set(THEMIS_GEO_CUDA OFF CACHE BOOL
"CUDA geo kernels (requires THEMIS_ENABLE_CUDA=ON)" FORCE)
endif()
# Geospatial HIP kernel dispatch (ROCm/AMD hardware)
# Enables real HIP kernels for batch point-in-polygon and Haversine distance in
# the geo GPU backend. Requires THEMIS_ENABLE_HIP=ON.
# THEMIS_GEO_CUDA takes precedence when both are available.
# Default OFF so CPU-only and CUDA-only builds are unaffected.
if(THEMIS_ENABLE_HIP AND NOT THEMIS_GEO_CUDA)
option(THEMIS_GEO_HIP "Enable HIP kernel dispatch in geo GPU backend (AMD ROCm)" ON)
else()
set(THEMIS_GEO_HIP OFF CACHE BOOL
"HIP geo kernels (requires THEMIS_ENABLE_HIP=ON and THEMIS_GEO_CUDA=OFF)" FORCE)
endif()
# PDF Document Processing (Q2 2026)
# Enables poppler-cpp integration for layout-preserving PDF text extraction
option(THEMIS_ENABLE_PDF "Enable PDF text extraction with layout preservation (requires poppler-cpp)" OFF)
# Office Document Processing (P2 - v1.4.0+)
# Enables libzip and pugixml integration for DOCX/XLSX/PPTX support
option(THEMIS_ENABLE_OFFICE "Enable Office document support (DOCX/XLSX/PPTX) with libzip+pugixml" ON)
# OCR Processing (Phase 3 - Advanced Format Support)
# Enables Tesseract OCR for text extraction from image content (JPEG, PNG, TIFF)
option(THEMIS_ENABLE_OCR "Enable Tesseract OCR for image text extraction (requires libtesseract+leptonica)" OFF)
# Performance Optimization Options (Research-based, see docs/de/research/)
# Phase 1: Quick Wins - Low effort, high impact optimizations (from PR #157)
# NOTE: These are automatically enabled when building tests/benchmarks for accurate performance measurement
option(THEMIS_ENABLE_MIMALLOC "Use mimalloc allocator for +10-20% performance" OFF)
option(THEMIS_ENABLE_JEMALLOC "Use jemalloc allocator as alternative (best fragmentation resistance, Linux/Mac only)" OFF)
option(THEMIS_ENABLE_HUGE_PAGES "Enable huge pages support for +15-30% memory performance" OFF)
option(THEMIS_ENABLE_RCU_INDEX "Use RCU for read-heavy index paths (+200-500% read performance)" OFF)
option(THEMIS_ENABLE_LIRS_CACHE "Use LIRS cache replacement policy (+30-40% hit rate)" OFF)
# Auto-enable Phase 1 performance features for tests/benchmarks
if(THEMIS_BUILD_TESTS OR THEMIS_BUILD_BENCHMARKS)
if(NOT DEFINED THEMIS_PERF_AUTO_ENABLE)
set(THEMIS_PERF_AUTO_ENABLE ON CACHE BOOL "Auto-enable performance features for tests/benchmarks")
endif()
if(THEMIS_PERF_AUTO_ENABLE)
message(STATUS "Auto-enabling Phase 1 performance optimizations for tests/benchmarks")
message(STATUS " (Disable with: cmake -DTHEMIS_PERF_AUTO_ENABLE=OFF)")
# Only auto-enable if not explicitly set by user
if(NOT THEMIS_ENABLE_MIMALLOC)
set(THEMIS_ENABLE_MIMALLOC ON CACHE BOOL "Auto-enabled for tests/benchmarks" FORCE)
message(STATUS " → THEMIS_ENABLE_MIMALLOC=ON (auto)")
endif()
if(NOT THEMIS_ENABLE_RCU_INDEX)
set(THEMIS_ENABLE_RCU_INDEX ON CACHE BOOL "Auto-enabled for tests/benchmarks" FORCE)
message(STATUS " → THEMIS_ENABLE_RCU_INDEX=ON (auto)")
endif()
if(NOT THEMIS_ENABLE_LIRS_CACHE)
set(THEMIS_ENABLE_LIRS_CACHE ON CACHE BOOL "Auto-enabled for tests/benchmarks" FORCE)
message(STATUS " → THEMIS_ENABLE_LIRS_CACHE=ON (auto)")
endif()
# Huge Pages nur auf Linux auto-enablen
if(NOT WIN32 AND NOT THEMIS_ENABLE_HUGE_PAGES)
set(THEMIS_ENABLE_HUGE_PAGES ON CACHE BOOL "Auto-enabled for tests/benchmarks (Linux only)" FORCE)
message(STATUS " → THEMIS_ENABLE_HUGE_PAGES=ON (auto, Linux)")
endif()
endif()
endif()
# Phase 2: Medium-Term - Higher impact, medium effort optimizations (from PR #156/#157 research)
# Medium-term optimizations (3-6 months effort, +100-200% overall performance)
option(THEMIS_ENABLE_WISCKEY "Enable WiscKey key/value separation (+40-60% writes)" OFF)
option(THEMIS_ENABLE_DOSTOEVSKY "Enable Dostoevsky adaptive LSM (+25-35% mixed)" OFF)
option(THEMIS_ENABLE_CICADA "Enable Cicada optimistic CC (+100-150% transactions)" OFF)
option(THEMIS_ENABLE_LIGRA "Enable Ligra graph processing (+200-300% graph)" OFF)
option(THEMIS_ENABLE_RABITQ "Enable RaBitQ vector quantization (16x memory reduction)" OFF)
# Phase 3: Long-Term - Very high impact, high effort optimizations (from PR #156/#157 research)
# Long-term optimizations (6-12 months effort, +200-500% specialized workloads)
option(THEMIS_ENABLE_DISKANN "Enable DiskANN billion-scale vector search (+300-400%)" OFF)
option(THEMIS_ENABLE_BWTREE "Enable Bw-Tree lock-free index (+100-200%)" OFF)
option(THEMIS_ENABLE_SPLINTERDB "Enable SplinterDB concurrent compaction (-70% P99)" OFF)
option(THEMIS_ENABLE_GUNROCK "Enable Gunrock GPU graph analytics (+1000-3000%)" OFF)
option(THEMIS_ENABLE_BAO "Enable Bao ML query optimizer (+30-70%)" OFF)
option(THEMIS_ENABLE_PER_QUERY_COST_MODEL "Enable per-query cost model integration with query optimizer (+10-30% plan accuracy)" OFF)
# Phase 4: ML & CI Integration - Very high impact, very high effort (Issue #2424)
# Long-term optimizations (6-12 months effort, +50-200% PMem-heavy workloads)
option(THEMIS_ENABLE_PMEM "Enable Persistent Memory (Optane) aware storage layout (+50-200%)" OFF)
option(THEMIS_ENABLE_PMU_COUNTERS "Enable hardware performance counter (PMU) integration for cache-miss analysis" OFF)
option(THEMIS_ENABLE_IO_URING "Enable io_uring zero-copy I/O path for network performance (Linux kernel ≥ 5.1)" OFF)
# Build options
option(THEMIS_BUILD_BENCHMARKS "Build performance benchmarks (requires Google Benchmark)" ON)
# Performance Optimization Dependencies
if(THEMIS_ENABLE_MIMALLOC)
message(STATUS "Enabling mimalloc allocator optimization (+10-20% performance)")
find_package(mimalloc CONFIG)
if(NOT mimalloc_FOUND)
message(WARNING "mimalloc not found via vcpkg. Install with: vcpkg install mimalloc")
message(WARNING "Building without mimalloc. Performance optimization disabled.")
set(THEMIS_ENABLE_MIMALLOC OFF CACHE BOOL "mimalloc not available" FORCE)
else()
message(STATUS "Found mimalloc: ${mimalloc_DIR}")
add_compile_definitions(THEMIS_ENABLE_MIMALLOC)
# On Windows: exclude mimalloc-redirect.dll to prevent DLL-injection crash
# Use only mimalloc.dll (static override is safer)
if(WIN32)
message(STATUS "Windows: Disabling mimalloc-redirect DLL to prevent loader crash")
# Tell mimalloc to use static override instead of DLL redirection
add_compile_definitions(MI_DISABLE_REDIRECT=1)
endif()
endif()
endif()
if(THEMIS_ENABLE_JEMALLOC)
if(WIN32)
message(WARNING "jemalloc is not supported on Windows. THEMIS_ENABLE_JEMALLOC will be ignored.")
set(THEMIS_ENABLE_JEMALLOC OFF CACHE BOOL "jemalloc not supported on Windows" FORCE)
else()
message(STATUS "Enabling jemalloc allocator (best fragmentation resistance for RocksDB-heavy workloads)")
if(THEMIS_ENABLE_MIMALLOC)
message(WARNING "Both THEMIS_ENABLE_JEMALLOC and THEMIS_ENABLE_MIMALLOC are ON. jemalloc takes priority.")
set(THEMIS_ENABLE_MIMALLOC OFF CACHE BOOL "Disabled: jemalloc selected" FORCE)
endif()
find_package(jemalloc CONFIG QUIET)
if(NOT jemalloc_FOUND)
# Try pkg-config fallback
find_package(PkgConfig QUIET)
if(PkgConfig_FOUND)
pkg_check_modules(jemalloc QUIET jemalloc)
endif()
endif()
if(NOT jemalloc_FOUND AND NOT jemalloc_LIBRARIES)
message(WARNING "jemalloc not found via vcpkg or pkg-config. Install with: vcpkg install jemalloc OR apt install libjemalloc-dev")
message(WARNING "Building without jemalloc. Performance optimization disabled.")
set(THEMIS_ENABLE_JEMALLOC OFF CACHE BOOL "jemalloc not available" FORCE)
else()
message(STATUS "Found jemalloc")
add_compile_definitions(THEMIS_ENABLE_JEMALLOC)
endif()
endif()
endif()
if(THEMIS_ENABLE_HUGE_PAGES)
message(STATUS "Enabling huge pages optimization (+15-30% memory performance)")
# Check platform support
if(UNIX)
message(STATUS "Huge pages: Linux/Unix support enabled")
message(STATUS "Configure with: echo 1024 | sudo tee /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages")
add_compile_definitions(THEMIS_USE_HUGE_PAGES)
elseif(WIN32)
message(STATUS "Huge pages: Windows large pages support enabled")
message(STATUS "Configure via: secpol.msc -> Lock pages in memory")
add_compile_definitions(THEMIS_USE_HUGE_PAGES)
else()
message(WARNING "Huge pages not supported on this platform")
set(THEMIS_ENABLE_HUGE_PAGES OFF CACHE BOOL "Platform not supported" FORCE)
endif()
endif()
if(THEMIS_ENABLE_RCU_INDEX)
message(STATUS "Enabling RCU index optimization (+200-500% read performance)")
message(STATUS "RCU: Read-Copy-Update for lock-free reads in read-heavy workloads")
add_compile_definitions(THEMIS_USE_RCU_INDEX)
# RCU requires C++17 or later (already set to C++20)
# No additional dependencies needed
endif()
if(THEMIS_ENABLE_LIRS_CACHE)
message(STATUS "Enabling LIRS cache optimization (+30-40% cache hit rate)")
message(STATUS "LIRS: Low Inter-reference Recency Set for scan-resistant caching")
add_compile_definitions(THEMIS_USE_LIRS_CACHE)
# LIRS requires C++17 or later (already set to C++20)
# No additional dependencies needed
endif()
# Static build configuration for QNAP/older systems
if(THEMIS_STATIC_BUILD)
message(STATUS "Configuring static build for maximum portability")
# Static linking flags
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libgcc -static-libstdc++")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -static-libgcc -static-libstdc++")
# For fully static builds, link everything statically
# Note: This requires static versions of all libraries
# set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static")
endif()
# Prefer static libraries on Linux
set(BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE)
set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
else()
# Windows: Use dynamic linking (exe + DLLs)
set(BUILD_SHARED_LIBS ON CACHE BOOL "" FORCE)
endif()
option(THEMIS_ENABLE_ZLUDA "Enable AMD ZLUDA (CUDA compatibility on AMD)" OFF)
option(THEMIS_ENABLE_ROCM "Enable AMD ROCm acceleration" OFF)
option(THEMIS_ENABLE_DIRECTX "Enable DirectX 12 Compute Shaders (Windows)" OFF)
option(THEMIS_ENABLE_VULKAN "Enable Vulkan Compute acceleration" OFF)
option(THEMIS_ENABLE_OPENGL "Enable OpenGL Compute Shaders" OFF)
option(THEMIS_ENABLE_METAL "Enable Apple Metal acceleration" OFF)
option(THEMIS_ENABLE_ONEAPI "Enable Intel OneAPI/SYCL acceleration" OFF)
option(THEMIS_ENABLE_OPENCL "Enable OpenCL acceleration" OFF)
option(THEMIS_ENABLE_WEBGPU "Enable WebGPU acceleration (experimental)" OFF)
# Lokal aktivierbare Code-Qualit�t (clang-tidy) ohne CI-Kosten.
option(ENABLE_LOCAL_CLANG_TIDY "Enable local clang-tidy analysis (off by default)" OFF)
# v1.1.0 Build Variants (Q1 2026)
option(THEMIS_ENABLE_OLAP_VARIANT "Build with DuckDB for OLAP workloads" OFF)
option(THEMIS_EMBEDDED "Build embedded/lightweight variant (reduced dependencies)" OFF)
option(THEMIS_VLLM_COLOCATION "Optimize for vLLM co-location (AI/ML workloads)" OFF)
# Network Protocol Support Options
# Security: All protocols are opt-in (OFF by default) except HTTP/1.1 and protocols already in production
# Note: HTTP/1.1 is always enabled as the base protocol and cannot be disabled
option(THEMIS_ENABLE_HTTP2 "Enable HTTP/2 protocol support" OFF)
option(THEMIS_ENABLE_HTTP3 "Enable HTTP/3 (QUIC) protocol support" OFF)
option(THEMIS_ENABLE_GRPC "Enable gRPC protocol support (inter-shard communication)" ON) # Already implemented in v1.3.0
option(THEMIS_ENABLE_WEBSOCKET "Enable WebSocket protocol support" OFF)
option(THEMIS_ENABLE_GRAPHQL "Enable GraphQL API support" ON) # Already implemented
option(THEMIS_ENABLE_SSE "Enable Server-Sent Events (SSE) support" ON) # Already implemented
option(THEMIS_ENABLE_MCP "Enable Model Context Protocol (MCP) support for LLM integration" OFF)
option(THEMIS_ENABLE_MQTT "Enable MQTT protocol support (IoT)" OFF)
option(THEMIS_ENABLE_POSTGRES_WIRE "Enable PostgreSQL Wire Protocol support" OFF)
option(THEMIS_ENABLE_KAFKA "Enable Kafka-compatible CDC producer (requires librdkafka)" OFF)
option(THEMIS_ENABLE_SERVICE_MESH "Enable Istio/Envoy service mesh sidecar proxy mode (xDS v3 REST client)" OFF)
# vLLM Co-Location: Automatically enable CUDA (Kernbestand, not Enterprise!)
if(THEMIS_VLLM_COLOCATION)
set(THEMIS_ENABLE_CUDA ON CACHE BOOL "Force CUDA for vLLM co-location" FORCE)
message(STATUS "vLLM Co-Location enabled: CUDA forced ON (Kernbestand)")
endif()
# Embedded variant: Disable heavy dependencies
if(THEMIS_EMBEDDED)
set(THEMIS_ENABLE_TRACING OFF CACHE BOOL "Disable OpenTelemetry for embedded" FORCE)
set(THEMIS_USE_MIMALLOC OFF CACHE BOOL "Disable mimalloc for embedded (minimal deps)" FORCE)
message(STATUS "Embedded variant: Lightweight build (TBB/Arrow/OpenTelemetry/CUDA disabled)")
endif()
# Geo feature tiering options (Core vs. Enterprise add-ins)
option(THEMIS_GEO "Enable Geo core feature scaffolding" ON)
option(THEMIS_GEO_SIMD "Enable SIMD kernels for Geo (enterprise add-in)" OFF)
option(THEMIS_GEO_GPU "Enable GPU backend for Geo (enterprise add-in)" OFF)
option(THEMIS_GEO_H3 "Enable H3 integration (enterprise add-in)" OFF)
option(THEMIS_GEO_GEOS_PLUGIN "Enable GEOS prepared geometries plugin (enterprise add-in)" OFF)
option(THEMIS_ENTERPRISE "Enable enterprise capabilities bundle" OFF)
# Multi-Edition Support (v1.3.5+)
# THEMIS_EDITION: One of MINIMAL, COMMUNITY, ENTERPRISE, or HYPERSCALER (compile-time selection)
# This setting determines feature availability, licensing limits, and hardware constraints
# MINIMAL: Core database only (embedded/IoT), COMMUNITY: Full features (default), ENTERPRISE: Scaling+HA, HYPERSCALER: Unlimited
set(THEMIS_EDITION "COMMUNITY" CACHE STRING "Edition: MINIMAL, COMMUNITY, ENTERPRISE, or HYPERSCALER")
set_property(CACHE THEMIS_EDITION PROPERTY STRINGS MINIMAL COMMUNITY ENTERPRISE HYPERSCALER)
# Validate edition selection
if(NOT THEMIS_EDITION MATCHES "^(MINIMAL|COMMUNITY|ENTERPRISE|HYPERSCALER)$")
message(FATAL_ERROR "THEMIS_EDITION must be MINIMAL, COMMUNITY, ENTERPRISE, or HYPERSCALER (got: ${THEMIS_EDITION})")
endif()
# Edition feature configuration (compile-time feature flags)
# These determine which functionality is available at build time
# GPU Memory Limits: Edition-specific VRAM constraints
# MINIMAL: No GPU, no LLM, no sharding - only core database features
# COMMUNITY: 24 GB (typical gaming GPU, consumer hardware)
# ENTERPRISE: 256 GB (data center grade A100/H100)
# HYPERSCALER: Unlimited (custom, OEM deployments)
if(THEMIS_EDITION STREQUAL "MINIMAL")
# MINIMAL Edition: Core database features only
# No LLM, no GPU acceleration, no sharding, no replication, no advanced analytics
# Smallest footprint, fastest build time, ideal for embedded/edge deployments
set(THEMIS_GPU_MAX_VRAM_GB 0 CACHE INTERNAL "No GPU support in Minimal Edition")
set(THEMIS_SHARDING_MAX_NODES 1 CACHE INTERNAL "Single-node only in Minimal Edition")
set(THEMIS_ENABLE_ENTERPRISE_PLUGINS OFF CACHE INTERNAL "Enterprise plugins disabled in Minimal")
set(THEMIS_ENABLE_MULTI_MASTER OFF CACHE INTERNAL "Multi-master replication disabled in Minimal")
set(THEMIS_ENABLE_FIELD_ENCRYPTION OFF CACHE INTERNAL "Field-level encryption disabled in Minimal")
set(THEMIS_ENABLE_RBAC OFF CACHE INTERNAL "RBAC disabled in Minimal")
set(THEMIS_ENABLE_HSM OFF CACHE INTERNAL "HSM disabled in Minimal")
set(THEMIS_ENABLE_LLM OFF CACHE INTERNAL "LLM disabled in Minimal")
set(THEMIS_ENABLE_GPU OFF CACHE INTERNAL "GPU disabled in Minimal")
set(THEMIS_ENABLE_CUDA OFF CACHE INTERNAL "CUDA disabled in Minimal")
set(THEMIS_ENABLE_HIP OFF CACHE INTERNAL "HIP disabled in Minimal")
set(THEMIS_ENABLE_VULKAN OFF CACHE INTERNAL "Vulkan disabled in Minimal")
set(THEMIS_ENABLE_CONTENT_PROCESSORS OFF CACHE INTERNAL "Content processors disabled in Minimal")
set(THEMIS_ENABLE_TRACING OFF CACHE INTERNAL "OpenTelemetry tracing disabled in Minimal")
set(THEMIS_ENABLE_VOICE_ASSISTANT OFF CACHE INTERNAL "Voice assistant disabled in Minimal")
set(THEMIS_ENABLE_WHISPER OFF CACHE INTERNAL "Whisper disabled in Minimal")
set(THEMIS_ENABLE_PIPER_TTS OFF CACHE INTERNAL "Piper TTS disabled in Minimal")
set(THEMIS_ENABLE_RNNOISE OFF CACHE INTERNAL "RNNoise disabled in Minimal")
set(THEMIS_ENABLE_GRPC OFF CACHE INTERNAL "gRPC disabled in Minimal")
set(THEMIS_ENABLE_HTTP2 OFF CACHE INTERNAL "HTTP/2 disabled in Minimal")
set(THEMIS_ENABLE_HTTP3 OFF CACHE INTERNAL "HTTP/3 disabled in Minimal")
set(THEMIS_ENABLE_WEBSOCKET OFF CACHE INTERNAL "WebSocket disabled in Minimal")
set(THEMIS_ENABLE_MQTT OFF CACHE INTERNAL "MQTT disabled in Minimal")
set(THEMIS_ENABLE_POSTGRES_WIRE OFF CACHE INTERNAL "PostgreSQL Wire disabled in Minimal")
set(THEMIS_ENABLE_MCP OFF CACHE INTERNAL "MCP disabled in Minimal")
set(THEMIS_BUILD_TESTS OFF CACHE INTERNAL "Tests disabled in Minimal for faster builds")
set(THEMIS_BUILD_BENCHMARKS OFF CACHE INTERNAL "Benchmarks disabled in Minimal")
message(STATUS "Edition: MINIMAL - Core database only, no GPU, no LLM, no sharding, no advanced features")
message(STATUS " Features: ACID transactions, multi-model storage, secondary indexes, basic queries")
message(STATUS " Protocols: HTTP/1.1, REST API only")
message(STATUS " Build time: ~5-10 minutes (vs ~30-40 for full build)")
elseif(THEMIS_EDITION STREQUAL "COMMUNITY")
set(THEMIS_GPU_MAX_VRAM_GB 24 CACHE INTERNAL "Max GPU VRAM for Community Edition")
set(THEMIS_SHARDING_MAX_NODES 5 CACHE INTERNAL "Max sharding nodes for Community Edition")
set(THEMIS_ENABLE_ENTERPRISE_PLUGINS OFF CACHE INTERNAL "Enterprise plugins disabled in Community")
set(THEMIS_ENABLE_MULTI_MASTER OFF CACHE INTERNAL "Multi-master replication disabled in Community")
set(THEMIS_ENABLE_FIELD_ENCRYPTION OFF CACHE INTERNAL "Field-level encryption disabled in Community")
set(THEMIS_ENABLE_RBAC OFF CACHE INTERNAL "RBAC disabled in Community")
set(THEMIS_ENABLE_HSM OFF CACHE INTERNAL "HSM disabled in Community")
# GPU acceleration: Vulkan as default (cross-platform, multi-vendor)
# Vulkan works on NVIDIA, AMD, Intel GPUs across Windows/Linux/macOS/Android
# CUDA is vendor-specific (NVIDIA only) and must be explicitly enabled
if(NOT DEFINED THEMIS_ENABLE_VULKAN)
set(THEMIS_ENABLE_VULKAN ON CACHE BOOL "Enable Vulkan GPU acceleration (default ON, cross-platform)")
endif()
# CUDA is OFF by default (NVIDIA-specific, use -DTHEMIS_ENABLE_CUDA=ON to enable)
# When enabled alongside Vulkan, CUDA takes priority for NVIDIA GPUs
if(NOT DEFINED THEMIS_ENABLE_CUDA)
set(THEMIS_ENABLE_CUDA OFF CACHE BOOL "Enable CUDA GPU acceleration (default OFF, NVIDIA-specific)")
endif()
# LLM support enabled by default in Community Edition (v1.3.0+)
if(NOT DEFINED THEMIS_ENABLE_LLM)
set(THEMIS_ENABLE_LLM ON CACHE BOOL "Enable LLM support in Community Edition (default ON)")
endif()
message(STATUS "Edition: COMMUNITY - GPU limited to ${THEMIS_GPU_MAX_VRAM_GB}GB, up to ${THEMIS_SHARDING_MAX_NODES} nodes")
message(STATUS " GPU Backend: Vulkan=${THEMIS_ENABLE_VULKAN} (cross-platform), CUDA=${THEMIS_ENABLE_CUDA} (NVIDIA-only)")
message(STATUS " LLM Support: ${THEMIS_ENABLE_LLM}")
if(THEMIS_ENABLE_VULKAN)
message(STATUS " Vulkan will provide GPU acceleration on NVIDIA/AMD/Intel GPUs with CPU fallback")
endif()
elseif(THEMIS_EDITION STREQUAL "ENTERPRISE")
set(THEMIS_GPU_MAX_VRAM_GB 256 CACHE INTERNAL "Max GPU VRAM for Enterprise Edition")
set(THEMIS_SHARDING_MAX_NODES 100 CACHE INTERNAL "Max sharding nodes for Enterprise Edition")
set(THEMIS_ENABLE_ENTERPRISE_PLUGINS ON CACHE INTERNAL "Enterprise plugins enabled")
set(THEMIS_ENABLE_MULTI_MASTER ON CACHE INTERNAL "Multi-master replication enabled")
set(THEMIS_ENABLE_FIELD_ENCRYPTION ON CACHE INTERNAL "Field-level encryption enabled")
set(THEMIS_ENABLE_RBAC ON CACHE INTERNAL "RBAC enabled")
set(THEMIS_ENABLE_HSM ON CACHE INTERNAL "HSM enabled")
# GPU acceleration: Vulkan as default (cross-platform, multi-vendor)
if(NOT DEFINED THEMIS_ENABLE_VULKAN)
set(THEMIS_ENABLE_VULKAN ON CACHE BOOL "Enable Vulkan GPU acceleration (default ON, cross-platform)")
endif()
# CUDA OFF by default (enable with -DTHEMIS_ENABLE_CUDA=ON for NVIDIA-specific optimizations)
if(NOT DEFINED THEMIS_ENABLE_CUDA)
set(THEMIS_ENABLE_CUDA OFF CACHE BOOL "Enable CUDA GPU acceleration (default OFF, NVIDIA-specific)")
endif()
# LLM support enabled by default
if(NOT DEFINED THEMIS_ENABLE_LLM)
set(THEMIS_ENABLE_LLM ON CACHE BOOL "Enable LLM support in Enterprise Edition (default ON)")
endif()
message(STATUS "Edition: ENTERPRISE - GPU up to ${THEMIS_GPU_MAX_VRAM_GB}GB, up to ${THEMIS_SHARDING_MAX_NODES} nodes")
message(STATUS " GPU Backend: Vulkan=${THEMIS_ENABLE_VULKAN} (cross-platform), CUDA=${THEMIS_ENABLE_CUDA} (NVIDIA-only)")
message(STATUS " LLM Support: ${THEMIS_ENABLE_LLM}")
elseif(THEMIS_EDITION STREQUAL "HYPERSCALER")
set(THEMIS_GPU_MAX_VRAM_GB 999999 CACHE INTERNAL "Max GPU VRAM for Hyperscaler Edition (unlimited)")
set(THEMIS_SHARDING_MAX_NODES 999999 CACHE INTERNAL "Max sharding nodes for Hyperscaler Edition (unlimited)")
set(THEMIS_ENABLE_ENTERPRISE_PLUGINS ON CACHE INTERNAL "Enterprise plugins enabled")
set(THEMIS_ENABLE_MULTI_MASTER ON CACHE INTERNAL "Multi-master replication enabled")
set(THEMIS_ENABLE_FIELD_ENCRYPTION ON CACHE INTERNAL "Field-level encryption enabled")
set(THEMIS_ENABLE_RBAC ON CACHE INTERNAL "RBAC enabled")
set(THEMIS_ENABLE_HSM ON CACHE INTERNAL "HSM enabled")
# GPU acceleration: Vulkan as default (cross-platform, multi-vendor)
if(NOT DEFINED THEMIS_ENABLE_VULKAN)
set(THEMIS_ENABLE_VULKAN ON CACHE BOOL "Enable Vulkan GPU acceleration (default ON, cross-platform)")
endif()
# CUDA OFF by default (enable with -DTHEMIS_ENABLE_CUDA=ON for NVIDIA-specific optimizations)
if(NOT DEFINED THEMIS_ENABLE_CUDA)
set(THEMIS_ENABLE_CUDA OFF CACHE BOOL "Enable CUDA GPU acceleration (default OFF, NVIDIA-specific)")
endif()
# LLM support enabled by default
if(NOT DEFINED THEMIS_ENABLE_LLM)
set(THEMIS_ENABLE_LLM ON CACHE BOOL "Enable LLM support in Hyperscaler Edition (default ON)")
endif()
message(STATUS "Edition: HYPERSCALER - Unlimited GPU/VRAM and nodes")
message(STATUS " GPU Backend: Vulkan=${THEMIS_ENABLE_VULKAN} (cross-platform), CUDA=${THEMIS_ENABLE_CUDA} (NVIDIA-only)")
message(STATUS " LLM Support: ${THEMIS_ENABLE_LLM}")
set(THEMIS_ENABLE_ENTERPRISE_PLUGINS ON CACHE INTERNAL "Enterprise plugins enabled")
set(THEMIS_ENABLE_MULTI_MASTER ON CACHE INTERNAL "Multi-master replication enabled")
set(THEMIS_ENABLE_FIELD_ENCRYPTION ON CACHE INTERNAL "Field-level encryption enabled")
set(THEMIS_ENABLE_RBAC ON CACHE INTERNAL "RBAC enabled")
set(THEMIS_ENABLE_HSM ON CACHE INTERNAL "HSM enabled")
message(STATUS "Edition: HYPERSCALER - Unlimited GPU VRAM, unlimited nodes, full custom capabilities")
endif()
# ============================================================================
# LICENSE ENFORCEMENT (v1.4.0+)
# ============================================================================
# Enforce license requirements for ENTERPRISE and HYPERSCALER editions
# ENTERPRISE Edition: License REQUIRED for Release builds only
if(THEMIS_EDITION STREQUAL "ENTERPRISE")
# Check CMAKE_BUILD_TYPE - if not set, default to Release for safety
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Build type" FORCE)
endif()
if(CMAKE_BUILD_TYPE STREQUAL "Release")
# Release builds: License is MANDATORY
if(NOT THEMIS_LICENSE_FILE OR THEMIS_LICENSE_FILE STREQUAL "")
message(FATAL_ERROR
"ENTERPRISE Edition Release builds require an embedded license file.\n"
"Usage: cmake -B build -S . \\\n"
" -DTHEMIS_EDITION=ENTERPRISE \\\n"
" -DCMAKE_BUILD_TYPE=Release \\\n"
" -DTHEMIS_LICENSE_FILE=/path/to/license.json\n"
"\n"
"For development/testing, use Debug build:\n"
" cmake -B build -S . -DTHEMIS_EDITION=ENTERPRISE -DCMAKE_BUILD_TYPE=Debug\n")
endif()
message(STATUS "ENTERPRISE Edition (Release): License requirement ENFORCED")
else()
# Debug/Development builds: License is OPTIONAL
message(STATUS "ENTERPRISE Edition (${CMAKE_BUILD_TYPE}): License requirement OPTIONAL (dev build)")
endif()
endif()
# HYPERSCALER Edition: License ALWAYS MANDATORY (no exceptions)
if(THEMIS_EDITION STREQUAL "HYPERSCALER")
if(NOT THEMIS_LICENSE_FILE OR THEMIS_LICENSE_FILE STREQUAL "")
message(FATAL_ERROR
"HYPERSCALER Edition requires an embedded license file (mandatory for all builds).\n"
"This edition is only available with volume licensing.\n"
"\n"
"Usage: cmake -B build -S . \\\n"
" -DTHEMIS_EDITION=HYPERSCALER \\\n"
" -DTHEMIS_LICENSE_FILE=/path/to/hyperscaler-license.json\n"
"\n"
"For licensing inquiries, contact: licensing@themisdb.io\n")
endif()
message(STATUS "HYPERSCALER Edition: License requirement ENFORCED (mandatory)")
endif()
# Compile-time edition identifier for runtime checks and telemetry
add_compile_definitions(
"THEMIS_EDITION_STRING=\"${THEMIS_EDITION}\""
"THEMIS_GPU_MAX_VRAM_GB=${THEMIS_GPU_MAX_VRAM_GB}"
"THEMIS_SHARDING_MAX_NODES=${THEMIS_SHARDING_MAX_NODES}"
)
# ============================================================================
# BUILD REPRODUCIBILITY – Git commit metadata (v1.7.0+)
# ============================================================================
# Capture the current HEAD commit, branch, dirty flag, and build environment
# so that any binary can be traced back to its exact source revision.
find_package(Git QUIET)
set(_THEMIS_GIT_COMMIT "unknown")
set(_THEMIS_GIT_COMMIT_DATE "unknown")
set(_THEMIS_GIT_BRANCH "unknown")
set(_THEMIS_GIT_DIRTY 0)
if(Git_FOUND)
execute_process(
COMMAND ${GIT_EXECUTABLE} log -1 --format=%H
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
OUTPUT_VARIABLE _THEMIS_GIT_COMMIT
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET
)
execute_process(
COMMAND ${GIT_EXECUTABLE} log -1 --format=%ci
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
OUTPUT_VARIABLE _THEMIS_GIT_COMMIT_DATE
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET
)
execute_process(
COMMAND ${GIT_EXECUTABLE} rev-parse --abbrev-ref HEAD
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
OUTPUT_VARIABLE _THEMIS_GIT_BRANCH
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET
)
execute_process(
COMMAND ${GIT_EXECUTABLE} status --porcelain
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
OUTPUT_VARIABLE _git_dirty_output
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET
)
if(_git_dirty_output)
set(_THEMIS_GIT_DIRTY 1)
endif()
endif()
# Build host / user (best-effort)
cmake_host_system_information(RESULT _THEMIS_BUILD_HOST QUERY HOSTNAME)
if(DEFINED ENV{USER})
set(_THEMIS_BUILD_USER "$ENV{USER}")
elseif(DEFINED ENV{USERNAME})
set(_THEMIS_BUILD_USER "$ENV{USERNAME}")
else()
set(_THEMIS_BUILD_USER "unknown")
endif()
message(STATUS "Build reproducibility: commit=${_THEMIS_GIT_COMMIT} branch=${_THEMIS_GIT_BRANCH} dirty=${_THEMIS_GIT_DIRTY}")
add_compile_definitions(
"THEMIS_GIT_COMMIT=\"${_THEMIS_GIT_COMMIT}\""
"THEMIS_GIT_COMMIT_DATE=\"${_THEMIS_GIT_COMMIT_DATE}\""
"THEMIS_GIT_BRANCH=\"${_THEMIS_GIT_BRANCH}\""
"THEMIS_GIT_DIRTY=${_THEMIS_GIT_DIRTY}"
"THEMIS_BUILD_HOST=\"${_THEMIS_BUILD_HOST}\""
"THEMIS_BUILD_USER=\"${_THEMIS_BUILD_USER}\""
)
# Allows embedding company/license data into the binary at build time.
# This supports both offline deployments and CI/CD pipelines.
#
# Default Behavior:
# If no license file is specified, automatically uses the community license
# from config/license_community_default.json
#
# Usage:
# cmake -B build -S . # Uses community license by default
# cmake -B build -S . -DTHEMIS_LICENSE_FILE=path/to/license.json # Custom license
#
# The license file should be a JSON file with the following structure:
# {
# "organization_name": "Company Name",
# "organization_id": "optional-org-id",
# "contact_email": "contact@company.com",
# "license_key": "THEMIS-XXX-XXXXXXXXXXXX",
# "edition": "ENTERPRISE",
# "issued_date": "2026-01-01",
# "expiry_date": "2027-12-31",
# "max_nodes": 100,
# "max_cores": -1,
# "max_storage_tb": -1,
# "build_id": "optional-build-id",
# "signature": "optional-rsa-signature"
# }
set(THEMIS_LICENSE_FILE "" CACHE FILEPATH "Path to license JSON file for embedding")
# Auto-detect default license file if none specified
if(NOT THEMIS_LICENSE_FILE OR THEMIS_LICENSE_FILE STREQUAL "")
set(DEFAULT_LICENSE_FILE "${THEMIS_ROOT_DIR}/config/license_community_default.json")
if(EXISTS "${DEFAULT_LICENSE_FILE}")
set(THEMIS_LICENSE_FILE "${DEFAULT_LICENSE_FILE}")
message(STATUS "No license file specified, using default community license: ${THEMIS_LICENSE_FILE}")
endif()
endif()
# Default license values (empty/unset if no license file provided)
set(THEMIS_LICENSE_ORG_NAME "")
set(THEMIS_LICENSE_ORG_ID "")
set(THEMIS_LICENSE_CONTACT_EMAIL "")
set(THEMIS_LICENSE_KEY "")
set(THEMIS_LICENSE_EDITION "")
set(THEMIS_LICENSE_ISSUED_DATE "")
set(THEMIS_LICENSE_EXPIRY_DATE "")
set(THEMIS_LICENSE_MAX_NODES -1)
set(THEMIS_LICENSE_MAX_CORES -1)
set(THEMIS_LICENSE_MAX_STORAGE_TB -1)
set(THEMIS_LICENSE_BUILD_ID "")
set(THEMIS_LICENSE_BUILD_TIMESTAMP "")
set(THEMIS_LICENSE_SIGNATURE "")
# If license file is provided or auto-detected, read and parse it
if(THEMIS_LICENSE_FILE AND EXISTS "${THEMIS_LICENSE_FILE}")
message(STATUS "Embedding license data from: ${THEMIS_LICENSE_FILE}")
# Read the license file
file(READ "${THEMIS_LICENSE_FILE}" LICENSE_JSON_CONTENT)
# Parse JSON using CMake's built-in JSON support (CMake 3.19+)
# Note: We need to extract values using string operations since CMake's JSON support is limited
# Helper macro to extract JSON string value
macro(extract_json_string VAR_NAME JSON_KEY)
string(REGEX MATCH "\"${JSON_KEY}\"[ \t\n]*:[ \t\n]*\"([^\"]*)\"" _match "${LICENSE_JSON_CONTENT}")
if(_match)
set(${VAR_NAME} "${CMAKE_MATCH_1}")
endif()
endmacro()
# Helper macro to extract JSON integer value
macro(extract_json_int VAR_NAME JSON_KEY)
string(REGEX MATCH "\"${JSON_KEY}\"[ \t\n]*:[ \t\n]*(-?[0-9]+)" _match "${LICENSE_JSON_CONTENT}")
if(_match)
set(${VAR_NAME} "${CMAKE_MATCH_1}")
endif()
endmacro()
# Extract all license fields
extract_json_string(THEMIS_LICENSE_ORG_NAME "organization_name")
extract_json_string(THEMIS_LICENSE_ORG_ID "organization_id")
extract_json_string(THEMIS_LICENSE_CONTACT_EMAIL "contact_email")
extract_json_string(THEMIS_LICENSE_KEY "license_key")
extract_json_string(THEMIS_LICENSE_EDITION "edition")
extract_json_string(THEMIS_LICENSE_ISSUED_DATE "issued_date")
extract_json_string(THEMIS_LICENSE_EXPIRY_DATE "expiry_date")
extract_json_int(THEMIS_LICENSE_MAX_NODES "max_nodes")
extract_json_int(THEMIS_LICENSE_MAX_CORES "max_cores")
extract_json_int(THEMIS_LICENSE_MAX_STORAGE_TB "max_storage_tb")
extract_json_string(THEMIS_LICENSE_BUILD_ID "build_id")
extract_json_string(THEMIS_LICENSE_SIGNATURE "signature")
# Set build timestamp to current time
string(TIMESTAMP THEMIS_LICENSE_BUILD_TIMESTAMP "%Y-%m-%d %H:%M:%S UTC" UTC)
# Display embedded license information
message(STATUS " Organization: ${THEMIS_LICENSE_ORG_NAME}")
message(STATUS " License Key: ${THEMIS_LICENSE_KEY}")
message(STATUS " Edition: ${THEMIS_LICENSE_EDITION}")
message(STATUS " Expiry Date: ${THEMIS_LICENSE_EXPIRY_DATE}")
message(STATUS " Max Nodes: ${THEMIS_LICENSE_MAX_NODES}")
message(STATUS " Build Timestamp: ${THEMIS_LICENSE_BUILD_TIMESTAMP}")
# Validate that license edition matches build edition
if(THEMIS_LICENSE_EDITION AND NOT THEMIS_LICENSE_EDITION STREQUAL THEMIS_EDITION)
# For ENTERPRISE and HYPERSCALER, edition mismatch is a FATAL error
if(THEMIS_EDITION STREQUAL "ENTERPRISE" OR THEMIS_EDITION STREQUAL "HYPERSCALER")
message(FATAL_ERROR
"License edition mismatch: License is for '${THEMIS_LICENSE_EDITION}' but build is '${THEMIS_EDITION}'.\n"
"You must use a license file that matches your build edition.\n"
"License file: ${THEMIS_LICENSE_FILE}")
else()
# For MINIMAL/COMMUNITY, just warn
message(WARNING "License edition (${THEMIS_LICENSE_EDITION}) does not match build edition (${THEMIS_EDITION})")
endif()
endif()
else()
if(THEMIS_LICENSE_FILE)
message(WARNING "License file specified but not found: ${THEMIS_LICENSE_FILE}")
endif()
message(STATUS "No license data will be embedded in this build")
endif()
# Add license data as compile definitions
add_compile_definitions(
"THEMIS_LICENSE_ORG_NAME=\"${THEMIS_LICENSE_ORG_NAME}\""
"THEMIS_LICENSE_ORG_ID=\"${THEMIS_LICENSE_ORG_ID}\""
"THEMIS_LICENSE_CONTACT_EMAIL=\"${THEMIS_LICENSE_CONTACT_EMAIL}\""
"THEMIS_LICENSE_KEY=\"${THEMIS_LICENSE_KEY}\""
"THEMIS_LICENSE_EDITION=\"${THEMIS_LICENSE_EDITION}\""
"THEMIS_LICENSE_ISSUED_DATE=\"${THEMIS_LICENSE_ISSUED_DATE}\""
"THEMIS_LICENSE_EXPIRY_DATE=\"${THEMIS_LICENSE_EXPIRY_DATE}\""
"THEMIS_LICENSE_MAX_NODES=${THEMIS_LICENSE_MAX_NODES}"
"THEMIS_LICENSE_MAX_CORES=${THEMIS_LICENSE_MAX_CORES}"
"THEMIS_LICENSE_MAX_STORAGE_TB=${THEMIS_LICENSE_MAX_STORAGE_TB}"
"THEMIS_LICENSE_BUILD_ID=\"${THEMIS_LICENSE_BUILD_ID}\""
"THEMIS_LICENSE_BUILD_TIMESTAMP=\"${THEMIS_LICENSE_BUILD_TIMESTAMP}\""
"THEMIS_LICENSE_SIGNATURE=\"${THEMIS_LICENSE_SIGNATURE}\""
)
# MSVC: sanitize any accidentally injected '/WX:NO' options (invalid for cl.exe)
if(MSVC)
get_property(_allTargets DIRECTORY PROPERTY BUILDSYSTEM_TARGETS)
foreach(_t IN LISTS _allTargets)
foreach(_prop IN ITEMS COMPILE_OPTIONS INTERFACE_COMPILE_OPTIONS)
get_target_property(_opts ${_t} ${_prop})
if(_opts)
list(TRANSFORM _opts REPLACE "/WX:NO" "")
list(TRANSFORM _opts REPLACE "/WX:No" "")
list(TRANSFORM _opts REPLACE "/WX:0" "")
set_target_properties(${_t} PROPERTIES ${_prop} "${_opts}")
endif()
endforeach()
endforeach()
endif()
# Note: Architecture detection and optimization moved to cmake/platforms/
# See cmake/platforms/PlatformDetection.cmake and ArchitectureOptimizations.cmake
# Compiler warnings and optimizations
if(MSVC)
# Replace /Zi (shared PDB) with /Z7 (embedded debug info in .obj) to eliminate
# PDB write contention (C1041) in parallel Ninja builds.
foreach(_lang C CXX)
foreach(_cfg DEBUG RELWITHDEBINFO)
string(REPLACE "/Zi" "/Z7"
CMAKE_${_lang}_FLAGS_${_cfg} "${CMAKE_${_lang}_FLAGS_${_cfg}}")
set(CMAKE_${_lang}_FLAGS_${_cfg} "${CMAKE_${_lang}_FLAGS_${_cfg}}"
CACHE STRING "" FORCE)
endforeach()
endforeach()
add_compile_options(/W4 /utf-8 /wd4701 /bigobj)
# /FS removed: /Z7 renders it unnecessary (no shared PDB file at compile time)
# Suppress unreachable code warnings from external headers (e.g., nlohmann/json)
add_compile_options(/wd4702)
# Suppress AddressSanitizer warnings treated as errors (C5072)
add_compile_options(/wd5072)
# Suppress OpenSSL 3.0 deprecation warnings globally (C4996)
add_compile_options(/wd4996)
if(THEMIS_STRICT_BUILD)
add_compile_options(/WX)
endif()
add_compile_definitions(NOMINMAX _CRT_SECURE_NO_WARNINGS _WIN32_WINNT=0x0A00)
# Apply Release-specific settings for single- and multi-config generators
add_compile_options($<$<CONFIG:Release>:/O2>)
# Disable iterator debugging in Release to match vcpkg RocksDB
add_compile_definitions($<$<CONFIG:Release>:_ITERATOR_DEBUG_LEVEL=0>)
# Note: AVX2 optimization moved to cmake/platforms/ArchitectureOptimizations.cmake
# Disable LTCG to avoid file locking issues on Windows with Ninja
add_link_options($<$<CONFIG:Release>:/INCREMENTAL:NO>)
else()
add_compile_options(-Wall -Wextra -Wpedantic)
if(THEMIS_STRICT_BUILD)
add_compile_options(-Werror)
endif()
if(CMAKE_BUILD_TYPE STREQUAL "Release")
add_compile_options(-O3)
# Note: Architecture-specific optimizations moved to cmake/platforms/ArchitectureOptimizations.cmake
endif()
endif()
# AddressSanitizer support
if(THEMIS_ENABLE_ASAN)
if(MSVC)
add_compile_options(/fsanitize=address)
else()
add_compile_options(-fsanitize=address -fno-omit-frame-pointer)
add_link_options(-fsanitize=address)
endif()
endif()