xref: /aosp_15_r20/external/webrtc/tools_webrtc/iwyu/apply-iwyu (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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