• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/bin/bash
2# Copyright 2021 Google LLC
3#
4# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
6
7export LD_LIBRARY_PATH="external/clang_linux_amd64/usr/lib/x86_64-linux-gnu"
8
9set -euo pipefail
10
11if [[ "$@" == *DSKIA_SKIP_LINKING* ]]; then
12  # The output executable binary file is listed as the second argument to this script, and we must
13  # make sure it exists or Bazel will fail a validation step.
14  touch $2
15  exit 0
16fi
17
18# We only want to run include-what-you-use if DSKIA_ENFORCE_IWYU is in the arguments
19# passed in (i.e. the "skia_enforce_iwyu" feature is enabled) and we are not linking
20# (as detected by the presence of -fuse-ld).
21if [[ "$@" != *DSKIA_ENFORCE_IWYU* || "$@" == *use-ld* ]]; then
22  external/clang_linux_amd64/bin/clang $@
23  exit 0
24fi
25
26supported_files_or_dirs=(
27  "gm/"
28  "include/core/"
29  "include/effects/"
30  "include/encode/"
31  "include/gpu/ganesh/gen/"
32  "include/gpu/gen/"
33  "include/gpu/vk/gen/"
34  "include/private/"
35  "modules/bentleyottmann/"
36  "modules/skottie/"
37  "modules/sksg/"
38  "modules/skshaper/"
39  "modules/skunicode/"
40  "src/base/"
41  "src/codec/"
42  "src/core/"
43  "src/effects/"
44  "src/encode/"
45  "src/gpu/ganesh/effects/"
46  "src/gpu/ganesh/gen/"
47  "src/gpu/ganesh/geometry/"
48  "src/gpu/ganesh/glsl/"
49  "src/gpu/ganesh/image/"
50  "src/gpu/ganesh/mock/"
51  "src/gpu/ganesh/surface/"
52  "src/gpu/ganesh/text/"
53  "src/gpu/tessellate/"
54  "src/gpu/gen/"
55  "src/gpu/vk/"
56  "src/image/"
57  "src/pathops/"
58  "src/pdf/"
59  "src/ports/SkFontMgr_fontconfig"
60  "src/ports/SkFontMgr_fontations"
61  "src/shaders/"
62  "src/sksl/"
63  "src/svg/"
64  "src/text/"
65  "src/utils/"
66  "tests/"
67  "tools/debugger/"
68  "tools/viewer/"
69  "src/gpu/A"
70  "src/gpu/B"
71  "src/gpu/C"
72  "src/gpu/D"
73  "src/gpu/G"
74  "src/gpu/J"
75  "src/gpu/K"
76  "src/gpu/M"
77  "src/gpu/P"
78  "src/gpu/R"
79  "src/gpu/S"
80  "src/gpu/MutableTextureState.cpp"
81  "src/gpu/ganesh/Device.cpp"
82  "src/gpu/ganesh/GrBackendSemaphore.cpp"
83  "src/gpu/ganesh/GrBackendSurface.cpp"
84  "src/gpu/ganesh/GrBackendUtils.cpp"
85  "src/gpu/ganesh/GrBlurUtils.cpp"
86  "src/gpu/ganesh/GrCanvas.cpp"
87  "src/gpu/ganesh/GrCaps.cpp"
88  "src/gpu/ganesh/GrContext_Base.cpp"
89  "src/gpu/ganesh/GrDataUtils.cpp"
90  "src/gpu/ganesh/GrDef"
91  "src/gpu/ganesh/GrDirectContext.cpp"
92  "src/gpu/ganesh/GrFragmentProcessors.cpp"
93  "src/gpu/ganesh/GrGpu"
94  "src/gpu/ganesh/GrImageContext.cpp"
95  "src/gpu/ganesh/GrImageUtils.cpp"
96  "src/gpu/ganesh/GrMemoryPool.cpp"
97  "src/gpu/ganesh/GrMesh"
98  "src/gpu/ganesh/GrOp"
99  "src/gpu/ganesh/GrProcessor.cpp"
100  "src/gpu/ganesh/GrPromiseImageTexture.cpp"
101  "src/gpu/ganesh/GrRecordingContext.cpp"
102  "src/gpu/ganesh/GrRenderTargetProxy.cpp"
103  "src/gpu/ganesh/GrResourceProvider.cpp"
104  "src/gpu/ganesh/GrStencilSettings.cpp"
105  "src/gpu/ganesh/GrSurfaceCharacterization.cpp"
106  "src/gpu/ganesh/GrSurfaceProxy.cpp"
107  "src/gpu/ganesh/GrSurfaceProxyView.cpp"
108  "src/gpu/ganesh/GrTex"
109  "src/gpu/ganesh/GrTransferFromRenderTask.cpp"
110  "src/gpu/ganesh/GrXferProcessor.cpp"
111  "src/gpu/ganesh/SkGr.cpp"
112  "src/gpu/ganesh/gl/GrGLBackendSurface.cpp"
113  "src/gpu/ganesh/gl/GrGLCaps.cpp"
114  "src/gpu/ganesh/gl/GrGLDirectContext.cpp"
115  "src/gpu/ganesh/gl/GrGLGpu.cpp"
116  "src/gpu/ganesh/gl/GrGLSemaphore.cpp"
117  "src/gpu/ganesh/gl/GrGLVertexArray.cpp"
118  "src/gpu/ganesh/gl/builders/GrGLShaderStringBuilder.cpp"
119  "src/gpu/ganesh/ops/AtlasTextOp.cpp"
120  "src/gpu/ganesh/ops/DrawAtlasPathOp.cpp"
121  "src/gpu/ganesh/tessellate/StrokeTessellator.cpp"
122  "src/gpu/ganesh/vk/GrVkContextThread"
123  "src/gpu/ganesh/vk/GrVkDirectContext.cpp"
124  "tools/DecodeUtils.cpp"
125  "tools/EncodeUtils.cpp"
126  "tools/GpuToolUtils.cpp"
127  "tools/Resources.cpp"
128  "tools/SvgPathExtractor.cpp"
129  "tools/ToolUtils.cpp"
130  "tools/fonts/FontToolUtils.cpp"
131)
132
133excluded_files=(
134# Causes IWYU 8.17 to assert because it includes SkVX.h
135# "iwyu.cc:1977: Assertion failed: TODO(csilvers): for objc and clang lang extensions"
136  "tests/SkVxTest.cpp"
137  "src/base/SkHalf.cpp"
138  "src/core/SkMipmap.cpp"
139  "src/core/SkMipmapHQDownSampler.cpp"
140  "src/core/SkMaskBlurFilter.cpp"
141  "src/core/SkM44.cpp"
142  "src/core/SkPixmap.cpp"
143  "modules/skottie/src/effects/MotionBlurEffect.cpp"
144# This file sets and checks for defines in a way that confuses IWYU
145  "src/gpu/vk/vulkanmemoryallocator/VulkanMemoryAllocatorWrapper.cpp"
146)
147
148function opted_in_to_IWYU_checks() {
149  # Need [@] for entire list: https://stackoverflow.com/a/46137325
150  for path in ${supported_files_or_dirs[@]}; do
151    # If this was a generated file, it will be in a different subdirectory, starting with
152    # bazel-out, (e.g. bazel-out/k8-iwyu-dbg/bin/src/gen/SkRefCnt.cpp) so check that location also.
153    if [[ $1 == *"-c $path"* ]] || [[ $1 == *"-c bazel-out"*"$path"* ]]; then
154        for e_path in ${excluded_files[@]}; do
155          if [[ $1 == *"-c $e_path"* ]]; then
156            echo ""
157            return 0
158          fi
159        done
160      echo $path
161      return 0
162    fi
163  done
164  echo ""
165  return 0
166}
167
168# We want to concatenate all args into a string so we can do some
169# string matching in the opted_in_to_IWYU_checks function.
170# https://unix.stackexchange.com/a/197794
171opt_in=$(opted_in_to_IWYU_checks "'$*'")
172if [[ -z $opt_in ]]; then
173  external/clang_linux_amd64/bin/clang $@
174  exit 0
175else
176  # IWYU always [1] returns a non-zero code because it doesn't produce the .o file (that's why
177  # we ran Clang first). As such, we do not want bash to fail after running IWYU.
178  # [1] Until v0.18 at least
179  set +e
180  # Get absolute path to the mapping file because resolving the relative path is tricky, given
181  # how Bazel locates the toolchain files.
182  MAPPING_FILE=$(realpath $(dirname ${BASH_SOURCE[0]}))"/IWYU_mapping.imp"
183  # IWYU always outputs something to stderr, which can be noisy if everything is fixed.
184  # Otherwise, we send the exact same arguments to include-what-you-use that we would for
185  # regular compilation with clang.
186  # We always allow SkTypes.h because it sets some defines that later #ifdefs use and IWYU is
187  # not consistent with detecting that.
188  external/clang_linux_amd64/bin/include-what-you-use $@ \
189      -Xiwyu --keep="include/core/SkTypes.h" \
190      -Xiwyu --keep="include/private/base/SkDebug.h" \
191      -Xiwyu --no_default_mappings \
192      -Xiwyu --error=3 \
193      -Xiwyu --mapping_file=$MAPPING_FILE 2>/dev/null
194  # IWYU returns 0 if everything looks good. It returns some other non-zero exit code otherwise.
195  if [ $? -eq 0 ]; then
196    # The expected .d file is the third argument. Bazel expects this file to be created, even
197    # if it is empty. We don't really need to create this file or compile the target since
198    # we will be skipping linking anyway and not using the output for real.
199    touch $3
200    # The expected .o file is the last argument passed into clang. Make sure this file exists
201    # or Bazel validation will fail
202    touch ${!#}
203    exit 0 # keep the build going
204  else
205    # Run IWYU again, but this time display the output. Then return non-zero to fail the build.
206    # These flags are a little different, but only in ways that affect what was displayed, not the
207    # analysis. If we aren't sure why IWYU wants to include something, try changing verbose to 3.
208    external/clang_linux_amd64/bin/include-what-you-use $@ \
209        -Xiwyu --keep="include/core/SkTypes.h" \
210        -Xiwyu --keep="include/private/base/SkDebug.h" \
211        -Xiwyu --no_default_mappings \
212        -Xiwyu --mapping_file=$MAPPING_FILE -Xiwyu --no_comments \
213        -Xiwyu --quoted_includes_first -Xiwyu --verbose=3
214    exit 1 # fail the build
215  fi
216fi
217