| #!/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." |