]>
Commit | Line | Data |
---|---|---|
7c673cae | 1 | #!/bin/sh -e |
9f95a23c TL |
2 | # SPDX-License-Identifier: BSD-3-Clause |
3 | # Copyright 2016 6WIND S.A. | |
7c673cae FG |
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 shell 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/*' \ | |
11fdf7f2 TL |
83 | 'rte_vhost.h' \ |
84 | 'rte_eth_vhost.h' \ | |
9f95a23c | 85 | 'rte_eal_interrupts.h' \ |
7c673cae FG |
86 | } |
87 | : ${IGNORE_CXX= \ | |
11fdf7f2 | 88 | 'rte_vhost.h' \ |
7c673cae | 89 | 'rte_eth_vhost.h' \ |
7c673cae FG |
90 | } |
91 | ||
9f95a23c | 92 | temp_cc=$(mktemp -t dpdk.${0##*/}.XXX.c) |
7c673cae FG |
93 | pass_cc= |
94 | failures_cc=0 | |
95 | ||
9f95a23c | 96 | temp_cxx=$(mktemp -t dpdk.${0##*/}.XXX.cc) |
7c673cae FG |
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 ] |