gcc-wrapper.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. #! /usr/bin/env python2
  2. # -*- coding: utf-8 -*-
  3. # Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
  4. #
  5. # Redistribution and use in source and binary forms, with or without
  6. # modification, are permitted provided that the following conditions are met:
  7. # * Redistributions of source code must retain the above copyright
  8. # notice, this list of conditions and the following disclaimer.
  9. # * Redistributions in binary form must reproduce the above copyright
  10. # notice, this list of conditions and the following disclaimer in the
  11. # documentation and/or other materials provided with the distribution.
  12. # * Neither the name of The Linux Foundation nor
  13. # the names of its contributors may be used to endorse or promote
  14. # products derived from this software without specific prior written
  15. # permission.
  16. #
  17. # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  18. # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  19. # IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  20. # NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  21. # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  22. # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  23. # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
  24. # OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  25. # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  26. # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  27. # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  28. # Invoke gcc, looking for warnings, and causing a failure if there are
  29. # non-whitelisted warnings.
  30. import errno
  31. import re
  32. import os
  33. import sys
  34. import subprocess
  35. # Note that gcc uses unicode, which may depend on the locale. TODO:
  36. # force LANG to be set to en_US.UTF-8 to get consistent warnings.
  37. allowed_warnings = set([
  38. "core.c:144",
  39. "inet_connection_sock.c:430",
  40. "inet_connection_sock.c:467",
  41. "inet6_connection_sock.c:89",
  42. ])
  43. # Capture the name of the object file, can find it.
  44. ofile = None
  45. warning_re = re.compile(r'''(.*/|)([^/]+\.[a-z]+:\d+):(\d+:)? warning:''')
  46. def interpret_warning(line):
  47. """Decode the message from gcc. The messages we care about have a filename, and a warning"""
  48. line = line.rstrip('\n')
  49. m = warning_re.match(line)
  50. if m and m.group(2) not in allowed_warnings:
  51. print >> sys.stderr, "error, forbidden warning:", m.group(2)
  52. # If there is a warning, remove any object if it exists.
  53. if ofile:
  54. try:
  55. os.remove(ofile)
  56. except OSError:
  57. pass
  58. sys.exit(1)
  59. def run_gcc():
  60. args = sys.argv[1:]
  61. # Look for -o
  62. try:
  63. i = args.index('-o')
  64. global ofile
  65. ofile = args[i+1]
  66. except (ValueError, IndexError):
  67. pass
  68. compiler = sys.argv[0]
  69. try:
  70. proc = subprocess.Popen(args, stderr=subprocess.PIPE)
  71. for line in proc.stderr:
  72. print >> sys.stderr, line,
  73. interpret_warning(line)
  74. result = proc.wait()
  75. except OSError as e:
  76. result = e.errno
  77. if result == errno.ENOENT:
  78. print >> sys.stderr, args[0] + ':',e.strerror
  79. print >> sys.stderr, 'Is your PATH set correctly?'
  80. else:
  81. print >> sys.stderr, ' '.join(args), str(e)
  82. return result
  83. if __name__ == '__main__':
  84. status = run_gcc()
  85. sys.exit(status)