tree: Replace scan-build by clang-tidy

Change-Id: I0e59a1667759723bbf8d76232e7e5375837d2e9a
Signed-off-by: Elyes Haouas <ehaouas@noos.fr>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/87908
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Martin L Roth <gaumless@gmail.com>
This commit is contained in:
Elyes Haouas 2025-06-01 15:54:13 +02:00 committed by Martin L Roth
commit ef10e93e0a
8 changed files with 71 additions and 59 deletions

View file

@ -532,8 +532,8 @@ CFLAGS_common += -Wstring-compare
ifeq ($(CONFIG_COMPILER_GCC),y)
CFLAGS_common += -Wold-style-declaration
CFLAGS_common += -Wcast-function-type
# Don't add these GCC specific flags when running scan-build
ifeq ($(CCC_ANALYZER_OUTPUT_FORMAT),)
# Don't add these GCC specific flags when running clang-tidy
ifeq ($(CLANG_TIDY),)
CFLAGS_common += -Wno-packed-not-aligned
CFLAGS_common += -fconserve-stack
CFLAGS_common += -Wnull-dereference

View file

@ -33,7 +33,7 @@ ifneq ($(words $(CURDIR)),1)
$(error ERROR: Path to the main directory cannot contain spaces)
endif
ifeq ($(INNER_SCANBUILD),y)
ifeq ($(INNER_STATIC_ANALYSIS),y)
CC_real:=$(CC)
endif
@ -95,7 +95,7 @@ DOXYGEN_OUTPUT_DIR := doxygen
all: real-all
ifeq ($(INNER_SCANBUILD),y)
ifeq ($(INNER_STATIC_ANALYSIS),y)
CC:=$(CC_real)
HOSTCC:=$(CC_real) --hostcc
HOSTCXX:=$(CC_real) --hostcxx
@ -218,7 +218,6 @@ endif
CFLAGS += -std=gnu11 $(CFLAGS_$(ARCH-y))
ifneq ($(INNER_SCANBUILD),y)
ifeq ($(CONFIG_LP_COMPILER_LLVM_CLANG),y)
CC:=clang
ifneq ($(CONFIG_LP_ARCH_MOCK),y)
@ -226,7 +225,6 @@ CC += -m32
endif
HOSTCC:=clang
endif
endif
ifeq ($(CONFIG_LP_CCACHE),y)
CCACHE:=$(word 1,$(wildcard $(addsuffix /ccache,$(subst :, ,$(PATH)))))
@ -244,22 +242,17 @@ strip_quotes = $(subst ",,$(subst \",,$(1)))
# The primary target needs to be here before we include the
# other files
ifeq ($(INNER_SCANBUILD),y)
CONFIG_LP_SCANBUILD_ENABLE:=
ifeq ($(INNER_STATIC_ANALYSIS),y)
CONFIG_LP_STATIC_ANALYSIS__ENABLE:=
endif
ifeq ($(CONFIG_LP_SCANBUILD_ENABLE),y)
ifneq ($(CONFIG_LP_SCANBUILD_REPORT_LOCATION),)
CONFIG_LP_SCANBUILD_REPORT_LOCATION:=-o $(CONFIG_LP_SCANBUILD_REPORT_LOCATION)
ifeq ($(CONFIG_LP_STATIC_ANALYSIS_ENABLE),y)
ifneq ($(CONFIG_LP_STATIC_ANALYSIS_REPORT_LOCATION),)
CONFIG_LP_STATIC_ANALYSIS_LOCATION:=-o $(CONFIG_LP_STATIC_ANALYSIS_REPORT_LOCATION)
endif
real-all:
echo '#!/bin/sh' > .ccwrap
echo 'CC="$(CC)"' >> .ccwrap
echo 'if [ "$$1" = "--hostcc" ]; then shift; CC="$(HOSTCC)"; fi' >> .ccwrap
echo 'if [ "$$1" = "--hostcxx" ]; then shift; CC="$(HOSTCXX)"; fi' >> .ccwrap
echo 'eval $$CC $$*' >> .ccwrap
chmod +x .ccwrap
scan-build $(CONFIG_LP_SCANBUILD_REPORT_LOCATION) -analyze-headers --use-cc=$(top)/.ccwrap --use-c++=$(top)/.ccwrap $(MAKE) INNER_SCANBUILD=y
find src -name '*.c' -o -name '*.h' | xargs clang-tidy $(CONFIG_LP_CLANG_TIDY_CHECKS)
$(MAKE) INNER_STATIC_ANALYSIS=y
else
real-all: real-target
endif

View file

@ -31,7 +31,7 @@ else
MARCH_SUFFIX=
endif
ifeq ($(CCC_ANALYZER_OUTPUT_FORMAT),)
ifeq ($(CLANG_TIDY),)
riscv_flags += -march=$(CONFIG_RISCV_ARCH)$(MARCH_SUFFIX) -mabi=$(CONFIG_RISCV_ABI) -mcmodel=$(CONFIG_RISCV_CODEMODEL)
simple_riscv_flags += -march=$(CONFIG_RISCV_ARCH) -mabi=$(CONFIG_RISCV_ABI) -mcmodel=$(CONFIG_RISCV_CODEMODEL)
else

View file

@ -19,12 +19,10 @@ HOSTCC:=$(CCACHE) $(HOSTCC)
HOSTCXX:=$(CCACHE) $(HOSTCXX)
endif
# scan-build integration
ifneq ($(CCC_ANALYZER_OUTPUT_FORMAT),)
ifeq ($(CCC_ANALYZER_ANALYSIS),)
export CCC_ANALYZER_ANALYSIS := -analyzer-opt-analyze-headers
endif
# clang-tidy integration
ifneq ($(CLANG_TIDY),)
CLANG_TIDY_CHECKS ?= -checks=*
CLANG_TIDY_ARGS ?= -extra-arg=-Wno-packed-not-aligned
$(foreach arch,$(ARCH_SUPPORTED), \
$(eval CC_$(arch):=CCC_CC="$(CC_$(arch))" $(CC) ))

View file

@ -85,8 +85,8 @@ mode=text
# quiet mode: only print pass, failure, and 'skipped' messages
quiet=false
# clang mode enabled by -sb option.
scanbuild=false
# clang-tidy mode enabled by -sb option.
clangtidy=false
# Mark whether abuild was called recursively
recursive=false
@ -417,6 +417,35 @@ ts_delta_string()
fi
}
run_clang_tidy()
{
local build_dir="$1"
local log_file="$2"
local clang_tidy_args=""
if [[ -n "${CLANG_TIDY_CHECKS}" ]]; then
clang_tidy_args+="-checks=${CLANG_TIDY_CHECKS} "
fi
# Generate compilation database
printf "Generating compilation database for clang-tidy...\n"
${MAKE} -C "${ROOT}" DOTCONFIG="${build_dir}/config.build" obj="${build_dir}" \
objutil="${TARGET}/sharedutils" BUILD_TIMELESS=${TIMELESS} \
compiledb >/dev/null 2>&1
if [[ ! -f "${build_dir}/compile_commands.json" ]]; then
printf "Error: Failed to generate compilation database\n" >> "${log_file}"
return 1
fi
# Run clang-tidy on all source files
find "${ROOT}/src" -type f \( -name "*.c" -o -name "*.h" \) | while read -r src_file; do
clang-tidy ${clang_tidy_args} "${src_file}" >> "${log_file}" 2>&1
done
return 0
}
compile_target()
{
local BUILD_NAME=$1
@ -453,6 +482,17 @@ compile_target()
printf "ok\n" > compile.status
printf "%s built successfully. (took %s)\n" "${BUILD_NAME}" "${duration_str}"
echo "${BUILD_NAME}" >> "${PASSED_BOARDS}"
# Run clang-tidy after successful build
if [[ "${clangtidy}" = "true" ]]; then
printf "Running clang-tidy for %s...\n" "${BUILD_NAME}"
run_clang_tidy "${build_dir}" "${build_dir}/clang-tidy.log"
if [[ $? -eq 0 ]]; then
printf "clang-tidy completed for %s\n" "${BUILD_NAME}"
else
printf "clang-tidy failed for %s (see %s/clang-tidy.log)\n" "${BUILD_NAME}" "${build_dir}"
fi
fi
else
junit "<failure type='BuildFailed'>"
junitfile make.log
@ -606,16 +646,10 @@ EOF
if [[ ${BUILDENV_CREATED} -eq 0 ]] && [[ ${configureonly} -eq 0 ]]; then
BUILDPREFIX=
if [[ "${scanbuild}" = "true" ]]; then
scanbuild_out="${TARGET}/${BUILD_NAME}-scanbuild"
rm -rf "${scanbuild_out}"
BUILDPREFIX="scan-build ${SCANBUILD_ARGS} -o ${scanbuild_out}tmp"
if [[ "${clangtidy}" = "true" ]]; then
printf "Enabling clang-tidy for static analysis\n"
fi
compile_target "${BUILD_NAME}"
if [[ "${scanbuild}" = "true" ]]; then
mv "${scanbuild_out}tmp"/* "${scanbuild_out}"
rmdir "${scanbuild_out}tmp"
fi
fi
junit "</testcase>"
@ -720,7 +754,7 @@ Options:\n
[-r|--remove] Remove output dir after build
[-R|--root <path>] Absolute path to coreboot sources
(defaults to ${ROOT})
[--scan-build] Use clang's static analyzer
[--static-analysis] Run clang-tidy for static code analysis
[--skip_set <value>] Skip building boards with this Kconfig set
[--skip_unset <value>] Skip building boards with this Kconfig not set
[--timeless] Generate timeless builds
@ -780,7 +814,7 @@ getoptbrand="$(getopt -V)"
# shellcheck disable=SC2086
if [[ "${getoptbrand:0:6}" == "getopt" ]]; then
# Detected GNU getopt that supports long options.
args=$(getopt -l version,verbose,quiet,help,all,target:,board-variant:,payloads:,cpus:,silent,junit,config,loglevel:,remove,prefix:,update,scan-build,ccache,blobs,clang,any-toolchain,clean,clean-somewhat,outdir:,chromeos,xmlfile:,kconfig:,dir:,root:,recursive,checksum:,timeless,exitcode,asserts,name:,skip_set:,skip_unset: -o Vvqhat:b:p:c:sJCl:rP:uyBLAzZo:xX:K:d:R:Ien: -- "$@") || exit 1
args=$(getopt -l version,verbose,quiet,help,all,target:,board-variant:,payloads:,cpus:,silent,junit,config,loglevel:,remove,prefix:,update,static-analysis,ccache,blobs,clang,any-toolchain,clean,clean-somewhat,outdir:,chromeos,xmlfile:,kconfig:,dir:,root:,recursive,checksum:,timeless,exitcode,asserts,name:,skip_set:,skip_unset: -o Vvqhat:b:p:c:sJCl:rP:uyBLAzZo:xX:K:d:R:Ien: -- "$@") || exit 1
eval set -- ${args}
retval=$?
else
@ -828,10 +862,9 @@ while true ; do
shift;;
# obsolete option
-s|--silent) shift;;
--scan-build) shift
scanbuild=true
customizing="${customizing}, scan-build"
SCANBUILD_ARGS=${SCANBUILD_ARGS:-'-k'}
--static-analysis) shift
clangtidy=true
customizing="${customizing}, static-analysis"
configoptions="${configoptions}CONFIG_FATAL_ASSERTS=y\n"
;;
--skip_set) shift
@ -1008,17 +1041,12 @@ build_targets()
printf "%s" "${configoptions}" > "${TMPCFG}"
${MAKE} -j "${cpus}" DOTCONFIG="${TMPCFG}" obj="${TARGET}/temp" objutil="${TARGET}/sharedutils" olddefconfig 2>/dev/null
BUILDPREFIX=
if [[ "${scanbuild}" = "true" ]]; then
scanbuild_out="${TARGET}/sharedutils-scanbuild"
rm -rf "${scanbuild_out}"
BUILDPREFIX="scan-build -o ${scanbuild_out}tmp"
fi
mkdir -p "${TARGET}/abuild"
ABSPATH="$(cd "${TARGET}/abuild" && pwd)"
XMLFILE="${ABSPATH}/__util.xml"
rm -f "${XMLFILE}"
stime=$(add_timestamp)
${BUILDPREFIX} "${MAKE}" -j "${cpus}" DOTCONFIG="${TMPCFG}" obj="${TARGET}/temp" objutil="${TARGET}/sharedutils" tools > "${TARGET}/sharedutils/make.log" 2>&1
${MAKE} -j "${cpus}" DOTCONFIG="${TMPCFG}" obj="${TARGET}/temp" objutil="${TARGET}/sharedutils" tools > "${TARGET}/sharedutils/make.log" 2>&1
local ret=$?
etime=$(add_timestamp)
duration=$(ts_delta_seconds "${stime}" "${etime}")
@ -1039,10 +1067,6 @@ build_targets()
return
fi
if [[ "${scanbuild}" = "true" ]]; then
mv "${scanbuild_out}"tmp/* "${scanbuild_out}"
rmdir "${scanbuild_out}tmp"
fi
rm -rf "${TARGET}/temp" "${TMPCFG}"
num_targets=$(wc -w <<<"${targets}")
cpus_per_target=$(((${cpus:-1} + num_targets - 1) / num_targets))
@ -1106,4 +1130,4 @@ if [[ "${recursive}" = "false" ]]; then
fi
fi
exit ${failed}
exit ${failed}

View file

@ -81,7 +81,7 @@ sanitize: clean
CFLAGS="-O3 -g -fsanitize=undefined" $(MAKE) test CC=clang FUZZER_TIME="-T1mn" NB_LOOPS=-i1
staticAnalyze: clean
CFLAGS=-g scan-build --status-bugs -v $(MAKE) all
CFLAGS=-g clang-tidy $(CLANG_TIDY_CHECKS) $(CLANG_TIDY_ARGS) $(SRCS)
armtest: clean
CFLAGS="-O3 -Werror" $(MAKE) -C $(LZ4DIR) all CC=arm-linux-gnueabi-gcc

View file

@ -941,9 +941,6 @@ build_LLVM() {
$MAKE install || touch .failed
rm -f ../llvm ../clang ../clang-tools-extra ../compiler-rt ../cmake ../lld ../libunwind ../runtimes
cp -a ../$CLANG_DIR/tools/scan-build/* "$DESTDIR$TARGETDIR/bin"
cp -a ../$CLANG_DIR/tools/scan-view/* "$DESTDIR$TARGETDIR/bin"
}
build_CMAKE() {

View file

@ -116,8 +116,8 @@ test-lint:
util/lint/lint lint-extended $(JUNIT)
test-abuild:
ifneq ($(JENKINS_SKIP_SCANBUILD_TEST),y)
NAME=scanbuild; SCANBUILD_ARGS='-k -plist-html -maxloop 10' util/abuild/abuild -o $(COREBOOT_BUILD_DIR)/$${NAME} $(ABUILD_OPTIONS) --scan-build --target EMULATION_QEMU_X86_Q35 --exitcode --name $${NAME}
ifneq ($(JENKINS_SKIP_STATIC_ANALYSIS_TEST),y)
NAME=clangtidy; util/abuild/abuild -o $(COREBOOT_BUILD_DIR)/$${NAME} $(ABUILD_OPTIONS) --static-analysis --target EMULATION_QEMU_X86_Q35
endif
ifneq ($(JENKINS_SKIP_GCC_TESTS),y)
ifneq ($(JENKINS_SKIP_ALLTHREAD_TEST),y)
@ -172,7 +172,7 @@ test-tools:
test-cleanup:
rm -rf $(COREBOOT_BUILD_DIR)/chromeos $(COREBOOT_BUILD_DIR)/default
rm -rf $(COREBOOT_BUILD_DIR)/chromeos-clang $(COREBOOT_BUILD_DIR)/default-clang
rm -rf $(COREBOOT_BUILD_DIR)/scanbuild
rm -rf $(COREBOOT_BUILD_DIR)/clangtidy
$(MAKE) clean
$(foreach tool, $(TOOLLIST), $(MAKE) -C util/$(tool) clean ; )
$(MAKE) -C src/soc/nvidia/tegra124/lp0 clean