1#!/usr/bin/env python 2# ************************************************************* 3# 4# Licensed to the Apache Software Foundation (ASF) under one 5# or more contributor license agreements. See the NOTICE file 6# distributed with this work for additional information 7# regarding copyright ownership. The ASF licenses this file 8# to you under the Apache License, Version 2.0 (the 9# "License"); you may not use this file except in compliance 10# with the License. You may obtain a copy of the License at 11# 12# http://www.apache.org/licenses/LICENSE-2.0 13# 14# Unless required by applicable law or agreed to in writing, 15# software distributed under the License is distributed on an 16# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17# KIND, either express or implied. See the License for the 18# specific language governing permissions and limitations 19# under the License. 20# 21# ************************************************************* 22import sys 23import os 24 25class CxxTarget: 26 def __init__(self, line): 27 self.directory = '' 28 self.outputfile = '' 29 self.includeflags = [] 30 self.cxxflags = [] 31 self.inputfiles = [] 32 self.nolink = False 33 options = line[:-1].split(' ') 34 self.directory = options.pop(0) 35 parsing_outputfile = False 36 for option in options: 37 if parsing_outputfile: 38 self.outputfile = option 39 parsing_outputfile = False 40 elif option == '-o': 41 parsing_outputfile = True 42 elif option == '-c': 43 self.nolink = True 44 elif option.startswith('-I'): 45 self.includeflags.append(CxxFlag(option)) 46 elif option.startswith('-'): 47 self.cxxflags.append(CxxFlag(option)) 48 else: 49 self.inputfiles.append(option) 50 self.cxxflags.sort() 51 self.includeflags.sort() 52 cxxflags_tmp = dict() 53 for flag in self.cxxflags: 54 cxxflags_tmp[flag.name] = flag 55 self.cxxflags = cxxflags_tmp.values() 56 includeflags_tmp = dict() 57 for flag in self.includeflags: 58 includeflags_tmp[flag.name] = flag 59 self.includeflags = includeflags_tmp.values() 60 CxxTargets.by_name[self.getFullOutputname()] = self 61 def __str__(self): 62 return '%s' % (self.getFullOutputname()) 63 def getFullOutputname(self): 64 return self.directory + '/' + self.outputfile 65 def __cmp__(self, other): 66 return cmp(self.getFullOutputname(), other.getFullOutputname()) 67 68class CxxFlag: 69 def __init__(self, name): 70 self.name = name 71 CxxFlags.by_name[self.name] = self 72 def __str__(self): 73 return 'Flag %s' % (self.name) 74 def __cmp__(self, other): 75 return cmp(self.name, other.name) 76 77class CxxFlags: 78 by_name = dict() 79 80class CxxTargets: 81 by_name = dict() 82 83if __name__ == '__main__': 84 [CxxTarget(line) for line in sys.stdin.readlines()] 85 compile_targets = [target for target in CxxTargets.by_name.values() if target.nolink] 86 link_targets = [target for target in CxxTargets.by_name.values() if not target.nolink] 87 common_compile_flags = [] 88 for flag in CxxFlags.by_name.values(): 89 if sum((flag in target.cxxflags for target in compile_targets)) == len(compile_targets): 90 common_compile_flags.append(flag) 91 common_link_flags = [] 92 for flag in CxxFlags.by_name.values(): 93 if sum((flag in target.cxxflags for target in compile_targets)) == len(compile_targets): 94 common_link_flags.append(flag) 95 96 for target in compile_targets: 97 target.cxxflags = [flag for flag in target.cxxflags if flag not in common_compile_flags] 98 target.cxxflags.sort() 99 for target in link_targets: 100 target.cxxflags = [flag for flag in target.cxxflags if flag not in common_link_flags] 101 target.cxxflags.sort() 102 103 common_compile_flags.sort() 104 common_link_flags.sort() 105 print 'common compile flags: %s' % (' '.join(flag.name for flag in common_compile_flags)) 106 print 'common link flags: %s' % (' '.join(flag.name for flag in common_link_flags)) 107 108 by_flagset = dict() 109 for target in CxxTargets.by_name.values(): 110 flagset = ' '.join((flag.name for flag in target.cxxflags)) 111 if flagset not in by_flagset: 112 by_flagset[flagset] = list() 113 by_flagset[flagset].append(target) 114 for targetlist in by_flagset.values(): 115 targetlist.sort() 116 flagsets = by_flagset.keys() 117 flagsets.sort() 118 print '%d compilerflag groups:' % (len(flagsets)) 119 for flagset in flagsets: 120 print flagset 121 for target in by_flagset[flagset]: 122 print '%s' % (target) 123 print 124 125 by_flagset = dict() 126 for target in CxxTargets.by_name.values(): 127 flagset = ' '.join((flag.name for flag in target.includeflags)) 128 if flagset not in by_flagset: 129 by_flagset[flagset] = list() 130 by_flagset[flagset].append(target) 131 for targetlist in by_flagset.values(): 132 targetlist.sort() 133 flagsets = by_flagset.keys() 134 flagsets.sort() 135 print '%d include flag groups:' % (len(flagsets)) 136 for flagset in flagsets: 137 print flagset 138 for target in by_flagset[flagset]: 139 print '%s' % (target) 140 print 141 142 print 'sources:' 143 by_name = dict() 144 for target in CxxTargets.by_name.values(): 145 by_name[os.path.basename(target.outputfile)] = target 146 names = by_name.keys() 147 names.sort() 148 for target in CxxTargets.by_name.values(): 149 if len(target.inputfiles) > 1: 150 objects = [os.path.basename(object) for object in target.inputfiles] 151 sources = list() 152 for object in objects: 153 if object in by_name: 154 sources.append(by_name[object].inputfiles[0]) 155 else: 156 sources.append('!!!!' + object) 157 sources.sort() 158 print '%s %s' % (target.getFullOutputname(), ' '.join(sources)) 159