Updating trunk VERSION from 2139.0 to 2140.0
[chromium-blink-merge.git] / native_client_sdk / src / tools / fix_deps.py
blob91b4fa7e7997df05fb49067620ba0ad1525b471a
1 #!/usr/bin/env python
2 # Copyright (c) 2013 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
6 """Fixup GCC-generated dependency files.
8 Modify GCC generated dependency files so they are more suitable for including
9 in a GNU Makefile. Without the fixups, deleting or renaming headers can cause
10 the build to be broken.
12 See http://mad-scientist.net/make/autodep.html for more details of the problem.
13 """
15 import os
16 import optparse
17 import sys
19 TAG_LINE = '# Updated by fix_deps.py\n'
22 class Error(Exception):
23 pass
26 def ParseLine(line, new_target):
27 """Parse one line of a GCC-generated deps file.
29 Each line contains an optional target and then a list
30 of space seperated dependencies. Spaces within filenames
31 are escaped with a backslash.
32 """
33 filenames = []
35 if new_target and ':' in line:
36 line = line.split(':', 1)[1]
38 line = line.strip()
39 line = line.rstrip('\\')
41 while True:
42 # Find the next non-escaped space
43 line = line.strip()
44 pos = line.find(' ')
45 while pos > 0 and line[pos-1] == '\\':
46 pos = line.find(' ', pos+1)
48 if pos == -1:
49 filenames.append(line)
50 break
51 filenames.append(line[:pos])
52 line = line[pos+1:]
54 return filenames
57 def FixupDepFile(filename, output_filename=None):
58 if not os.path.exists(filename):
59 raise Error('File not found: %s' % filename)
61 if output_filename is None:
62 output_filename = filename
64 outlines = [TAG_LINE]
65 deps = []
66 new_target = True
67 with open(filename) as infile:
68 for line in infile:
69 if line == TAG_LINE:
70 raise Error('Already processed: %s' % filename)
71 outlines.append(line)
72 deps += ParseLine(line, new_target)
73 new_target = line.endswith('\\')
75 # For every depenency found output a dummy target with no rules
76 for dep in deps:
77 outlines.append('%s:\n' % dep)
79 with open(output_filename, 'w') as outfile:
80 for line in outlines:
81 outfile.write(line)
84 def main(argv):
85 usage = "usage: %prog [options] <dep_file>"
86 parser = optparse.OptionParser(usage=usage, description=__doc__)
87 parser.add_option('-o', '--output', help='Output filename (defaults to '
88 'input name with .deps extension')
89 parser.add_option('-c', '--clean', action='store_true',
90 help='Remove input file after writing output')
91 options, args = parser.parse_args(argv)
92 if not args:
93 raise parser.error('No input file specified')
94 if len(args) > 1:
95 raise parser.error('Only one argument supported')
96 input_filename = args[0]
97 output_filename = options.output
98 if not output_filename:
99 output_filename = os.path.splitext(input_filename)[0] + '.deps'
100 FixupDepFile(input_filename, output_filename)
101 if options.clean and input_filename != output_filename:
102 os.remove(input_filename)
105 if __name__ == '__main__':
106 try:
107 sys.exit(main(sys.argv[1:]))
108 except Error as e:
109 sys.stderr.write('%s: %s\n' % (os.path.basename(__file__), e))
110 sys.exit(1)