1*d9f75844SAndroid Build Coastguard Worker#!/usr/bin/env bash 2*d9f75844SAndroid Build Coastguard Worker# 3*d9f75844SAndroid Build Coastguard Worker# Run the include-what-you-use tool (iwyu) on a file in the webrtc source 4*d9f75844SAndroid Build Coastguard Worker# directory. 5*d9f75844SAndroid Build Coastguard Worker# 6*d9f75844SAndroid Build Coastguard Worker# The script uses a subsequent grep pass to remove #include files 7*d9f75844SAndroid Build Coastguard Worker# that are problematic to include. 8*d9f75844SAndroid Build Coastguard Worker# 9*d9f75844SAndroid Build Coastguard Worker# In order to handle include paths correctly, you need to provide 10*d9f75844SAndroid Build Coastguard Worker# a compile DB (aka compile_commands.json). 11*d9f75844SAndroid Build Coastguard Worker# You can create it in one of the following ways: 12*d9f75844SAndroid Build Coastguard Worker# "gn gen --export-compile-commands path/to/out" 13*d9f75844SAndroid Build Coastguard Worker# "tools/clang/scripts/generate_compdb.py -p path/to/out > compile_commands.json" 14*d9f75844SAndroid Build Coastguard Worker# If "out/Default" exists, the script will attempt to generate it for you. 15*d9f75844SAndroid Build Coastguard Worker# 16*d9f75844SAndroid Build Coastguard Worker# To get iwyu on Debian/glinux, do "sudo apt-get install iwyu". 17*d9f75844SAndroid Build Coastguard Worker 18*d9f75844SAndroid Build Coastguard Worker# Set this to 1 to get more debug information. 19*d9f75844SAndroid Build Coastguard Worker# Set this to 2 to also get a dump of the iwyu tool output. 20*d9f75844SAndroid Build Coastguard WorkerDEBUG=0 21*d9f75844SAndroid Build Coastguard Worker 22*d9f75844SAndroid Build Coastguard Workerset -e 23*d9f75844SAndroid Build Coastguard Workerif [ $DEBUG -gt 0 ]; then 24*d9f75844SAndroid Build Coastguard Worker set -x 25*d9f75844SAndroid Build Coastguard Workerfi 26*d9f75844SAndroid Build Coastguard Worker 27*d9f75844SAndroid Build Coastguard Workererror() { 28*d9f75844SAndroid Build Coastguard Worker echo "$*" >&2 29*d9f75844SAndroid Build Coastguard Worker exit 1 30*d9f75844SAndroid Build Coastguard Worker} 31*d9f75844SAndroid Build Coastguard Worker 32*d9f75844SAndroid Build Coastguard Workerfind_alternates() { 33*d9f75844SAndroid Build Coastguard Worker for name in "$@" 34*d9f75844SAndroid Build Coastguard Worker do 35*d9f75844SAndroid Build Coastguard Worker name_path=$(which "${name}") 36*d9f75844SAndroid Build Coastguard Worker if [ ! -z "${name_path}" ]; then 37*d9f75844SAndroid Build Coastguard Worker echo ${name_path} 38*d9f75844SAndroid Build Coastguard Worker return 0 39*d9f75844SAndroid Build Coastguard Worker fi 40*d9f75844SAndroid Build Coastguard Worker done 41*d9f75844SAndroid Build Coastguard Worker error "Could not find any of the tools '$@' in PATH." 42*d9f75844SAndroid Build Coastguard Worker return 1 43*d9f75844SAndroid Build Coastguard Worker} 44*d9f75844SAndroid Build Coastguard Worker 45*d9f75844SAndroid Build Coastguard WorkerIWYU_TOOL=$(find_alternates iwyu_tool iwyu_tool.py) 46*d9f75844SAndroid Build Coastguard WorkerFIX_INCLUDE=$(find_alternates fix_include fix_includes.py) 47*d9f75844SAndroid Build Coastguard WorkerFIX_INCLUDE_ARGS='' 48*d9f75844SAndroid Build Coastguard WorkerIWYU_TOOL_DIR="${IWYU_TOOL_DIR:-tools_webrtc/iwyu}" 49*d9f75844SAndroid Build Coastguard WorkerCOMPILE_COMMANDS='' 50*d9f75844SAndroid Build Coastguard Worker 51*d9f75844SAndroid Build Coastguard Workerusage() { 52*d9f75844SAndroid Build Coastguard Worker echo "Usage: $0 [ -c compile-commands-file.json ] [-r] file.cc" 53*d9f75844SAndroid Build Coastguard Worker echo "Runs the IWYU and fix-include on a CC file and its associated .h file" 54*d9f75844SAndroid Build Coastguard Worker echo "Arguments:" 55*d9f75844SAndroid Build Coastguard Worker echo " -c compile-commands: Compiler command file" 56*d9f75844SAndroid Build Coastguard Worker echo " -r : Remove non-required includes from .h file" 57*d9f75844SAndroid Build Coastguard Worker echo " -h : Print this help message" 58*d9f75844SAndroid Build Coastguard Worker echo "(default command file: out/Default/compile_commands.json - this" 59*d9f75844SAndroid Build Coastguard Worker echo "will be generated if not present" 60*d9f75844SAndroid Build Coastguard Worker} 61*d9f75844SAndroid Build Coastguard Worker 62*d9f75844SAndroid Build Coastguard Workerwhile getopts 'c:rh' opts; do 63*d9f75844SAndroid Build Coastguard Worker case "${opts}" in 64*d9f75844SAndroid Build Coastguard Worker c) COMPILE_COMMANDS="${OPTARG}" ;; 65*d9f75844SAndroid Build Coastguard Worker r) FIX_INCLUDE_ARGS="${FIX_INCLUDE_ARGS} --nosafe_headers" ;; 66*d9f75844SAndroid Build Coastguard Worker h) usage; exit 1 ;; 67*d9f75844SAndroid Build Coastguard Worker *) error "Unexpected option ${opts}" ;; 68*d9f75844SAndroid Build Coastguard Worker esac 69*d9f75844SAndroid Build Coastguard Workerdone 70*d9f75844SAndroid Build Coastguard Workershift $(expr $OPTIND - 1 ) 71*d9f75844SAndroid Build Coastguard Worker 72*d9f75844SAndroid Build Coastguard Workerif [[ -z "$COMPILE_COMMANDS" ]]; then 73*d9f75844SAndroid Build Coastguard Worker if [ -d "out/Default" ]; then 74*d9f75844SAndroid Build Coastguard Worker if [ ! -f "out/Default/compile_commands.json" ]; then 75*d9f75844SAndroid Build Coastguard Worker gn gen --export-compile-commands out/Default 76*d9f75844SAndroid Build Coastguard Worker fi 77*d9f75844SAndroid Build Coastguard Worker COMPILE_COMMANDS="out/Default/compile_commands.json" 78*d9f75844SAndroid Build Coastguard Worker else 79*d9f75844SAndroid Build Coastguard Worker error "compile_commands.json must be passed." 80*d9f75844SAndroid Build Coastguard Worker fi 81*d9f75844SAndroid Build Coastguard Workerfi 82*d9f75844SAndroid Build Coastguard Worker 83*d9f75844SAndroid Build Coastguard WorkerFILE="$1" 84*d9f75844SAndroid Build Coastguard Worker 85*d9f75844SAndroid Build Coastguard Workerif [ ! -f $FILE_CC ]; then 86*d9f75844SAndroid Build Coastguard Worker error "File $FILE is not found" 87*d9f75844SAndroid Build Coastguard Workerfi 88*d9f75844SAndroid Build Coastguard Worker 89*d9f75844SAndroid Build Coastguard Worker# Find the .h file that IWYU will modify, if any. 90*d9f75844SAndroid Build Coastguard WorkerFILE_CC=$FILE 91*d9f75844SAndroid Build Coastguard Workerif [ -f $(dirname $FILE)/$(basename -s .cc $FILE).h ]; then 92*d9f75844SAndroid Build Coastguard Worker FILE_H=$(dirname $FILE)/$(basename -s .cc $FILE).h 93*d9f75844SAndroid Build Coastguard Workerelse 94*d9f75844SAndroid Build Coastguard Worker FILE_H="" 95*d9f75844SAndroid Build Coastguard Workerfi 96*d9f75844SAndroid Build Coastguard Worker 97*d9f75844SAndroid Build Coastguard Workertmpfile=$(realpath $(mktemp iwyu.XXXXXXX)) 98*d9f75844SAndroid Build Coastguard Workertrap 'rm -f -- "${tmpfile}"' EXIT 99*d9f75844SAndroid Build Coastguard Worker 100*d9f75844SAndroid Build Coastguard Worker# IWYU has a confusing set of exit codes. Discard it. 101*d9f75844SAndroid Build Coastguard Worker"$IWYU_TOOL" -p "$COMPILE_COMMANDS" "$FILE_CC" -- -Xiwyu --no_fwd_decls \ 102*d9f75844SAndroid Build Coastguard Worker -Xiwyu --mapping_file=../../$IWYU_TOOL_DIR/mappings.imp \ 103*d9f75844SAndroid Build Coastguard Worker >& ${tmpfile} || echo "IWYU done, code $?" 104*d9f75844SAndroid Build Coastguard Worker 105*d9f75844SAndroid Build Coastguard Workerif grep 'fatal error' ${tmpfile}; then 106*d9f75844SAndroid Build Coastguard Worker echo "iwyu run failed" 107*d9f75844SAndroid Build Coastguard Worker cat ${tmpfile} 108*d9f75844SAndroid Build Coastguard Worker exit 1 109*d9f75844SAndroid Build Coastguard Workerelse 110*d9f75844SAndroid Build Coastguard Worker if [ $DEBUG -gt 1 ]; then 111*d9f75844SAndroid Build Coastguard Worker cat ${tmpfile} 112*d9f75844SAndroid Build Coastguard Worker fi 113*d9f75844SAndroid Build Coastguard Worker # In compile_commands.json, the file name is recorded 114*d9f75844SAndroid Build Coastguard Worker # as a relative path to the build directory. 115*d9f75844SAndroid Build Coastguard Worker pushd "$(dirname "$COMPILE_COMMANDS")" || error "pushd failed" 116*d9f75844SAndroid Build Coastguard Worker "$FIX_INCLUDE" $FIX_INCLUDE_ARGS < ${tmpfile} || echo "Some files modified" 117*d9f75844SAndroid Build Coastguard Worker popd 118*d9f75844SAndroid Build Coastguard Workerfi 119*d9f75844SAndroid Build Coastguard Worker 120*d9f75844SAndroid Build Coastguard Workergrep -v -f tools_webrtc/iwyu/iwyu-filter-list $FILE_CC > $FILE_CC.new 121*d9f75844SAndroid Build Coastguard Workermv $FILE_CC.new $FILE_CC 122*d9f75844SAndroid Build Coastguard Worker 123*d9f75844SAndroid Build Coastguard Workerif [ -n "$FILE_H" ]; then 124*d9f75844SAndroid Build Coastguard Worker grep -v -f tools_webrtc/iwyu/iwyu-filter-list $FILE_H > $FILE_H.new 125*d9f75844SAndroid Build Coastguard Worker mv $FILE_H.new $FILE_H 126*d9f75844SAndroid Build Coastguard Workerfi 127*d9f75844SAndroid Build Coastguard Worker 128*d9f75844SAndroid Build Coastguard Workerecho "Finished. Check diff, compile and git cl format before uploading." 129