[dpdk-dev] [PATCH v2 11/11] scripts: check compilation of exported header files

Adrien Mazarguil adrien.mazarguil at 6wind.com
Tue Jul 5 12:44:57 CEST 2016


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.

Signed-off-by: Adrien Mazarguil <adrien.mazarguil at 6wind.com>
---
 MAINTAINERS               |   1 +
 scripts/check-includes.sh | 286 +++++++++++++++++++++++++++++++++++++++++
 scripts/test-build.sh     |  14 ++
 3 files changed, 301 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index a59191e..c12db3d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -26,6 +26,7 @@ T: git://dpdk.org/dpdk
 F: MAINTAINERS
 F: scripts/check-maintainers.sh
 F: scripts/check-git-log.sh
+F: scripts/check-includes.sh
 F: scripts/checkpatches.sh
 F: scripts/load-devel-config.sh
 F: scripts/test-build.sh
diff --git a/scripts/check-includes.sh b/scripts/check-includes.sh
new file mode 100755
index 0000000..d65adc6
--- /dev/null
+++ b/scripts/check-includes.sh
@@ -0,0 +1,286 @@
+#!/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 ]
diff --git a/scripts/test-build.sh b/scripts/test-build.sh
index 5bcecfc..b2ea602 100755
--- a/scripts/test-build.sh
+++ b/scripts/test-build.sh
@@ -229,6 +229,20 @@ for conf in $configs ; do
 	make -j$J -sC examples/performance-thread \
 		EXTRA_LDFLAGS="$DPDK_DEP_LDFLAGS" $verbose \
 		O=$(readlink -m $dir/examples/performance-thread)
+	echo "================== Check includes in $dir"
+	if echo $target | grep -q 'gcc'; then
+		CC=gcc
+		CXX=g++
+	elif echo $target | grep -q 'clang'; then
+		CC=clang
+		CXX=clang++
+	else
+		CXX=$CC
+	fi
+	CC=$CROSS$CC CXX=$CROSS$CXX \
+		VERBOSE="$((! ! ${#verbose}))" \
+		QUIET="$((! ${#verbose}))" \
+		scripts/check-includes.sh "$dir/include"
 	unset RTE_TARGET
 	echo "################## $dir done."
 done
-- 
2.1.4



More information about the dev mailing list