blob: c0242aa6b4944072ecb902db7474ae7c15159bbf [file] [log] [blame]
#!/bin/sh
#
# Run the include-what-you-use tool (iwyu) on a file in the webrtc source
# directory.
#
# The script uses a subsequent grep pass to remove #include files from .cc
# that are also in the .h file, or are problematic to include.
#
# In order to handle include paths correctly, you need to provide
# a compile DB (aka compile_commands.json).
# You can create it in one of the following ways:
# "gn gen --export-compile-commands path/to/out"
# "tools/clang/scripts/generate_compdb.py -p path/to/out > compile_commands.json"
#
# To get iwyu on Debian/glinux, do "sudo apt-get install iwyu".
set -e
set -x
IWYU_TOOL="${IWYU_TOOL:-/usr/bin/iwyu_tool}"
FIX_INCLUDE="${FIX_INCLUDE:-/usr/bin/fix_include}"
# If you want to exclude files that are in $FILE.h from $FILE.cc, set
# the following variable to "yes". This is a style guide violation.
REMOVE_CC_INCLUDES=no
COMPILE_COMMANDS=''
error() {
echo "$*" >&2
exit 1
}
while getopts 'c:r' opts; do
case "${opts}" in
c) COMPILE_COMMANDS="${OPTARG}" ;;
r) REMOVE_CC_INCLUDES=yes ;;
*) error "Unexpected option ${opts}" ;;
esac
done
shift $(expr $OPTIND - 1 )
if [[ -z "$COMPILE_COMMANDS" ]]; then
error "compile_commands.json must be passed."
fi
FILE="$1"
if [ ! -f $FILE ]; then
# See if we have the root name of a .cc/.h pair
if [ ! -f $FILE.h ]; then
echo "$FILE.h not found"
exit 1
fi
FILE_H=$FILE.h
if [ ! -f $FILE.cc ]; then
echo "$FILE.cc not found"
exit 1
fi
FILE_CC=$FILE.cc
else
# Exact file, no .h file
FILE_CC=$FILE
FILE_H=""
fi
# IWYU has a confusing set of exit codes. Discard it.
"$IWYU_TOOL" -p "$COMPILE_COMMANDS" "$FILE_CC" \
>& /tmp/includefixes$$ || echo "IWYU done, code $?"
if grep 'fatal error' /tmp/includefixes$$; then
echo "iwyu run failed"
cat /tmp/includefixes$$
rm /tmp/includefixes$$
exit 1
else
# In compile_commands.json, the file name is recorded
# as a relative path to the build directory.
pushd "$(dirname "$COMPILE_COMMANDS")" || error "pushd failed"
"$FIX_INCLUDE" < /tmp/includefixes$$ || echo "Some files modified"
popd
rm /tmp/includefixes$$
fi
if [ $REMOVE_CC_INCLUDES == "yes" ]; then
if [ -n "$FILE_H" ]; then
# Don't include in .cc what's already included in .h
grep ^#include $FILE_H | grep -v -f - $FILE_CC > $FILE_CC.new
else
cp $FILE_CC $FILE_CC.new
fi
# Don't include stuff on the banlist
grep -v -f tools_webrtc/iwyu/iwyu-filter-list $FILE_CC.new > $FILE_CC
rm $FILE.ccnew
else
grep -v -f tools_webrtc/iwyu/iwyu-filter-list $FILE_CC > $FILE_CC.new
mv $FILE_CC.new $FILE_CC
fi
if [ -n "$FILE_H" ]; then
grep -v -f tools_webrtc/iwyu/iwyu-filter-list $FILE_H > $FILE_H.new
mv $FILE_H.new $FILE_H
fi
echo "Finished. Check diff, compile and git cl format before uploading."