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.
19 TAG_LINE
= '# Updated by fix_deps.py\n'
22 class Error(Exception):
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.
35 if new_target
and ':' in line
:
36 line
= line
.split(':', 1)[1]
39 line
= line
.rstrip('\\')
42 # Find the next non-escaped space
45 while pos
> 0 and line
[pos
-1] == '\\':
46 pos
= line
.find(' ', pos
+1)
49 filenames
.append(line
)
51 filenames
.append(line
[:pos
])
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
67 with
open(filename
) as infile
:
70 raise Error('Already processed: %s' % filename
)
72 deps
+= ParseLine(line
, new_target
)
73 new_target
= line
.endswith('\\')
75 # For every depenency found output a dummy target with no rules
77 outlines
.append('%s:\n' % dep
)
79 with
open(output_filename
, 'w') as outfile
:
85 parser
= argparse
.ArgumentParser(description
=__doc__
)
86 parser
.add_argument('-o', '--output', help='Output filename (defaults to '
87 'input name with .deps extension')
88 parser
.add_argument('-c', '--clean', action
='store_true',
89 help='Remove input file after writing output')
90 parser
.add_argument('dep_file')
91 options
= parser
.parse_args(argv
)
92 output_filename
= options
.output
93 if not output_filename
:
94 output_filename
= os
.path
.splitext(options
.dep_file
)[0] + '.deps'
95 FixupDepFile(options
.dep_file
, output_filename
)
96 if options
.clean
and options
.dep_file
!= output_filename
:
97 os
.remove(options
.dep_file
)
102 if __name__
== '__main__':
104 sys
.exit(main(sys
.argv
[1:]))
106 sys
.stderr
.write('%s: %s\n' % (os
.path
.basename(__file__
), e
))