- add sources.
[platform/framework/web/crosswalk.git] / src / native_client_sdk / src / tools / fix_deps.py
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.
5
6 """Fixup GCC-generated dependency files.
7
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.
11
12 See http://mad-scientist.net/make/autodep.html for more details of the problem.
13 """
14
15 import os
16 import optparse
17 import sys
18
19 TAG_LINE = '# Updated by fix_deps.py\n'
20
21
22 class Error(Exception):
23   pass
24
25
26 def ParseLine(line, new_target):
27   """Parse one line of a GCC-generated deps file.
28
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 = []
34
35   if new_target and ':' in line:
36     line = line.split(':', 1)[1]
37
38   line = line.strip()
39   line = line.rstrip('\\')
40
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)
47
48     if pos == -1:
49       filenames.append(line)
50       break
51     filenames.append(line[:pos])
52     line = line[pos+1:]
53
54   return filenames
55
56
57 def FixupDepFile(filename, output_filename=None):
58   if not os.path.exists(filename):
59     raise Error('File not found: %s' % filename)
60
61   if output_filename is None:
62     output_filename = filename
63
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('\\')
74
75   # For every depenency found output a dummy target with no rules
76   for dep in deps:
77     outlines.append('%s:\n' % dep)
78
79   with open(output_filename, 'w') as outfile:
80     for line in outlines:
81       outfile.write(line)
82
83
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)
103
104
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)