Skip to content

Commit

Permalink
Clang-Tidy Cache
Browse files Browse the repository at this point in the history
Use ccache in the clang-tidy CI. This allows us to skip clang-tidy checks on
files that are not changed as reported by ccache.
  • Loading branch information
WeiqunZhang committed Nov 28, 2023
1 parent f1eb2b2 commit 35d96f4
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 20 deletions.
44 changes: 24 additions & 20 deletions .github/workflows/clang_tidy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,28 +16,26 @@ jobs:
- name: install dependencies
run: |
.github/workflows/dependencies/clang14.sh
- name: build WarpX using clang-tidy
- name: set up cache
uses: actions/cache@v3
with:
path: ~/.cache/ccache
key: ccache-clang-tidy-${{ github.job }}-git-${{ github.sha }}
restore-keys: |
ccache-clang-tidy-${{ github.job }}-git-
- name: build WarpX & run clang-tidy
run: |
export CCACHE_COMPRESS=1
export CCACHE_COMPRESSLEVEL=10
export CCACHE_MAXSIZE=300M
export CCACHE_EXTRAFILES=${{ github.workspace }}/.clang-tidy
export CCACHE_LOGFILE=${{ github.workspace }}/ccache.log.txt
ccache -z
export CXX=$(which clang++)
export CC=$(which clang)
# The following wrapper ensures that only source files
# in WarpX/Source/* are actually processed by clang-tidy
#_______________________________
cat > clang_tidy_wrapper << EOF
#!/bin/bash
REGEX="[a-z_A-Z0-9\/]*WarpX\/Source[a-z_A-Z0-9\/]+.cpp"
if [[ \$4 =~ \$REGEX ]];then
clang-tidy \$@
fi
EOF
chmod +x clang_tidy_wrapper
#_____________________________________
cmake -S . -B build_clang_tidy \
-DCMAKE_CXX_CLANG_TIDY="$PWD/clang_tidy_wrapper;--system-headers=0;--config-file=$PWD/.clang-tidy" \
-DCMAKE_VERBOSE_MAKEFILE=ON \
-DWarpX_DIMS="1;2;3;RZ" \
-DWarpX_MPI=ON \
Expand All @@ -46,9 +44,15 @@ jobs:
-DWarpX_QED=ON \
-DWarpX_QED_TABLE_GEN=ON \
-DWarpX_OPENPMD=ON \
-DWarpX_PRECISION=SINGLE
-DWarpX_PRECISION=SINGLE \
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache
cmake --build build_clang_tidy -j 2
cmake --build build_clang_tidy -j 2 2> build_clang_tidy/clang-tidy.log
${{github.workspace}}/.github/workflows/source/makeMakefileForClangTidy.py --input ${{github.workspace}}/ccache.log.txt
make -j2 -f clang-tidy-ccache-misses.mak \
CLANG_TIDY=clang-tidy \
CLANG_TIDY_ARGS="--config-file=${{github.workspace}}/.clang-tidy --warnings-as-errors=*"
cat build_clang_tidy/clang-tidy.log
if [[ $(wc -m <build_clang_tidy/clang-tidy.log) -gt 1 ]]; then exit 1; fi
ccache -s
du -hs ~/.cache/ccache
61 changes: 61 additions & 0 deletions .github/workflows/source/makeMakefileForClangTidy.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#!/usr/bin/env python3

"""
A script processing ccache log file to make Make file for Clang-Tidy
This generates a makefile for clang-tidying ccache-cache-missing files. This
could be used to speed up clang-tidy in CIs.
"""

import argparse, re, sys

def makeMakefileForClangTidy(argv):
parser = argparse.ArgumentParser()
parser.add_argument("--input",
help="Ccache log file",
default="ccache.log.txt")
parser.add_argument("--identifier",
help="Unique identifier for finding compilation line in the log file",
default="WarpX/Source")
# We assume Src/Base can be used as an identifier to distinguish amrex code
# from cmake's temporary files like build/CMakeFiles/CMakeScratch/TryCompile-hw3x4m/test_mpi.cpp
parser.add_argument("--output",
help="Make file for clang-tidy",
default="clang-tidy-ccache-misses.mak")
args = parser.parse_args()

fin = open(args.input, "r")
fout = open(args.output, "w")

fout.write("CLANG_TIDY ?= clang-tidy\n")
fout.write("override CLANG_TIDY_ARGS += --extra-arg=-Wno-unknown-warning-option --extra-arg-before=--driver-mode=g++\n")
fout.write("\n")

fout.write(".SECONDEXPANSION:\n")
fout.write("clang-tidy: $$(all_targets)\n")
fout.write("\t@echo SUCCESS\n\n")

exe_re = re.compile(r" Executing .*? (-.*{}.*) -c .* -o .* (\S*)".format(args.identifier))

count = 0
for line in fin.readlines():
ret_exe_re = exe_re.search(line)
if (ret_exe_re):
fout.write("target_{}: {}\n".format(count, ret_exe_re.group(2)))
fout.write("\t$(CLANG_TIDY) $(CLANG_TIDY_ARGS) $< -- {}\n".format
(ret_exe_re.group(1)))
fout.write("\ttouch target_{}\n\n".format(count))
count = count + 1

fout.write("all_targets =")
for i in range(count):
fout.write(" target_{}".format(i))
fout.write("\n\n")

fout.write("clean:\n\t$(RM) $(all_targets)\n\n")

fout.close()
fin.close()

if __name__ == "__main__":
makeMakefileForClangTidy(sys.argv)

0 comments on commit 35d96f4

Please sign in to comment.