dpdk-fm10k/devtools/check-includes.sh
Jerin Jacob 8b9dae0cc3 doc: use globbing terminology
Glob is the terminology used in fnmatch man page.
Use glob terminology across DPDK for shell pattern.

Signed-off-by: Jerin Jacob <jerinj@marvell.com>
Acked-by: Thomas Monjalon <thomas@monjalon.net>
2020-05-19 16:05:17 +02:00

261 lines
4.5 KiB
Bash
Executable file

#!/bin/sh -e
# SPDX-License-Identifier: BSD-3-Clause
# Copyright 2016 6WIND S.A.
# This script checks that header files in a given directory do not miss
# dependencies when included on their own, do not conflict and accept being
# compiled with the strictest possible flags.
#
# Files are looked up in the directory provided as the first argument,
# otherwise build/include by default.
#
# Recognized environment variables:
#
# VERBOSE=1 is the same as -v.
#
# QUIET=1 is the same as -q.
#
# SUMMARY=1 is the same as -s.
#
# CC, CPPFLAGS, CFLAGS, EXTRA_CPPFLAGS, EXTRA_CFLAGS, CXX, CXXFLAGS and
# EXTRA_CXXFLAGS are taken into account.
#
# PEDANTIC_CFLAGS, PEDANTIC_CXXFLAGS and PEDANTIC_CPPFLAGS provide strict
# C/C++ compilation flags.
#
# IGNORE contains a list of globbing patterns matching files (relative to the
# include directory) to avoid. It is set by default to known DPDK headers
# which must not be included on their own.
#
# IGNORE_CXX provides additional files for C++.
while getopts hqvs arg; do
case $arg in
h)
cat <<EOF
usage: $0 [-h] [-q] [-v] [-s] [DIR]
This script checks that header files in a given directory do not miss
dependencies when included on their own, do not conflict and accept being
compiled with the strictest possible flags.
-h display this help and exit
-q quiet mode, disable normal output
-v show command lines being executed
-s show summary
With no DIR, default to build/include.
Any failed header check yields a nonzero exit status.
EOF
exit
;;
q)
QUIET=1
;;
v)
VERBOSE=1
;;
s)
SUMMARY=1
;;
*)
exit 1
;;
esac
done
shift $(($OPTIND - 1))
include_dir=${1:-build/include}
: ${PEDANTIC_CFLAGS=-std=c99 -pedantic -Wall -Wextra -Werror}
: ${PEDANTIC_CXXFLAGS=}
: ${PEDANTIC_CPPFLAGS=-D_XOPEN_SOURCE=600}
: ${CC:=cc}
: ${CXX:=c++}
: ${IGNORE= \
'rte_atomic_32.h' \
'rte_atomic_64.h' \
'rte_byteorder_32.h' \
'rte_byteorder_64.h' \
'generic/*' \
'rte_vhost.h' \
'rte_eth_vhost.h' \
'rte_eal_interrupts.h' \
}
: ${IGNORE_CXX= \
'rte_vhost.h' \
'rte_eth_vhost.h' \
}
temp_cc=$(mktemp -t dpdk.${0##*/}.XXX.c)
pass_cc=
failures_cc=0
temp_cxx=$(mktemp -t dpdk.${0##*/}.XXX.cc)
pass_cxx=
failures_cxx=0
# Process output parameters.
[ "$QUIET" = 1 ] &&
exec 1> /dev/null
[ "$VERBOSE" = 1 ] &&
output ()
{
local CCV
local CXXV
shift
CCV=$CC
CXXV=$CXX
CC="echo $CC" CXX="echo $CXX" "$@"
CC=$CCV
CXX=$CXXV
"$@"
} ||
output ()
{
printf ' %s\n' "$1"
shift
"$@"
}
trap 'rm -f "$temp_cc" "$temp_cxx"' EXIT
compile_cc ()
{
${CC} -I"$include_dir" \
${PEDANTIC_CPPFLAGS} ${CPPFLAGS} ${EXTRA_CPPFLAGS} \
${PEDANTIC_CFLAGS} ${CFLAGS} ${EXTRA_CFLAGS} \
-c -o /dev/null "${temp_cc}"
}
compile_cxx ()
{
${CXX} -I"$include_dir" \
${PEDANTIC_CPPFLAGS} ${CPPFLAGS} ${EXTRA_CPPFLAGS} \
${PEDANTIC_CXXFLAGS} ${CXXFLAGS} ${EXTRA_CXXFLAGS} \
-c -o /dev/null "${temp_cxx}"
}
ignore ()
{
file="$1"
shift
while [ $# -ne 0 ]; do
case "$file" in
$1)
return 0
;;
esac
shift
done
return 1
}
# Check C/C++ compilation for each header file.
while read -r path
do
file=${path#$include_dir}
file=${file##/}
if ignore "$file" $IGNORE; then
output "SKIP $file" :
continue
fi
if printf "\
#include <%s>
int main(void)
{
return 0;
}
" "$file" > "$temp_cc" &&
output "CC $file" compile_cc
then
pass_cc="$pass_cc $file"
else
failures_cc=$(($failures_cc + 1))
fi
if ignore "$file" $IGNORE_CXX; then
output "SKIP CXX $file" :
continue
fi
if printf "\
#include <%s>
int main()
{
}
" "$file" > "$temp_cxx" &&
output "CXX $file" compile_cxx
then
pass_cxx="$pass_cxx $file"
else
failures_cxx=$(($failures_cxx + 1))
fi
done <<EOF
$(find "$include_dir" -name '*.h')
EOF
# Check C compilation with all includes.
: > "$temp_cc" &&
for file in $pass_cc; do
printf "\
#include <%s>
" "$file" >> $temp_cc
done
if printf "\
int main(void)
{
return 0;
}
" >> "$temp_cc" &&
output "CC (all includes that did not fail)" compile_cc
then
:
else
failures_cc=$(($failures_cc + 1))
fi
# Check C++ compilation with all includes.
: > "$temp_cxx" &&
for file in $pass_cxx; do
printf "\
#include <%s>
" "$file" >> $temp_cxx
done
if printf "\
int main()
{
}
" >> "$temp_cxx" &&
output "CXX (all includes that did not fail)" compile_cxx
then
:
else
failures_cxx=$(($failures_cxx + 1))
fi
# Report results.
if [ "$SUMMARY" = 1 ]; then
printf "\
Summary:
%u failure(s) for C using '%s'.
%u failure(s) for C++ using '%s'.
" $failures_cc "$CC" $failures_cxx "$CXX" 1>&2
fi
# Exit with nonzero status if there are failures.
[ $failures_cc -eq 0 ] &&
[ $failures_cxx -eq 0 ]