- Remove the TOOL without NAME defined and its definition in ARCH_build.opt
[mirror_edk2.git] / Tools / Python / buildgen / SurfaceAreaElement.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 """Framework SurfaceArea Elemments"""
13 #
14 # TODO: FFS layout, Flash, FV, PCD
15 #
16 import os, sys, re, getopt, string, glob, xml.dom.minidom, pprint, time, copy, shelve, pickle
17 from XmlRoutines import *
18 import FrameworkElement
19 import BuildConfig
20
21 ################################################################################
22 ##
23 ## Convert given list to a string in the format like: [a, b, c]
24 ##
25 ################################################################################
26 def ListString(lst):
27 return "[%s]" % ",".join(lst)
28
29 class SurfaceAreaElement:
30 """Base class for Surface Area XML element"""
31 _ModuleTypes = ('BASE', 'SEC', 'PEI_CORE', 'PEIM', 'DXE_CORE', 'DXE_DRIVER',
32 'DXE_RUNTIME_DRIVER', 'DXE_SAL_DRIVER', 'DXE_SMM_DRIVER',
33 'TOOL', 'UEFI_DRIVER', 'UEFI_APPLICATION', 'USER_DEFINED')
34 _GuidTypes = ('DATA_HUB_RECORD', 'EFI_EVENT', 'EFI_SYSTEM_CONFIGURATION_TABLE',
35 'EFI_VARIABLE', 'GUID', 'HII_PACKAGE_LIST', 'HOB', 'TOKEN_SPACE_GUID')
36 _Archs = ('EBC', 'IA32', 'X64', 'IPF', 'ARM', 'PPC')
37 _Usages = ('ALWAYS_CONSUMED', 'SOMETIMES_CONSUMED', 'ALWAYS_PRODUCED',
38 'SOMETIMES_PRODUCED', 'TO_START', 'BY_START', 'PRIVATE')
39 _FileTypes = {
40 ".c" : "CCode",
41 ".C" : "CCode",
42 ".cpp" : "CCode",
43 ".Cpp" : "CCode",
44 ".CPP" : "CCode",
45 ".h" : "CHeader",
46 ".H" : "CHeader",
47 ".asm" : "ASM",
48 ".Asm" : "Assembly",
49 ".ASM" : "Assembly",
50 ".s" : "IpfAssembly",
51 ".S" : "GccAssembly",
52 ".uni" : "UNI",
53 ".Uni" : "Unicode",
54 ".UNI" : "Unicode",
55 ".vfr" : "VFR",
56 ".Vfr" : "VFR",
57 ".VFR" : "VFR",
58 ".dxs" : "DPX",
59 ".Dxs" : "DPX",
60 ".DXS" : "DPX",
61 ".fv" : "FirmwareVolume",
62 ".Fv" : "FirmwareVolume",
63 ".FV" : "FirmwareVolume",
64 ".efi" : "EFI",
65 ".Efi" : "EFI",
66 ".EFI" : "EFI",
67 ".SEC" : "FFS",
68 ".PEI" : "FFS",
69 ".DXE" : "FFS",
70 ".APP" : "FFS",
71 ".FYI" : "FFS",
72 ".FFS" : "FFS",
73 ".bmp" : "BMP",
74 ".i" : "PPCode",
75 ".asl" : "ASL",
76 ".Asl" : "ASL",
77 ".ASL" : "ASL",
78 }
79 _ToolMapping = {
80 "CCode" : "CC",
81 "CHeader" : "",
82 "ASM" : "ASM",
83 "Assembly" : "ASM",
84 "IpfAssembly" : "ASM",
85 "GccAssembly" : "ASM",
86 "UNI" : "",
87 "Unicode" : "",
88 "VFR" : "",
89 "DPX" : "",
90 "FirmwareVolume" : "",
91 "EFI" : "",
92 "FFS" : "",
93 "PPCode" : "PP",
94 "BMP" : "",
95 }
96
97 _BuildableFileTypes = ("CCode", "ASM", "Assembly", "IpfAssembly", "GccAssembly", "UNI", "Unicode", "VFR", "DPX", "EFI")
98
99 def __init__(self, workspace, owner=None, dom=None, parse=True, postprocess=True):
100 self._Workspace = workspace
101
102 if owner == None: self._Owner = ""
103 else: self._Owner = owner
104
105 if dom == None: self._Root = ""
106 else: self._Root = dom
107
108 self._Elements = {}
109
110 if parse: self.Parse()
111 if postprocess: self.Postprocess()
112
113 def Parse(self):
114 """Parse the XML element in DOM form"""
115 pass
116
117 def Postprocess(self):
118 """Re-organize the original information form XML DOM into a format which can be used directly"""
119 pass
120
121 def GetArchList(self, dom):
122 """Parse the SupArchList attribute. If not spcified, return all ARCH supported"""
123 archs = XmlAttribute(dom, "SupArchList").split()
124 if archs == []:
125 if self._Owner.Archs != []:
126 archs = self._Owner.Archs
127 elif self._Workspace.ActiveArchs != []:
128 archs = self._Workspace.ActiveArchs
129 elif self._Workspace.ActivePlatform != "" and self._Workspace.ActivePlatform.Archs != []:
130 archs = self._Workspace.ActivePlatform.Archs
131 else:
132 archs = self._Archs
133 return archs
134
135 def GetModuleTypeList(self, dom):
136 """Parse the SupModuleList attribute. If not specified, return all supported module types"""
137 moduleTypes = XmlAttribute(dom, "SupModuleList").split()
138 if moduleTypes == []:
139 moduleTypes = self._ModuleTypes
140 return moduleTypes
141
142 def GetGuidTypeList(self, dom):
143 """Parse GuidTypeList attribute. Default to GUID if not specified"""
144 guidTypes = XmlAttribute(dom, "GuidTypeList")
145 if guidTypes == []:
146 guidTypes = ["GUID"]
147 return guidTypes
148
149 def GetFeatureList(self, dom):
150 """Parse FeatureFlag attribute"""
151 return XmlAttribute(dom, "FeatureFlag").split()
152
153 def GetToolchainTagList(self, dom):
154 """Parse TagName attribute. Return all defined toolchains defined in tools_def.txt if not given"""
155 toolchainTagString = XmlAttribute(dom, "TagName")
156 if toolchainTagString == "":
157 return self._Workspace.ToolConfig.Toolchains
158 return toolchainTagString.split()
159
160 def GetToolchainFamilyList(self, dom):
161 """Parse ToolChainFamily attribute. Return all defined toolchain families in tools_def.txt if not given"""
162 familyString = XmlAttribute(dom, "ToolChainFamily")
163 if familyString != "":
164 return familyString.split()
165 return self._Workspace.ToolConfig.Families
166
167 def GetTargetList(self, dom):
168 """Parse BuildTargets attribute. Return all build targets defined in tools_def.txt if not given"""
169 targetList = XmlAttribute(dom, "BuildTargets").split()
170 if targetList == []:
171 targetList = self._Workspace.ToolConfig.Targets
172 return targetList
173
174 def GetUsage(self, dom):
175 """Parse Usage attribute. Default to ALWAYS_CONSUMED if not given"""
176 usageString = XmlAttribute(dom, "Usage")
177 if usageString == "":
178 return "ALWAYS_CONSUMED"
179 return usageString
180
181 def GetBuildOptionList(self, dom):
182 """Parse Options/Option element. Return a options dictionay with keys as (toolchain, target, arch, toolcode, attr)"""
183 optionList = XmlList(dom, "/Options/Option")
184 buildOptions = {}
185 for option in optionList:
186 targets = self.GetTargetList(option)
187 toolchainFamilies = self.GetToolchainFamilyList(option)
188 toolchainTags = self.GetToolchainTagList(option)
189 toolcode = XmlAttribute(option, "ToolCode")
190 archs = self.GetArchList(option)
191 flag = XmlElementData(option)
192 # print flag
193
194 toolchains = []
195 if toolchainTags != []:
196 toolchains = toolchainTags
197 elif toolchainFamilies != []:
198 toolchains = toolchainFamilies
199 else:
200 raise Exception("No toolchain specified for a build option: " + self._Owner.Name)
201
202 if targets == []: targets = self._Workspace.ActiveTargets
203 if archs == []: archs = self._Workspace.ActiveArchs
204
205 for toolchain in toolchains:
206 for target in targets:
207 for arch in archs:
208 buildOptions[(toolchain, target, arch, toolcode, "FLAGS")] = flag
209 return buildOptions
210
211 def GetFvBindingList(self, dom):
212 """Parse FvBinding element. If not specified, return NULL FV"""
213 fvBindingList = XmlElementData(dom).split()
214 if fvBindingList == []:
215 fvBindingList = ["NULL"]
216 return fvBindingList
217
218 def IsBuildable(self, type):
219 """Test if a file with the type can be built by a tool"""
220 return type in self._BuildableFileTypes
221
222 def GetToolCode(self, type):
223 """Get the toolcode which must be used to build files with the type"""
224 toolcode = ""
225 if type in self._ToolMapping:
226 toolcode = self._ToolMapping[type]
227 return toolcode
228
229 def GetBoolean(self, dom):
230 """Transate true/false in string form to python's True/False value"""
231 boolString = XmlElementData(dom).upper()
232 if boolString == "" or boolString == "FALSE" or boolString == "NO":
233 return False
234 else:
235 return True
236
237 class LibraryDeclaration(FrameworkElement.LibraryInterface, SurfaceAreaElement):
238 def __init__(self, workspace, package, dom):
239 FrameworkElement.LibraryInterface.__init__(self)
240 self.Package = package
241 SurfaceAreaElement.__init__(self, workspace, package, dom)
242
243 def Parse(self):
244 dom = self._Root
245 self.Name = XmlAttribute(dom, "Name")
246 self.Path = os.path.normpath(XmlElementData(XmlNode(dom, "/LibraryClass/IncludeHeader")))
247 self.Dir = os.path.dirname(self.Path)
248
249 attribute = XmlAttribute(dom, "RecommendedInstanceGuid")
250 if attribute is not '':
251 self.FavoriteIntance = FrameworkElement.Module()
252 self.FavoriteIntance.Guid = attribute
253
254 attribute = XmlAttribute(dom, "RecommendedInstanceVersion")
255 if attribute is not '':
256 if self.FavoriteIntance == "":
257 raise "No GUID for the recommened library instance"
258 self.FavoriteIntance.Version = attribute
259
260 self.Archs = self.GetArchList(dom)
261 self.ModuleTypes = self.GetModuleTypeList(dom)
262
263 class LibraryClass(FrameworkElement.LibraryClass, SurfaceAreaElement):
264 def __init__(self, workspace, module, dom):
265 FrameworkElement.LibraryClass.__init__(self)
266 SurfaceAreaElement.__init__(self, workspace, module, dom)
267
268 def Parse(self):
269 dom = self._Root
270
271 self.Name = XmlElementData(XmlNode(dom, "/LibraryClass/Keyword"))
272 self.Usage = self.GetUsage(dom)
273 self.Features = self.GetFeatureList(dom)
274 self.Archs = self.GetArchList(dom)
275
276 attribute = XmlAttribute(dom, "RecommendedInstanceGuid")
277 if attribute is not '':
278 self.FavoriteIntance = FrameworkElement.Module()
279 self.FavoriteIntance.Guid = attribute
280
281 attribute = XmlAttribute(dom, "RecommendedInstanceVersion")
282 if attribute is not '':
283 if self.FavoriteIntance == "":
284 self.FavoriteIntance = FrameworkElement.Module()
285 self.FavoriteIntance.Version = attribute
286
287 class SourceFile(FrameworkElement.SourceFile, SurfaceAreaElement):
288 def __init__(self, workspace, module, dom):
289 FrameworkElement.SourceFile.__init__(self)
290 SurfaceAreaElement.__init__(self, workspace, module, dom)
291
292 def Parse(self):
293 dom = self._Root
294 self.Path = os.path.normpath(XmlElementData(dom))
295 self.Dir = os.path.dirname(self.Path)
296 self.Type = self.GetFileType()
297 self.Toolchains = self.GetToolchainTagList(dom)
298 self.Families = self.GetToolchainFamilyList(dom)
299 self.Archs = self.GetArchList(dom)
300 self.Features = self.GetFeatureList(dom)
301
302 def GetFileType(self):
303 type = XmlAttribute(self._Root, "ToolCode")
304 if type == "":
305 fileName = os.path.basename(self.Path)
306 self.BaseName,self.Ext = os.path.splitext(fileName)
307 if self.Ext in self._FileTypes:
308 type = self._FileTypes[self.Ext]
309 else:
310 type = ""
311 return type
312
313 class PackageDependency(FrameworkElement.PackageDependency, SurfaceAreaElement):
314 def __init__(self, workspace, module, dom):
315 FrameworkElement.PackageDependency.__init__(self)
316 SurfaceAreaElement.__init__(self, workspace, module, dom)
317
318 def Parse(self):
319 dom = self._Root
320 self.GuidValue = XmlAttribute(dom, "PackageGuid").upper()
321 self.Version = XmlAttribute(dom, "PackageVersion")
322 self.Archs = self.GetArchList(dom)
323 self.Features = self.GetFeatureList(dom)
324
325 def Postprocess(self):
326 self.Package = self._Workspace.GetPackage(self.GuidValue, self.Version)
327 if self.Package == "": raise "No package with GUID=" + self.GuidValue + "VERSION=" + self.Version
328
329 class Protocol(FrameworkElement.Protocol, SurfaceAreaElement):
330 def __init__(self, workspace, module, dom):
331 FrameworkElement.Protocol.__init__(self)
332 SurfaceAreaElement.__init__(self, workspace, module, dom)
333
334 def Parse(self):
335 dom = self._Root
336 self.CName = XmlElementData(XmlNode(dom, "/Protocol/ProtocolCName"))
337 self.Usage = self.GetUsage(dom)
338 self.Archs = self.GetArchList(dom)
339 self.Features = self.GetFeatureList(dom)
340
341 def Postprocess(self):
342 for pd in self._Owner._Elements["PackageDependencies"]:
343 if self.CName not in pd.Package.Protocols: continue
344 self.GuidValue = pd.Package.Protocols[self.CName]
345
346 class ProtocolNotify(FrameworkElement.ProtocolNotify, SurfaceAreaElement):
347 def __init__(self, workspace, module, dom):
348 FrameworkElement.ProtocolNotify.__init__(self)
349 SurfaceAreaElement.__init__(self, workspace, module, dom)
350
351 def Parse(self):
352 dom = self._Root
353
354 self.CName = XmlElementData(XmlNode(dom, "/ProtocolNotify/ProtocolCName"))
355 self.Usage = self.GetUsage(dom)
356 self.Archs = self.GetArchList(dom)
357 self.Features = self.GetFeatureList(dom)
358
359 def Postprocess(self):
360 for pd in self._Owner._Elements["PackageDependencies"]:
361 if self.CName not in pd.Package.Protocols: continue
362 self.GuidValue = pd.Package.Protocols[self.CName]
363
364 class Ppi(FrameworkElement.Ppi, SurfaceAreaElement):
365 def __init__(self, workspace, module, dom):
366 FrameworkElement.Ppi.__init__(self)
367 SurfaceAreaElement.__init__(self, workspace, module, dom)
368
369 def Parse(self):
370 dom = self._Root
371 self.CName = XmlElementData(XmlNode(dom, "/Ppi/PpiCName"))
372 self.Usage = self.GetUsage(dom)
373 self.Archs = self.GetArchList(dom)
374 self.Features = self.GetFeatureList(dom)
375
376 def Postprocess(self):
377 for pd in self._Owner._Elements["PackageDependencies"]:
378 if self.CName not in pd.Package.Ppis: continue
379 self.GuidValue = pd.Package.Ppis[self.CName]
380
381 class PpiNotify(FrameworkElement.PpiNotify, SurfaceAreaElement):
382 def __init__(self, workspace, module, dom):
383 FrameworkElement.PpiNotify.__init__(self)
384 SurfaceAreaElement.__init__(self, workspace, module, dom)
385
386 def Parse(self):
387 dom = self._Root
388 self.CName = XmlElementData(XmlNode(dom, "/PpiNotify/PpiCName"))
389 self.Usage = self.GetUsage(dom)
390 self.Archs = self.GetArchList(dom)
391 self.Features = self.GetFeatureList(dom)
392
393 def Postprocess(self):
394 for pd in self._Owner._Elements["PackageDependencies"]:
395 if self.CName not in pd.Package.Ppis: continue
396 self.GuidValue = pd.Package.Ppis[self.CName]
397
398 class Guid(FrameworkElement.Guid, SurfaceAreaElement):
399 def __init__(self, workspace, module, dom):
400 FrameworkElement.Guid.__init__(self)
401 SurfaceAreaElement.__init__(self, workspace, module, dom)
402
403 def Parse(self):
404 dom = self._Root
405 self.CName = XmlElementData(XmlNode(dom, "/GuidCNames/GuidCName"))
406 self.Usage = self.GetUsage(dom)
407 self.Archs = self.GetArchList(dom)
408 self.Features = self.GetFeatureList(dom)
409
410 def Postprocess(self):
411 for pd in self._Owner._Elements["PackageDependencies"]:
412 if self.CName not in pd.Package.Guids: continue
413 self.GuidValue = pd.Package.Guids[self.CName]
414
415 class Extern(FrameworkElement.Extern, SurfaceAreaElement):
416 def __init__(self, workspace, module, dom):
417 FrameworkElement.Extern.__init__(self)
418 SurfaceAreaElement.__init__(self, workspace, module, dom)
419
420 def Parse(self):
421 dom = self._Root
422 self.Archs = self.GetArchList(dom)
423 self.Features = self.GetFeatureList(dom)
424
425 extern = XmlNode(dom, "/Extern/ModuleEntryPoint")
426 if extern is not None and extern is not '':
427 self.ModuleEntryPoints.append(XmlElementData(extern))
428
429 extern = XmlNode(dom, "/Extern/ModuleUnloadImage")
430 if extern is not None and extern is not '':
431 self.ModuleUnloadImages.append(XmlElementData(extern))
432
433 extern = XmlNode(dom, "/Extern/Constructor")
434 if extern is not None and extern is not '':
435 self.Constructors.append(XmlElementData(extern))
436
437 extern = XmlNode(dom, "/Extern/Destructor")
438 if extern is not None and extern is not '':
439 self.Destructors.append(XmlElementData(extern))
440
441 extern = XmlNode(dom, "/Extern/DriverBinding")
442 if extern is not None and extern is not '':
443 self.DriverBindings.append(XmlElementData(extern))
444
445 extern = XmlNode(dom, "/Extern/ComponentName")
446 if extern is not None and extern is not '':
447 self.ComponentNames.append(XmlElementData(extern))
448
449 extern = XmlNode(dom, "/Extern/DriverConfig")
450 if extern is not None and extern is not '':
451 self.DriverConfigs.append(XmlElementData(extern))
452
453 extern = XmlNode(dom, "/Extern/DriverDiag")
454 if extern is not None and extern is not '':
455 self.DriverDiags.append(XmlElementData(extern))
456
457 extern = XmlNode(dom, "/Extern/SetVirtualAddressMapCallBacks")
458 if extern is not None and extern is not '':
459 self.SetVirtualAddressMapCallBacks.append(XmlElementData(extern))
460
461 extern = XmlNode(dom, "/Extern/ExitBootServicesCallBack")
462 if extern is not None and extern is not '':
463 self.ExitBootServicesCallBacks.append(XmlElementData(extern))
464
465 class IndustryStdHeader(FrameworkElement.IncludeFile, SurfaceAreaElement):
466 def __init__(self, workspace, package, dom):
467 FrameworkElement.IncludeFile.__init__(self)
468 SurfaceAreaElement.__init__(self, workspace, package, dom)
469
470 def Parse(self):
471 dom = self._Root
472 self.Path = os.path.normpath(XmlElementData(XmlNode(dom, "/IndustryStdHeader/IncludeHeader")))
473 self.Dir = os.path.dirname(self.Path)
474 self.Archs = self.GetArchList(dom)
475 self.ModuleTypes = self.GetModuleTypeList(dom)
476
477 class PackageHeader(FrameworkElement.IncludeFile, SurfaceAreaElement):
478 def __init__(self, workspace, package, dom):
479 FrameworkElement.IncludeFile.__init__(self)
480 SurfaceAreaElement.__init__(self, workspace, package, dom)
481
482 def Parse(self):
483 dom = self._Root
484 self.Path = os.path.normpath(XmlElementData(dom))
485 self.Dir = os.path.dirname(self.Path)
486 self.ModuleType = XmlAttribute(dom, "ModuleType")
487
488 class GuidDeclaration(FrameworkElement.Guid, SurfaceAreaElement):
489 def __init__(self, workspace, package, dom):
490 FrameworkElement.Guid.__init__(self)
491 SurfaceAreaElement.__init__(self, workspace, package, dom)
492
493 def Parse(self):
494 dom = self._Root
495 self.CName = XmlElementData(XmlNode(dom, "/Entry/C_Name"))
496 self.GuidValue = XmlElementData(XmlNode(dom, "/Entry/GuidValue")).upper()
497 self.Name = XmlAttribute(dom, "Name")
498 self.Types = self.GetGuidTypeList(dom)
499 self.Archs = self.GetArchList(dom)
500 self.ModuleTypes = self.GetModuleTypeList(dom)
501
502 def Postprocess(self):
503 pass
504
505 class ProtocolDeclaration(GuidDeclaration, SurfaceAreaElement):
506 pass
507
508 class PpiDeclaration(GuidDeclaration, SurfaceAreaElement):
509 pass
510
511 class PcdDeclaration(FrameworkElement.Pcd, SurfaceAreaElement):
512 def __init__(self, workspace, package, dom):
513 FrameworkElement.Pcd.__init__(self)
514 SurfaceAreaElement.__init__(self, workspace, package, dom)
515
516 def Parse(self):
517 dom = self._Root
518 self.Types = XmlElementData(XmlNode(dom, "/PcdEntry/ValidUsage")).split()
519 self.CName = XmlElementData(XmlNode(dom, "/PcdEntry/C_Name"))
520 self.Token = XmlElementData(XmlNode(dom, "/PcdEntry/Token"))
521 self.TokenSpace = XmlElementData(XmlNode(dom, "/PcdEntry/TokenSpaceGuidCName"))
522 self.DatumType = XmlElementData(XmlNode(dom, "/PcdEntry/DatumType"))
523 self.Default = XmlElementData(XmlNode(dom, "/PcdEntry/DefaultValue"))
524 self.Archs = self.GetArchList(dom)
525 self.ModuleTypes= self.GetModuleTypeList(dom)
526
527 class LibraryInstance(FrameworkElement.PlatformModule, SurfaceAreaElement):
528 def __init__(self, workspace, platformModule, dom):
529 FrameworkElement.PlatformModule.__init__(self)
530 SurfaceAreaElement.__init__(self, workspace, platformModule, dom)
531
532 def Parse(self):
533 dom = self._Root
534 self.GuidValue = XmlAttribute(dom, "ModuleGuid").upper()
535 self.Version = XmlAttribute(dom, "ModuleVersion")
536 self._Elements["PackageGuid"] = XmlAttribute(dom, "PackageGuid").upper()
537 self._Elements["PackageVersion"] = XmlAttribute(dom, "PackageVersion")
538
539 def Postprocess(self):
540 self.Module = self._Workspace.GetModule(self.GuidValue, self.Version,
541 self._Elements["PackageGuid"], self._Elements["PackageVersion"])
542 self.Platform = self._Owner.Platform
543 self.Archs = self._Owner.Archs
544 self.Pcds = self._Owner.Pcds
545 self.BuildType = "lib"
546
547 class PlatformModule(FrameworkElement.PlatformModule, SurfaceAreaElement):
548 def __init__(self, workspace, platform, dom):
549 FrameworkElement.PlatformModule.__init__(self)
550 self.Platform = platform
551 SurfaceAreaElement.__init__(self, workspace, platform, dom)
552
553 def Parse(self):
554 dom = self._Root
555 self.GuidValue = XmlAttribute(dom, "ModuleGuid").upper()
556 self.Version = XmlAttribute(dom, "ModuleVersion")
557 self.Archs = self.GetArchList(dom)
558
559 self._Elements["PackageGuid"] = XmlAttribute(dom, "PackageGuid").upper()
560 self._Elements["PackageVersion"] = XmlAttribute(dom, "PackageVersion")
561
562 libraryList = XmlList(dom, "/ModuleSA/Libraries/Instance")
563 for lib in libraryList:
564 self.Libraries.append(LibraryInstance(self._Workspace, self, lib))
565
566 dom = XmlNode(dom, "/ModuleSA/ModuleSaBuildOptions")
567 self.FvBindings = self.GetFvBindingList(XmlNode(dom, "/ModuleSaBuildOptions/FvBinding"))
568 self.FfsLayouts = XmlElementData(XmlNode(dom, "/ModuleSaBuildOptions/FfsFormatKey")).split()
569 self.BuildOptions = self.GetBuildOptionList(XmlNode(dom, "/ModuleSaBuildOptions/Options"))
570
571 def Postprocess(self):
572 self.Module = self._Workspace.GetModule(self.GuidValue, self.Version,
573 self._Elements["PackageGuid"], self._Elements["PackageVersion"])
574 if self.Module == "":
575 raise Exception("No module found: \n\t\tGUID=%s \n\t\tVERSION=%s \n\t\tPACKAGE_GUID=%s \n\t\tPACKAGE_VERSION=%s" % (
576 self.GuidValue, self.Version, self._Elements["PackageGuid"], self._Elements["PackageVersion"]))
577
578 ## def SetupEnvironment(self):
579 ## self.Environment = {
580 ## "ARCH" : "",
581 ## "MODULE_BUILD_TARGET" : "",
582 ## "SINGLE_MODULE_BUILD" : "",
583 ## "PLATFORM_PREBUILD" : "",
584 ## "PLATFORM_POSTBUILD" : "",
585 ## "LIBS" : "",
586 ## "SOURCE_FILES" : "",
587 ## "ENTRYPOINT" : "_ModuleEntryPoint",
588 ## } # name/value pairs
589 ## self.Environment["MODULE_BUILD_TARGET"] = "platform_module_build"
590
591 class ModuleSurfaceArea(FrameworkElement.Module, SurfaceAreaElement):
592 def __init__(self, workspace, package, path):
593 FrameworkElement.Module.__init__(self)
594
595 self.Path = os.path.normpath(path)
596 self.Dir = os.path.dirname(self.Path)
597 self.FileBaseName,_ext = os.path.splitext(os.path.basename(self.Path))
598 self.Package = package
599 SurfaceAreaElement.__init__(self, workspace, package)
600
601 def _MsaHeader(self, xpath):
602 dom = XmlNode(self._Root, xpath)
603 if dom == '': return
604 self.Name = XmlElementData(XmlNode(dom, "/MsaHeader/ModuleName"))
605 self.Type = XmlElementData(XmlNode(dom, "/MsaHeader/ModuleType"))
606 self.GuidValue = XmlElementData(XmlNode(dom, "/MsaHeader/GuidValue")).upper()
607 self.Version = XmlElementData(XmlNode(dom, "/MsaHeader/Version"))
608
609 def _ModuleDefinitions(self, xpath):
610 dom = XmlNode(self._Root, xpath)
611 if dom == '': return
612 self.Archs = XmlElementData(XmlNode(dom, "/ModuleDefinitions/SupportedArchitectures")).split()
613 self.IsBinary = self.GetBoolean(XmlNode(dom, "/ModuleDefinitions/BinaryModule"))
614 self.BaseName = XmlElementData(XmlNode(dom, "/ModuleDefinitions/OutputFileBasename"))
615
616 def _LibraryClassDefinitions(self, xpath):
617 dom = XmlNode(self._Root, xpath)
618 if dom == '': return
619 lcList = []
620 for lc in XmlList(dom, "/LibraryClassDefinitions/LibraryClass"):
621 lcList.append(LibraryClass(self._Workspace, self, lc))
622 self._Elements["LibraryClassDefinitions"] = lcList
623
624 def _SourceFiles(self, xpath):
625 dom = XmlNode(self._Root, xpath)
626 if dom == '': return
627 srcList = []
628 for f in XmlList(dom, "/SourceFiles/Filename"):
629 srcList.append(SourceFile(self._Workspace, self, f))
630 self._Elements["SourceFiles"] = srcList
631
632 def _NonProcessedFiles(self, xpath):
633 dom = XmlNode(self._Root, xpath)
634 if dom == '': return
635 for f in XmlList(dom, "/NonProcessedFiles/Filename"):
636 self.NonProcessedFiles.append(SourceFile(self._Workspace, self, f))
637
638 def _PackageDependencies(self, xpath):
639 dom = XmlNode(self._Root, xpath)
640 if dom == '': return
641 pdList = []
642 for pkg in XmlList(dom, "/PackageDependencies/Package"):
643 pdList.append(PackageDependency(self._Workspace, self, pkg))
644 self._Elements["PackageDependencies"] = pdList
645
646 def _Protocols(self, xpath):
647 dom = XmlNode(self._Root, xpath)
648 if dom == '': return
649
650 protocolList = []
651 for p in XmlList(dom, "/Protocols/Protocol"):
652 protocolList.append(Protocol(self._Workspace, self, p))
653 for p in XmlList(dom, "/Protocols/ProtocolNotify"):
654 protocolList.append(ProtocolNotify(self._Workspace, self, p))
655
656 self._Elements["Protocols"] = protocolList
657
658 def _Ppis(self, xpath):
659 dom = XmlNode(self._Root, xpath)
660 if dom == '': return
661
662 ppiList = []
663 for p in XmlList(dom, "/PPIs/Ppi"):
664 ppiList.append(Ppi(self._Workspace, self, p))
665 for p in XmlList(dom, "/PPIs/PpiNotify"):
666 ppiList.append(PpiNotify(self._Workspace, self, p))
667
668 self._Elements["PPIs"] = ppiList
669
670 def _Guids(self, xpath):
671 dom = XmlNode(self._Root, xpath)
672 if dom == '': return
673 guidList = []
674 for g in XmlList(dom, "/Guids/GuidCNames"):
675 guidList.append(Guid(self._Workspace, self, g))
676 self._Elements["Guids"] = guidList
677
678 def _Externs(self, xpath):
679 dom = XmlNode(self._Root, xpath)
680 if dom == '': return
681 self.PcdIsDriver = self.GetBoolean(XmlNode(dom, "/Externs/PcdIsDriver"))
682 self.NeedsFlashMap_h = self.GetBoolean(XmlNode(dom, "/Externs/TianoR8FlashMap_h"))
683
684 externList = []
685 specs = FrameworkElement.Extern()
686 specs.Archs = self._Archs
687 externList.append(specs)
688 for spec in XmlList(dom, "/Externs/Specification"):
689 specs.Specifications.append(XmlElementData(spec))
690 for ext in XmlList(dom, "/Externs/Extern"):
691 externList.append(Extern(self._Workspace, self, ext))
692 self._Elements["Externs"] = externList
693
694 def _ModuleBuildOptions(self, xpath):
695 dom = XmlNode(self._Root, xpath)
696 if dom == '': return
697 self.BuildOptions = self.GetBuildOptionList(XmlNode(dom, "/ModuleBuildOptions/Options"))
698
699 def _UserExtensions(self, xpath):
700 domList = XmlList(self._Root, xpath)
701 if domList == []: return
702 for extension in domList:
703 userId = XmlAttribute(extension, "UserID")
704 identifier = XmlAttribute(extension, "Identifier")
705 if userId == '' or identifier == '':
706 raise Exception("No UserId or Identifier specified")
707 if userId != "TianoCore": continue
708 if identifier not in self.UserExtensions:
709 self.UserExtensions[identifier] = []
710
711 contentList = self.UserExtensions[identifier]
712 for node in extension.childNodes:
713 #print node.nodeType
714 contentList.append(node.cloneNode(True))
715
716 def Parse(self):
717 fileFullPath = self._Workspace.SubPath(os.path.dirname(self.Package.Path), self.Path)
718 self._Root = xml.dom.minidom.parse(fileFullPath)
719 assert self._Root.documentElement.tagName == "ModuleSurfaceArea"
720
721 # print " Parsing...",self.Path
722 self._MsaHeader("/ModuleSurfaceArea/MsaHeader")
723 self._ModuleDefinitions("/ModuleSurfaceArea/ModuleDefinitions")
724 self._PackageDependencies("/ModuleSurfaceArea/PackageDependencies")
725 self._LibraryClassDefinitions("/ModuleSurfaceArea/LibraryClassDefinitions")
726 self._SourceFiles("/ModuleSurfaceArea/SourceFiles")
727 self._NonProcessedFiles("/ModuleSurfaceArea/NonProcessedFiles")
728 self._Protocols("/ModuleSurfaceArea/Protocols")
729 self._Ppis("/ModuleSurfaceArea/Ppis")
730 self._Guids("/ModuleSurfaceArea/Guids")
731 self._Externs("/ModuleSurfaceArea/Externs")
732 self._ModuleBuildOptions("/ModuleSurfaceArea/ModuleBuildOptions")
733 self._UserExtensions("/ModuleSurfaceArea/UserExtensions")
734
735 def Postprocess(self):
736 # resolve package dependency
737 if self._Elements.has_key("PackageDependencies"):
738 for pd in self._Elements["PackageDependencies"]:
739 package = pd.Package
740 if self.Type not in package.PackageIncludes:
741 print "! Module type %s is not supported in the package %s" % (self.Type, package.Name)
742
743 for arch in pd.Archs:
744 if arch not in self.IncludePaths:
745 self.IncludePaths[arch] = []
746 self.IncludePaths[arch].append(package.SubPath("Include"))
747 self.IncludePaths[arch].append(package.SubPath("Include", arch.capitalize()))
748
749 if arch not in self.IncludeFiles:
750 self.IncludeFiles[arch] = []
751 if self.Type in package.PackageIncludes:
752 for path in package.PackageIncludes[self.Type]:
753 self.IncludeFiles[arch].append(package.SubPath(path))
754
755 # resolve library class
756 if self._Elements.has_key("LibraryClassDefinitions"):
757 for lc in self._Elements["LibraryClassDefinitions"]:
758 lc.Interface = self.GetLibraryInterface(lc.Name)
759 if "ALWAYS_PRODUCED" in lc.Usage:
760 self.IsLibrary = True
761 lc.Interface.Instances.append(self)
762 else:
763 lc.Interface.Consumers.append(self)
764
765 for arch in lc.Archs:
766 if arch not in self.LibraryClasses:
767 self.LibraryClasses[arch] = []
768 self.LibraryClasses[arch].append(lc)
769
770 # expand source files
771 if self._Elements.has_key("SourceFiles"):
772 for src in self._Elements["SourceFiles"]:
773 for arch in src.Archs:
774 if arch not in self.SourceFiles:
775 self.SourceFiles[arch] = {}
776 if src.Type not in self.SourceFiles[arch]:
777 self.SourceFiles[arch][src.Type] = []
778 self.SourceFiles[arch][src.Type].append(src)
779
780 # expand guids
781 if self._Elements.has_key("Guids"):
782 for guid in self._Elements["Guids"]:
783 for arch in guid.Archs:
784 if arch not in self.Guids:
785 self.Guids[arch] = []
786 self.Guids[arch].append(guid)
787
788 # expand protocol
789 if self._Elements.has_key("Protocols"):
790 for protocol in self._Elements["Protocols"]:
791 for arch in protocol.Archs:
792 if arch not in self.Protocols:
793 self.Protocols[arch] = []
794 self.Protocols[arch].append(protocol)
795
796 # expand ppi
797 if self._Elements.has_key("PPIs"):
798 for ppi in self._Elements["PPIs"]:
799 for arch in ppi.Archs:
800 if arch not in self.Ppis:
801 self.Ppis[arch] = []
802 self.Ppis[arch].append(ppi)
803
804 # expand extern
805 if self._Elements.has_key("Externs"):
806 for extern in self._Elements["Externs"]:
807 for arch in extern.Archs:
808 if arch not in self.Externs:
809 self.Externs[arch] = []
810 self.Externs[arch].append(extern)
811
812 def GetLibraryInterface(self, name):
813 if name in self.Package.LibraryInterfaces:
814 return self.Package.LibraryInterfaces[name]
815 for pd in self._Elements["PackageDependencies"]:
816 if name in pd.Package.LibraryInterfaces:
817 return pd.Package.LibraryInterfaces[name]
818 return ""
819 ## def SetupEnvironment(self):
820 ## self.Environment["MODULE"] = self.Name
821 ## self.Environment["MODULE_GUID"] = self.GuidValue
822 ## self.Environment["MODULE_VERSION"] = self.Version
823 ## self.Environment["MODULE_TYPE"] = self.Type
824 ## self.Environment["MODULE_FILE_BASE_NAME"] = os.path.basename(self.Path).split(".")[0]
825 ## self.Environment["MODULE_RELATIVE_DIR"] = os.path.dirname(self.Path)
826 ## self.Environment["BASE_NAME"] = self.OutputName
827
828 class Workspace(FrameworkElement.Workspace, SurfaceAreaElement):
829 _Db = "Tools/Conf/FrameworkDatabase.db"
830 _Target = "Tools/Conf/Target.txt"
831 _PlatformBuildPath = "Tools/Conf/platform_build_path.txt"
832 _ModuleBuildPath = "Tools/Conf/module_build_path.txt"
833
834 def __init__(self, path, fpdList=None, msaList=None):
835 FrameworkElement.Workspace.__init__(self)
836 SurfaceAreaElement.__init__(self, self, None, None, False, False)
837 self.Path = os.path.normpath(path)
838 self.Dir = os.path.dirname(self.Path)
839 self._Elements["PlatformList"] = fpdList
840 self._Elements["ModuleList"] = msaList
841 self.Parse()
842 self.Postprocess()
843
844 def _FdbHeader(self, xpath):
845 dom = XmlNode(self._Root, xpath)
846 if dom == '': return
847 self.Name = XmlElementData(XmlNode(dom, "/FdbHeader/DatabaseName"))
848 self.GuidValue = XmlElementData(XmlNode(dom, "/FdbHeader/GuidValue")).upper()
849 self.Version = XmlElementData(XmlNode(dom, "/FdbHeader/Version"))
850
851 def _PackageList(self, xpath):
852 dom = XmlNode(self._Root, xpath)
853 if dom == '': return
854
855 fileList = XmlList(dom, "/PackageList/Filename")
856 packages = []
857 for f in fileList:
858 packages.append(os.path.normpath(XmlElementData(f)))
859 self._Elements["PackageList"] = packages
860
861 def _PlatformList(self, xpath):
862 if len(self._Elements["PlatformList"]) > 0:
863 return
864
865 dom = XmlNode(self._Root, xpath)
866 if dom == '': return
867
868 fileList = XmlList(dom, "/PlatformList/Filename")
869 platforms = []
870 for f in fileList:
871 platforms.append(os.path.normpath(XmlElementData(f)))
872 self._Elements["PlatformList"] = platforms
873
874 def _FarList(self, xpath):
875 dom = XmlNode(self._Root, xpath)
876 if dom == '': return
877
878 fileList = XmlList(dom, "/FarList/Filename")
879 fars = []
880 for f in fileList:
881 fars.append(os.path.normpath(XmlElementData(f)))
882 self._Elements["FarList"] = fars
883
884 def ParseWorkspaceDatabase(self):
885 # parse frameworkdatabase.db
886 self._Root = xml.dom.minidom.parse(self.SubPath(self._Db))
887 assert self._Root.documentElement.tagName == "FrameworkDatabase"
888
889 self._FdbHeader("/FrameworkDatabase/FdbHeader")
890 self._PackageList("/FrameworkDatabase/PackageList")
891 self._PlatformList("/FrameworkDatabase/PlatformList")
892 self._FarList("/FrameworkDatabase/FarList")
893
894 def ParseConfig(self):
895 # parse target.txt
896 self.ParseTargetConfig()
897 # parse tools_def.txt
898 self.ParseToolConfig()
899 # parse platform/module_build_path.txt
900
901 # active toolchain
902 # print self.TargetConfig
903 self.ActiveToolchain = self.TargetConfig["TOOL_CHAIN_TAG"]
904 if self.ActiveToolchain not in self.ToolConfig.Toolchains:
905 raise "Not supported tool chain tag %s" % self.ActiveToolchain
906
907 # active toolchain family
908 self.ActiveFamilies = []
909 for key in self.ToolConfig:
910 if self.ActiveToolchain in key and "FAMILY" in key:
911 family = self.ToolConfig[key]
912 if family not in self.ActiveFamilies:
913 self.ActiveFamilies.append(family)
914
915
916 def ParsePackage(self, packagePaths=None):
917 if packagePaths == None:
918 return
919
920 for packagePath in packagePaths:
921 self.Packages.append(PackageSurfaceArea(self, packagePath))
922
923 def ParsePlatform(self, platformPaths=None):
924 # Only one active platform is allowed
925 activePlatformPath = ""
926 if self.TargetConfig["ACTIVE_PLATFORM"] == "":
927 if platformPaths != None and len(platformPaths) == 1:
928 activePlatformPath = platformPaths[0]
929 else:
930 raise Exception("No active platform specified or implied!")
931 else:
932 activePlatformPath = os.path.normpath(self.TargetConfig["ACTIVE_PLATFORM"])
933
934 self.ActivePlatform = PlatformSurfaceArea(self, activePlatformPath)
935 self.Platforms.append(self.ActivePlatform)
936
937 def ParseTargetConfig(self):
938 self.TargetConfig = BuildConfig.TargetConfig(self.SubPath(self._Target))
939 # print self.TargetConfig
940
941 def ParseToolConfig(self):
942 self.ToolConfig = BuildConfig.ToolConfig(self.SubPath(self.TargetConfig["TOOL_CHAIN_CONF"]))
943
944 def GetModule(self, guid, version, packageGuid, packageVersion):
945 moduleGuidIndex = self.ModuleXref["GUID"]
946 if guid not in moduleGuidIndex:
947 print "! No module has GUID=" + guid
948 return ""
949
950 moduleVersionList = moduleGuidIndex[guid]
951 # print moduleVersionList
952 moduleList = []
953 module = ""
954 if version != "":
955 if version in moduleVersionList:
956 moduleList = moduleVersionList[version]
957 else:
958 return ""
959 else:
960 ## no version given, return the first one
961 version = "0.0"
962 for ver in moduleVersionList:
963 if ver > version: version = ver
964 moduleList = moduleVersionList[version]
965
966 if packageGuid == "":
967 ## if no package GUID given, just return the latest one
968 version = "0.0"
969 for m in moduleList:
970 if m.Package.Version > version:
971 version = m.Package.Version
972 module = m
973 else:
974 version = "0.0"
975 for m in moduleList:
976 if m.Package.GuidValue != packageGuid: continue
977 if packageVersion == "":
978 ## if no version given, just return the latest
979 if m.Package.Version > version:
980 version = m.Package.Version
981 module = m
982 elif packageVersion == m.Package.Version:
983 module = m
984 break;
985
986 return module
987
988 def GetModuleByPath(self, path):
989 ownerPackage = ""
990 ownerPackageFullPath = ""
991 for package in self.Packages:
992 ownerPackageFullPath = self.SubPath(package.Path)
993 if path.startswith(packageFullPath): break
994
995 if ownerPackage == "":
996 return ""
997
998 for module in ownerPackage.Modules:
999 moduleFullPath = os.path.join(ownerPackageFullPath, module.Path)
1000 if moduleFullPath == path:
1001 return module
1002
1003 return ""
1004
1005 def GetPackage(self, guid, version):
1006 packageGuidIndex = self.PackageXref["GUID"]
1007 if guid not in packageGuidIndex:
1008 # raise Exception("No package has GUID=" + guid)
1009 return ""
1010
1011 packageList = packageGuidIndex[guid]
1012 package = ""
1013 if version != "":
1014 if version in packageList:
1015 package = packageList[version]
1016 else:
1017 ## no version given, return the latest one
1018 version = "0.0"
1019 for ver in packageList:
1020 if ver > version: version = ver
1021 package = packageList[version]
1022
1023 return package
1024
1025 def GetPlatform(self, guid, version):
1026 pass
1027
1028 def GetPlatformByPath(self, path):
1029 for platform in self.Platforms:
1030 platformFullPath = self.SubPath(platform.Path)
1031 if platformFullPath == path:
1032 return platform
1033 return ""
1034
1035 def GetLibraryInterface(self, name, package):
1036 if name not in self.LibraryInterfaceXref["NAME"]:
1037 return ""
1038 liList = self.LibraryInterfaceXref["NAME"][name]
1039 for li in liList:
1040 if li.Package == package:
1041 return li
1042 return ""
1043
1044 def SubPath(self, *relativePathList):
1045 return os.path.normpath(os.path.join(self.Path, *relativePathList))
1046
1047 def SetupCrossRef(self):
1048 ##
1049 ## setup platform cross reference as nest-dict
1050 ## guid -> {version -> platform}
1051 ##
1052 ## platformList = self.Platforms
1053 ## for p in platformList:
1054 ## guid = p.GuidValue
1055 ## version = p.Version
1056 ## if guid not in self.PlatformIndex:
1057 ## self.PlatformIndex[guid] = {}
1058 ## if version in self.PlatformIndex[guid]:
1059 ## raise Exception("Duplicate platform")
1060 ## self.PlatformIndex[guid][version] = p
1061
1062 ##
1063 ## setup package cross reference as nest-dict
1064 ## guid -> {version -> package}
1065 ## name -> [package list]
1066 ## path -> package
1067 ##
1068 packageList = self.Packages
1069 for p in packageList:
1070 guid = p.GuidValue
1071 version = p.Version
1072 packageGuidIndex = self.PackageXref["GUID"]
1073 if guid not in packageGuidIndex:
1074 packageGuidIndex[guid] = {}
1075 if version in packageGuidIndex[guid]:
1076 raise Exception("Duplicate package: %s-%s [%s]" % p.Name, version, guid)
1077 packageGuidIndex[guid][version] = p
1078
1079 packageNameIndex = self.PackageXref["NAME"]
1080 name = p.Name
1081 if name not in packageNameIndex:
1082 packageNameIndex[name] = []
1083 packageNameIndex[name].append(p)
1084
1085 packagePathIndex = self.PackageXref["PATH"]
1086 path = p.Path
1087 if path in packagePathIndex:
1088 raise Exception("Duplicate package: %s %s" % p.Name, p.Path)
1089 packagePathIndex[path] = p.Path
1090
1091 ##
1092 ## setup library class cross reference as
1093 ## library class name -> library class object
1094 ##
1095 for lcname in p.LibraryInterfaces:
1096 if lcname not in self.LibraryInterfaceXref["NAME"]:
1097 # raise Exception("Duplicate library class: %s in package %s" % (lcname, name))
1098 self.LibraryInterfaceXref["NAME"][lcname] = []
1099 lcInterface = p.LibraryInterfaces[lcname]
1100 self.LibraryInterfaceXref["NAME"][lcname].append(lcInterface)
1101
1102 lcHeader = p.SubPath(lcInterface.Path)
1103 if lcHeader not in self.LibraryInterfaceXref["PATH"]:
1104 # raise Exception("Duplicate library class interface: %s in package %s" % (lcInterface, name))
1105 self.LibraryInterfaceXref["PATH"][lcHeader] = []
1106 self.LibraryInterfaceXref["PATH"][lcHeader].append(lcInterface)
1107
1108 ##
1109 ## setup package cross reference as nest-dict
1110 ## guid -> {version -> [module list]}
1111 ## name -> [module list]
1112 ## path -> module
1113 for p in packageList:
1114 p.ParseMsaFile()
1115
1116 moduleList = p.Modules
1117 for m in moduleList:
1118 name = m.Name
1119 path = m.Path
1120 guid = m.GuidValue
1121 version = m.Version
1122 moduleGuidIndex = self.ModuleXref["GUID"]
1123 if guid not in moduleGuidIndex:
1124 moduleGuidIndex[guid] = {}
1125 else:
1126 print "! Duplicate module GUID found:", guid, p.SubPath(path)
1127 dm = moduleGuidIndex[guid].values()[0][0]
1128 print " ", dm.GuidValue,\
1129 dm.Package.SubPath(dm.Path)
1130
1131 if version not in moduleGuidIndex[guid]:
1132 moduleGuidIndex[guid][version] = []
1133 if m in moduleGuidIndex[guid][version]:
1134 raise Exception("Duplicate modules in the same package: %s-%s [%s]" % (name, version, guid))
1135 moduleGuidIndex[guid][version].append(m)
1136
1137 modulePathIndex = self.ModuleXref["PATH"]
1138 path = p.SubPath(m.Path)
1139 if path in modulePathIndex:
1140 raise Exception("Duplicate modules in the same package: %s %s" % (name, path))
1141 modulePathIndex[path] = m
1142
1143 moduleNameIndex = self.ModuleXref["NAME"]
1144 if name not in moduleNameIndex:
1145 moduleNameIndex[name] = []
1146 moduleNameIndex[name].append(m)
1147
1148 def GetToolDef(self, toolchain, target, arch, toolcode, attr):
1149 return self.ToolConfig[(toolchain, target, arch, toolcode, attr)]
1150
1151 def Parse(self):
1152 self.ParseConfig()
1153 self.ParseWorkspaceDatabase()
1154
1155 def SetupBuild(self):
1156 # active archs
1157 self.ActiveArchs = self.TargetConfig["TARGET_ARCH"].split()
1158 if self.ActiveArchs == []:
1159 self.ActiveArchs = self.ActivePlatform.Archs
1160
1161 # active targets
1162 self.ActiveTargets = self.TargetConfig["TARGET"].split()
1163 if self.ActiveTargets == []:
1164 self.ActiveTargets = self.ActivePlatform.Targets
1165
1166
1167 # active modules
1168 for msa in self._Elements["ModuleList"]:
1169 module = self.GetModuleByPath(msa)
1170 if module == "":
1171 raise Exception(msa + " is not in any package!")
1172 self.ActiveModules.append(module)
1173 self.IndividualModuleBuild = True
1174 if self.TargetConfig["MULTIPLE_THREAD"].upper() == "ENABLE":
1175 self.MultiThreadBuild = True
1176 if "MAX_CONCURRENT_THREAD_NUMBER" in self.TargetConfig:
1177 self.ThreadCount = self.TargetConfig["MAX_CONCURRENT_THREAD_NUMBER"]
1178 else:
1179 self.ThreadCount = "1"
1180
1181 def Postprocess(self):
1182 self.ParsePackage(self._Elements["PackageList"])
1183 self.SetupCrossRef()
1184 self.ParsePlatform(self._Elements["PlatformList"])
1185 self.SetupBuild()
1186
1187 ## def SetupEnvironment(self):
1188 ## config = BuildConfig.Config(self.SubPath(self._PlatformBuildPath))
1189 ## for name in config:
1190 ## self.Environment[name] = config[name]
1191 ##
1192 ## config = BuildConfig.Config(self.SubPath(self._ModuleBuildPath))
1193 ## for name in config:
1194 ## self.Environment[name] = config[name]
1195 ##
1196 ## multiThread = self.TargetConfig["MULTIPLE_THREAD"].upper()
1197 ## threadNumber = self.TargetConfig["MAX_CONCURRENT_THREAD_NUMBER"]
1198 ## if multiThread == "" or multiThread == "FALSE":
1199 ## self.Environment["MULTIPLE_THREAD"] = False
1200 ## self.Environment["MAX_CONCURRENT_THREAD_NUMBER"] = 1
1201 ## else:
1202 ## self.Environment["MULTIPLE_THREAD"] = True
1203 ## if threadNumber != "":
1204 ## self.Environment["MAX_CONCURRENT_THREAD_NUMBER"] = threadNumber
1205 ## else:
1206 ## self.Environment["MAX_CONCURRENT_THREAD_NUMBER"] = 2
1207
1208 class PackageSurfaceArea(FrameworkElement.Package, SurfaceAreaElement):
1209 def __init__(self, workspace, path):
1210 FrameworkElement.Package.__init__(self)
1211
1212 self.Path = os.path.normpath(path)
1213 self.Dir = os.path.dirname(self.Path)
1214 SurfaceAreaElement.__init__(self, workspace, workspace, None, True, True)
1215
1216 def _SpdHeader(self, xpath):
1217 dom = XmlNode(self._Root, xpath)
1218 self.Name = XmlElementData(XmlNode(dom, "/SpdHeader/PackageName"))
1219 self.GuidValue = XmlElementData(XmlNode(dom, "/SpdHeader/GuidValue")).upper()
1220 self.Version = XmlElementData(XmlNode(dom, "/SpdHeader/Version"))
1221
1222 def _PackageDefinitions(self, xpath):
1223 dom = XmlNode(self._Root, xpath)
1224 self.ReadOnly = XmlElementData(XmlNode(dom, "/PackageDefinitions/ReadOnly"))
1225 self.Repackage = XmlElementData(XmlNode(dom, "/PackageDefinitions/RePackage"))
1226
1227 def _LibraryClassDeclarations(self, xpath):
1228 dom = XmlNode(self._Root, xpath)
1229 lcdList = XmlList(dom, "/LibraryClassDeclarations/LibraryClass")
1230 lcds = []
1231 for lc in lcdList:
1232 lcds.append(LibraryDeclaration(self._Workspace, self, lc))
1233 self._Elements["LibraryClassDeclarations"] = lcds
1234
1235 def _IndustryStdIncludes(self, xpath):
1236 dom = XmlNode(self._Root, xpath)
1237 headerList = XmlList(dom, "/IndustryStdIncludes/IndustryStdHeader")
1238 headers = []
1239 for h in headerList:
1240 headers.append(IndustryStdHeader(self._Workspace, self, h))
1241 self._Elements["IndustryStdIncludes"] = headers
1242
1243 def _MsaFiles(self, xpath):
1244 dom = XmlNode(self._Root, xpath)
1245 msaFileList = XmlList(dom, "/MsaFiles/Filename")
1246 msaFiles = []
1247 for msa in msaFileList:
1248 filePath = os.path.normpath(XmlElementData(msa))
1249 msaFiles.append(filePath)
1250 self._Elements["MsaFiles"] = msaFiles
1251
1252 def _PackageHeaders(self, xpath):
1253 dom = XmlNode(self._Root, xpath)
1254 headerList = XmlList(dom, "/PackageHeaders/IncludePkgHeader")
1255 headers = []
1256 for h in headerList:
1257 headers.append(PackageHeader(self._Workspace, self, h))
1258 self._Elements["PackageHeaders"] = headers
1259
1260 def _GuidDeclarations(self, xpath):
1261 dom = XmlNode(self._Root, xpath)
1262 guidList = XmlList(dom, "/GuidDeclarations/Entry")
1263 guids = []
1264 for guid in guidList:
1265 guids.append(GuidDeclaration(self._Workspace, self, guid))
1266 self._Elements["GuidDeclarations"] = guids
1267
1268 def _ProtocolDeclarations(self, xpath):
1269 dom = XmlNode(self._Root, xpath)
1270 protocolList = XmlList(dom, "/ProtocolDeclarations/Entry")
1271 protocols = []
1272 for p in protocolList:
1273 protocols.append(ProtocolDeclaration(self._Workspace, self, p))
1274 self._Elements["ProtocolDeclarations"] = protocols
1275
1276 def _PpiDeclarations(self, xpath):
1277 dom = XmlNode(self._Root, xpath)
1278 ppiList = XmlList(dom, "/PpiDeclarations/Entry")
1279 ppis = []
1280 for p in ppiList:
1281 ppis.append(PpiDeclaration(self._Workspace, self, p))
1282 self._Elements["PpiDeclarations"] = ppis
1283
1284 def _PcdDeclarations(self, xpath):
1285 dom = XmlNode(self._Root, xpath)
1286 pcdList = XmlList(dom, "/PcdDeclarations/PcdEntry")
1287 pcds = []
1288 for p in pcdList:
1289 pcds.append(PcdDeclaration(self._Workspace, self, p))
1290 self._Elements["PcdDeclarations"] = pcds
1291
1292 def SubPath(self, *relativePathList):
1293 return os.path.normpath(os.path.join(self.Dir, *relativePathList))
1294
1295 def Parse(self):
1296 self._Root = xml.dom.minidom.parse(self._Workspace.SubPath(self.Path))
1297 assert self._Root.documentElement.tagName == "PackageSurfaceArea"
1298
1299 # print "Parsing...",self.Path
1300 self._SpdHeader("/PackageSurfaceArea/SpdHeader")
1301 self._PackageDefinitions("/PackageSurfaceArea/PackageDefinitions")
1302 self._LibraryClassDeclarations("/PackageSurfaceArea/LibraryClassDeclarations")
1303 self._IndustryStdIncludes("/PackageSurfaceArea/IndustryStdIncludes")
1304 self._MsaFiles("/PackageSurfaceArea/MsaFiles")
1305 self._PackageHeaders("/PackageSurfaceArea/PackageHeaders")
1306 self._GuidDeclarations("/PackageSurfaceArea/GuidDeclarations")
1307 self._ProtocolDeclarations("/PackageSurfaceArea/ProtocolDeclarations")
1308 self._PpiDeclarations("/PackageSurfaceArea/PpiDeclarations")
1309 self._PcdDeclarations("/PackageSurfaceArea/PcdDeclarations")
1310
1311 def Postprocess(self):
1312 # setup guid, protocol, ppi
1313 for guid in self._Elements["GuidDeclarations"]:
1314 if guid.CName in self.Guids:
1315 print "! Duplicate GUID CName (%s) in package %s" % (guid.CName, self.Path)
1316 self.Guids[guid.CName] = guid
1317
1318 for protocol in self._Elements["ProtocolDeclarations"]:
1319 if protocol.CName in self.Protocols:
1320 print "! Duplicate Protocol CName (%s) in package %s" % (protocol.CName, self.Path)
1321 self.Protocols[protocol.CName] = protocol
1322
1323 for ppi in self._Elements["PpiDeclarations"]:
1324 if ppi.CName in self.Ppis:
1325 print "! Duplicate PPI CName (%s) in package (%s)" % (ppi.CName, self.Path)
1326 self.Ppis[ppi.CName] = ppi
1327
1328 # package header
1329 for inc in self._Elements["PackageHeaders"]:
1330 if inc.ModuleType not in self.PackageIncludes:
1331 self.PackageIncludes[inc.ModuleType] = []
1332 self.PackageIncludes[inc.ModuleType].append(inc.Path)
1333
1334 # library class
1335 for lcd in self._Elements["LibraryClassDeclarations"]:
1336 if lcd.Name in self.LibraryInterfaces:
1337 raise "Duplicate library class: " + lcd.Name
1338 self.LibraryInterfaces[lcd.Name] = lcd
1339
1340 # parse mas files
1341 # self.ParseMsaFile()
1342 # resolve RecommendedInstance
1343
1344 def ParseMsaFile(self):
1345 for msaFilePath in self._Elements["MsaFiles"]:
1346 self.Modules.append(ModuleSurfaceArea(self._Workspace, self, msaFilePath))
1347
1348 class PlatformSurfaceArea(FrameworkElement.Platform, SurfaceAreaElement):
1349 def __init__(self, workspace, path):
1350 FrameworkElement.Platform.__init__(self)
1351
1352 self.Path = os.path.normpath(path)
1353 self.Dir = os.path.dirname(self.Path)
1354 SurfaceAreaElement.__init__(self, workspace)
1355
1356 def _PlatformHeader(self, xpath):
1357 dom = XmlNode(self._Root, xpath)
1358 if dom == '': return
1359 self.Name = XmlElementData(XmlNode(dom, "/PlatformHeader/PlatformName"))
1360 self.GuidValue = XmlElementData(XmlNode(dom, "/PlatformHeader/GuidValue")).upper()
1361 self.Version = XmlElementData(XmlNode(dom, "/PlatformHeader/Version"))
1362
1363 def _PlatformDefinitions(self, xpath):
1364 dom = XmlNode(self._Root, xpath)
1365 if dom == '': return
1366 self.Archs = XmlElementData(XmlNode(dom, "/PlatformDefinitions/SupportedArchitectures")).split()
1367 if self.Archs == []:
1368 raise Exception("No ARCH specified in platform " + self.Path)
1369 self.Targets = XmlElementData(XmlNode(dom, "/PlatformDefinitions/BuildTargets")).split()
1370 self.OutputPath = os.path.normpath(XmlElementData(XmlNode(dom, "/PlatformDefinitions/OutputDirectory")))
1371
1372 def _Flash(self, xpath):
1373 dom = XmlNode(self._Root, xpath)
1374 if dom == '': return
1375
1376 def _FrameworkModules(self, xpath):
1377 dom = XmlNode(self._Root, xpath)
1378 if dom == '': return
1379 moduleList = XmlList(dom, "/FrameworkModules/ModuleSA")
1380 modules = []
1381 for m in moduleList:
1382 modules.append(PlatformModule(self._Workspace, self, m))
1383 self._Elements["FrameworkModules"] = modules
1384
1385 def _DynamicPcdBuildDefinitions(self, xpath):
1386 dom = XmlNode(self._Root, xpath)
1387 if dom == '': return
1388
1389 def _BuildOptions(self, xpath):
1390 dom = XmlNode(self._Root, xpath)
1391 if dom == '': return
1392 self.BuildOptions = self.GetBuildOptionList(XmlNode(dom, "/BuildOptions/Options"))
1393 # print self.BuildOptions
1394
1395 def _UserExtensions(self, xpath):
1396 domList = XmlList(self._Root, xpath)
1397 if domList == []: return
1398 for extension in domList:
1399 userId = XmlAttribute(extension, "UserID")
1400 identifier = XmlAttribute(extension, "Identifier")
1401
1402 if userId == '' or identifier == '':
1403 raise Exception("No UserId or Identifier specified")
1404 if userId != "TianoCore": continue
1405 if identifier not in self.UserExtensions:
1406 self.UserExtensions[identifier] = []
1407
1408 contentList = self.UserExtensions[identifier]
1409 for node in extension.childNodes:
1410 # print node.nodeType
1411 contentList.append(node.cloneNode(True))
1412
1413 def Parse(self):
1414 self._Root = xml.dom.minidom.parse(self._Workspace.SubPath(self.Path))
1415 assert self._Root.documentElement.tagName == "PlatformSurfaceArea"
1416
1417 self._PlatformHeader("/PlatformSurfaceArea/PlatformHeader")
1418 self._PlatformDefinitions("/PlatformSurfaceArea/PlatformDefinitions")
1419 self._Flash("/PlatformSurfaceArea/Flash")
1420 self._FrameworkModules("/PlatformSurfaceArea/FrameworkModules")
1421 self._DynamicPcdBuildDefinitions("/PlatformSurfaceArea/DynamicPcdBuildDefinitions")
1422 self._BuildOptions("/PlatformSurfaceArea/BuildOptions")
1423 self._UserExtensions("/PlatformSurfaceArea/UserExtensions")
1424
1425 def Postprocess(self):
1426 # summarize all library modules for build
1427 for module in self._Elements["FrameworkModules"]:
1428 for arch in module.Archs:
1429 if arch not in self.Modules:
1430 self.Modules[arch] = []
1431 self.Modules[arch].append(module)
1432
1433 if arch not in self.Libraries:
1434 self.Libraries[arch] = []
1435 for li in module.Libraries:
1436 if li in self.Libraries[arch]: continue
1437 self.Libraries[arch].append(li)
1438
1439 # FV
1440 for fvName in module.FvBindings:
1441 if fvName not in self.Fvs:
1442 self.Fvs[fvName] = []
1443 self.Fvs[fvName].append(module)
1444 # build options
1445 # user extension
1446
1447 ## def SetupEnvironment(self):
1448 ## self.Environment["PLATFORM"] = self.Name
1449 ## self.Environment["PLATFORM_GUID"] = self.GuidValue
1450 ## self.Environment["PLATFORM_VERSION"] = self.Version
1451 ## self.Environment["PLATFORM_RELATIVE_DIR"] = self.Path
1452 ## self.Environment["PLATFORM_OUTPUT_DIR"] = self.OutputPath
1453
1454 def PrintWorkspace(ws):
1455 print "\nPlatforms:\n"
1456 for guid in ws.PlatformXref["GUID"]:
1457 for ver in ws.PlatformXref["GUID"][guid]:
1458 platform = ws.PlatformXref["GUID"][guid][ver]
1459 print " %s %s-%s" % (guid, platform.Name, ver)
1460 for pm in platform.Modules:
1461 print " %-40s %-10s <%s-%s>" % (pm.Module.Name+"-"+pm.Module.Version,
1462 ListString(pm.Archs), pm.Module.Package.Name,
1463 pm.Module.Package.Version)
1464 for li in pm.Libraries:
1465 print " %-47s <%s-%s>" % (li.Module.Name+"-"+li.Module.Version,
1466 li.Module.Package.Name, li.Module.Package.Version)
1467 print ""
1468
1469 print "\nPackages:\n"
1470 for guid in ws.PackageXref["GUID"]:
1471 for ver in ws.PackageXref["GUID"][guid]:
1472 print " %s %s-%s" % (guid, ws.PackageXref["GUID"][guid][ver].Name, ver)
1473
1474 print "\nModules:\n"
1475 for guid in ws.ModuleXref["GUID"]:
1476 for ver in ws.ModuleXref["GUID"][guid]:
1477 for module in ws.ModuleXref["GUID"][guid][ver]:
1478 print " %s %-40s [%s-%s]" % (guid, module.Name+"-"+ver, module.Package.Name, module.Package.Version)
1479 print " Depending on packages:"
1480 for arch in module.IncludePaths:
1481 print " ", arch, ":"
1482 for path in module.IncludePaths[arch]:
1483 print " ", path
1484 print "\n"
1485
1486 for arch in module.IncludeFiles:
1487 print " ", arch, ":"
1488 for path in module.IncludeFiles[arch]:
1489 print " ", path
1490 print "\n"
1491
1492 print " Source files:"
1493 for arch in module.SourceFiles:
1494 print " ", arch, ":"
1495 for type in module.SourceFiles[arch]:
1496 for src in module.SourceFiles[arch][type]:
1497 print " %-40s (%s)" % (src.Path, src.Type)
1498 print "\n"
1499 print "\nLibrary Classes:"
1500 for name in ws.LibraryInterfaceXref["NAME"]:
1501 lcList = ws.LibraryInterfaceXref["NAME"][name]
1502 for lc in lcList:
1503 pkgPath = os.path.dirname(lc.Package.Path)
1504 print "\n [%s] <%s>" % (lc.Name, pkgPath + os.path.sep + lc.Path)
1505
1506 print " Produced By:"
1507 for li in lc.Instances:
1508 print " %-40s <%s>" % (li.Name+"-"+li.Version, li.Package.SubPath(li.Path))
1509
1510 print " Consumed By:"
1511 for li in lc.Consumers:
1512 print " %-40s <%s>" % (li.Name+"-"+li.Version, li.Package.SubPath(li.Path))
1513
1514 print "\nActive Platform:"
1515 for arch in ws.ActivePlatform.Libraries:
1516 print " Library Instances (%s) (%d libraries)" % (arch , len(ws.ActivePlatform.Libraries[arch]))
1517 for li in ws.ActivePlatform.Libraries[arch]:
1518 print " %s-%s (%s-%s)" % (li.Module.Name, li.Module.Version,
1519 li.Module.Package.Name, li.Module.Package.Version)
1520
1521 for arch in ws.ActivePlatform.Modules:
1522 print " Driver Modules (%s) (%d modules)" % (arch, len(ws.ActivePlatform.Modules[arch]))
1523 for m in ws.ActivePlatform.Modules[arch]:
1524 print " %s-%s (%s-%s)" % (m.Module.Name, m.Module.Version,
1525 m.Module.Package.Name, m.Module.Package.Version)
1526
1527 for fv in ws.ActivePlatform.Fvs:
1528 print
1529 print " Firmware Volume (%s) (%d modules)" % (fv, len(ws.ActivePlatform.Fvs[fv]))
1530 for m in ws.ActivePlatform.Fvs[fv]:
1531 print " %s-%s (%s-%s)" % (m.Module.Name, m.Module.Version,
1532 m.Module.Package.Name, m.Module.Package.Version)
1533
1534 # for test
1535 if __name__ == "__main__":
1536 # os.environ["WORKSPACE"]
1537 workspacePath = os.getenv("WORKSPACE", os.getcwd())
1538 workspacePath = "C:\\home\\src\\R9\\pbuild"
1539 saFile = ""
1540 if len(sys.argv) <= 1:
1541 saFile = os.path.join(workspacePath, "Tools/Conf/FrameworkDatabase.db")
1542 else:
1543 saFile = sys.argv[1]
1544
1545 print "Parsing ... %s\n" % saFile
1546
1547 startTime = time.clock()
1548 sa = Workspace(workspacePath, [], [])
1549 # sa = PackageSurfaceArea(saFile)
1550 # sa = PlatformSurfaceArea(saFile)
1551 # sa = ModuleSurfaceArea(saFile)
1552 # print sa
1553
1554 PrintWorkspace(sa)
1555 print "\n[Finished in %fs]" % (time.clock() - startTime)
1556