find-make-dist-errors 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. #!/usr/bin/python
  2. # Copyright (C) 2011 Igalia S.L.
  3. #
  4. # This library is free software; you can redistribute it and/or
  5. # modify it under the terms of the GNU Lesser General Public
  6. # License as published by the Free Software Foundation; either
  7. # version 2 of the License, or (at your option) any later version.
  8. #
  9. # This library is distributed in the hope that it will be useful,
  10. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. # Lesser General Public License for more details.
  13. #
  14. # You should have received a copy of the GNU Lesser General Public
  15. # License along with this library; if not, write to the Free Software
  16. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  17. import common
  18. import os
  19. import subprocess
  20. import sys
  21. def is_source_file_listing(line):
  22. return line.strip().startswith('Source')
  23. def get_listed_makefile_headers():
  24. makefile_text = open(os.path.join(common.build_path('GNUmakefile'))).read()
  25. # Automake often places separate includes on the same line.
  26. makefile_text = makefile_text.replace(' ', '\n')
  27. headers = []
  28. for line in makefile_text.splitlines():
  29. # $(srcdir)/ is the same as an empty string in a source file listing.
  30. line = line.replace('$(srcdir)/', '')
  31. # If the line doesn't start with 'Source' it isn't listing for
  32. # a source file.
  33. if not is_source_file_listing(line):
  34. continue
  35. # Most source listings end with \ indicating that the listing
  36. # continues onto the next line.
  37. line = line.replace('\\', '')
  38. # We only care about header files. Source files result in build
  39. # breakage, so we will detect them without this script.
  40. line = line.strip()
  41. if not line.endswith('.h'):
  42. continue
  43. # If the line contains a makefile variable we do not care about it.
  44. if line.find('$') != -1:
  45. continue
  46. headers.append(line)
  47. return headers
  48. def scan_headers_from_dependency_files():
  49. process = subprocess.Popen(['find . -name *.Plo | xargs cat | grep .h:$'],
  50. cwd=common.build_path(),
  51. stdout=subprocess.PIPE,
  52. shell=True)
  53. sanitized_lines = set()
  54. for line in process.communicate()[0].splitlines():
  55. # Paths in Plo files are relative to the build directory so they might contain
  56. # ../.. if the build directory is something like WebKitBuild/Release.
  57. line = line.replace('../../', '')
  58. if not is_source_file_listing(line):
  59. continue
  60. # The lines we care about end with ':'.
  61. line = line.replace(':', '')
  62. line = line.strip()
  63. sanitized_lines.add(line)
  64. return sanitized_lines
  65. def get_unlisted_headers(listed_makefile_headers):
  66. unlisted = set()
  67. for header in scan_headers_from_dependency_files():
  68. if not header in listed_makefile_headers:
  69. unlisted.add(header)
  70. return unlisted
  71. def get_missing_headers(listed_makefile_headers):
  72. missing = set()
  73. for header in listed_makefile_headers:
  74. if not os.path.exists(common.top_level_path(header)):
  75. missing.add(header)
  76. return missing
  77. listed_makefile_headers = get_listed_makefile_headers()
  78. unlisted_headers = get_unlisted_headers(listed_makefile_headers)
  79. missing_headers = get_missing_headers(listed_makefile_headers)
  80. if unlisted_headers:
  81. print 'Headers not listed in the GNUmakefiles:'
  82. for header in sorted(unlisted_headers):
  83. print '\t%s' % header
  84. print
  85. if missing_headers:
  86. print 'Headers listed in the GNUmakefiles that do not exist:'
  87. for header in sorted(missing_headers):
  88. print '\t%s' % header
  89. print
  90. sys.exit(len(unlisted_headers) + len(missing_headers))