summaryrefslogtreecommitdiffstats
path: root/native_client_sdk/src/tools/fix_deps.py
blob: a10feacc119c2f768f8bda30968ce0d13d045bac (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#!/usr/bin/env python
# Copyright (c) 2013 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Fixup GCC-generated dependency files.

Modify GCC generated dependency files in-place so they are more suitable
for including in a GNU Makefile.  Without the fixups, deleting or renaming
headers can cause the build to be broken. See:
http://mad-scientist.net/make/autodep.html for more details of the problem.
"""

import os
import optparse
import sys

TAG_LINE = '# Updated by fix_deps.py\n'


class Error(Exception):
  pass


def ParseLine(line, new_target):
  """Parse one line of a GCC-generated deps file.

  Each line contains an optional target and then a list
  of space seperated dependencies.  Spaces within filenames
  are escaped with a backslash.
  """
  filenames = []

  if new_target and ':' in line:
    line = line.split(':', 1)[1]

  line = line.strip()
  line = line.rstrip('\\')

  while True:
    # Find the next non-escaped space
    line = line.strip()
    pos = line.find(' ')
    while pos > 0 and line[pos-1] == '\\':
      pos = line.find(' ', pos+1)

    if pos == -1:
      filenames.append(line)
      break
    filenames.append(line[:pos])
    line = line[pos+1:]

  return filenames


def FixupDepFile(filename):
  if not os.path.exists(filename):
    raise Error('File not found: %s' % filename)

  outlines = [TAG_LINE]
  deps = []
  new_target = True
  with open(filename) as infile:
    for line in infile:
      if line == TAG_LINE:
        raise Error('Already processed: %s' % filename)
      outlines.append(line)
      deps += ParseLine(line, new_target)
      new_target = line.endswith('\\')

  # For every depenency found output a dummy target with no rules
  for dep in deps:
    outlines.append('%s:\n' % dep)

  with open(filename, 'w') as outfile:
    for line in outlines:
      outfile.write(line)


def main(argv):
  usage = "usage: %prog [options] <dep_file ...>"
  parser = optparse.OptionParser(usage=usage, description=__doc__)
  args = parser.parse_args(argv)[1]
  if not args:
    raise parser.error('expected one or more files as arguments')
  for arg in args:
    FixupDepFile(arg)


if __name__ == '__main__':
  try:
    sys.exit(main(sys.argv[1:]))
  except Error as e:
    sys.stderr.write('%s: %s\n' % (os.path.basename(__file__), e))
    sys.exit(1)