- Merged the local copy of XmlRoutines.py in buildgen into upper directory's XmlRouti...
[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 def Postprocess(self):
288 self.Interface = self._Workspace.GetLibraryInterface(self.Name)
289
290 class SourceFile(FrameworkElement.SourceFile, SurfaceAreaElement):
291 def __init__(self, workspace, module, dom):
292 FrameworkElement.SourceFile.__init__(self)
293 SurfaceAreaElement.__init__(self, workspace, module, dom)
294
295 def Parse(self):
296 dom = self._Root
297 self.Path = os.path.normpath(XmlElementData(dom))
298 self.Dir = os.path.dirname(self.Path)
299 self.Type = self.GetFileType()
300 self.Toolchains = self.GetToolchainTagList(dom)
301 self.Families = self.GetToolchainFamilyList(dom)
302 self.Archs = self.GetArchList(dom)
303 self.Features = self.GetFeatureList(dom)
304
305 def GetFileType(self):
306 type = XmlAttribute(self._Root, "ToolCode")
307 if type == "":
308 fileName = os.path.basename(self.Path)
309 self.BaseName,self.Ext = os.path.splitext(fileName)
310 if self.Ext in self._FileTypes:
311 type = self._FileTypes[self.Ext]
312 else:
313 type = ""
314 return type
315
316 class PackageDependency(FrameworkElement.PackageDependency, SurfaceAreaElement):
317 def __init__(self, workspace, module, dom):
318 FrameworkElement.PackageDependency.__init__(self)
319 SurfaceAreaElement.__init__(self, workspace, module, dom)
320
321 def Parse(self):
322 dom = self._Root
323 self.GuidValue = XmlAttribute(dom, "PackageGuid").upper()
324 self.Version = XmlAttribute(dom, "PackageVersion")
325 self.Archs = self.GetArchList(dom)
326 self.Features = self.GetFeatureList(dom)
327
328 def Postprocess(self):
329 self.Package = self._Workspace.GetPackage(self.GuidValue, self.Version)
330 if self.Package == "": raise "No package with GUID=" + self.GuidValue + "VERSION=" + self.Version
331
332 class Protocol(FrameworkElement.Protocol, SurfaceAreaElement):
333 def __init__(self, workspace, module, dom):
334 FrameworkElement.Protocol.__init__(self)
335 SurfaceAreaElement.__init__(self, workspace, module, dom)
336
337 def Parse(self):
338 dom = self._Root
339 self.CName = XmlElementData(XmlNode(dom, "/Protocol/ProtocolCName"))
340 self.Usage = self.GetUsage(dom)
341 self.Archs = self.GetArchList(dom)
342 self.Features = self.GetFeatureList(dom)
343
344 def Postprocess(self):
345 for pd in self._Owner._Elements["PackageDependencies"]:
346 if self.CName not in pd.Package.Protocols: continue
347 self.GuidValue = pd.Package.Protocols[self.CName]
348
349 class ProtocolNotify(FrameworkElement.ProtocolNotify, SurfaceAreaElement):
350 def __init__(self, workspace, module, dom):
351 FrameworkElement.ProtocolNotify.__init__(self)
352 SurfaceAreaElement.__init__(self, workspace, module, dom)
353
354 def Parse(self):
355 dom = self._Root
356
357 self.CName = XmlElementData(XmlNode(dom, "/ProtocolNotify/ProtocolCName"))
358 self.Usage = self.GetUsage(dom)
359 self.Archs = self.GetArchList(dom)
360 self.Features = self.GetFeatureList(dom)
361
362 def Postprocess(self):
363 for pd in self._Owner._Elements["PackageDependencies"]:
364 if self.CName not in pd.Package.Protocols: continue
365 self.GuidValue = pd.Package.Protocols[self.CName]
366
367 class Ppi(FrameworkElement.Ppi, SurfaceAreaElement):
368 def __init__(self, workspace, module, dom):
369 FrameworkElement.Ppi.__init__(self)
370 SurfaceAreaElement.__init__(self, workspace, module, dom)
371
372 def Parse(self):
373 dom = self._Root
374 self.CName = XmlElementData(XmlNode(dom, "/Ppi/PpiCName"))
375 self.Usage = self.GetUsage(dom)
376 self.Archs = self.GetArchList(dom)
377 self.Features = self.GetFeatureList(dom)
378
379 def Postprocess(self):
380 for pd in self._Owner._Elements["PackageDependencies"]:
381 if self.CName not in pd.Package.Ppis: continue
382 self.GuidValue = pd.Package.Ppis[self.CName]
383
384 class PpiNotify(FrameworkElement.PpiNotify, SurfaceAreaElement):
385 def __init__(self, workspace, module, dom):
386 FrameworkElement.PpiNotify.__init__(self)
387 SurfaceAreaElement.__init__(self, workspace, module, dom)
388
389 def Parse(self):
390 dom = self._Root
391 self.CName = XmlElementData(XmlNode(dom, "/PpiNotify/PpiCName"))
392 self.Usage = self.GetUsage(dom)
393 self.Archs = self.GetArchList(dom)
394 self.Features = self.GetFeatureList(dom)
395
396 def Postprocess(self):
397 for pd in self._Owner._Elements["PackageDependencies"]:
398 if self.CName not in pd.Package.Ppis: continue
399 self.GuidValue = pd.Package.Ppis[self.CName]
400
401 class Guid(FrameworkElement.Guid, SurfaceAreaElement):
402 def __init__(self, workspace, module, dom):
403 FrameworkElement.Guid.__init__(self)
404 SurfaceAreaElement.__init__(self, workspace, module, dom)
405
406 def Parse(self):
407 dom = self._Root
408 self.CName = XmlElementData(XmlNode(dom, "/GuidCNames/GuidCName"))
409 self.Usage = self.GetUsage(dom)
410 self.Archs = self.GetArchList(dom)
411 self.Features = self.GetFeatureList(dom)
412
413 def Postprocess(self):
414 for pd in self._Owner._Elements["PackageDependencies"]:
415 if self.CName not in pd.Package.Guids: continue
416 self.GuidValue = pd.Package.Guids[self.CName]
417
418 class Extern(FrameworkElement.Extern, SurfaceAreaElement):
419 def __init__(self, workspace, module, dom):
420 FrameworkElement.Extern.__init__(self)
421 SurfaceAreaElement.__init__(self, workspace, module, dom)
422
423 def Parse(self):
424 dom = self._Root
425 self.Archs = self.GetArchList(dom)
426 self.Features = self.GetFeatureList(dom)
427
428 extern = XmlNode(dom, "/Extern/ModuleEntryPoint")
429 if extern is not None and extern is not '':
430 self.ModuleEntryPoints.append(XmlElementData(extern))
431
432 extern = XmlNode(dom, "/Extern/ModuleUnloadImage")
433 if extern is not None and extern is not '':
434 self.ModuleUnloadImages.append(XmlElementData(extern))
435
436 extern = XmlNode(dom, "/Extern/Constructor")
437 if extern is not None and extern is not '':
438 self.Constructors.append(XmlElementData(extern))
439
440 extern = XmlNode(dom, "/Extern/Destructor")
441 if extern is not None and extern is not '':
442 self.Destructors.append(XmlElementData(extern))
443
444 extern = XmlNode(dom, "/Extern/DriverBinding")
445 if extern is not None and extern is not '':
446 self.DriverBindings.append(XmlElementData(extern))
447
448 extern = XmlNode(dom, "/Extern/ComponentName")
449 if extern is not None and extern is not '':
450 self.ComponentNames.append(XmlElementData(extern))
451
452 extern = XmlNode(dom, "/Extern/DriverConfig")
453 if extern is not None and extern is not '':
454 self.DriverConfigs.append(XmlElementData(extern))
455
456 extern = XmlNode(dom, "/Extern/DriverDiag")
457 if extern is not None and extern is not '':
458 self.DriverDiags.append(XmlElementData(extern))
459
460 extern = XmlNode(dom, "/Extern/SetVirtualAddressMapCallBacks")
461 if extern is not None and extern is not '':
462 self.SetVirtualAddressMapCallBacks.append(XmlElementData(extern))
463
464 extern = XmlNode(dom, "/Extern/ExitBootServicesCallBack")
465 if extern is not None and extern is not '':
466 self.ExitBootServicesCallBacks.append(XmlElementData(extern))
467
468 class IndustryStdHeader(FrameworkElement.IncludeFile, SurfaceAreaElement):
469 def __init__(self, workspace, package, dom):
470 FrameworkElement.IncludeFile.__init__(self)
471 SurfaceAreaElement.__init__(self, workspace, package, dom)
472
473 def Parse(self):
474 dom = self._Root
475 self.Path = os.path.normpath(XmlElementData(XmlNode(dom, "/IndustryStdHeader/IncludeHeader")))
476 self.Dir = os.path.dirname(self.Path)
477 self.Archs = self.GetArchList(dom)
478 self.ModuleTypes = self.GetModuleTypeList(dom)
479
480 class PackageHeader(FrameworkElement.IncludeFile, SurfaceAreaElement):
481 def __init__(self, workspace, package, dom):
482 FrameworkElement.IncludeFile.__init__(self)
483 SurfaceAreaElement.__init__(self, workspace, package, dom)
484
485 def Parse(self):
486 dom = self._Root
487 self.Path = os.path.normpath(XmlElementData(dom))
488 self.Dir = os.path.dirname(self.Path)
489 self.ModuleType = XmlAttribute(dom, "ModuleType")
490
491 class GuidDeclaration(FrameworkElement.Guid, SurfaceAreaElement):
492 def __init__(self, workspace, package, dom):
493 FrameworkElement.Guid.__init__(self)
494 SurfaceAreaElement.__init__(self, workspace, package, dom)
495
496 def Parse(self):
497 dom = self._Root
498 self.CName = XmlElementData(XmlNode(dom, "/Entry/C_Name"))
499 self.GuidValue = XmlElementData(XmlNode(dom, "/Entry/GuidValue")).upper()
500 self.Name = XmlAttribute(dom, "Name")
501 self.Types = self.GetGuidTypeList(dom)
502 self.Archs = self.GetArchList(dom)
503 self.ModuleTypes = self.GetModuleTypeList(dom)
504
505 def Postprocess(self):
506 pass
507
508 class ProtocolDeclaration(GuidDeclaration, SurfaceAreaElement):
509 pass
510
511 class PpiDeclaration(GuidDeclaration, SurfaceAreaElement):
512 pass
513
514 class PcdDeclaration(FrameworkElement.Pcd, SurfaceAreaElement):
515 def __init__(self, workspace, package, dom):
516 FrameworkElement.Pcd.__init__(self)
517 SurfaceAreaElement.__init__(self, workspace, package, dom)
518
519 def Parse(self):
520 dom = self._Root
521 self.Types = XmlElementData(XmlNode(dom, "/PcdEntry/ValidUsage")).split()
522 self.CName = XmlElementData(XmlNode(dom, "/PcdEntry/C_Name"))
523 self.Token = XmlElementData(XmlNode(dom, "/PcdEntry/Token"))
524 self.TokenSpace = XmlElementData(XmlNode(dom, "/PcdEntry/TokenSpaceGuidCName"))
525 self.DatumType = XmlElementData(XmlNode(dom, "/PcdEntry/DatumType"))
526 self.Default = XmlElementData(XmlNode(dom, "/PcdEntry/DefaultValue"))
527 self.Archs = self.GetArchList(dom)
528 self.ModuleTypes= self.GetModuleTypeList(dom)
529
530 class LibraryInstance(FrameworkElement.PlatformModule, SurfaceAreaElement):
531 def __init__(self, workspace, platformModule, dom):
532 FrameworkElement.PlatformModule.__init__(self)
533 SurfaceAreaElement.__init__(self, workspace, platformModule, dom)
534
535 def Parse(self):
536 dom = self._Root
537 self.GuidValue = XmlAttribute(dom, "ModuleGuid").upper()
538 self.Version = XmlAttribute(dom, "ModuleVersion")
539 self._Elements["PackageGuid"] = XmlAttribute(dom, "PackageGuid").upper()
540 self._Elements["PackageVersion"] = XmlAttribute(dom, "PackageVersion")
541
542 def Postprocess(self):
543 self.Module = self._Workspace.GetModule(self.GuidValue, self.Version,
544 self._Elements["PackageGuid"], self._Elements["PackageVersion"])
545 self.Platform = self._Owner.Platform
546 self.Archs = self._Owner.Archs
547 self.Pcds = self._Owner.Pcds
548 self.BuildType = "lib"
549
550 class PlatformModule(FrameworkElement.PlatformModule, SurfaceAreaElement):
551 def __init__(self, workspace, platform, dom):
552 FrameworkElement.PlatformModule.__init__(self)
553 self.Platform = platform
554 SurfaceAreaElement.__init__(self, workspace, platform, dom)
555
556 def Parse(self):
557 dom = self._Root
558 self.GuidValue = XmlAttribute(dom, "ModuleGuid").upper()
559 self.Version = XmlAttribute(dom, "ModuleVersion")
560 self.Archs = self.GetArchList(dom)
561
562 self._Elements["PackageGuid"] = XmlAttribute(dom, "PackageGuid").upper()
563 self._Elements["PackageVersion"] = XmlAttribute(dom, "PackageVersion")
564
565 libraryList = XmlList(dom, "/ModuleSA/Libraries/Instance")
566 for lib in libraryList:
567 self.Libraries.append(LibraryInstance(self._Workspace, self, lib))
568
569 dom = XmlNode(dom, "/ModuleSA/ModuleSaBuildOptions")
570 self.FvBindings = self.GetFvBindingList(XmlNode(dom, "/ModuleSaBuildOptions/FvBinding"))
571 self.FfsLayouts = XmlElementData(XmlNode(dom, "/ModuleSaBuildOptions/FfsFormatKey")).split()
572 self.BuildOptions = self.GetBuildOptionList(XmlNode(dom, "/ModuleSaBuildOptions/Options"))
573
574 def Postprocess(self):
575 self.Module = self._Workspace.GetModule(self.GuidValue, self.Version,
576 self._Elements["PackageGuid"], self._Elements["PackageVersion"])
577 if self.Module == "":
578 raise Exception("No module found: \n\t\tGUID=%s \n\t\tVERSION=%s \n\t\tPACKAGE_GUID=%s \n\t\tPACKAGE_VERSION=%s" % (
579 self.GuidValue, self.Version, self._Elements["PackageGuid"], self._Elements["PackageVersion"]))
580
581 ## def SetupEnvironment(self):
582 ## self.Environment = {
583 ## "ARCH" : "",
584 ## "MODULE_BUILD_TARGET" : "",
585 ## "SINGLE_MODULE_BUILD" : "",
586 ## "PLATFORM_PREBUILD" : "",
587 ## "PLATFORM_POSTBUILD" : "",
588 ## "LIBS" : "",
589 ## "SOURCE_FILES" : "",
590 ## "ENTRYPOINT" : "_ModuleEntryPoint",
591 ## } # name/value pairs
592 ## self.Environment["MODULE_BUILD_TARGET"] = "platform_module_build"
593
594 class ModuleSurfaceArea(FrameworkElement.Module, SurfaceAreaElement):
595 def __init__(self, workspace, package, path):
596 FrameworkElement.Module.__init__(self)
597
598 self.Path = os.path.normpath(path)
599 self.Dir = os.path.dirname(self.Path)
600 self.FileBaseName,_ext = os.path.splitext(os.path.basename(self.Path))
601 self.Package = package
602 SurfaceAreaElement.__init__(self, workspace, package)
603
604 def _MsaHeader(self, xpath):
605 dom = XmlNode(self._Root, xpath)
606 if dom == '': return
607 self.Name = XmlElementData(XmlNode(dom, "/MsaHeader/ModuleName"))
608 self.Type = XmlElementData(XmlNode(dom, "/MsaHeader/ModuleType"))
609 self.GuidValue = XmlElementData(XmlNode(dom, "/MsaHeader/GuidValue")).upper()
610 self.Version = XmlElementData(XmlNode(dom, "/MsaHeader/Version"))
611
612 def _ModuleDefinitions(self, xpath):
613 dom = XmlNode(self._Root, xpath)
614 if dom == '': return
615 self.Archs = XmlElementData(XmlNode(dom, "/ModuleDefinitions/SupportedArchitectures")).split()
616 self.IsBinary = self.GetBoolean(XmlNode(dom, "/ModuleDefinitions/BinaryModule"))
617 self.BaseName = XmlElementData(XmlNode(dom, "/ModuleDefinitions/OutputFileBasename"))
618
619 def _LibraryClassDefinitions(self, xpath):
620 dom = XmlNode(self._Root, xpath)
621 if dom == '': return
622 lcList = []
623 for lc in XmlList(dom, "/LibraryClassDefinitions/LibraryClass"):
624 lcList.append(LibraryClass(self._Workspace, self, lc))
625 self._Elements["LibraryClassDefinitions"] = lcList
626
627 def _SourceFiles(self, xpath):
628 dom = XmlNode(self._Root, xpath)
629 if dom == '': return
630 srcList = []
631 for f in XmlList(dom, "/SourceFiles/Filename"):
632 srcList.append(SourceFile(self._Workspace, self, f))
633 self._Elements["SourceFiles"] = srcList
634
635 def _NonProcessedFiles(self, xpath):
636 dom = XmlNode(self._Root, xpath)
637 if dom == '': return
638 for f in XmlList(dom, "/NonProcessedFiles/Filename"):
639 self.NonProcessedFiles.append(SourceFile(self._Workspace, self, f))
640
641 def _PackageDependencies(self, xpath):
642 dom = XmlNode(self._Root, xpath)
643 if dom == '': return
644 pdList = []
645 for pkg in XmlList(dom, "/PackageDependencies/Package"):
646 pdList.append(PackageDependency(self._Workspace, self, pkg))
647 self._Elements["PackageDependencies"] = pdList
648
649 def _Protocols(self, xpath):
650 dom = XmlNode(self._Root, xpath)
651 if dom == '': return
652
653 protocolList = []
654 for p in XmlList(dom, "/Protocols/Protocol"):
655 protocolList.append(Protocol(self._Workspace, self, p))
656 for p in XmlList(dom, "/Protocols/ProtocolNotify"):
657 protocolList.append(ProtocolNotify(self._Workspace, self, p))
658
659 self._Elements["Protocols"] = protocolList
660
661 def _Ppis(self, xpath):
662 dom = XmlNode(self._Root, xpath)
663 if dom == '': return
664
665 ppiList = []
666 for p in XmlList(dom, "/PPIs/Ppi"):
667 ppiList.append(Ppi(self._Workspace, self, p))
668 for p in XmlList(dom, "/PPIs/PpiNotify"):
669 ppiList.append(PpiNotify(self._Workspace, self, p))
670
671 self._Elements["PPIs"] = ppiList
672
673 def _Guids(self, xpath):
674 dom = XmlNode(self._Root, xpath)
675 if dom == '': return
676 guidList = []
677 for g in XmlList(dom, "/Guids/GuidCNames"):
678 guidList.append(Guid(self._Workspace, self, g))
679 self._Elements["Guids"] = guidList
680
681 def _Externs(self, xpath):
682 dom = XmlNode(self._Root, xpath)
683 if dom == '': return
684 self.PcdIsDriver = self.GetBoolean(XmlNode(dom, "/Externs/PcdIsDriver"))
685 self.NeedsFlashMap_h = self.GetBoolean(XmlNode(dom, "/Externs/TianoR8FlashMap_h"))
686
687 externList = []
688 specs = FrameworkElement.Extern()
689 specs.Archs = self._Archs
690 externList.append(specs)
691 for spec in XmlList(dom, "/Externs/Specification"):
692 specs.Specifications.append(XmlElementData(spec))
693 for ext in XmlList(dom, "/Externs/Extern"):
694 externList.append(Extern(self._Workspace, self, ext))
695 self._Elements["Externs"] = externList
696
697 def _ModuleBuildOptions(self, xpath):
698 dom = XmlNode(self._Root, xpath)
699 if dom == '': return
700 self.BuildOptions = self.GetBuildOptionList(XmlNode(dom, "/ModuleBuildOptions/Options"))
701
702 def _UserExtensions(self, xpath):
703 domList = XmlList(self._Root, xpath)
704 if domList == []: return
705 for extension in domList:
706 userId = XmlAttribute(extension, "UserID")
707 identifier = XmlAttribute(extension, "Identifier")
708 if userId == '' or identifier == '':
709 raise Exception("No UserId or Identifier specified")
710 if userId != "TianoCore": continue
711 if identifier not in self.UserExtensions:
712 self.UserExtensions[identifier] = []
713
714 contentList = self.UserExtensions[identifier]
715 for node in extension.childNodes:
716 #print node.nodeType
717 contentList.append(node.cloneNode(True))
718
719 def Parse(self):
720 fileFullPath = self._Workspace.SubPath(os.path.dirname(self.Package.Path), self.Path)
721 self._Root = xml.dom.minidom.parse(fileFullPath)
722 assert self._Root.documentElement.tagName == "ModuleSurfaceArea"
723
724 # print " Parsing...",self.Path
725 self._MsaHeader("/ModuleSurfaceArea/MsaHeader")
726 self._ModuleDefinitions("/ModuleSurfaceArea/ModuleDefinitions")
727 self._PackageDependencies("/ModuleSurfaceArea/PackageDependencies")
728 self._LibraryClassDefinitions("/ModuleSurfaceArea/LibraryClassDefinitions")
729 self._SourceFiles("/ModuleSurfaceArea/SourceFiles")
730 self._NonProcessedFiles("/ModuleSurfaceArea/NonProcessedFiles")
731 self._Protocols("/ModuleSurfaceArea/Protocols")
732 self._Ppis("/ModuleSurfaceArea/Ppis")
733 self._Guids("/ModuleSurfaceArea/Guids")
734 self._Externs("/ModuleSurfaceArea/Externs")
735 self._ModuleBuildOptions("/ModuleSurfaceArea/ModuleBuildOptions")
736 self._UserExtensions("/ModuleSurfaceArea/UserExtensions")
737
738 def Postprocess(self):
739 # resolve package dependency
740 if self._Elements.has_key("PackageDependencies"):
741 for pd in self._Elements["PackageDependencies"]:
742 package = pd.Package
743 if self.Type not in package.PackageIncludes:
744 print "! Module type %s is not supported in the package %s" % (self.Type, package.Name)
745
746 for arch in pd.Archs:
747 if arch not in self.IncludePaths:
748 self.IncludePaths[arch] = []
749 self.IncludePaths[arch].append(package.SubPath("Include"))
750 self.IncludePaths[arch].append(package.SubPath("Include", arch.capitalize()))
751
752 if arch not in self.IncludeFiles:
753 self.IncludeFiles[arch] = []
754 if self.Type in package.PackageIncludes:
755 for path in package.PackageIncludes[self.Type]:
756 self.IncludeFiles[arch].append(package.SubPath(path))
757
758 # resolve library class
759 if self._Elements.has_key("LibraryClassDefinitions"):
760 for lc in self._Elements["LibraryClassDefinitions"]:
761 lc.Interface = self._Workspace.GetLibraryInterface(lc.Name)
762 if "ALWAYS_PRODUCED" in lc.Usage:
763 self.IsLibrary = True
764 lc.Interface.Instances.append(self)
765 else:
766 lc.Interface.Consumers.append(self)
767
768 for arch in lc.Archs:
769 if arch not in self.LibraryClasses:
770 self.LibraryClasses[arch] = []
771 self.LibraryClasses[arch].append(lc)
772
773 # expand source files
774 if self._Elements.has_key("SourceFiles"):
775 for src in self._Elements["SourceFiles"]:
776 for arch in src.Archs:
777 if arch not in self.SourceFiles:
778 self.SourceFiles[arch] = {}
779 if src.Type not in self.SourceFiles[arch]:
780 self.SourceFiles[arch][src.Type] = []
781 self.SourceFiles[arch][src.Type].append(src)
782
783 # expand guids
784 if self._Elements.has_key("Guids"):
785 for guid in self._Elements["Guids"]:
786 for arch in guid.Archs:
787 if arch not in self.Guids:
788 self.Guids[arch] = []
789 self.Guids[arch].append(guid)
790
791 # expand protocol
792 if self._Elements.has_key("Protocols"):
793 for protocol in self._Elements["Protocols"]:
794 for arch in protocol.Archs:
795 if arch not in self.Protocols:
796 self.Protocols[arch] = []
797 self.Protocols[arch].append(protocol)
798
799 # expand ppi
800 if self._Elements.has_key("PPIs"):
801 for ppi in self._Elements["PPIs"]:
802 for arch in ppi.Archs:
803 if arch not in self.Ppis:
804 self.Ppis[arch] = []
805 self.Ppis[arch].append(ppi)
806
807 # expand extern
808 if self._Elements.has_key("Externs"):
809 for extern in self._Elements["Externs"]:
810 for arch in extern.Archs:
811 if arch not in self.Externs:
812 self.Externs[arch] = []
813 self.Externs[arch].append(extern)
814 ## def SetupEnvironment(self):
815 ## self.Environment["MODULE"] = self.Name
816 ## self.Environment["MODULE_GUID"] = self.GuidValue
817 ## self.Environment["MODULE_VERSION"] = self.Version
818 ## self.Environment["MODULE_TYPE"] = self.Type
819 ## self.Environment["MODULE_FILE_BASE_NAME"] = os.path.basename(self.Path).split(".")[0]
820 ## self.Environment["MODULE_RELATIVE_DIR"] = os.path.dirname(self.Path)
821 ## self.Environment["BASE_NAME"] = self.OutputName
822
823 class Workspace(FrameworkElement.Workspace, SurfaceAreaElement):
824 _Db = "Tools/Conf/FrameworkDatabase.db"
825 _Target = "Tools/Conf/Target.txt"
826 _PlatformBuildPath = "Tools/Conf/platform_build_path.txt"
827 _ModuleBuildPath = "Tools/Conf/module_build_path.txt"
828
829 def __init__(self, path, fpdList=None, msaList=None):
830 FrameworkElement.Workspace.__init__(self)
831 SurfaceAreaElement.__init__(self, self, None, None, False, False)
832 self.Path = os.path.normpath(path)
833 self.Dir = os.path.dirname(self.Path)
834 self._Elements["PlatformList"] = fpdList
835 self._Elements["ModuleList"] = msaList
836 self.Parse()
837 self.Postprocess()
838
839 def _FdbHeader(self, xpath):
840 dom = XmlNode(self._Root, xpath)
841 if dom == '': return
842 self.Name = XmlElementData(XmlNode(dom, "/FdbHeader/DatabaseName"))
843 self.GuidValue = XmlElementData(XmlNode(dom, "/FdbHeader/GuidValue")).upper()
844 self.Version = XmlElementData(XmlNode(dom, "/FdbHeader/Version"))
845
846 def _PackageList(self, xpath):
847 dom = XmlNode(self._Root, xpath)
848 if dom == '': return
849
850 fileList = XmlList(dom, "/PackageList/Filename")
851 packages = []
852 for f in fileList:
853 packages.append(os.path.normpath(XmlElementData(f)))
854 self._Elements["PackageList"] = packages
855
856 def _PlatformList(self, xpath):
857 if len(self._Elements["PlatformList"]) > 0:
858 return
859
860 dom = XmlNode(self._Root, xpath)
861 if dom == '': return
862
863 fileList = XmlList(dom, "/PlatformList/Filename")
864 platforms = []
865 for f in fileList:
866 platforms.append(os.path.normpath(XmlElementData(f)))
867 self._Elements["PlatformList"] = platforms
868
869 def _FarList(self, xpath):
870 dom = XmlNode(self._Root, xpath)
871 if dom == '': return
872
873 fileList = XmlList(dom, "/FarList/Filename")
874 fars = []
875 for f in fileList:
876 fars.append(os.path.normpath(XmlElementData(f)))
877 self._Elements["FarList"] = fars
878
879 def ParseWorkspaceDatabase(self):
880 # parse frameworkdatabase.db
881 self._Root = xml.dom.minidom.parse(self.SubPath(self._Db))
882 assert self._Root.documentElement.tagName == "FrameworkDatabase"
883
884 self._FdbHeader("/FrameworkDatabase/FdbHeader")
885 self._PackageList("/FrameworkDatabase/PackageList")
886 self._PlatformList("/FrameworkDatabase/PlatformList")
887 self._FarList("/FrameworkDatabase/FarList")
888
889 def ParseConfig(self):
890 # parse target.txt
891 self.ParseTargetConfig()
892 # parse tools_def.txt
893 self.ParseToolConfig()
894 # parse platform/module_build_path.txt
895
896 # active toolchain
897 # print self.TargetConfig
898 self.ActiveToolchain = self.TargetConfig["TOOL_CHAIN_TAG"]
899 if self.ActiveToolchain not in self.ToolConfig.Toolchains:
900 raise "Not supported tool chain tag %s" % self.ActiveToolchain
901
902 # active toolchain family
903 self.ActiveFamilies = []
904 for key in self.ToolConfig:
905 if self.ActiveToolchain in key and "FAMILY" in key:
906 family = self.ToolConfig[key]
907 if family not in self.ActiveFamilies:
908 self.ActiveFamilies.append(family)
909
910
911 def ParsePackage(self, packagePaths=None):
912 if packagePaths == None:
913 return
914
915 for packagePath in packagePaths:
916 self.Packages.append(PackageSurfaceArea(self, packagePath))
917
918 def ParsePlatform(self, platformPaths=None):
919 # Only one active platform is allowed
920 activePlatformPath = ""
921 if self.TargetConfig["ACTIVE_PLATFORM"] == "":
922 if platformPaths != None and len(platformPaths) == 1:
923 activePlatformPath = platformPaths[0]
924 else:
925 raise Exception("No active platform specified or implied!")
926 else:
927 activePlatformPath = os.path.normpath(self.TargetConfig["ACTIVE_PLATFORM"])
928
929 self.ActivePlatform = PlatformSurfaceArea(self, activePlatformPath)
930 self.Platforms.append(self.ActivePlatform)
931
932 def ParseTargetConfig(self):
933 self.TargetConfig = BuildConfig.TargetConfig(self.SubPath(self._Target))
934 # print self.TargetConfig
935
936 def ParseToolConfig(self):
937 self.ToolConfig = BuildConfig.ToolConfig(self.SubPath(self.TargetConfig["TOOL_CHAIN_CONF"]))
938
939 def GetModule(self, guid, version, packageGuid, packageVersion):
940 moduleGuidIndex = self.ModuleXref["GUID"]
941 if guid not in moduleGuidIndex:
942 print "! No module has GUID=" + guid
943 return ""
944
945 moduleVersionList = moduleGuidIndex[guid]
946 # print moduleVersionList
947 moduleList = []
948 module = ""
949 if version != "":
950 if version in moduleVersionList:
951 moduleList = moduleVersionList[version]
952 else:
953 return ""
954 else:
955 ## no version given, return the first one
956 version = "0.0"
957 for ver in moduleVersionList:
958 if ver > version: version = ver
959 moduleList = moduleVersionList[version]
960
961 if packageGuid == "":
962 ## if no package GUID given, just return the latest one
963 version = "0.0"
964 for m in moduleList:
965 if m.Package.Version > version:
966 version = m.Package.Version
967 module = m
968 else:
969 version = "0.0"
970 for m in moduleList:
971 if m.Package.GuidValue != packageGuid: continue
972 if packageVersion == "":
973 ## if no version given, just return the latest
974 if m.Package.Version > version:
975 version = m.Package.Version
976 module = m
977 elif packageVersion == m.Package.Version:
978 module = m
979 break;
980
981 return module
982
983 def GetModuleByPath(self, path):
984 ownerPackage = ""
985 ownerPackageFullPath = ""
986 for package in self.Packages:
987 ownerPackageFullPath = self.SubPath(package.Path)
988 if path.startswith(packageFullPath): break
989
990 if ownerPackage == "":
991 return ""
992
993 for module in ownerPackage.Modules:
994 moduleFullPath = os.path.join(ownerPackageFullPath, module.Path)
995 if moduleFullPath == path:
996 return module
997
998 return ""
999
1000 def GetPackage(self, guid, version):
1001 packageGuidIndex = self.PackageXref["GUID"]
1002 if guid not in packageGuidIndex:
1003 # raise Exception("No package has GUID=" + guid)
1004 return ""
1005
1006 packageList = packageGuidIndex[guid]
1007 package = ""
1008 if version != "":
1009 if version in packageList:
1010 package = packageList[version]
1011 else:
1012 ## no version given, return the latest one
1013 version = "0.0"
1014 for ver in packageList:
1015 if ver > version: version = ver
1016 package = packageList[version]
1017
1018 return package
1019
1020 def GetPlatform(self, guid, version):
1021 pass
1022
1023 def GetPlatformByPath(self, path):
1024 for platform in self.Platforms:
1025 platformFullPath = self.SubPath(platform.Path)
1026 if platformFullPath == path:
1027 return platform
1028 return ""
1029
1030 def GetLibraryInterface(self, name):
1031 if name not in self.LibraryInterfaceXref["NAME"]:
1032 return ""
1033 return self.LibraryInterfaceXref["NAME"][name]
1034
1035 def SubPath(self, *relativePathList):
1036 return os.path.normpath(os.path.join(self.Path, *relativePathList))
1037
1038 def SetupCrossRef(self):
1039 ##
1040 ## setup platform cross reference as nest-dict
1041 ## guid -> {version -> platform}
1042 ##
1043 ## platformList = self.Platforms
1044 ## for p in platformList:
1045 ## guid = p.GuidValue
1046 ## version = p.Version
1047 ## if guid not in self.PlatformIndex:
1048 ## self.PlatformIndex[guid] = {}
1049 ## if version in self.PlatformIndex[guid]:
1050 ## raise Exception("Duplicate platform")
1051 ## self.PlatformIndex[guid][version] = p
1052
1053 ##
1054 ## setup package cross reference as nest-dict
1055 ## guid -> {version -> package}
1056 ## name -> [package list]
1057 ## path -> package
1058 ##
1059 packageList = self.Packages
1060 for p in packageList:
1061 guid = p.GuidValue
1062 version = p.Version
1063 packageGuidIndex = self.PackageXref["GUID"]
1064 if guid not in packageGuidIndex:
1065 packageGuidIndex[guid] = {}
1066 if version in packageGuidIndex[guid]:
1067 raise Exception("Duplicate package: %s-%s [%s]" % p.Name, version, guid)
1068 packageGuidIndex[guid][version] = p
1069
1070 packageNameIndex = self.PackageXref["NAME"]
1071 name = p.Name
1072 if name not in packageNameIndex:
1073 packageNameIndex[name] = []
1074 packageNameIndex[name].append(p)
1075
1076 packagePathIndex = self.PackageXref["PATH"]
1077 path = p.Path
1078 if path in packagePathIndex:
1079 raise Exception("Duplicate package: %s %s" % p.Name, p.Path)
1080 packagePathIndex[path] = p.Path
1081
1082 ##
1083 ## setup library class cross reference as
1084 ## library class name -> library class object
1085 ##
1086 for lcname in p.LibraryInterfaces:
1087 if lcname in self.LibraryInterfaceXref["NAME"]:
1088 raise Exception("Duplicate library class: %s in package %s" % (lcname, name))
1089 lcInterface = p.LibraryInterfaces[lcname]
1090 self.LibraryInterfaceXref["NAME"][lcname] = lcInterface
1091
1092 if lcInterface not in self.LibraryInterfaceXref["PATH"]:
1093 self.LibraryInterfaceXref["PATH"][lcInterface] = []
1094 self.LibraryInterfaceXref["PATH"][lcInterface].append(lcname)
1095
1096 ##
1097 ## setup package cross reference as nest-dict
1098 ## guid -> {version -> [module list]}
1099 ## name -> [module list]
1100 ## path -> module
1101 for p in packageList:
1102 p.ParseMsaFile()
1103
1104 moduleList = p.Modules
1105 for m in moduleList:
1106 name = m.Name
1107 path = m.Path
1108 guid = m.GuidValue
1109 version = m.Version
1110 moduleGuidIndex = self.ModuleXref["GUID"]
1111 if guid not in moduleGuidIndex:
1112 moduleGuidIndex[guid] = {}
1113 else:
1114 print "! Duplicate module GUID found:", guid, path
1115
1116 if version not in moduleGuidIndex[guid]:
1117 moduleGuidIndex[guid][version] = []
1118 if m in moduleGuidIndex[guid][version]:
1119 raise Exception("Duplicate modules in the same package: %s-%s [%s]" % (name, version, guid))
1120 moduleGuidIndex[guid][version].append(m)
1121
1122 modulePathIndex = self.ModuleXref["PATH"]
1123 path = p.SubPath(m.Path)
1124 if path in modulePathIndex:
1125 raise Exception("Duplicate modules in the same package: %s %s" % (name, path))
1126 modulePathIndex[path] = m
1127
1128 moduleNameIndex = self.ModuleXref["NAME"]
1129 if name not in moduleNameIndex:
1130 moduleNameIndex[name] = []
1131 moduleNameIndex[name].append(m)
1132
1133 def GetToolDef(self, toolchain, target, arch, toolcode, attr):
1134 return self.ToolConfig[(toolchain, target, arch, toolcode, attr)]
1135
1136 def Parse(self):
1137 self.ParseConfig()
1138 self.ParseWorkspaceDatabase()
1139
1140 def SetupBuild(self):
1141 # active archs
1142 self.ActiveArchs = self.TargetConfig["TARGET_ARCH"].split()
1143 if self.ActiveArchs == []:
1144 self.ActiveArchs = self.ActivePlatform.Archs
1145
1146 # active targets
1147 self.ActiveTargets = self.TargetConfig["TARGET"].split()
1148 if self.ActiveTargets == []:
1149 self.ActiveTargets = self.ActivePlatform.Targets
1150
1151
1152 # active modules
1153 for msa in self._Elements["ModuleList"]:
1154 module = self.GetModuleByPath(msa)
1155 if module == "":
1156 raise Exception(msa + " is not in any package!")
1157 self.ActiveModules.append(module)
1158 self.IndividualModuleBuild = True
1159 if self.TargetConfig["MULTIPLE_THREAD"].upper() == "ENABLE":
1160 self.MultiThreadBuild = True
1161 if "MAX_CONCURRENT_THREAD_NUMBER" in self.TargetConfig:
1162 self.ThreadCount = self.TargetConfig["MAX_CONCURRENT_THREAD_NUMBER"]
1163 else:
1164 self.ThreadCount = "1"
1165
1166 def Postprocess(self):
1167 self.ParsePackage(self._Elements["PackageList"])
1168 self.SetupCrossRef()
1169 self.ParsePlatform(self._Elements["PlatformList"])
1170 self.SetupBuild()
1171
1172 ## def SetupEnvironment(self):
1173 ## config = BuildConfig.Config(self.SubPath(self._PlatformBuildPath))
1174 ## for name in config:
1175 ## self.Environment[name] = config[name]
1176 ##
1177 ## config = BuildConfig.Config(self.SubPath(self._ModuleBuildPath))
1178 ## for name in config:
1179 ## self.Environment[name] = config[name]
1180 ##
1181 ## multiThread = self.TargetConfig["MULTIPLE_THREAD"].upper()
1182 ## threadNumber = self.TargetConfig["MAX_CONCURRENT_THREAD_NUMBER"]
1183 ## if multiThread == "" or multiThread == "FALSE":
1184 ## self.Environment["MULTIPLE_THREAD"] = False
1185 ## self.Environment["MAX_CONCURRENT_THREAD_NUMBER"] = 1
1186 ## else:
1187 ## self.Environment["MULTIPLE_THREAD"] = True
1188 ## if threadNumber != "":
1189 ## self.Environment["MAX_CONCURRENT_THREAD_NUMBER"] = threadNumber
1190 ## else:
1191 ## self.Environment["MAX_CONCURRENT_THREAD_NUMBER"] = 2
1192
1193 class PackageSurfaceArea(FrameworkElement.Package, SurfaceAreaElement):
1194 def __init__(self, workspace, path):
1195 FrameworkElement.Package.__init__(self)
1196
1197 self.Path = os.path.normpath(path)
1198 self.Dir = os.path.dirname(self.Path)
1199 SurfaceAreaElement.__init__(self, workspace, workspace, None, True, True)
1200
1201 def _SpdHeader(self, xpath):
1202 dom = XmlNode(self._Root, xpath)
1203 self.Name = XmlElementData(XmlNode(dom, "/SpdHeader/PackageName"))
1204 self.GuidValue = XmlElementData(XmlNode(dom, "/SpdHeader/GuidValue")).upper()
1205 self.Version = XmlElementData(XmlNode(dom, "/SpdHeader/Version"))
1206
1207 def _PackageDefinitions(self, xpath):
1208 dom = XmlNode(self._Root, xpath)
1209 self.ReadOnly = XmlElementData(XmlNode(dom, "/PackageDefinitions/ReadOnly"))
1210 self.Repackage = XmlElementData(XmlNode(dom, "/PackageDefinitions/RePackage"))
1211
1212 def _LibraryClassDeclarations(self, xpath):
1213 dom = XmlNode(self._Root, xpath)
1214 lcdList = XmlList(dom, "/LibraryClassDeclarations/LibraryClass")
1215 lcds = []
1216 for lc in lcdList:
1217 lcds.append(LibraryDeclaration(self._Workspace, self, lc))
1218 self._Elements["LibraryClassDeclarations"] = lcds
1219
1220 def _IndustryStdIncludes(self, xpath):
1221 dom = XmlNode(self._Root, xpath)
1222 headerList = XmlList(dom, "/IndustryStdIncludes/IndustryStdHeader")
1223 headers = []
1224 for h in headerList:
1225 headers.append(IndustryStdHeader(self._Workspace, self, h))
1226 self._Elements["IndustryStdIncludes"] = headers
1227
1228 def _MsaFiles(self, xpath):
1229 dom = XmlNode(self._Root, xpath)
1230 msaFileList = XmlList(dom, "/MsaFiles/Filename")
1231 msaFiles = []
1232 for msa in msaFileList:
1233 filePath = os.path.normpath(XmlElementData(msa))
1234 msaFiles.append(filePath)
1235 self._Elements["MsaFiles"] = msaFiles
1236
1237 def _PackageHeaders(self, xpath):
1238 dom = XmlNode(self._Root, xpath)
1239 headerList = XmlList(dom, "/PackageHeaders/IncludePkgHeader")
1240 headers = []
1241 for h in headerList:
1242 headers.append(PackageHeader(self._Workspace, self, h))
1243 self._Elements["PackageHeaders"] = headers
1244
1245 def _GuidDeclarations(self, xpath):
1246 dom = XmlNode(self._Root, xpath)
1247 guidList = XmlList(dom, "/GuidDeclarations/Entry")
1248 guids = []
1249 for guid in guidList:
1250 guids.append(GuidDeclaration(self._Workspace, self, guid))
1251 self._Elements["GuidDeclarations"] = guids
1252
1253 def _ProtocolDeclarations(self, xpath):
1254 dom = XmlNode(self._Root, xpath)
1255 protocolList = XmlList(dom, "/ProtocolDeclarations/Entry")
1256 protocols = []
1257 for p in protocolList:
1258 protocols.append(ProtocolDeclaration(self._Workspace, self, p))
1259 self._Elements["ProtocolDeclarations"] = protocols
1260
1261 def _PpiDeclarations(self, xpath):
1262 dom = XmlNode(self._Root, xpath)
1263 ppiList = XmlList(dom, "/PpiDeclarations/Entry")
1264 ppis = []
1265 for p in ppiList:
1266 ppis.append(PpiDeclaration(self._Workspace, self, p))
1267 self._Elements["PpiDeclarations"] = ppis
1268
1269 def _PcdDeclarations(self, xpath):
1270 dom = XmlNode(self._Root, xpath)
1271 pcdList = XmlList(dom, "/PcdDeclarations/PcdEntry")
1272 pcds = []
1273 for p in pcdList:
1274 pcds.append(PcdDeclaration(self._Workspace, self, p))
1275 self._Elements["PcdDeclarations"] = pcds
1276
1277 def SubPath(self, *relativePathList):
1278 return os.path.normpath(os.path.join(self.Dir, *relativePathList))
1279
1280 def Parse(self):
1281 self._Root = xml.dom.minidom.parse(self._Workspace.SubPath(self.Path))
1282 assert self._Root.documentElement.tagName == "PackageSurfaceArea"
1283
1284 # print "Parsing...",self.Path
1285 self._SpdHeader("/PackageSurfaceArea/SpdHeader")
1286 self._PackageDefinitions("/PackageSurfaceArea/PackageDefinitions")
1287 self._LibraryClassDeclarations("/PackageSurfaceArea/LibraryClassDeclarations")
1288 self._IndustryStdIncludes("/PackageSurfaceArea/IndustryStdIncludes")
1289 self._MsaFiles("/PackageSurfaceArea/MsaFiles")
1290 self._PackageHeaders("/PackageSurfaceArea/PackageHeaders")
1291 self._GuidDeclarations("/PackageSurfaceArea/GuidDeclarations")
1292 self._ProtocolDeclarations("/PackageSurfaceArea/ProtocolDeclarations")
1293 self._PpiDeclarations("/PackageSurfaceArea/PpiDeclarations")
1294 self._PcdDeclarations("/PackageSurfaceArea/PcdDeclarations")
1295
1296 def Postprocess(self):
1297 # setup guid, protocol, ppi
1298 for guid in self._Elements["GuidDeclarations"]:
1299 if guid.CName in self.Guids:
1300 print "! Duplicate GUID CName (%s) in package %s" % (guid.CName, self.Path)
1301 self.Guids[guid.CName] = guid
1302
1303 for protocol in self._Elements["ProtocolDeclarations"]:
1304 if protocol.CName in self.Protocols:
1305 print "! Duplicate Protocol CName (%s) in package %s" % (protocol.CName, self.Path)
1306 self.Protocols[protocol.CName] = protocol
1307
1308 for ppi in self._Elements["PpiDeclarations"]:
1309 if ppi.CName in self.Ppis:
1310 print "! Duplicate PPI CName (%s) in package (%s)" % (ppi.CName, self.Path)
1311 self.Ppis[ppi.CName] = ppi
1312
1313 # package header
1314 for inc in self._Elements["PackageHeaders"]:
1315 if inc.ModuleType not in self.PackageIncludes:
1316 self.PackageIncludes[inc.ModuleType] = []
1317 self.PackageIncludes[inc.ModuleType].append(inc.Path)
1318
1319 # library class
1320 for lcd in self._Elements["LibraryClassDeclarations"]:
1321 if lcd.Name in self.LibraryInterfaces:
1322 raise "Duplicate library class: " + lcd.Name
1323 self.LibraryInterfaces[lcd.Name] = lcd
1324
1325 # parse mas files
1326 # self.ParseMsaFile()
1327 # resolve RecommendedInstance
1328
1329 def ParseMsaFile(self):
1330 for msaFilePath in self._Elements["MsaFiles"]:
1331 self.Modules.append(ModuleSurfaceArea(self._Workspace, self, msaFilePath))
1332
1333 class PlatformSurfaceArea(FrameworkElement.Platform, SurfaceAreaElement):
1334 def __init__(self, workspace, path):
1335 FrameworkElement.Platform.__init__(self)
1336
1337 self.Path = os.path.normpath(path)
1338 self.Dir = os.path.dirname(self.Path)
1339 SurfaceAreaElement.__init__(self, workspace)
1340
1341 def _PlatformHeader(self, xpath):
1342 dom = XmlNode(self._Root, xpath)
1343 if dom == '': return
1344 self.Name = XmlElementData(XmlNode(dom, "/PlatformHeader/PlatformName"))
1345 self.GuidValue = XmlElementData(XmlNode(dom, "/PlatformHeader/GuidValue")).upper()
1346 self.Version = XmlElementData(XmlNode(dom, "/PlatformHeader/Version"))
1347
1348 def _PlatformDefinitions(self, xpath):
1349 dom = XmlNode(self._Root, xpath)
1350 if dom == '': return
1351 self.Archs = XmlElementData(XmlNode(dom, "/PlatformDefinitions/SupportedArchitectures")).split()
1352 if self.Archs == []:
1353 raise Exception("No ARCH specified in platform " + self.Path)
1354 self.Targets = XmlElementData(XmlNode(dom, "/PlatformDefinitions/BuildTargets")).split()
1355 self.OutputPath = os.path.normpath(XmlElementData(XmlNode(dom, "/PlatformDefinitions/OutputDirectory")))
1356
1357 def _Flash(self, xpath):
1358 dom = XmlNode(self._Root, xpath)
1359 if dom == '': return
1360
1361 def _FrameworkModules(self, xpath):
1362 dom = XmlNode(self._Root, xpath)
1363 if dom == '': return
1364 moduleList = XmlList(dom, "/FrameworkModules/ModuleSA")
1365 modules = []
1366 for m in moduleList:
1367 modules.append(PlatformModule(self._Workspace, self, m))
1368 self._Elements["FrameworkModules"] = modules
1369
1370 def _DynamicPcdBuildDefinitions(self, xpath):
1371 dom = XmlNode(self._Root, xpath)
1372 if dom == '': return
1373
1374 def _BuildOptions(self, xpath):
1375 dom = XmlNode(self._Root, xpath)
1376 if dom == '': return
1377 self.BuildOptions = self.GetBuildOptionList(XmlNode(dom, "/BuildOptions/Options"))
1378 # print self.BuildOptions
1379
1380 def _UserExtensions(self, xpath):
1381 domList = XmlList(self._Root, xpath)
1382 if domList == []: return
1383 for extension in domList:
1384 userId = XmlAttribute(extension, "UserID")
1385 identifier = XmlAttribute(extension, "Identifier")
1386
1387 if userId == '' or identifier == '':
1388 raise Exception("No UserId or Identifier specified")
1389 if userId != "TianoCore": continue
1390 if identifier not in self.UserExtensions:
1391 self.UserExtensions[identifier] = []
1392
1393 contentList = self.UserExtensions[identifier]
1394 for node in extension.childNodes:
1395 # print node.nodeType
1396 contentList.append(node.cloneNode(True))
1397
1398 def Parse(self):
1399 self._Root = xml.dom.minidom.parse(self._Workspace.SubPath(self.Path))
1400 assert self._Root.documentElement.tagName == "PlatformSurfaceArea"
1401
1402 self._PlatformHeader("/PlatformSurfaceArea/PlatformHeader")
1403 self._PlatformDefinitions("/PlatformSurfaceArea/PlatformDefinitions")
1404 self._Flash("/PlatformSurfaceArea/Flash")
1405 self._FrameworkModules("/PlatformSurfaceArea/FrameworkModules")
1406 self._DynamicPcdBuildDefinitions("/PlatformSurfaceArea/DynamicPcdBuildDefinitions")
1407 self._BuildOptions("/PlatformSurfaceArea/BuildOptions")
1408 self._UserExtensions("/PlatformSurfaceArea/UserExtensions")
1409
1410 def Postprocess(self):
1411 # summarize all library modules for build
1412 for module in self._Elements["FrameworkModules"]:
1413 for arch in module.Archs:
1414 if arch not in self.Modules:
1415 self.Modules[arch] = []
1416 self.Modules[arch].append(module)
1417
1418 if arch not in self.Libraries:
1419 self.Libraries[arch] = []
1420 for li in module.Libraries:
1421 if li in self.Libraries[arch]: continue
1422 self.Libraries[arch].append(li)
1423
1424 # FV
1425 for fvName in module.FvBindings:
1426 if fvName not in self.Fvs:
1427 self.Fvs[fvName] = []
1428 self.Fvs[fvName].append(module)
1429 # build options
1430 # user extension
1431
1432 ## def SetupEnvironment(self):
1433 ## self.Environment["PLATFORM"] = self.Name
1434 ## self.Environment["PLATFORM_GUID"] = self.GuidValue
1435 ## self.Environment["PLATFORM_VERSION"] = self.Version
1436 ## self.Environment["PLATFORM_RELATIVE_DIR"] = self.Path
1437 ## self.Environment["PLATFORM_OUTPUT_DIR"] = self.OutputPath
1438
1439 def PrintWorkspace(ws):
1440 print "\nPlatforms:\n"
1441 for guid in ws.PlatformXref["GUID"]:
1442 for ver in ws.PlatformXref["GUID"][guid]:
1443 platform = ws.PlatformXref["GUID"][guid][ver]
1444 print " %s %s-%s" % (guid, platform.Name, ver)
1445 for pm in platform.Modules:
1446 print " %-40s %-10s <%s-%s>" % (pm.Module.Name+"-"+pm.Module.Version,
1447 ListString(pm.Archs), pm.Module.Package.Name,
1448 pm.Module.Package.Version)
1449 for li in pm.Libraries:
1450 print " %-47s <%s-%s>" % (li.Module.Name+"-"+li.Module.Version,
1451 li.Module.Package.Name, li.Module.Package.Version)
1452 print ""
1453
1454 print "\nPackages:\n"
1455 for guid in ws.PackageXref["GUID"]:
1456 for ver in ws.PackageXref["GUID"][guid]:
1457 print " %s %s-%s" % (guid, ws.PackageXref["GUID"][guid][ver].Name, ver)
1458
1459 print "\nModules:\n"
1460 for guid in ws.ModuleXref["GUID"]:
1461 for ver in ws.ModuleXref["GUID"][guid]:
1462 for module in ws.ModuleXref["GUID"][guid][ver]:
1463 print " %s %-40s [%s-%s]" % (guid, module.Name+"-"+ver, module.Package.Name, module.Package.Version)
1464 print " Depending on packages:"
1465 for arch in module.IncludePaths:
1466 print " ", arch, ":"
1467 for path in module.IncludePaths[arch]:
1468 print " ", path
1469 print "\n"
1470
1471 for arch in module.IncludeFiles:
1472 print " ", arch, ":"
1473 for path in module.IncludeFiles[arch]:
1474 print " ", path
1475 print "\n"
1476
1477 print " Source files:"
1478 for arch in module.SourceFiles:
1479 print " ", arch, ":"
1480 for type in module.SourceFiles[arch]:
1481 for src in module.SourceFiles[arch][type]:
1482 print " %-40s (%s)" % (src.Path, src.Type)
1483 print "\n"
1484 print "\nLibrary Classes:"
1485 for name in ws.LibraryInterfaceXref["NAME"]:
1486 lc = ws.LibraryInterfaceXref["NAME"][name]
1487 pkgPath = os.path.dirname(lc.Package.Path)
1488 print "\n [%s] <%s>" % (lc.Name, pkgPath + os.path.sep + lc.Path)
1489
1490 print " Produced By:"
1491 for li in lc.Instances:
1492 print " %-40s <%s>" % (li.Name+"-"+li.Version, li.Package.SubPath(li.Path))
1493
1494 print " Consumed By:"
1495 for li in lc.Consumers:
1496 print " %-40s <%s>" % (li.Name+"-"+li.Version, li.Package.SubPath(li.Path))
1497
1498 print "\nActive Platform:"
1499 for arch in ws.ActivePlatform.Libraries:
1500 print " Library Instances (%s) (%d libraries)" % (arch , len(ws.ActivePlatform.Libraries[arch]))
1501 for li in ws.ActivePlatform.Libraries[arch]:
1502 print " %s-%s (%s-%s)" % (li.Module.Name, li.Module.Version,
1503 li.Module.Package.Name, li.Module.Package.Version)
1504
1505 for arch in ws.ActivePlatform.Modules:
1506 print " Driver Modules (%s) (%d modules)" % (arch, len(ws.ActivePlatform.Modules[arch]))
1507 for m in ws.ActivePlatform.Modules[arch]:
1508 print " %s-%s (%s-%s)" % (m.Module.Name, m.Module.Version,
1509 m.Module.Package.Name, m.Module.Package.Version)
1510
1511 for fv in ws.ActivePlatform.Fvs:
1512 print
1513 print " Firmware Volume (%s) (%d modules)" % (fv, len(ws.ActivePlatform.Fvs[fv]))
1514 for m in ws.ActivePlatform.Fvs[fv]:
1515 print " %s-%s (%s-%s)" % (m.Module.Name, m.Module.Version,
1516 m.Module.Package.Name, m.Module.Package.Version)
1517
1518 # for test
1519 if __name__ == "__main__":
1520 # os.environ["WORKSPACE"]
1521 workspacePath = os.getenv("WORKSPACE", os.getcwd())
1522 workspacePath = "C:\\home\\src\\R9\\pbuild"
1523 saFile = ""
1524 if len(sys.argv) <= 1:
1525 saFile = os.path.join(workspacePath, "Tools/Conf/FrameworkDatabase.db")
1526 else:
1527 saFile = sys.argv[1]
1528
1529 print "Parsing ... %s\n" % saFile
1530
1531 startTime = time.clock()
1532 sa = Workspace(workspacePath, [], [])
1533 # sa = PackageSurfaceArea(saFile)
1534 # sa = PlatformSurfaceArea(saFile)
1535 # sa = ModuleSurfaceArea(saFile)
1536 # print sa
1537
1538 PrintWorkspace(sa)
1539 print "\n[Finished in %fs]" % (time.clock() - startTime)
1540