blob: 786df4e3d111bbb9eb442e90a8364b7e55a62963 [file] [log] [blame]
#
# SPDX-License-Identifier: BSD-3-Clause
# SPDX-FileCopyrightText: Copyright TF-RMM Contributors.
#
#
# This script is called from main CMakeLists.txt to determine if header files
# included are in proper order
#
find_package(Git REQUIRED)
find_package(Python3 REQUIRED)
find_program(CHECKINCLUDES_EXECUTABLE "checkincludes.py"
PATHS ${CMAKE_SOURCE_DIR}
PATH_SUFFIXES tools/checkincludes
DOC "Path to checkincludes.py"
)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/tools/common")
include(GitUtils)
# List of directories and files to exclude from checking for target
list(APPEND glob_excludes "^.git")
list(APPEND glob_excludes "^out")
list(APPEND glob_excludes "^build")
list(APPEND glob_excludes "^ext")
list(APPEND glob_excludes "^tools")
# checkincludes_get_stats: Parse and returns number of errors and warnings
function(checkincludes_get_stats stats_arg errors_ret)
string(FIND "${stats_arg}" "total:" idx REVERSE)
if(NOT ${idx} EQUAL -1)
string(LENGTH "${stats_arg}" len)
string(SUBSTRING "${stats_arg}" ${idx} ${len} last_line)
string(REPLACE " " ";" last_line_list ${last_line})
list(GET last_line_list 1 errors)
else()
set(errors 1)
endif()
set(${errors_ret} ${errors} PARENT_SCOPE)
endfunction()
#
# print_stats_and_exit: Print summary of all errors and warnings.
# If there are errors call message(FATAL_ERROR)
#
function(print_stats_and_exit check_type total_errors)
message(STATUS "${check_type}: total errors: ${total_errors}")
if(${total_errors} GREATER 0)
message(FATAL_ERROR "${check_type}: FAILED")
endif()
message(STATUS "${check_type}: PASSED")
endfunction()
# filter all files except *.c/*.h/*.S files
function(filter_source_files all_files source_files_ret)
foreach(exclude IN LISTS glob_excludes)
list(FILTER all_files EXCLUDE REGEX "${exclude}")
endforeach()
foreach(source_file ${all_files})
if(NOT source_file MATCHES ".c$" AND
NOT source_file MATCHES ".S$" AND
NOT source_file MATCHES ".h$")
list(REMOVE_ITEM all_files ${source_file})
endif()
endforeach()
set(${source_files_ret} ${all_files} PARENT_SCOPE)
endfunction()
# Run checkincludes.py on the list of files.
function(run_checkincludes source_files errors_ret)
set(errors 0)
string(REPLACE ";" " " source_files "${source_files}")
separate_arguments(source_files NATIVE_COMMAND "${source_files}")
execute_process(
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
COMMAND ${CHECKINCLUDES_EXECUTABLE} ${source_files}
OUTPUT_VARIABLE checkincludes_output
RESULT_VARIABLE checkincludes_rc
ECHO_OUTPUT_VARIABLE
OUTPUT_STRIP_TRAILING_WHITESPACE
)
# checkincludes failed for this file. Collect no.of errors
if(${checkincludes_rc} GREATER 0)
checkincludes_get_stats("${checkincludes_output}" errors)
endif()
set(${errors_ret} ${errors} PARENT_SCOPE)
endfunction()
#
# Run checkincludes on entire codebase. This verifies all files in this
# repository in "GLOB_INCLUDES".
#
# Exits with FATAL_ERROR upon errors. Warnings are ignored (temporary)
#
if(CHECKINCLUDES_CODEBASE)
set(source_files "")
if (GIT_FOUND AND IS_DIRECTORY .git)
Git_Get_All_Files(all_files)
else()
file(GLOB_RECURSE all_files RELATIVE ${CMAKE_SOURCE_DIR} "*")
endif()
filter_source_files("${all_files}" source_files)
if(NOT source_files)
message(STATUS "checkincludes-codebase: No files to check")
return()
endif()
run_checkincludes("${source_files}" total_errors)
print_stats_and_exit("checkincludes-codebase" ${total_errors})
endif()
#
# Check header files include order on pending commits.
#
# Exits with FATAL_ERROR upon errors.
#
if(CHECKINCLUDES_PATCH)
if(GIT_NOT_FOUND OR NOT IS_DIRECTORY .git)
message(FATAL_ERROR "Required dependencies Git not found")
endif()
# Get list of commits to check
Git_Get_Pending_Commits(pending_commits)
# Iterate throuth list of commit ids
set(total_errors 0)
foreach(commit IN LISTS pending_commits)
message(STATUS "Checking commit: ${commit}")
Git_Get_Files_In_Commit("${commit}" files_in_commit)
set(source_files "")
filter_source_files("${files_in_commit}" source_files)
run_checkincludes("${source_files}" errors)
MATH(EXPR total_errors "${total_errors}+${errors}")
endforeach()
print_stats_and_exit("checkincludes-patch" ${total_errors})
endif()