Skip to content

[WIP] Experiment with ClangTidy alongside compilation #1824

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@ option(SOURCEMETA_CORE_CONTRIB_GOOGLEBENCHMARK "Build the GoogleBenchmark librar

include(Sourcemeta)

# Don't force downstream consumers on it
# Don't force downstream consumers on this
if(PROJECT_IS_TOP_LEVEL)
sourcemeta_enable_simd()
sourcemeta_clang_tidy_enable()
endif()

# TODO: Turn this into a re-usable utility CMake function
Expand Down Expand Up @@ -120,7 +121,6 @@ if(PROJECT_IS_TOP_LEVEL)
src/*.h src/*.cc
benchmark/*.h benchmark/*.cc
test/*.h test/*.cc)
sourcemeta_target_clang_tidy(SOURCES src/*.cc)
endif()

# Testing
Expand Down
3 changes: 0 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,6 @@ compile: .always
$(CMAKE) --install ./build --prefix ./build/dist --config $(PRESET) --verbose \
--component sourcemeta_core_dev

lint: .always
$(CMAKE) --build ./build --config $(PRESET) --target clang_tidy

test: .always
$(CMAKE) -E env UBSAN_OPTIONS=print_stacktrace=1 \
$(CTEST) --test-dir ./build --build-config $(PRESET) \
Expand Down
2 changes: 1 addition & 1 deletion cmake/Sourcemeta.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ include("${SOURCEMETA_UTILITIES_DIRECTORY}/commands/copy-file.cmake")
include("${SOURCEMETA_UTILITIES_DIRECTORY}/targets/library.cmake")
include("${SOURCEMETA_UTILITIES_DIRECTORY}/targets/executable.cmake")
include("${SOURCEMETA_UTILITIES_DIRECTORY}/targets/clang-format.cmake")
include("${SOURCEMETA_UTILITIES_DIRECTORY}/targets/clang-tidy.cmake")
include("${SOURCEMETA_UTILITIES_DIRECTORY}/targets/shellcheck.cmake")
include("${SOURCEMETA_UTILITIES_DIRECTORY}/targets/doxygen.cmake")
include("${SOURCEMETA_UTILITIES_DIRECTORY}/targets/googletest.cmake")
include("${SOURCEMETA_UTILITIES_DIRECTORY}/targets/googlebenchmark.cmake")
include("${SOURCEMETA_UTILITIES_DIRECTORY}/clang-tidy.cmake")

# To let downstream projects directly include this file
if(NOT PROJECT_IS_TOP_LEVEL)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
function(sourcemeta_target_clang_tidy_attempt_install)
function(sourcemeta_clang_tidy_attempt_install)
cmake_parse_arguments(SOURCEMETA_TARGET_CLANG_TIDY_ATTEMPT_INSTALL "" "OUTPUT_DIRECTORY" "" ${ARGN})
if(NOT SOURCEMETA_TARGET_CLANG_TIDY_ATTEMPT_INSTALL_OUTPUT_DIRECTORY)
message(FATAL_ERROR "You must pass the output directory in the OUTPUT_DIRECTORY option")
Expand Down Expand Up @@ -76,9 +76,19 @@ function(sourcemeta_target_clang_tidy_attempt_install)
message(STATUS "Installed `clang-tidy` pre-built binary to ${CLANG_TIDY_BINARY_OUTPUT}")
endfunction()

function(sourcemeta_target_clang_tidy)
cmake_parse_arguments(SOURCEMETA_TARGET_CLANG_TIDY "REQUIRED" "" "SOURCES" ${ARGN})
sourcemeta_target_clang_tidy_attempt_install(OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin")
# TODO: Automatically enable and disable on targets

function(sourcemeta_clang_tidy_enable)
cmake_parse_arguments(SOURCEMETA_TARGET_CLANG_TIDY "REQUIRED" "" "" ${ARGN})

if(SOURCEMETA_COMPILER_LLVM)
message(STATUS "Enabling ClangTidy alongside compilation")
else()
message(STATUS "Ignoring ClangTidy setup on a compiler other than LLVM")
return()
endif()

sourcemeta_clang_tidy_attempt_install(OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin")

if(SOURCEMETA_TARGET_CLANG_TIDY_REQUIRED)
find_program(CLANG_TIDY_BIN NAMES clang-tidy NO_DEFAULT_PATH
Expand All @@ -94,37 +104,40 @@ function(sourcemeta_target_clang_tidy)
endif()
endif()


# This covers the empty list too
if(NOT SOURCEMETA_TARGET_CLANG_TIDY_SOURCES)
message(FATAL_ERROR "You must pass file globs to analyze in the SOURCES option")
endif()
file(GLOB_RECURSE SOURCEMETA_TARGET_CLANG_TIDY_FILES
${SOURCEMETA_TARGET_CLANG_TIDY_SOURCES})

set(CLANG_TIDY_CONFIG "${CMAKE_CURRENT_FUNCTION_LIST_DIR}/clang-tidy.config")

if(CMAKE_SYSTEM_NAME STREQUAL "MSYS")
# Because `clang-tidy` is typically a Windows `.exe`, transform the path accordingly
execute_process(COMMAND cygpath -w "${CLANG_TIDY_CONFIG}"
OUTPUT_VARIABLE CLANG_TIDY_CONFIG OUTPUT_STRIP_TRAILING_WHITESPACE)
endif()

if(CLANG_TIDY_BIN)
add_custom_target(clang_tidy
WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}"
VERBATIM
COMMAND "${CLANG_TIDY_BIN}" -p "${PROJECT_BINARY_DIR}"
--config-file "${CLANG_TIDY_CONFIG}"
${SOURCEMETA_TARGET_CLANG_TIDY_FILES}
COMMENT "Analyzing sources using ClangTidy")
if(APPLE)
execute_process(COMMAND xcrun --show-sdk-path
OUTPUT_VARIABLE MACOSX_SDK_PATH OUTPUT_STRIP_TRAILING_WHITESPACE)
execute_process(COMMAND "${CMAKE_CXX_COMPILER}" -print-resource-dir
OUTPUT_VARIABLE MACOSX_RESOURCE_PATH OUTPUT_STRIP_TRAILING_WHITESPACE)
set(CMAKE_CXX_CLANG_TIDY
"${CLANG_TIDY_BIN};--config-file=${CLANG_TIDY_CONFIG};-header-filter=${PROJECT_SOURCE_DIR}/src/*"
"--extra-arg=-std=c++${CMAKE_CXX_STANDARD}"
"--extra-arg=-isysroot"
"--extra-arg=${MACOSX_SDK_PATH}"
"--extra-arg=-resource-dir=${MACOSX_RESOURCE_PATH}"
PARENT_SCOPE)
else()
add_custom_target(clang_tidy
WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}"
VERBATIM
COMMAND "${CMAKE_COMMAND}" -E echo "Could not locate ClangTidy"
COMMAND "${CMAKE_COMMAND}" -E false)
endif()
execute_process(COMMAND "${CMAKE_CXX_COMPILER}" -v -E -x c++ /dev/null
ERROR_VARIABLE CLANG_OUTPUT OUTPUT_QUIET)
string(REPLACE "\n" ";" CLANG_OUTPUT_LINES "${CLANG_OUTPUT}")
set(CLANG_HEADER_PATH_LIST "")
foreach(line IN LISTS CLANG_OUTPUT_LINES)
string(REGEX MATCH "^ /[^ \n]+" MATCHED_LINE "${line}")
if(MATCHED_LINE)
list(APPEND CLANG_HEADER_PATH_LIST "${MATCHED_LINE}")
endif()
endforeach()
set(CLANG_TIDY_EXTRA_ARGS "")
foreach(P IN LISTS CLANG_HEADER_PATH_LIST)
list(APPEND CLANG_TIDY_EXTRA_ARGS "--extra-arg=-isystem${P}")
endforeach()

set_target_properties(clang_tidy PROPERTIES FOLDER "Linting")
set(CMAKE_CXX_CLANG_TIDY
"${CLANG_TIDY_BIN};--config-file=${CLANG_TIDY_CONFIG}"
"--extra-arg=-std=c++${CMAKE_CXX_STANDARD}"
${CLANG_TIDY_EXTRA_ARGS}
PARENT_SCOPE)
endif()
endfunction()
19 changes: 19 additions & 0 deletions cmake/common/clang-tidy.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
# See https://clang.llvm.org/extra/clang-tidy/index.html
# First disable all default checks (with -*)
Checks: '-*,
modernize-*'
# TODO(bavulapati): iterate through the rules and enable them incrementally inorder to send smaller PRs
# bugprone-*,-bugprone-branch-clone,-bugprone-easily-swappable-parameters,-bugprone-empty-catch,
# clang-analyzer-*,
# clang-diagnostic-*,
# modernize-*,
# concurrency-*,
# cppcoreguidelines-*,-cppcoreguidelines-rvalue-reference-param-not-moved,
# performance-*,-performance-enum-size,
# portability-*,
# objc-*,
# misc-*,-misc-no-recursion,-misc-unused-parameters,-misc-const-correctness'
WarningsAsErrors: '*'
FormatStyle: none
UseColor: true
22 changes: 0 additions & 22 deletions cmake/common/targets/clang-tidy.config

This file was deleted.

Loading