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