Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Scripts to run clang-format formatting and clang-tidy checks on all source c++/cuda files #111

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
125 changes: 125 additions & 0 deletions build_support/check_all_c_c++_cu_files.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
#!/bin/bash

#
# This file is part of NEST GPU.
#
# Copyright (C) 2021 The NEST Initiative
#
# NEST GPU is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# NEST GPU is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with NEST GPU. If not, see <http://www.gnu.org/licenses/>.
#

# With this script you can easily check all C/C++/CU files contained in
# the src directory of NEST GPU. Internally it uses clang-tidy to do
# the actual check.
#

function make_temp_dir {
# Create a temporary directory and store its name in a variable.
TEMPD=$(mktemp -d)

# Exit if the temp directory wasn't created successfully.
if [ ! -e "$TEMPD" ]; then
>&2 echo "Error: failed to create temp directory"
exit 1
fi


# Make sure the temp directory gets removed on script exit.
trap "exit 1" HUP INT PIPE QUIT TERM
trap 'rm -rf "$TEMPD"' EXIT
}

if [ "$#" -ne 1 ]; then
echo "Usage: $0 <src-folder-path>"
exit 1
fi

CMD_DIR=$(dirname $(echo $0))
CLANG_TIDY=${CMD_DIR}/clang-tidy-cuda.sh

if [ ! -f $CLANG_TIDY ]; then
echo "Error: $CLANG_TIDY file not found in $CMD_DIR folder"
exit 1
fi

SRC_DIR=$1
if [ -d "$SRC_DIR" ]; then
if [ -L "$SRC_DIR" ]; then
# It is a symlink
echo "Error: cannot pass a symboloc link as source path"
exit 1
fi
else
echo "Error: source path $SRC_DIR not found"
exit 1
fi

make_temp_dir
CONF_DIR=${TEMPD}/config
mkdir $CONF_DIR
if [ ! -e "$CONF_DIR" ]; then
>&2 echo "Error: failed to create $CONF_DIR directory"
exit 1
fi
CONF_H=${CONF_DIR}/config.h
:>$CONF_H
if [ ! -f $CONF_H ]; then
echo "Error: cannot create temporary file $CONF_H"
exit 1
fi


cp $CLANG_TIDY $TEMPD
CLANG_TIDY=$(basename $CLANG_TIDY)
if [ ! -f $TEMPD/$CLANG_TIDY ]; then
echo "Error: cannot create temporary executable $CLANG_TIDY in folder $TEMPD"
exit 1
fi

pushd .
cd $SRC_DIR

for fn in $(ls *.cu *.cpp *.cc *.c *.cuh *.hpp *.h); do
cat $fn | sed 's://<BEGIN-CLANG-TIDY-SKIP>//:#if 0:;s://<END-CLANG-TIDY-SKIP>//:#endif:' > $TEMPD/$fn
if [ ! -f $TEMPD/$fn ]; then
echo "Error: cannot create file $TEMPD/$fn"
popd
exit 1
fi
done


cd $TEMPD

PASSED_NUM=0
for fn in $(ls *.cu *.cpp *.cc *.c | grep -v user_m); do
echo " - Check with $CLANG_TIDY C/C++/CUDA file: $fn"
#$TEMPD/$CLANG_TIDY --include-path=../../build_cmake/libnestutil/ $fn
echo "$TEMPD/$CLANG_TIDY --include-path=$CONF_DIR $fn"
$TEMPD/$CLANG_TIDY --include-path=$CONF_DIR $fn
if [ $? -eq 0 ]; then
echo PASSED
PASSED_NUM=$(($PASSED_NUM + 1))
else
popd
exit 1
fi

done

popd
echo "Checked $PASSED_NUM files with clang-tidy-cuda.sh"
echo "All tests PASSED"

exit 0
35 changes: 35 additions & 0 deletions build_support/clang-format-cuda.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#!/bin/bash

if [ "$#" -ne 1 ]; then
echo "Usage: $0 input-file"
return
fi

if [ ! -f .clang-format ]; then
echo "Error: .clang-format file not found in current directory"
return
fi

if [ ! -f $1 ]; then
echo "Error: input file $1 not found"
return
fi

if grep -q '$$<' $1; then
echo 'Error: illegal character sequence in input file: "$$<"'
return
fi
if grep -q '$ >' $1; then
echo 'Error: illegal character sequence in input file: "$ >"'
return
fi
if grep -q '$>' $1; then
echo 'Error: illegal character sequence in input file: "$>"'
return
fi

cat $1 | sed 's/<<</$$</g;s/>>>/$ >/g;' > tmp1~
clang-format -style=file:.clang-format tmp1~ > tmp2~
cat tmp2~ | sed 's/$$</<<</g;s/$ >/>>>/g;s/$>/>>>/g;' > $1
rm -f tmp1~
rm -f tmp2~
145 changes: 145 additions & 0 deletions build_support/clang-tidy-cuda.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
#!/bin/bash

#
# This file is part of NEST GPU.
#
# Copyright (C) 2021 The NEST Initiative
#
# NEST GPU is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# NEST GPU is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with NEST GPU. If not, see <http://www.gnu.org/licenses/>.
#

cuda_default_path="/usr/local/cuda/include"

if [ "$#" -eq 0 ]; then
echo "Usage: $0 [--include-path=INCLUDE_PATHS] [--cuda-path=CUDA_PATHS] [--mpi-path=MPI_PATHS] input-file"
echo "where INCLUDE_PATHS are optional header paths separated by colons,"
echo "CUDA_PATHS are the paths of CUDA headers separated by colons"
echo "(default: $cuda_default_path)"
echo "and MPI_PATHS are the paths of MPI headers separated by colons"
exit 0
fi

cuda_path=""
mpi_path=""
include_path=""

for i in "$@"; do
case $i in
--include-path=*)
include_path="${i#*=}"
shift # past argument=value
;;
--cuda-path=*)
cuda_path="${i#*=}"
shift # past argument=value
;;
--mpi-path=*)
mpi_path="${i#*=}"
shift # past argument=value
;;
-*|--*)
echo "Error: unknown option $i"
exit 1
;;
*)
;;
esac
done

if [[ -n $1 ]]; then
echo "Input file: $1"
else
echo "Error: input file not specified."
exit 1
fi

if [ ! -f $1 ]; then
echo "Error: input file $1 not found."
exit 1
fi

if [ "$include_path" != "" ]; then
include_path=$(echo ":$include_path" | sed 's/::*/:/g;s/:$//;s/:/ -I /g')
fi

# Searches the paths of CUDA headers
if [ "$cuda_path" == "" ]; then
cuda_path=":/usr/local/cuda/include"
else
cuda_path=$(echo ":$cuda_path" | sed 's/::*/:/g;s/:$//')
fi

cuda_path_spaced=$(echo $cuda_path | tr ':' ' ')
cuda_err=1
for dn in $cuda_path_spaced; do
if test -f "$dn/cuda.h" ; then
echo "cuda.h found in path $dn"
cuda_err=0
break
fi
done

if [ $cuda_err -eq 1 ]; then
echo "cuda.h not found in path(s) $cuda_path_spaced"
echo "You can specify path for CUDA headers with the option --cuda-path=CUDA_PATHS"
echo "where CUDA_PATHS are the paths of CUDA headers separated by colons"
echo "(default: $cuda_default_path)"
exit 1
fi

cuda_include=$(echo $cuda_path | sed 's/:/ -isystem /g')

#cat $1 | sed 's://<BEGIN-CLANG-TIDY-SKIP>//:#if 0:;s://<END-CLANG-TIDY-SKIP>//:#endif:' > tmp~

#cat ../build_cmake/compile_commands.json | sed "s:-Xcompiler=-fPIC::;s:-forward-unknown-to-host-compiler::;s:--compiler-options='.*'::;s:--generate-code=arch=compute_80,code=\[compute_80,sm_80\]::;s:--maxrregcount=55::" > compile_commands.json

# Searches the paths of MPI headers
if [ "$mpi_path" == "" ]; then
mpi_include=$( \
for l in $(mpicc -showme); do \
echo $l; \
done | grep '^-I')
if [ "$mpi_include" == "" ]; then
echo "Error: cannot find MPI include paths"
echo "You can specify path for MPI headers with the option --mpi-path=MPI_PATHS"
echo "where MPI_PATHS are the paths of MPI headers separated by colons"
exit 1
fi
mpi_include=$(echo $mpi_include | sed 's/-I/ -isystem /g')
mpi_path_spaced=$(echo $mpi_include | sed 's/-I/ /g')
else
mpi_path=$(echo ":$mpi_path" | sed 's/::*/:/g;s/:$//')
mpi_path_spaced=$(echo $mpi_path | tr ':' ' ')
mpi_include=$(echo $mpi_path | sed 's/:/ -isystem /g')
fi

mpi_err=1
for dn in $mpi_path_spaced; do
if test -f "$dn/mpi.h" ; then
echo "mpi.h found in path $dn"
mpi_err=0
break
fi
done

if [ $mpi_err -eq 1 ]; then
echo "mpi.h not found in path(s) $mpi_path_spaced"
echo "You can specify path for MPI headers with the option --mpi-path=MPI_PATHS"
echo "where MPI_PATHS are the paths of MPI headers separated by colons"
exit 1
fi

echo "clang-tidy $1 -p . -- $include_path $mpi_include $cuda_include --no-cuda-version-check"

clang-tidy $1 -p . -- $include_path $mpi_include $cuda_include --no-cuda-version-check
Loading
Loading