@@ -12,6 +12,12 @@ endif()
1212option (PTK_BUILD_EXAMPLES "Build Protocol Toolkit examples" ${PTK_IS_MAIN_PROJECT} )
1313option (PTK_BUILD_TESTS "Build Protocol Toolkit tests" ${PTK_IS_MAIN_PROJECT} )
1414option (PTK_INSTALL "Install Protocol Toolkit files" ${PTK_IS_MAIN_PROJECT} )
15+ option (PTK_STATIC_BUILD "Build static libraries only" OFF )
16+ option (PTK_ENABLE_STATIC_ANALYSIS "Enable static analysis tools" OFF )
17+ option (PTK_ENABLE_ASAN "Enable AddressSanitizer" OFF )
18+ option (PTK_ENABLE_MSAN "Enable MemorySanitizer" OFF )
19+ option (PTK_ENABLE_UBSAN "Enable UndefinedBehaviorSanitizer" OFF )
20+ option (PTK_ENABLE_TSAN "Enable ThreadSanitizer" OFF )
1521
1622# Set C standard
1723set (CMAKE_C_STANDARD 11)
@@ -40,6 +46,126 @@ elseif(CMAKE_C_COMPILER_ID STREQUAL "MSVC")
4046 set (CMAKE_C_FLAGS_RELEASE "/O2 /DNDEBUG" )
4147endif ()
4248
49+ #=============================================================================
50+ # SANITIZERS AND STATIC ANALYSIS
51+ #=============================================================================
52+
53+ # Sanitizers are disabled for static builds as they typically don't work well together
54+ if (NOT PTK_STATIC_BUILD)
55+ # Sanitizer configuration
56+ set (SANITIZER_FLAGS "" )
57+ set (SANITIZER_LINK_FLAGS "" )
58+
59+ # AddressSanitizer
60+ if (PTK_ENABLE_ASAN)
61+ if (PTK_ENABLE_MSAN OR PTK_ENABLE_TSAN)
62+ message (FATAL_ERROR "AddressSanitizer cannot be used with MemorySanitizer or ThreadSanitizer" )
63+ endif ()
64+ set (SANITIZER_FLAGS "${SANITIZER_FLAGS} -fsanitize=address -fno-omit-frame-pointer" )
65+ set (SANITIZER_LINK_FLAGS "${SANITIZER_LINK_FLAGS} -fsanitize=address" )
66+ message (STATUS "AddressSanitizer enabled" )
67+ endif ()
68+
69+ # MemorySanitizer
70+ if (PTK_ENABLE_MSAN)
71+ if (PTK_ENABLE_ASAN OR PTK_ENABLE_TSAN)
72+ message (FATAL_ERROR "MemorySanitizer cannot be used with AddressSanitizer or ThreadSanitizer" )
73+ endif ()
74+ if (NOT CMAKE_C_COMPILER_ID STREQUAL "Clang" )
75+ message (FATAL_ERROR "MemorySanitizer requires Clang" )
76+ endif ()
77+ set (SANITIZER_FLAGS "${SANITIZER_FLAGS} -fsanitize=memory -fno-omit-frame-pointer" )
78+ set (SANITIZER_LINK_FLAGS "${SANITIZER_LINK_FLAGS} -fsanitize=memory" )
79+ message (STATUS "MemorySanitizer enabled" )
80+ endif ()
81+
82+ # UndefinedBehaviorSanitizer
83+ if (PTK_ENABLE_UBSAN)
84+ set (SANITIZER_FLAGS "${SANITIZER_FLAGS} -fsanitize=undefined" )
85+ set (SANITIZER_LINK_FLAGS "${SANITIZER_LINK_FLAGS} -fsanitize=undefined" )
86+ message (STATUS "UndefinedBehaviorSanitizer enabled" )
87+ endif ()
88+
89+ # ThreadSanitizer
90+ if (PTK_ENABLE_TSAN)
91+ if (PTK_ENABLE_ASAN OR PTK_ENABLE_MSAN)
92+ message (FATAL_ERROR "ThreadSanitizer cannot be used with AddressSanitizer or MemorySanitizer" )
93+ endif ()
94+ set (SANITIZER_FLAGS "${SANITIZER_FLAGS} -fsanitize=thread" )
95+ set (SANITIZER_LINK_FLAGS "${SANITIZER_LINK_FLAGS} -fsanitize=thread" )
96+ message (STATUS "ThreadSanitizer enabled" )
97+ endif ()
98+
99+ # Apply sanitizer flags
100+ if (SANITIZER_FLAGS)
101+ set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${SANITIZER_FLAGS} " )
102+ set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${SANITIZER_LINK_FLAGS} " )
103+ set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${SANITIZER_LINK_FLAGS} " )
104+ endif ()
105+ else ()
106+ if (PTK_ENABLE_ASAN OR PTK_ENABLE_MSAN OR PTK_ENABLE_UBSAN OR PTK_ENABLE_TSAN)
107+ message (WARNING "Sanitizers are disabled for static builds" )
108+ endif ()
109+ endif ()
110+
111+ # Static Analysis Tools
112+ if (PTK_ENABLE_STATIC_ANALYSIS)
113+ # Find cppcheck
114+ find_program (CPPCHECK_EXECUTABLE cppcheck )
115+ if (CPPCHECK_EXECUTABLE)
116+ message (STATUS "Found cppcheck: ${CPPCHECK_EXECUTABLE} " )
117+
118+ # Create cppcheck target
119+ add_custom_target (cppcheck
120+ COMMAND ${CPPCHECK_EXECUTABLE}
121+ --enable=all
122+ --std=c11
123+ --verbose
124+ --quiet
125+ --xml
126+ --xml-version=2
127+ --suppress=missingIncludeSystem
128+ --suppress=unusedFunction
129+ --suppress=unmatchedSuppression
130+ src/
131+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
132+ COMMENT "Running cppcheck static analysis"
133+ )
134+ else ()
135+ message (WARNING "cppcheck not found. Static analysis will be limited." )
136+ endif ()
137+
138+ # Find scan-build (Clang Static Analyzer)
139+ find_program (SCAN_BUILD_EXECUTABLE scan-build )
140+ if (SCAN_BUILD_EXECUTABLE)
141+ message (STATUS "Found scan-build: ${SCAN_BUILD_EXECUTABLE} " )
142+
143+ # Create scan-build target
144+ add_custom_target (scan-build
145+ COMMAND ${SCAN_BUILD_EXECUTABLE}
146+ --status-bugs
147+ --use-cc=${CMAKE_C_COMPILER}
148+ -o ${CMAKE_BINARY_DIR} /scan-build-reports
149+ make -C ${CMAKE_BINARY_DIR}
150+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
151+ COMMENT "Running Clang Static Analyzer"
152+ )
153+ else ()
154+ message (WARNING "scan-build not found. Install clang-tools for static analysis." )
155+ endif ()
156+
157+ # Combined static analysis target
158+ if (CPPCHECK_EXECUTABLE OR SCAN_BUILD_EXECUTABLE)
159+ add_custom_target (static -analysis )
160+ if (CPPCHECK_EXECUTABLE)
161+ add_dependencies (static -analysis cppcheck )
162+ endif ()
163+ if (SCAN_BUILD_EXECUTABLE)
164+ add_dependencies (static -analysis scan-build )
165+ endif ()
166+ endif ()
167+ endif ()
168+
43169# Platform-specific settings
44170if (WIN32 )
45171 # Windows-specific settings
0 commit comments