diff options
Diffstat (limited to 'tools/check-headers-self-sufficient')
-rwxr-xr-x | tools/check-headers-self-sufficient | 247 |
1 files changed, 148 insertions, 99 deletions
diff --git a/tools/check-headers-self-sufficient b/tools/check-headers-self-sufficient index 8e5ced47dd..0513aeff47 100755 --- a/tools/check-headers-self-sufficient +++ b/tools/check-headers-self-sufficient @@ -1,107 +1,156 @@ -#!/bin/sh +#!/usr/bin/env python # Copyright 2017 Google Inc. # # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -cd "$(dirname "$0")/.." +import fnmatch +import multiprocessing +import os +import subprocess +import sys -compile_header() { - # test each header for self-sufficiency and idempotency. - printf '#include "%s"\n#include "%s"\n' "$1" "$1" | \ - c++ --std=c++11 \ - -Iinclude/core \ - -Iinclude/config \ - -Iinclude/android \ - -Iinclude/c \ - -Iinclude/codec \ - -Iinclude/effects \ - -Iinclude/gpu \ - -Iinclude/gpu/gl \ - -Iinclude/pathops \ - -Iinclude/ports \ - -Iinclude/private \ - -Iinclude/svg \ - -Iinclude/utils \ - -Iinclude/utils/mac \ - -Iinclude/views \ - -Iinclude/xml \ - -Isrc/codec \ - -Isrc/core \ - -Isrc/effects \ - -Isrc/effects/gradients \ - -Isrc/fonts \ - -Isrc/gpu \ - -Isrc/image \ - -Isrc/images \ - -Isrc/lazy \ - -Isrc/opts \ - -Isrc/pathops \ - -Isrc/ports \ - -Isrc/sfnt \ - -Isrc/sksl \ - -Isrc/utils \ - -Isrc/utils/win \ - -Igm \ - -Itests \ - -Itools \ - -Itools/debugger \ - -Itools/flags \ - -Itools/gpu \ - -Itools/timer \ - -Ithird_party/etc1 \ - -Ithird_party/externals/jsoncpp/include \ - -Ithird_party/externals/sfntly/cpp/src \ - -Ithird_party/externals/zlib \ - -Ithird_party/gif \ - -o /dev/null -c -x c++ - -} -FAIL=0 -for header in $(git ls-files | grep '\.h$'); do - # The following headers don't pass this test for one reason or another. - case $header in - */osmesa_wrapper.h) continue;; - debugger/QT/*) continue;; - example/*) continue;; - experimental/*) continue;; - include/config/*) continue;; - include/core/SkPostConfig.h) continue;; - include/gpu/vk/*) continue;; - include/ports/SkFontMgr_android.h) continue;; - include/ports/SkFontMgr_fontconfig.h) continue;; - include/ports/SkTypeface_win.h) continue;; - include/private/*_impl.h) continue;; - include/utils/mac/SkCGUtils.h) continue;; - include/views/SkOSWindow_*.h) continue;; - src/c/sk_c_from_to.h) continue;; - src/codec/SkJpegDecoderMgr.h) continue;; - src/codec/SkJpegUtility.h) continue;; - src/core/*Template.h) continue;; - src/core/SkBitmapProcState_*.h) continue;; - src/core/SkFDot6Constants.h) continue;; - src/core/SkLinearBitmapPipeline.h) continue;; - src/core/SkLinearBitmapPipeline_*.h) continue;; - src/core/SkUnPreMultiplyPriv.h) continue;; - src/gpu/vk/*.h) continue;; - src/images/SkJPEGWriteUtility.h) continue;; - src/opts/*_SSE2.h) continue;; - src/opts/*_SSSE3.h) continue;; - src/opts/*_neon.h) continue;; - src/opts/*_sse.h) continue;; - src/opts/Sk4px_*.h) continue;; - src/ports/*) continue;; - src/utils/*_win.h) continue;; - src/utils/win/*) continue;; - src/views/*) continue;; - third_party/*) continue;; - tools/fiddle/*) continue;; - tools/viewer/*) continue;; - esac - if ! compile_header "$header"; then - echo "FAILURE: $header" - FAIL=1 - fi -done -exit $FAIL +public_header_args = [ + '-Iinclude/core', + '-Iinclude/config', + '-Iinclude/android', + '-Iinclude/codec', + '-Iinclude/effects', + '-Iinclude/gpu', + '-Iinclude/gpu/gl', + '-Iinclude/pathops', + '-Iinclude/ports', + '-Iinclude/private', + '-Iinclude/svg', + '-Iinclude/utils', + '-Iinclude/utils/mac', + '-Iinclude/views', +] + +all_header_args = [ + '-Iinclude/core', + '-Iinclude/config', + '-Iinclude/android', + '-Iinclude/c', + '-Iinclude/codec', + '-Iinclude/effects', + '-Iinclude/gpu', + '-Iinclude/gpu/gl', + '-Iinclude/pathops', + '-Iinclude/ports', + '-Iinclude/private', + '-Iinclude/svg', + '-Iinclude/utils', + '-Iinclude/utils/mac', + '-Iinclude/views', + '-Isrc/codec', + '-Isrc/core', + '-Isrc/effects', + '-Isrc/effects/gradients', + '-Isrc/fonts', + '-Isrc/gpu', + '-Isrc/image', + '-Isrc/images', + '-Isrc/lazy', + '-Isrc/opts', + '-Isrc/pathops', + '-Isrc/ports', + '-Isrc/sfnt', + '-Isrc/sksl', + '-Isrc/utils', + '-Isrc/utils/win', + '-Isrc/xml', + '-Igm', + '-Itests', + '-Itools', + '-Itools/debugger', + '-Itools/flags', + '-Itools/gpu', + '-Itools/timer', + '-Ithird_party/etc1', + '-Ithird_party/externals/jsoncpp/include', + '-Ithird_party/externals/libjpeg-turbo', + '-Ithird_party/externals/sfntly/cpp/src', + '-Ithird_party/externals/zlib', + '-Ithird_party/gif', +] + +ignore = [ + '*/lex.*.h', + '*/osmesa_wrapper.h', + 'debugger/QT/*', + 'example/*', + 'experimental/*', + 'include/config/*', + 'include/core/SkPostConfig.h', + 'include/gpu/vk/*', + 'include/ports/SkFontMgr_android.h', + 'include/ports/SkFontMgr_fontconfig.h', + 'include/ports/SkTypeface_win.h', + 'include/private/*_impl.h', + 'include/utils/mac/SkCGUtils.h', + 'include/views/SkOSWindow_*.h', + 'src/c/sk_c_from_to.h', + 'src/core/*Template.h', + 'src/core/SkBitmapProcState_*.h', + 'src/core/SkFDot6Constants.h', + 'src/core/SkLinearBitmapPipeline.h', + 'src/core/SkLinearBitmapPipeline_*.h', + 'src/core/SkUnPreMultiplyPriv.h', + 'src/gpu/vk/*.h', + 'src/opts/*_SSE2.h', + 'src/opts/*_SSSE3.h', + 'src/opts/*_neon.h', + 'src/opts/*_sse.h', + 'src/opts/Sk4px_*.h', + 'src/ports/*', + 'src/utils/*_win.h', + 'src/utils/win/*', + 'src/views/*', + 'third_party/*', + 'tools/fiddle/*', + 'tools/viewer/*', +] + +# test header for self-sufficiency and idempotency. +# Returns a string containing errors, or None iff there are no errors. +def compile_header(header): + args = ([] if fnmatch.fnmatch(header, 'include/c/*') else + public_header_args if fnmatch.fnmatch(header, 'include/*') else + all_header_args) + cmd = ['c++', '--std=c++11'] + args + [ '-o', '/dev/null', '-c', '-x', 'c++', '-'] + proc = subprocess.Popen(cmd, stdin=subprocess.PIPE, + stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + proc.stdin.write('#include "%s"\n#include "%s"\n' % (header, header)) + proc.stdin.close() + errors = proc.stdout.read().strip() + if proc.wait() != 0 or len(errors) > 0: + return '\n\033[7m ERROR: %s \033[0m\n%s\n\n' % (header, errors) + return None + +def main(): + class N: good = True + # N.good is a global scoped to main() to make a print_and_exit_if() a closure + pool = multiprocessing.Pool() + def print_and_exit_if(r): + if r is not None: + sys.stdout.write(r) + N.good = False + pool.terminate() + + os.chdir(os.path.join(os.path.dirname(__file__), os.pardir)) + for path in subprocess.check_output(['git', 'ls-files']).splitlines(): + if path.endswith('.h') and not any(fnmatch.fnmatch(path, pattern) for pattern in ignore): + pool.apply_async(compile_header, args=(path, ), callback=print_and_exit_if) + pool.close() + pool.join() + if N.good: + sys.stdout.write('all good :)\n') + else: + exit(1) + +if __name__ == '__main__': + main() + |