Python script for generating build files for platform and modules, which uses the...
[mirror_edk2.git] / Tools / Python / buildgen / BuildConfig.py
1 #!/usr/bin/env python
2
3 # Copyright (c) 2007, Intel Corporation
4 # All rights reserved. This program and the accompanying materials
5 # are licensed and made available under the terms and conditions of the BSD License
6 # which accompanies this distribution. The full text of the license may be found at
7 # http://opensource.org/licenses/bsd-license.php
8 #
9 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 """Tools and build configuration"""
13
14 from sets import Set
15
16 class Config(dict):
17 def __init__(self, file):
18 """file (target configuration file)"""
19 configFile = open(file)
20 while True:
21 line = configFile.readline()
22 if line == "": break ## no more line
23
24 line = line.strip()
25 # skip blank line
26 if line == "": continue
27 # skip comment line
28 if line[0] == '#': continue
29 # skip invalid line
30 if line[0] == '=':
31 print "! invalid configuration:", line
32 continue
33
34 defStrings = line.split('=', 1)
35 name = defStrings[0].strip()
36 value = defStrings[1].strip()
37 self[name] = value
38
39 configFile.close()
40
41 def __getitem__(self, attr):
42 if attr not in self:
43 return ""
44
45 value = dict.__getitem__(self, attr)
46 if value == None:
47 value = ""
48 return value
49
50 class ToolConfig(dict):
51 def __init__(self, file):
52 """file (tools configuration file path)"""
53 self.Targets = Set()
54 self.Toolchains = Set()
55 self.Archs = Set()
56 self.ToolCodes = Set()
57 self.Families = Set()
58 self.Attributes = Set(["FAMILY", "NAME", "PATH", "FLAGS", "EXT", "DPATH", "SPATH", "LIBPATH", "INCLUDEPATH"])
59
60 configFile = open(file)
61 while True:
62 line = configFile.readline()
63 if line == "": break
64
65 line = line.strip()
66 # skip blank line
67 if line == "": continue
68 # skip comment line
69 if line[0] == '#': continue
70 # skip invalid line
71 if line[0] == '=':
72 print "! invalid definition:", line
73 continue
74
75 # split the definition at the first "="
76 tool_def = line.split('=', 1)
77 name = tool_def[0].strip()
78 value = tool_def[1].strip()
79
80 # the name of a tool definition must have five parts concatenated by "_"
81 keys = name.split('_')
82 # skip non-definition line
83 if len(keys) < 5: continue
84
85 keys = (keys[1], keys[0], keys[2], keys[3], keys[4])
86 self[keys] = value
87
88 ###############################################
89 ## statistics
90 ###############################################
91 if keys[0] != '*': self.Toolchains.add(keys[0])
92 if keys[1] != '*': self.Targets.add(keys[1])
93 if keys[2] != '*': self.Archs.add(keys[2])
94 if keys[3] != '*': self.ToolCodes.add(keys[3])
95 if keys[4] == "FAMILY": self.Families.add(value)
96 elif keys[4] == '*': raise Exception("No * allowed in ATTRIBUTE field")
97
98 configFile.close()
99 # expand the "*" in each field
100 self.expand()
101
102 def __getitem__(self, attrs):
103 if len(attrs) != 5:
104 return ""
105
106 if attrs not in self:
107 return ""
108
109 value = dict.__getitem__(self, attrs)
110 if value == None:
111 value = ""
112 return value
113
114 def expand(self):
115 summary = {}
116 toolchains = []
117 targets = []
118 archs = []
119 toolcodes = []
120 for key in self:
121 value = self[key]
122 if key[0] == '*':
123 toolchains = self.Toolchains
124 else:
125 toolchains = [key[0]]
126
127 for toolchain in toolchains:
128 if key[1] == '*':
129 targets = self.Targets
130 else:
131 targets = [key[1]]
132
133 for target in targets:
134 if key[2] == '*':
135 archs = self.Archs
136 else:
137 archs = [key[2]]
138
139 for arch in archs:
140 if key[3] == '*':
141 toolcodes = self.ToolCodes
142 else:
143 toolcodes = [key[3]]
144
145 for toolcode in toolcodes:
146 attribute = key[4]
147 summary[(toolchain, target, arch, toolcode, attribute)] = value
148 self.clear()
149 for toolchain in self.Toolchains:
150 for target in self.Targets:
151 for arch in self.Archs:
152 for toolcode in self.ToolCodes:
153 key = (toolchain, target, arch, toolcode, "NAME")
154 if key not in summary: continue
155 for attr in self.Attributes:
156 key = (toolchain, target, arch, toolcode, attr)
157 if key not in summary: continue
158 self[key] = summary[key]
159
160
161 def __str__(self):
162 s = ""
163 for entry in self:
164 s += entry[0] + "_" + entry[1] + "_" + entry[2] + "_" + entry[3] + "_" + entry[4]
165 s += " = " + self[entry] + "\n"
166 return s
167
168 class TargetConfig(Config):
169 pass
170
171 ## for test
172 if __name__ == "__main__":
173 import os
174 if "WORKSPACE" not in os.environ:
175 raise "No WORKSPACE given"
176 cfg = ToolConfig(os.path.join(os.environ["WORKSPACE"], "Tools", "Conf", "tools_def.txt"))
177 tgt = TargetConfig(os.path.join(os.environ["WORKSPACE"], "Tools", "Conf", "target.txt"))
178
179 for key in cfg:
180 print key,"=",cfg[key]
181
182 print
183 for name in tgt:
184 print name,"=",tgt[name]
185