gcc-wrapper.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. #! /usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. # Copyright (c) 2011-2012, 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. "return_address.c:62",
  39. "hci_conn.c:407",
  40. "cpufreq_interactive.c:804",
  41. "cpufreq_interactive.c:847",
  42. "ene_ub6250.c:2118",
  43. ])
  44. # Capture the name of the object file, can find it.
  45. ofile = None
  46. warning_re = re.compile(r'''(.*/|)([^/]+\.[a-z]+:\d+):(\d+:)? warning:''')
  47. def interpret_warning(line):
  48. """Decode the message from gcc. The messages we care about have a filename, and a warning"""
  49. line = line.rstrip('\n')
  50. m = warning_re.match(line)
  51. if m and m.group(2) not in allowed_warnings:
  52. print >> sys.stderr, "error, forbidden warning:", m.group(2)
  53. # If there is a warning, remove any object if it exists.
  54. if ofile:
  55. try:
  56. os.remove(ofile)
  57. except OSError:
  58. pass
  59. sys.exit(1)
  60. def run_gcc():
  61. args = sys.argv[1:]
  62. # Look for -o
  63. try:
  64. i = args.index('-o')
  65. global ofile
  66. ofile = args[i+1]
  67. except (ValueError, IndexError):
  68. pass
  69. compiler = sys.argv[0]
  70. try:
  71. proc = subprocess.Popen(args, stderr=subprocess.PIPE)
  72. for line in proc.stderr:
  73. print >> sys.stderr, line,
  74. interpret_warning(line)
  75. result = proc.wait()
  76. except OSError as e:
  77. result = e.errno
  78. if result == errno.ENOENT:
  79. print >> sys.stderr, args[0] + ':',e.strerror
  80. print >> sys.stderr, 'Is your PATH set correctly?'
  81. else:
  82. print >> sys.stderr, ' '.join(args), str(e)
  83. return result
  84. if __name__ == '__main__':
  85. status = run_gcc()
  86. sys.exit(status)