numam-dpdk/devtools/check-includes.sh
Thomas Monjalon 9a98f50e89 scripts: move to devtools
The remaining scripts in the scripts/ directory are only useful
to developers. That's why devtools/ is a better name.

Signed-off-by: Thomas Monjalon <thomas.monjalon@6wind.com>
Tested-by: Ferruh Yigit <ferruh.yigit@intel.com>
2017-01-04 21:17:32 +01:00

287 lines
5.9 KiB
Bash
Executable File

#!/bin/sh -e
#
# BSD LICENSE
#
# Copyright 2016 6WIND S.A.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# * Neither the name of 6WIND S.A. nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# 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 shell 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/*' \
'exec-env/*' \
}
: ${IGNORE_CXX= \
'rte_eth_vhost.h' \
'rte_virtio_net.h' \
}
temp_cc=/tmp/${0##*/}.$$.c
pass_cc=
failures_cc=0
temp_cxx=/tmp/${0##*/}.$$.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 ]