aboutsummaryrefslogtreecommitdiff
path: root/backend/cmake
diff options
context:
space:
mode:
Diffstat (limited to 'backend/cmake')
-rw-r--r--backend/cmake/RCCBackendConfig.cmake.in7
-rw-r--r--backend/cmake/modules/RCCBackendBuild.cmake116
-rw-r--r--backend/cmake/modules/RCCBackendClangTidy.cmake86
-rw-r--r--backend/cmake/modules/RCCBackendDeveloperTools.cmake72
4 files changed, 281 insertions, 0 deletions
diff --git a/backend/cmake/RCCBackendConfig.cmake.in b/backend/cmake/RCCBackendConfig.cmake.in
new file mode 100644
index 0000000..910572b
--- /dev/null
+++ b/backend/cmake/RCCBackendConfig.cmake.in
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+@PACKAGE_INIT@
+
+include("${CMAKE_CURRENT_LIST_DIR}/RCCBackendTargets.cmake")
+
+check_required_components(RCCBackend)
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()