|
76 | 76 | message(WARNING "clang-format not found, source code formatting targets will not be available") |
77 | 77 | endif() |
78 | 78 |
|
| 79 | +# enable compile_commands.json so clang-tidy can pick up per-TU flags (ignored by MSVC generator) |
| 80 | +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) |
| 81 | + |
79 | 82 | add_executable(redumper) |
80 | 83 | target_sources(redumper |
81 | 84 | PUBLIC |
@@ -217,6 +220,10 @@ endif() |
217 | 220 |
|
218 | 221 | target_link_libraries(redumper ${libs}) |
219 | 222 |
|
| 223 | +if(REDUMPER_TARGET_LINUX) |
| 224 | + target_link_options(redumper PRIVATE "-static") |
| 225 | +endif() |
| 226 | + |
220 | 227 | install(TARGETS redumper DESTINATION "bin") |
221 | 228 |
|
222 | 229 | # bundle LLVM libc++ for C++20 support (system libc++ is too old, static linking not allowed on macOS) |
@@ -254,3 +261,61 @@ endif() |
254 | 261 | enable_testing() |
255 | 262 |
|
256 | 263 | add_subdirectory("tests") |
| 264 | + |
| 265 | +# static analysis (clang-tidy) |
| 266 | +find_program(CLANG_TIDY NAMES clang-tidy clang-tidy-18) |
| 267 | +find_program(RUN_CLANG_TIDY NAMES run-clang-tidy run-clang-tidy-18 run-clang-tidy.py) |
| 268 | + |
| 269 | +if(CLANG_TIDY AND CMAKE_EXPORT_COMPILE_COMMANDS) |
| 270 | + # only exclude vendored sources pulled in by FetchContent (googletest) |
| 271 | + set(TIDY_FILE_FILTER "^(?!.*/(BUILD|build.*|_deps|tests/gtest/_deps)/).*\\.(cc|ixx)$") |
| 272 | + |
| 273 | + # collect every project target so all module BMIs are built before clang-tidy runs; |
| 274 | + # otherwise per-TU compile commands fail with "module file not found" / missing modmap files |
| 275 | + get_property(_tidy_root_targets DIRECTORY . PROPERTY BUILDSYSTEM_TARGETS) |
| 276 | + get_property(_tidy_gtest_targets DIRECTORY tests/gtest PROPERTY BUILDSYSTEM_TARGETS) |
| 277 | + set(_tidy_deps redumper) |
| 278 | + foreach(_t IN LISTS _tidy_root_targets _tidy_gtest_targets) |
| 279 | + if(TARGET ${_t}) |
| 280 | + get_target_property(_type ${_t} TYPE) |
| 281 | + if(_type STREQUAL "EXECUTABLE" OR _type STREQUAL "STATIC_LIBRARY" OR _type STREQUAL "SHARED_LIBRARY" OR _type STREQUAL "MODULE_LIBRARY" OR _type STREQUAL "OBJECT_LIBRARY") |
| 282 | + list(APPEND _tidy_deps ${_t}) |
| 283 | + endif() |
| 284 | + endif() |
| 285 | + endforeach() |
| 286 | + list(REMOVE_DUPLICATES _tidy_deps) |
| 287 | + |
| 288 | + if(RUN_CLANG_TIDY) |
| 289 | + add_custom_target(tidy |
| 290 | + COMMAND ${RUN_CLANG_TIDY} -p ${CMAKE_BINARY_DIR} |
| 291 | + -clang-tidy-binary ${CLANG_TIDY} |
| 292 | + -quiet |
| 293 | + "${TIDY_FILE_FILTER}" |
| 294 | + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} |
| 295 | + COMMENT "Running clang-tidy (report only)" |
| 296 | + VERBATIM) |
| 297 | + add_custom_target(tidy-fix |
| 298 | + COMMAND ${RUN_CLANG_TIDY} -p ${CMAKE_BINARY_DIR} |
| 299 | + -clang-tidy-binary ${CLANG_TIDY} |
| 300 | + -fix -format |
| 301 | + "${TIDY_FILE_FILTER}" |
| 302 | + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} |
| 303 | + COMMENT "Running clang-tidy with --fix" |
| 304 | + VERBATIM) |
| 305 | + else() |
| 306 | + message(STATUS "run-clang-tidy not found, falling back to single-process clang-tidy targets") |
| 307 | + # fallback: invoke clang-tidy directly per-file via compile_commands.json |
| 308 | + # (slower; install run-clang-tidy for parallelism) |
| 309 | + add_custom_target(tidy |
| 310 | + COMMAND ${CMAKE_COMMAND} -E echo "Run: clang-tidy -p ${CMAKE_BINARY_DIR} <file> for any source listed in compile_commands.json") |
| 311 | + endif() |
| 312 | + |
| 313 | + add_dependencies(tidy ${_tidy_deps}) |
| 314 | + if(TARGET tidy-fix) |
| 315 | + add_dependencies(tidy-fix ${_tidy_deps}) |
| 316 | + endif() |
| 317 | +else() |
| 318 | + if(NOT CLANG_TIDY) |
| 319 | + message(STATUS "clang-tidy not found, static analysis targets will not be available") |
| 320 | + endif() |
| 321 | +endif() |
0 commit comments