From 8ad6178eab7d948de2c9b578ac4aa1b3f4ed84e6 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Tue, 26 Aug 2025 18:39:26 +0000 Subject: [PATCH] misc: add simple clang-tidy setup clang-tidy can already read the compilation database from cmake to run on any file. This sets up some cmake targets to make it easier to run the check on all files applicable to the current platform. It also disables a few analyses to reduce the number of warnings to a manageable level. Actually making any fixes is left for later. --- .clang-tidy | 47 +++++++++++++++++++++++++++++++ CMakeLists.txt | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 122 insertions(+) create mode 100644 .clang-tidy diff --git a/.clang-tidy b/.clang-tidy new file mode 100644 index 000000000..0f912ae86 --- /dev/null +++ b/.clang-tidy @@ -0,0 +1,47 @@ +--- +# Configuration file for clang-tidy +# This configuration is tailored for the libuv C library project + +# Use default checks with minimal necessary disables +Checks: + # don't suggest reordering struct definitions + - -clang-analyzer-optin.performance.Padding + # allow memcpy (instead of memcpy_s) + - -clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling + # allow strcpy + - -clang-analyzer-security.insecureAPI.strcpy + # allow TBAA + - -clang-analyzer-unix.MallocSizeof + # always allow `if () statement;` instead of `if () { statement; }` + - -readability-braces-around-statements + # allow any use of case and _ conventions in names + - -readability-identifier-naming + # allow defining a function prototype without naming all arguments + - -readability-named-parameter + # allow 1u instead of 1U constants + - -readability-uppercase-literal-suffix + +# Configure specific check options +CheckOptions: + - key: performance-unnecessary-value-param.AllowedTypes + value: 'uv_.*_t' + - key: readability-braces-around-statements.ShortStatementLines + value: '2' + - key: readability-function-size.LineThreshold + value: '150' + - key: readability-function-size.StatementThreshold + value: '80' + - key: misc-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic + value: 'true' + +# Header filter - only analyze project files, not system headers +HeaderFilterRegex: '^.*/(src|include|test)/.*\.(h|c)$' + +# Format style for fix suggestions +FormatStyle: file + +# Treat warnings as errors +WarningsAsErrors: false + +# Use color, even when run through a program like ninja +UseColor: true diff --git a/CMakeLists.txt b/CMakeLists.txt index e725bff71..1b87f84cf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,6 +24,7 @@ set(CMAKE_C_STANDARD 11) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + option(LIBUV_BUILD_SHARED "Build shared lib" ON) cmake_dependent_option(LIBUV_BUILD_TESTS @@ -822,3 +823,77 @@ message(STATUS "summary of build options: C compiler: ${CMAKE_C_COMPILER} (${CMAKE_C_COMPILER_ID}) CFLAGS: ${CMAKE_C_FLAGS_${_build_type}} ${CMAKE_C_FLAGS} ") + +# clang-tidy support +option(ENABLE_CLANG_TIDY "Enable clang-tidy checks" ON) +if(ENABLE_CLANG_TIDY) + find_program(CLANG_TIDY_EXE NAMES "clang-tidy") + if(CLANG_TIDY_EXE) + set(CMAKE_C_CLANG_TIDY "${CLANG_TIDY_EXE}") + message(STATUS "clang-tidy found: ${CLANG_TIDY_EXE}") + else() + set(CMAKE_C_CLANG_TIDY "clang-tidy") + message(STATUS "clang-tidy not found: install clang-tidy or set -DCLANG_TIDY_EXE to run tidy analysis on this platform") + endif() + + # Collect source files from existing targets (deduplicated) + set(ALL_SOURCE_FILES) + set(SRC_TARGETS) + set(TEST_TARGETS) + set(TIDY_TARGETS) + + # Add main library sources + list(APPEND ALL_SOURCE_FILES ${uv_sources}) + + # Add test sources if tests are enabled + if(LIBUV_BUILD_TESTS) + list(APPEND ALL_SOURCE_FILES ${uv_test_sources}) + endif() + + # Remove duplicates and non-existent files + list(REMOVE_DUPLICATES ALL_SOURCE_FILES) + + foreach(SOURCE_FILE ${ALL_SOURCE_FILES}) + # Create a clean target name + string(REPLACE "/" "-" TARGET_NAME ${SOURCE_FILE}) + string(REGEX REPLACE "\\.[^.]*$" "" TARGET_NAME ${TARGET_NAME}) + set(FULL_TARGET_NAME "tidy-${TARGET_NAME}") + + # Create individual target for this source file + add_custom_target(${FULL_TARGET_NAME} + COMMAND ${CMAKE_C_CLANG_TIDY} -p "${CMAKE_BINARY_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/${SOURCE_FILE}" + COMMENT "Running clang-tidy on ${SOURCE_FILE}" + VERBATIM) + + # Add to appropriate folder list + if(SOURCE_FILE MATCHES "^src/") + list(APPEND SRC_TARGETS ${FULL_TARGET_NAME}) + elseif(SOURCE_FILE MATCHES "^test/") + list(APPEND TEST_TARGETS ${FULL_TARGET_NAME}) + endif() + + # Add to list of all tidy targets + list(APPEND TIDY_TARGETS ${FULL_TARGET_NAME}) + endforeach() + + # Create folder-based targets + if(SRC_TARGETS) + add_custom_target(tidy-src + COMMENT "Running clang-tidy on src files" + VERBATIM) + add_dependencies(tidy-src ${SRC_TARGETS}) + endif() + + if(TEST_TARGETS) + add_custom_target(tidy-test + COMMENT "Running clang-tidy on test files" + VERBATIM) + add_dependencies(tidy-test ${TEST_TARGETS}) + endif() + + # Create main tidy target that depends on all individual targets + add_custom_target(tidy + COMMENT "Running clang-tidy on all source files" + VERBATIM) + add_dependencies(tidy ${TIDY_TARGETS}) +endif()