diff options
Diffstat (limited to 'backend/cmake/modules')
| -rw-r--r-- | backend/cmake/modules/RCCBackendBuild.cmake | 116 | ||||
| -rw-r--r-- | backend/cmake/modules/RCCBackendClangTidy.cmake | 86 | ||||
| -rw-r--r-- | backend/cmake/modules/RCCBackendDeveloperTools.cmake | 72 |
3 files changed, 274 insertions, 0 deletions
diff --git a/backend/cmake/modules/RCCBackendBuild.cmake b/backend/cmake/modules/RCCBackendBuild.cmake new file mode 100644 index 0000000..36809ec --- /dev/null +++ b/backend/cmake/modules/RCCBackendBuild.cmake @@ -0,0 +1,116 @@ +# SPDX-License-Identifier: GPL-3.0-or-later + +function(rcc_backend_initialize_toolchain) + string(REGEX MATCH "^[0-9]+" RCCBackendClangMajor "${CMAKE_CXX_COMPILER_VERSION}") + + find_program( + RCC_BACKEND_CLANG_FORMAT + NAMES "clang-format-${RCCBackendClangMajor}" clang-format + REQUIRED + ) + find_program( + RCC_BACKEND_CLANG_TIDY + NAMES "clang-tidy-${RCCBackendClangMajor}" clang-tidy + REQUIRED + ) + find_program( + RCC_BACKEND_CLANG_TIDY_DIFF + NAMES clang-tidy-diff.py + HINTS "/usr/lib/llvm-${RCCBackendClangMajor}/share/clang" + REQUIRED + ) + find_program( + RCC_BACKEND_RUN_CLANG_TIDY + NAMES "run-clang-tidy-${RCCBackendClangMajor}" run-clang-tidy + REQUIRED + ) + find_program(RCC_BACKEND_GIT NAMES git REQUIRED) + + foreach(Tool IN ITEMS RCC_BACKEND_CLANG_FORMAT RCC_BACKEND_CLANG_TIDY) + execute_process( + COMMAND "${${Tool}}" --version + OUTPUT_VARIABLE ToolVersionOutput + ERROR_VARIABLE ToolVersionError + RESULT_VARIABLE ToolVersionResult + ) + if(NOT ToolVersionResult EQUAL 0) + message( + FATAL_ERROR + "Unable to query ${Tool}: ${ToolVersionOutput}${ToolVersionError}" + ) + endif() + + string(REGEX MATCH "version[ \t]+([0-9]+)" ToolVersionMatch "${ToolVersionOutput}") + if(NOT CMAKE_MATCH_1 STREQUAL RCCBackendClangMajor) + message( + FATAL_ERROR + "${Tool} must have Clang major version ${RCCBackendClangMajor}: " + "${ToolVersionOutput}" + ) + endif() + endforeach() + + set(RCC_BACKEND_CLANG_FORMAT "${RCC_BACKEND_CLANG_FORMAT}" PARENT_SCOPE) + set(RCC_BACKEND_CLANG_TIDY "${RCC_BACKEND_CLANG_TIDY}" PARENT_SCOPE) + set(RCC_BACKEND_CLANG_TIDY_DIFF "${RCC_BACKEND_CLANG_TIDY_DIFF}" PARENT_SCOPE) + set(RCC_BACKEND_RUN_CLANG_TIDY "${RCC_BACKEND_RUN_CLANG_TIDY}" PARENT_SCOPE) + set(RCC_BACKEND_GIT "${RCC_BACKEND_GIT}" PARENT_SCOPE) +endfunction() + +function(rcc_backend_configure_target Target) + target_compile_features("${Target}" PUBLIC cxx_std_23) + set_target_properties( + "${Target}" + PROPERTIES + CXX_EXTENSIONS OFF + CXX_STANDARD 23 + CXX_STANDARD_REQUIRED ON + ) + + target_compile_options( + "${Target}" + PRIVATE + -Wall + -Wextra + -Wpedantic + -Wconversion + -Wsign-conversion + -Wshadow + -Wnon-virtual-dtor + -Wold-style-cast + -Wcast-align + -Woverloaded-virtual + -Wnull-dereference + -Wdouble-promotion + -Wformat=2 + ) + + if(RCC_BACKEND_ENABLE_EH) + target_compile_options("${Target}" PRIVATE -fexceptions) + else() + target_compile_options("${Target}" PRIVATE -fno-exceptions) + endif() + + if(RCC_BACKEND_ENABLE_RTTI) + target_compile_options("${Target}" PRIVATE -frtti) + else() + target_compile_options("${Target}" PRIVATE -fno-rtti) + endif() + + if(RCC_BACKEND_WARNINGS_AS_ERRORS) + target_compile_options("${Target}" PRIVATE -Werror) + endif() + + if(RCC_BACKEND_ENABLE_CLANG_TIDY) + set_target_properties( + "${Target}" + PROPERTIES + CXX_CLANG_TIDY + "${RCC_BACKEND_CLANG_TIDY};--warnings-as-errors=*" + ) + endif() +endfunction() + +function(rcc_backend_register_format_files) + set_property(GLOBAL APPEND PROPERTY RCC_BACKEND_FORMAT_FILES ${ARGN}) +endfunction() diff --git a/backend/cmake/modules/RCCBackendClangTidy.cmake b/backend/cmake/modules/RCCBackendClangTidy.cmake new file mode 100644 index 0000000..eebb2d1 --- /dev/null +++ b/backend/cmake/modules/RCCBackendClangTidy.cmake @@ -0,0 +1,86 @@ +# SPDX-License-Identifier: GPL-3.0-or-later + +foreach(Variable IN ITEMS RCC_TIDY_GIT RCC_TIDY_SOURCE_DIR RCC_TIDY_BINARY_DIR RCC_TIDY_BASE + RCC_TIDY_JOBS RCC_TIDY_DIFF) + if(NOT DEFINED ${Variable} OR "${${Variable}}" STREQUAL "") + message(FATAL_ERROR "${Variable} is required for incremental clang-tidy") + endif() +endforeach() + +execute_process( + COMMAND "${RCC_TIDY_GIT}" -C "${RCC_TIDY_SOURCE_DIR}" rev-parse --show-toplevel + RESULT_VARIABLE GitRootResult + OUTPUT_VARIABLE GitRoot + ERROR_VARIABLE GitRootError + OUTPUT_STRIP_TRAILING_WHITESPACE +) +if(NOT GitRootResult EQUAL 0) + message(FATAL_ERROR "cannot locate the Git worktree: ${GitRootError}") +endif() + +file(RELATIVE_PATH TidyPath "${GitRoot}" "${RCC_TIDY_SOURCE_DIR}") +if(TidyPath MATCHES "^\\.\\.") + message(FATAL_ERROR "backend source directory is outside its Git worktree") +endif() + +set(DiffFile "${RCC_TIDY_BINARY_DIR}/CMakeFiles/rcc-backend-clang-tidy.diff") +execute_process( + COMMAND "${RCC_TIDY_GIT}" -C "${GitRoot}" diff --no-ext-diff --unified=0 --merge-base + "${RCC_TIDY_BASE}" -- "${TidyPath}" + RESULT_VARIABLE DiffResult + OUTPUT_FILE "${DiffFile}" + ERROR_VARIABLE DiffError +) +if(NOT DiffResult EQUAL 0) + message(FATAL_ERROR "cannot produce incremental clang-tidy diff: ${DiffError}") +endif() + +# git diff does not include untracked source files. Add their ordinary Git diff form so +# LLVM's unchanged clang-tidy-diff.py driver checks new translation units before staging. +execute_process( + COMMAND "${RCC_TIDY_GIT}" -C "${GitRoot}" ls-files --others --exclude-standard -- "${TidyPath}" + RESULT_VARIABLE UntrackedResult + OUTPUT_VARIABLE UntrackedFiles + ERROR_VARIABLE UntrackedError + OUTPUT_STRIP_TRAILING_WHITESPACE +) +if(NOT UntrackedResult EQUAL 0) + message(FATAL_ERROR "cannot list untracked clang-tidy files: ${UntrackedError}") +endif() +if(NOT UntrackedFiles STREQUAL "") + string(REPLACE "\n" ";" UntrackedFiles "${UntrackedFiles}") + foreach(UntrackedFile IN LISTS UntrackedFiles) + execute_process( + COMMAND "${RCC_TIDY_GIT}" -C "${GitRoot}" diff --no-index --no-ext-diff --unified=0 -- + /dev/null "${UntrackedFile}" + RESULT_VARIABLE UntrackedDiffResult + OUTPUT_VARIABLE UntrackedDiff + ERROR_VARIABLE UntrackedDiffError + ) + if(NOT UntrackedDiffResult EQUAL 0 AND NOT UntrackedDiffResult EQUAL 1) + message(FATAL_ERROR "cannot diff untracked file '${UntrackedFile}': ${UntrackedDiffError}") + endif() + file(APPEND "${DiffFile}" "${UntrackedDiff}") + endforeach() +endif() + +execute_process( + COMMAND "${RCC_TIDY_DIFF}" -path "${RCC_TIDY_BINARY_DIR}" -p1 -quiet -j "${RCC_TIDY_JOBS}" + INPUT_FILE "${DiffFile}" + WORKING_DIRECTORY "${GitRoot}" + RESULT_VARIABLE TidyResult + OUTPUT_VARIABLE TidyOutput + ERROR_VARIABLE TidyError +) +set(TidyDiagnostics "${TidyOutput}\n${TidyError}") +string(REGEX REPLACE "[0-9]+ warnings generated\\." "" TidyDiagnostics "${TidyDiagnostics}") +string(STRIP "${TidyDiagnostics}" TidyDiagnostics) +if(TidyResult EQUAL 0 AND TidyDiagnostics STREQUAL "No relevant changes found.") + set(TidyDiagnostics "") +endif() +if(NOT TidyDiagnostics STREQUAL "") + message("${TidyDiagnostics}") +endif() +if(NOT TidyResult EQUAL 0 OR NOT TidyDiagnostics STREQUAL "") + message(FATAL_ERROR "incremental clang-tidy failed") +endif() diff --git a/backend/cmake/modules/RCCBackendDeveloperTools.cmake b/backend/cmake/modules/RCCBackendDeveloperTools.cmake new file mode 100644 index 0000000..7ad99c2 --- /dev/null +++ b/backend/cmake/modules/RCCBackendDeveloperTools.cmake @@ -0,0 +1,72 @@ +# SPDX-License-Identifier: GPL-3.0-or-later + +function(rcc_backend_add_developer_targets) + get_property(FormatFiles GLOBAL PROPERTY RCC_BACKEND_FORMAT_FILES) + + if(FormatFiles) + list(REMOVE_DUPLICATES FormatFiles) + + add_custom_target( + rcc-backend-format + COMMAND "${RCC_BACKEND_CLANG_FORMAT}" -i ${FormatFiles} + COMMAND_EXPAND_LISTS + COMMENT "Formatting RCC Backend C++ sources" + VERBATIM + ) + + add_custom_target( + rcc-backend-format-check + COMMAND "${RCC_BACKEND_CLANG_FORMAT}" --dry-run --Werror ${FormatFiles} + COMMAND_EXPAND_LISTS + COMMENT "Checking RCC Backend C++ formatting" + VERBATIM + ) + endif() + + # Match LLVM's normal lint path: pass the changed backend lines to its + # clang-tidy-diff.py driver, which runs independent translation units in parallel. + add_custom_target( + rcc-backend-tidy + COMMAND + "${CMAKE_COMMAND}" + "-DRCC_TIDY_GIT=${RCC_BACKEND_GIT}" + "-DRCC_TIDY_SOURCE_DIR=${RCC_BACKEND_SOURCE_DIR}" + "-DRCC_TIDY_BINARY_DIR=${CMAKE_BINARY_DIR}" + "-DRCC_TIDY_BASE=${RCC_BACKEND_TIDY_BASE}" + "-DRCC_TIDY_JOBS=${RCC_BACKEND_TIDY_JOBS}" + "-DRCC_TIDY_DIFF=${RCC_BACKEND_CLANG_TIDY_DIFF}" + -P "${CMAKE_CURRENT_FUNCTION_LIST_DIR}/RCCBackendClangTidy.cmake" + COMMENT "Running incremental clang-tidy on RCC Backend" + USES_TERMINAL + VERBATIM + ) + + add_custom_target( + rcc-backend-tidy-all + COMMAND + "${RCC_BACKEND_RUN_CLANG_TIDY}" + "-p=${CMAKE_BINARY_DIR}" + -j "${RCC_BACKEND_TIDY_JOBS}" + -quiet + "-warnings-as-errors=*" + "${RCC_BACKEND_SOURCE_DIR}/.*" + COMMENT "Running full parallel clang-tidy audit on RCC Backend" + USES_TERMINAL + VERBATIM + ) + + add_custom_target( + rcc-backend-analyze + COMMAND + "${RCC_BACKEND_RUN_CLANG_TIDY}" + "-p=${CMAKE_BINARY_DIR}" + -j "${RCC_BACKEND_TIDY_JOBS}" + -quiet + "-checks=-*,clang-analyzer-*" + "-warnings-as-errors=*" + "${RCC_BACKEND_SOURCE_DIR}/.*" + COMMENT "Running full parallel Clang Static Analyzer audit on RCC Backend" + USES_TERMINAL + VERBATIM + ) +endfunction() |
