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 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
)
93 raise parser
.error('No input file specified')
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__':
107 sys
.exit(main(sys
.argv
[1:]))
109 sys
.stderr
.write('%s: %s\n' % (os
.path
.basename(__file__
), e
))