xref: /trunk/main/solenv/bin/buildalyzer (revision cdf0e10c)
1#!/usr/bin/env python
2import sys
3import os
4
5class CxxTarget:
6    def __init__(self, line):
7        self.directory = ''
8        self.outputfile = ''
9        self.includeflags = []
10        self.cxxflags = []
11        self.inputfiles = []
12        self.nolink = False
13        options = line[:-1].split(' ')
14        self.directory = options.pop(0)
15        parsing_outputfile = False
16        for option in options:
17            if parsing_outputfile:
18                self.outputfile = option
19                parsing_outputfile = False
20            elif option == '-o':
21                parsing_outputfile = True
22            elif option == '-c':
23                self.nolink = True
24            elif option.startswith('-I'):
25                self.includeflags.append(CxxFlag(option))
26            elif option.startswith('-'):
27                self.cxxflags.append(CxxFlag(option))
28            else:
29                self.inputfiles.append(option)
30        self.cxxflags.sort()
31        self.includeflags.sort()
32        cxxflags_tmp = dict()
33        for flag in self.cxxflags:
34            cxxflags_tmp[flag.name] = flag
35        self.cxxflags = cxxflags_tmp.values()
36        includeflags_tmp = dict()
37        for flag in self.includeflags:
38            includeflags_tmp[flag.name] = flag
39        self.includeflags = includeflags_tmp.values()
40        CxxTargets.by_name[self.getFullOutputname()] = self
41    def __str__(self):
42        return '%s' % (self.getFullOutputname())
43    def getFullOutputname(self):
44        return self.directory + '/' + self.outputfile
45    def __cmp__(self, other):
46        return cmp(self.getFullOutputname(), other.getFullOutputname())
47
48class CxxFlag:
49    def __init__(self, name):
50        self.name = name
51        CxxFlags.by_name[self.name] = self
52    def __str__(self):
53        return 'Flag %s' % (self.name)
54    def __cmp__(self, other):
55        return cmp(self.name, other.name)
56
57class CxxFlags:
58    by_name = dict()
59
60class CxxTargets:
61    by_name = dict()
62
63if __name__ == '__main__':
64    [CxxTarget(line) for line in sys.stdin.readlines()]
65    compile_targets = [target for target in CxxTargets.by_name.values() if target.nolink]
66    link_targets = [target for target in CxxTargets.by_name.values() if not target.nolink]
67    common_compile_flags = []
68    for flag in CxxFlags.by_name.values():
69        if sum((flag in target.cxxflags for target in compile_targets)) == len(compile_targets):
70            common_compile_flags.append(flag)
71    common_link_flags = []
72    for flag in CxxFlags.by_name.values():
73        if sum((flag in target.cxxflags for target in compile_targets)) == len(compile_targets):
74            common_link_flags.append(flag)
75
76    for target in compile_targets:
77        target.cxxflags = [flag for flag in target.cxxflags if flag not in common_compile_flags]
78        target.cxxflags.sort()
79    for target in link_targets:
80        target.cxxflags = [flag for flag in target.cxxflags if flag not in common_link_flags]
81        target.cxxflags.sort()
82
83    common_compile_flags.sort()
84    common_link_flags.sort()
85    print 'common compile flags: %s' % (' '.join(flag.name for flag in common_compile_flags))
86    print 'common link flags: %s' % (' '.join(flag.name for flag in common_link_flags))
87
88    by_flagset = dict()
89    for target in CxxTargets.by_name.values():
90        flagset = ' '.join((flag.name for flag in target.cxxflags))
91        if flagset not in by_flagset:
92            by_flagset[flagset] = list()
93        by_flagset[flagset].append(target)
94    for targetlist in by_flagset.values():
95        targetlist.sort()
96    flagsets = by_flagset.keys()
97    flagsets.sort()
98    print '%d compilerflag groups:' % (len(flagsets))
99    for flagset in flagsets:
100        print flagset
101        for target in by_flagset[flagset]:
102            print '%s' % (target)
103        print
104
105    by_flagset = dict()
106    for target in CxxTargets.by_name.values():
107        flagset = ' '.join((flag.name for flag in target.includeflags))
108        if flagset not in by_flagset:
109            by_flagset[flagset] = list()
110        by_flagset[flagset].append(target)
111    for targetlist in by_flagset.values():
112        targetlist.sort()
113    flagsets = by_flagset.keys()
114    flagsets.sort()
115    print '%d include flag groups:' % (len(flagsets))
116    for flagset in flagsets:
117        print flagset
118        for target in by_flagset[flagset]:
119            print '%s' % (target)
120        print
121
122    print 'sources:'
123    by_name = dict()
124    for target in CxxTargets.by_name.values():
125        by_name[os.path.basename(target.outputfile)] = target
126    names = by_name.keys()
127    names.sort()
128    for target in CxxTargets.by_name.values():
129        if len(target.inputfiles) > 1:
130            objects = [os.path.basename(object) for object in target.inputfiles]
131            sources = list()
132            for object in objects:
133                if object in by_name:
134                    sources.append(by_name[object].inputfiles[0])
135                else:
136                    sources.append('!!!!' + object)
137            sources.sort()
138            print '%s %s' % (target.getFullOutputname(), ' '.join(sources))
139