test mbuf attach
[dpdk.git] / devtools / check-includes.sh
1 #!/bin/sh -e
2 # SPDX-License-Identifier: BSD-3-Clause
3 # Copyright 2016 6WIND S.A.
4
5 # This script checks that header files in a given directory do not miss
6 # dependencies when included on their own, do not conflict and accept being
7 # compiled with the strictest possible flags.
8 #
9 # Files are looked up in the directory provided as the first argument,
10 # otherwise build/include by default.
11 #
12 # Recognized environment variables:
13 #
14 # VERBOSE=1 is the same as -v.
15 #
16 # QUIET=1 is the same as -q.
17 #
18 # SUMMARY=1 is the same as -s.
19 #
20 # CC, CPPFLAGS, CFLAGS, EXTRA_CPPFLAGS, EXTRA_CFLAGS, CXX, CXXFLAGS and
21 # EXTRA_CXXFLAGS are taken into account.
22 #
23 # PEDANTIC_CFLAGS, PEDANTIC_CXXFLAGS and PEDANTIC_CPPFLAGS provide strict
24 # C/C++ compilation flags.
25 #
26 # IGNORE contains a list of globbing patterns matching files (relative to the
27 # include directory) to avoid. It is set by default to known DPDK headers
28 # which must not be included on their own.
29 #
30 # IGNORE_CXX provides additional files for C++.
31
32 while getopts hqvs arg; do
33         case $arg in
34         h)
35                 cat <<EOF
36 usage: $0 [-h] [-q] [-v] [-s] [DIR]
37
38 This script checks that header files in a given directory do not miss
39 dependencies when included on their own, do not conflict and accept being
40 compiled with the strictest possible flags.
41
42   -h    display this help and exit
43   -q    quiet mode, disable normal output
44   -v    show command lines being executed
45   -s    show summary
46
47 With no DIR, default to build/include.
48
49 Any failed header check yields a nonzero exit status.
50 EOF
51                 exit
52                 ;;
53         q)
54                 QUIET=1
55                 ;;
56         v)
57                 VERBOSE=1
58                 ;;
59         s)
60                 SUMMARY=1
61                 ;;
62         *)
63                 exit 1
64                 ;;
65         esac
66 done
67
68 shift $(($OPTIND - 1))
69
70 include_dir=${1:-build/include}
71
72 : ${PEDANTIC_CFLAGS=-std=c99 -pedantic -Wall -Wextra -Werror}
73 : ${PEDANTIC_CXXFLAGS=}
74 : ${PEDANTIC_CPPFLAGS=-D_XOPEN_SOURCE=600}
75 : ${CC:=cc}
76 : ${CXX:=c++}
77 : ${IGNORE= \
78         'rte_atomic_32.h' \
79         'rte_atomic_64.h' \
80         'rte_byteorder_32.h' \
81         'rte_byteorder_64.h' \
82         'generic/*' \
83         'rte_vhost.h' \
84         'rte_eth_vhost.h' \
85         'rte_eal_interrupts.h' \
86 }
87 : ${IGNORE_CXX= \
88         'rte_vhost.h' \
89         'rte_eth_vhost.h' \
90 }
91
92 temp_cc=$(mktemp -t dpdk.${0##*/}.XXX.c)
93 pass_cc=
94 failures_cc=0
95
96 temp_cxx=$(mktemp -t dpdk.${0##*/}.XXX.cc)
97 pass_cxx=
98 failures_cxx=0
99
100 # Process output parameters.
101
102 [ "$QUIET" = 1 ] &&
103 exec 1> /dev/null
104
105 [ "$VERBOSE" = 1 ] &&
106 output ()
107 {
108         local CCV
109         local CXXV
110
111         shift
112         CCV=$CC
113         CXXV=$CXX
114         CC="echo $CC" CXX="echo $CXX" "$@"
115         CC=$CCV
116         CXX=$CXXV
117
118         "$@"
119 } ||
120 output ()
121 {
122
123         printf '  %s\n' "$1"
124         shift
125         "$@"
126 }
127
128 trap 'rm -f "$temp_cc" "$temp_cxx"' EXIT
129
130 compile_cc ()
131 {
132         ${CC} -I"$include_dir" \
133                 ${PEDANTIC_CPPFLAGS} ${CPPFLAGS} ${EXTRA_CPPFLAGS} \
134                 ${PEDANTIC_CFLAGS} ${CFLAGS} ${EXTRA_CFLAGS} \
135                 -c -o /dev/null "${temp_cc}"
136 }
137
138 compile_cxx ()
139 {
140         ${CXX} -I"$include_dir" \
141                 ${PEDANTIC_CPPFLAGS} ${CPPFLAGS} ${EXTRA_CPPFLAGS} \
142                 ${PEDANTIC_CXXFLAGS} ${CXXFLAGS} ${EXTRA_CXXFLAGS} \
143                 -c -o /dev/null "${temp_cxx}"
144 }
145
146 ignore ()
147 {
148         file="$1"
149         shift
150         while [ $# -ne 0 ]; do
151                 case "$file" in
152                 $1)
153                         return 0
154                         ;;
155                 esac
156                 shift
157         done
158         return 1
159 }
160
161 # Check C/C++ compilation for each header file.
162
163 while read -r path
164 do
165         file=${path#$include_dir}
166         file=${file##/}
167         if ignore "$file" $IGNORE; then
168                 output "SKIP $file" :
169                 continue
170         fi
171         if printf "\
172 #include <%s>
173
174 int main(void)
175 {
176         return 0;
177 }
178 " "$file" > "$temp_cc" &&
179                 output "CC $file" compile_cc
180         then
181                 pass_cc="$pass_cc $file"
182         else
183                 failures_cc=$(($failures_cc + 1))
184         fi
185         if ignore "$file" $IGNORE_CXX; then
186                 output "SKIP CXX $file" :
187                 continue
188         fi
189         if printf "\
190 #include <%s>
191
192 int main()
193 {
194 }
195 " "$file" > "$temp_cxx" &&
196                 output "CXX $file" compile_cxx
197         then
198                 pass_cxx="$pass_cxx $file"
199         else
200                 failures_cxx=$(($failures_cxx + 1))
201         fi
202 done <<EOF
203 $(find "$include_dir" -name '*.h')
204 EOF
205
206 # Check C compilation with all includes.
207
208 : > "$temp_cc" &&
209 for file in $pass_cc; do
210         printf "\
211 #include <%s>
212 " "$file" >> $temp_cc
213 done
214 if printf "\
215 int main(void)
216 {
217         return 0;
218 }
219 " >> "$temp_cc" &&
220         output "CC (all includes that did not fail)" compile_cc
221 then
222         :
223 else
224         failures_cc=$(($failures_cc + 1))
225 fi
226
227 # Check C++ compilation with all includes.
228
229 : > "$temp_cxx" &&
230 for file in $pass_cxx; do
231         printf "\
232 #include <%s>
233 " "$file" >> $temp_cxx
234 done
235 if printf "\
236 int main()
237 {
238 }
239 " >> "$temp_cxx" &&
240         output "CXX (all includes that did not fail)" compile_cxx
241 then
242         :
243 else
244         failures_cxx=$(($failures_cxx + 1))
245 fi
246
247 # Report results.
248
249 if [ "$SUMMARY" = 1 ]; then
250         printf "\
251 Summary:
252  %u failure(s) for C using '%s'.
253  %u failure(s) for C++ using '%s'.
254 " $failures_cc "$CC" $failures_cxx "$CXX" 1>&2
255 fi
256
257 # Exit with nonzero status if there are failures.
258
259 [ $failures_cc -eq 0 ] &&
260 [ $failures_cxx -eq 0 ]