]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/Common/EdkIIWorkspaceBuild.py
BaseTools: use built in OrderedDict instead of custom version.
[mirror_edk2.git] / BaseTools / Source / Python / Common / EdkIIWorkspaceBuild.py
1 ## @file
2 # This file is used to define each component of the build database
3 #
4 # Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
5 # This program and the accompanying materials
6 # are licensed and made available under the terms and conditions of the BSD License
7 # which accompanies this distribution. The full text of the license may be found at
8 # http://opensource.org/licenses/bsd-license.php
9 #
10 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12 #
13
14 ##
15 # Import Modules
16 #
17 import Common.LongFilePathOs as os, string, copy, pdb, copy
18 import EdkLogger
19 import DataType
20 from InfClassObject import *
21 from DecClassObject import *
22 from DscClassObject import *
23 from String import *
24 from BuildToolError import *
25 from collections import OrderedDict
26 import Database as Database
27 import time as time
28
29 ## PcdClassObject
30 #
31 # This Class is used for PcdObject
32 #
33 # @param object: Inherited from object class
34 # @param Name: Input value for Name of Pcd, default is None
35 # @param Guid: Input value for Guid of Pcd, default is None
36 # @param Type: Input value for Type of Pcd, default is None
37 # @param DatumType: Input value for DatumType of Pcd, default is None
38 # @param Value: Input value for Value of Pcd, default is None
39 # @param Token: Input value for Token of Pcd, default is None
40 # @param MaxDatumSize: Input value for MaxDatumSize of Pcd, default is None
41 # @param SkuInfoList: Input value for SkuInfoList of Pcd, default is {}
42 # @param IsOverrided: Input value for IsOverrided of Pcd, default is False
43 #
44 # @var TokenCName: To store value for TokenCName
45 # @var TokenSpaceGuidCName: To store value for TokenSpaceGuidCName
46 # @var Type: To store value for Type
47 # @var DatumType: To store value for DatumType
48 # @var TokenValue: To store value for TokenValue
49 # @var MaxDatumSize: To store value for MaxDatumSize
50 # @var SkuInfoList: To store value for SkuInfoList
51 # @var IsOverrided: To store value for IsOverrided
52 # @var Phase: To store value for Phase, default is "DXE"
53 #
54 class PcdClassObject(object):
55 def __init__(self, Name = None, Guid = None, Type = None, DatumType = None, Value = None, Token = None, MaxDatumSize = None, SkuInfoList = {}, IsOverrided = False):
56 self.TokenCName = Name
57 self.TokenSpaceGuidCName = Guid
58 self.Type = Type
59 self.DatumType = DatumType
60 self.DefaultValue = Value
61 self.TokenValue = Token
62 self.MaxDatumSize = MaxDatumSize
63 self.SkuInfoList = SkuInfoList
64 self.IsOverrided = IsOverrided
65 self.Phase = "DXE"
66
67 ## Convert the class to a string
68 #
69 # Convert each member of the class to string
70 # Organize to a signle line format string
71 #
72 # @retval Rtn Formatted String
73 #
74 def __str__(self):
75 Rtn = '\tTokenCName=' + str(self.TokenCName) + ', ' + \
76 'TokenSpaceGuidCName=' + str(self.TokenSpaceGuidCName) + ', ' + \
77 'Type=' + str(self.Type) + ', ' + \
78 'DatumType=' + str(self.DatumType) + ', ' + \
79 'DefaultValue=' + str(self.DefaultValue) + ', ' + \
80 'TokenValue=' + str(self.TokenValue) + ', ' + \
81 'MaxDatumSize=' + str(self.MaxDatumSize) + ', '
82 for Item in self.SkuInfoList.values():
83 Rtn = Rtn + 'SkuId=' + Item.SkuId + ', ' + 'SkuIdName=' + Item.SkuIdName
84 Rtn = Rtn + str(self.IsOverrided)
85
86 return Rtn
87
88 ## Override __eq__ function
89 #
90 # Check whether pcds are the same
91 #
92 # @retval False The two pcds are different
93 # @retval True The two pcds are the same
94 #
95 def __eq__(self, Other):
96 return Other is not None and self.TokenCName == Other.TokenCName and self.TokenSpaceGuidCName == Other.TokenSpaceGuidCName
97
98 ## Override __hash__ function
99 #
100 # Use (TokenCName, TokenSpaceGuidCName) as key in hash table
101 #
102 # @retval truple() Key for hash table
103 #
104 def __hash__(self):
105 return hash((self.TokenCName, self.TokenSpaceGuidCName))
106
107 ## LibraryClassObject
108 #
109 # This Class defines LibraryClassObject used in BuildDatabase
110 #
111 # @param object: Inherited from object class
112 # @param Name: Input value for LibraryClassName, default is None
113 # @param SupModList: Input value for SupModList, default is []
114 # @param Type: Input value for Type, default is None
115 #
116 # @var LibraryClass: To store value for LibraryClass
117 # @var SupModList: To store value for SupModList
118 # @var Type: To store value for Type
119 #
120 class LibraryClassObject(object):
121 def __init__(self, Name = None, SupModList = [], Type = None):
122 self.LibraryClass = Name
123 self.SupModList = SupModList
124 if Type is not None:
125 self.SupModList = CleanString(Type).split(DataType.TAB_SPACE_SPLIT)
126
127 ## ModuleBuildClassObject
128 #
129 # This Class defines ModuleBuildClass
130 #
131 # @param object: Inherited from object class
132 #
133 # @var DescFilePath: To store value for DescFilePath
134 # @var BaseName: To store value for BaseName
135 # @var ModuleType: To store value for ModuleType
136 # @var Guid: To store value for Guid
137 # @var Version: To store value for Version
138 # @var PcdIsDriver: To store value for PcdIsDriver
139 # @var BinaryModule: To store value for BinaryModule
140 # @var CustomMakefile: To store value for CustomMakefile
141 # @var Specification: To store value for Specification
142 # @var Shadow To store value for Shadow
143 # @var LibraryClass: To store value for LibraryClass, it is a list structure as
144 # [ LibraryClassObject, ...]
145 # @var ModuleEntryPointList: To store value for ModuleEntryPointList
146 # @var ModuleUnloadImageList: To store value for ModuleUnloadImageList
147 # @var ConstructorList: To store value for ConstructorList
148 # @var DestructorList: To store value for DestructorList
149 # @var Binaries: To store value for Binaries, it is a list structure as
150 # [ ModuleBinaryClassObject, ...]
151 # @var Sources: To store value for Sources, it is a list structure as
152 # [ ModuleSourceFilesClassObject, ... ]
153 # @var LibraryClasses: To store value for LibraryClasses, it is a set structure as
154 # { [LibraryClassName, ModuleType] : LibraryClassInfFile }
155 # @var Protocols: To store value for Protocols, it is a list structure as
156 # [ ProtocolName, ... ]
157 # @var Ppis: To store value for Ppis, it is a list structure as
158 # [ PpiName, ... ]
159 # @var Guids: To store value for Guids, it is a list structure as
160 # [ GuidName, ... ]
161 # @var Includes: To store value for Includes, it is a list structure as
162 # [ IncludePath, ... ]
163 # @var Packages: To store value for Packages, it is a list structure as
164 # [ DecFileName, ... ]
165 # @var Pcds: To store value for Pcds, it is a set structure as
166 # { [(PcdCName, PcdGuidCName)] : PcdClassObject}
167 # @var BuildOptions: To store value for BuildOptions, it is a set structure as
168 # { [BuildOptionKey] : BuildOptionValue}
169 # @var Depex: To store value for Depex
170 #
171 class ModuleBuildClassObject(object):
172 def __init__(self):
173 self.AutoGenVersion = 0
174 self.DescFilePath = ''
175 self.BaseName = ''
176 self.ModuleType = ''
177 self.Guid = ''
178 self.Version = ''
179 self.PcdIsDriver = ''
180 self.BinaryModule = ''
181 self.Shadow = ''
182 self.CustomMakefile = {}
183 self.Specification = {}
184 self.LibraryClass = []
185 self.ModuleEntryPointList = []
186 self.ModuleUnloadImageList = []
187 self.ConstructorList = []
188 self.DestructorList = []
189
190 self.Binaries = []
191 self.Sources = []
192 self.LibraryClasses = OrderedDict()
193 self.Libraries = []
194 self.Protocols = []
195 self.Ppis = []
196 self.Guids = []
197 self.Includes = []
198 self.Packages = []
199 self.Pcds = {}
200 self.BuildOptions = {}
201 self.Depex = ''
202
203 ## Convert the class to a string
204 #
205 # Convert member DescFilePath of the class to a string
206 #
207 # @retval string Formatted String
208 #
209 def __str__(self):
210 return self.DescFilePath
211
212 ## Override __eq__ function
213 #
214 # Check whether ModuleBuildClassObjects are the same
215 #
216 # @retval False The two ModuleBuildClassObjects are different
217 # @retval True The two ModuleBuildClassObjects are the same
218 #
219 def __eq__(self, Other):
220 return self.DescFilePath == str(Other)
221
222 ## Override __hash__ function
223 #
224 # Use DescFilePath as key in hash table
225 #
226 # @retval string Key for hash table
227 #
228 def __hash__(self):
229 return hash(self.DescFilePath)
230
231 ## PackageBuildClassObject
232 #
233 # This Class defines PackageBuildClass
234 #
235 # @param object: Inherited from object class
236 #
237 # @var DescFilePath: To store value for DescFilePath
238 # @var PackageName: To store value for PackageName
239 # @var Guid: To store value for Guid
240 # @var Version: To store value for Version
241 # @var Protocols: To store value for Protocols, it is a set structure as
242 # { [ProtocolName] : Protocol Guid, ... }
243 # @var Ppis: To store value for Ppis, it is a set structure as
244 # { [PpiName] : Ppi Guid, ... }
245 # @var Guids: To store value for Guids, it is a set structure as
246 # { [GuidName] : Guid, ... }
247 # @var Includes: To store value for Includes, it is a list structure as
248 # [ IncludePath, ... ]
249 # @var LibraryClasses: To store value for LibraryClasses, it is a set structure as
250 # { [LibraryClassName] : LibraryClassInfFile }
251 # @var Pcds: To store value for Pcds, it is a set structure as
252 # { [(PcdCName, PcdGuidCName)] : PcdClassObject}
253 #
254 class PackageBuildClassObject(object):
255 def __init__(self):
256 self.DescFilePath = ''
257 self.PackageName = ''
258 self.Guid = ''
259 self.Version = ''
260
261 self.Protocols = {}
262 self.Ppis = {}
263 self.Guids = {}
264 self.Includes = []
265 self.LibraryClasses = {}
266 self.Pcds = {}
267
268 ## Convert the class to a string
269 #
270 # Convert member DescFilePath of the class to a string
271 #
272 # @retval string Formatted String
273 #
274 def __str__(self):
275 return self.DescFilePath
276
277 ## Override __eq__ function
278 #
279 # Check whether PackageBuildClassObjects are the same
280 #
281 # @retval False The two PackageBuildClassObjects are different
282 # @retval True The two PackageBuildClassObjects are the same
283 #
284 def __eq__(self, Other):
285 return self.DescFilePath == str(Other)
286
287 ## Override __hash__ function
288 #
289 # Use DescFilePath as key in hash table
290 #
291 # @retval string Key for hash table
292 #
293 def __hash__(self):
294 return hash(self.DescFilePath)
295
296 ## PlatformBuildClassObject
297 #
298 # This Class defines PlatformBuildClass
299 #
300 # @param object: Inherited from object class
301 #
302 # @var DescFilePath: To store value for DescFilePath
303 # @var PlatformName: To store value for PlatformName
304 # @var Guid: To store value for Guid
305 # @var Version: To store value for Version
306 # @var DscSpecification: To store value for DscSpecification
307 # @var OutputDirectory: To store value for OutputDirectory
308 # @var FlashDefinition: To store value for FlashDefinition
309 # @var BuildNumber: To store value for BuildNumber
310 # @var MakefileName: To store value for MakefileName
311 # @var SkuIds: To store value for SkuIds, it is a set structure as
312 # { 'SkuName' : SkuId, '!include' : includefilename, ...}
313 # @var Modules: To store value for Modules, it is a list structure as
314 # [ InfFileName, ... ]
315 # @var Libraries: To store value for Libraries, it is a list structure as
316 # [ InfFileName, ... ]
317 # @var LibraryClasses: To store value for LibraryClasses, it is a set structure as
318 # { (LibraryClassName, ModuleType) : LibraryClassInfFile }
319 # @var Pcds: To store value for Pcds, it is a set structure as
320 # { [(PcdCName, PcdGuidCName)] : PcdClassObject }
321 # @var BuildOptions: To store value for BuildOptions, it is a set structure as
322 # { [BuildOptionKey] : BuildOptionValue }
323 #
324 class PlatformBuildClassObject(object):
325 def __init__(self):
326 self.DescFilePath = ''
327 self.PlatformName = ''
328 self.Guid = ''
329 self.Version = ''
330 self.DscSpecification = ''
331 self.OutputDirectory = ''
332 self.FlashDefinition = ''
333 self.BuildNumber = ''
334 self.MakefileName = ''
335
336 self.SkuIds = {}
337 self.Modules = []
338 self.LibraryInstances = []
339 self.LibraryClasses = {}
340 self.Libraries = {}
341 self.Pcds = {}
342 self.BuildOptions = {}
343
344 ## Convert the class to a string
345 #
346 # Convert member DescFilePath of the class to a string
347 #
348 # @retval string Formatted String
349 #
350 def __str__(self):
351 return self.DescFilePath
352
353 ## Override __eq__ function
354 #
355 # Check whether PlatformBuildClassObjects are the same
356 #
357 # @retval False The two PlatformBuildClassObjects are different
358 # @retval True The two PlatformBuildClassObjects are the same
359 #
360 def __eq__(self, other):
361 return self.DescFilePath == str(other)
362
363 ## Override __hash__ function
364 #
365 # Use DescFilePath as key in hash table
366 #
367 # @retval string Key for hash table
368 #
369 def __hash__(self):
370 return hash(self.DescFilePath)
371
372 ## ItemBuild
373 #
374 # This Class defines Module/Platform/Package databases for build system
375 #
376 # @param object: Inherited from object class
377 # @param Arch: Build arch
378 # @param Platform: Build Platform
379 # @param Package: Build Package
380 # @param Module: Build Module
381 #
382 # @var Arch: To store value for Build Arch
383 # @var PlatformDatabase: To store value for PlatformDatabase, it is a set structure as
384 # { [DscFileName] : PlatformBuildClassObject, ...}
385 # @var PackageDatabase: To store value for PackageDatabase, it is a set structure as
386 # { [DecFileName] : PacakgeBuildClassObject, ...}
387 # @var ModuleDatabase: To store value for ModuleDatabase, it is a list structure as
388 # { [InfFileName] : ModuleBuildClassObject, ...}
389 #
390 class ItemBuild(object):
391 def __init__(self, Arch, Platform = None, Package = None, Module = None):
392 self.Arch = Arch
393 self.PlatformDatabase = {}
394 self.PackageDatabase = {}
395 self.ModuleDatabase = {}
396
397 ## WorkspaceBuild
398 #
399 # This class is used to parse active platform to init all inf/dec/dsc files
400 # Generate module/package/platform databases for build
401 #
402 # @param object: Inherited from object class
403 # @param ActivePlatform: Input value for current active platform
404 # @param WorkspaceDir: Input value for current WorkspaceDir
405 #
406 # @var WorkspaceDir: To store value for WorkspaceDir
407 # @var SupArchList: To store value for SupArchList, selection scope is in below list
408 # EBC | IA32 | X64 | IPF | ARM | PPC | AARCH64
409 # @var BuildTarget: To store value for WorkspaceDir, selection scope is in below list
410 # RELEASE | DEBUG
411 # @var SkuId: To store value for SkuId
412 # @var Fdf: To store value for Fdf
413 # @var FdTargetList: To store value for FdTargetList
414 # @var FvTargetList: To store value for FvTargetList
415 # @var TargetTxt: To store value for TargetTxt, it is a set structure as
416 # TargetTxtClassObject
417 # @var ToolDef: To store value for ToolDef, it is a set structure as
418 # ToolDefClassObject
419 # @var InfDatabase: To store value for InfDatabase, it is a set structure as
420 # { [InfFileName] : InfClassObject}
421 # @var DecDatabase: To store value for DecDatabase, it is a set structure as
422 # { [DecFileName] : DecClassObject}
423 # @var DscDatabase: To store value for DscDatabase, it is a set structure as
424 # { [DscFileName] : DscClassObject}
425 # @var Build: To store value for DscDatabase, it is a set structure as
426 # ItemBuild
427 # @var DscFileName: To store value for Active Platform
428 # @var UnFoundPcdInDsc: To store values for the pcds defined in INF/DEC but not found in DSC, it is a set structure as
429 # { (PcdGuid, PcdCName, Arch) : DecFileName }
430 #
431 class WorkspaceBuild(object):
432 def __init__(self, ActivePlatform, WorkspaceDir):
433 self.WorkspaceDir = NormPath(WorkspaceDir)
434 self.SupArchList = []
435 self.BuildTarget = []
436 self.SkuId = ''
437 self.Fdf = ''
438 self.FdTargetList = []
439 self.FvTargetList = []
440 self.TargetTxt = None
441 self.ToolDef = None
442
443 self.InfDatabase = {}
444 self.DecDatabase = {}
445 self.DscDatabase = {}
446
447 self.UnFoundPcdInDsc = {}
448
449 #
450 # Init build for all arches
451 #
452 self.Build = {}
453 for Arch in DataType.ARCH_LIST:
454 self.Build[Arch] = ItemBuild(Arch)
455
456 #
457 # Init build database
458 #
459 self.Db = Database.Database(DATABASE_PATH)
460 self.Db.InitDatabase()
461
462 #
463 # Get active platform
464 #
465 self.DscFileName = NormPath(ActivePlatform)
466 File = self.WorkspaceFile(self.DscFileName)
467 if os.path.exists(File) and os.path.isfile(File):
468 self.DscDatabase[self.DscFileName] = Dsc(File, False, True, self.WorkspaceDir, self.Db)
469 else:
470 EdkLogger.error("AutoGen", FILE_NOT_FOUND, ExtraData = File)
471
472 #
473 # Parse platform to get module
474 #
475 for DscFile in self.DscDatabase.keys():
476 Platform = self.DscDatabase[DscFile].Platform
477
478 #
479 # Get global information
480 #
481 Tmp = set()
482 for Arch in DataType.ARCH_LIST:
483 for Item in Platform.Header[Arch].SupArchList:
484 Tmp.add(Item)
485 self.SupArchList = list(Tmp)
486 Tmp = set()
487 for Arch in DataType.ARCH_LIST:
488 for Item in Platform.Header[Arch].BuildTargets:
489 Tmp.add(Item)
490 self.BuildTarget = list(Tmp)
491 for Arch in self.SupArchList:
492 self.SkuId = Platform.Header[Arch].SkuIdName
493 self.Fdf = Platform.FlashDefinitionFile.FilePath
494
495 #
496 # Get all inf files
497 #
498 for Item in Platform.LibraryClasses.LibraryList:
499 for Arch in Item.SupArchList:
500 self.AddToInfDatabase(Item.FilePath)
501
502 for Item in Platform.Libraries.LibraryList:
503 for Arch in Item.SupArchList:
504 self.AddToInfDatabase(Item.FilePath)
505
506 for Item in Platform.Modules.ModuleList:
507 for Arch in Item.SupArchList:
508 #
509 # Add modules
510 #
511 Module = Item.FilePath
512 self.AddToInfDatabase(Module)
513 #
514 # Add library used in modules
515 #
516 for Lib in Item.LibraryClasses.LibraryList:
517 self.AddToInfDatabase(Lib.FilePath)
518 self.UpdateLibraryClassOfModule(Module, Lib.Name, Arch, Lib.FilePath)
519
520 #
521 # Parse module to get package
522 #
523 for InfFile in self.InfDatabase.keys():
524 Module = self.InfDatabase[InfFile].Module
525 #
526 # Get all dec
527 #
528 for Item in Module.PackageDependencies:
529 for Arch in Item.SupArchList:
530 self.AddToDecDatabase(Item.FilePath)
531 # End of self.Init()
532
533 ## Generate PlatformDatabase
534 #
535 # Go through each arch to get all items in DscDatabase to PlatformDatabase
536 #
537 def GenPlatformDatabase(self, PcdsSet={}):
538 for Dsc in self.DscDatabase.keys():
539 Platform = self.DscDatabase[Dsc].Platform
540 for Arch in self.SupArchList:
541 Pb = PlatformBuildClassObject()
542
543 #
544 # Defines
545 #
546 Pb.DescFilePath = Dsc
547 Pb.PlatformName = Platform.Header[Arch].Name
548 if Pb.PlatformName == '':
549 EdkLogger.error("AutoGen", PARSER_ERROR, "The BaseName of platform %s is not defined for arch %s" % (Dsc, Arch))
550 Pb.Guid = Platform.Header[Arch].Guid
551 Pb.Version = Platform.Header[Arch].Version
552 Pb.DscSpecification = Platform.Header[Arch].DscSpecification
553 Pb.OutputDirectory = Platform.Header[Arch].OutputDirectory
554 Pb.FlashDefinition = Platform.FlashDefinitionFile.FilePath
555 Pb.BuildNumber = Platform.Header[Arch].BuildNumber
556
557 #
558 # SkuId
559 #
560 for Key in Platform.SkuInfos.SkuInfoList.keys():
561 Pb.SkuIds[Key] = Platform.SkuInfos.SkuInfoList[Key]
562
563 #
564 # Module
565 #
566 for Item in Platform.Modules.ModuleList:
567 if Arch in Item.SupArchList:
568 Pb.Modules.append(Item.FilePath)
569
570 #
571 # BuildOptions
572 #
573 for Item in Platform.BuildOptions.BuildOptionList:
574 if Arch in Item.SupArchList:
575 Pb.BuildOptions[(Item.ToolChainFamily, Item.ToolChain)] = Item.Option
576
577 #
578 # LibraryClass
579 #
580 for Item in Platform.LibraryClasses.LibraryList:
581 SupModuleList = self.FindSupModuleListOfLibraryClass(Item, Platform.LibraryClasses.LibraryList, Arch)
582 if Arch in Item.SupArchList:
583 for ModuleType in SupModuleList:
584 Pb.LibraryClasses[(Item.Name, ModuleType)] = Item.FilePath
585
586 #
587 # Libraries
588 #
589 for Item in Platform.Libraries.LibraryList:
590 for ItemArch in Item.SupArchList:
591 Library = self.InfDatabase[Item.FilePath]
592 if ItemArch not in Library.Module.Header:
593 continue
594 Pb.Libraries[Library.Module.Header[ItemArch].Name] = Item.FilePath
595
596 #
597 # Pcds
598 #
599 for Item in Platform.DynamicPcdBuildDefinitions:
600 if Arch in Item.SupArchList:
601 Name = Item.CName
602 Guid = Item.TokenSpaceGuidCName
603 Type = Item.ItemType
604 DatumType = Item.DatumType
605 Value = Item.DefaultValue
606 Token = Item.Token
607 MaxDatumSize = Item.MaxDatumSize
608 SkuInfoList = Item.SkuInfoList
609 Pb.Pcds[(Name, Guid)] = PcdClassObject(Name, Guid, Type, DatumType, Value, Token, MaxDatumSize, SkuInfoList, False)
610
611 for (Name, Guid) in PcdsSet:
612 Value = PcdsSet[Name, Guid]
613 for PcdType in ["FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"]:
614 for Dec in self.Build[Arch].PackageDatabase:
615 Pcds = self.Build[Arch].PackageDatabase[Dec].Pcds
616 if (Name, Guid, PcdType) in Pcds:
617 Pcd = Pcds[(Name, Guid, PcdType)]
618 Type = PcdType
619 DatumType = Pcd.DatumType
620 Token = Pcd.TokenValue
621 MaxDatumSize = Pcd.MaxDatumSize
622 SkuInfoList = Pcd.SkuInfoList
623 Pb.Pcds[(Name, Guid)] = PcdClassObject(Name, Guid, Type, DatumType, Value, Token, MaxDatumSize, SkuInfoList, False)
624 break
625 else:
626 # nothing found
627 continue
628 # found in one package, find next PCD
629 break
630 else:
631 EdkLogger.error("AutoGen", PARSER_ERROR, "PCD is not found in any package", ExtraData="%s.%s" % (Guid, Name))
632 #
633 # Add to database
634 #
635 self.Build[Arch].PlatformDatabase[Dsc] = Pb
636 Pb = None
637
638 ## Generate PackageDatabase
639 #
640 # Go through each arch to get all items in DecDatabase to PackageDatabase
641 #
642 def GenPackageDatabase(self):
643 for Dec in self.DecDatabase.keys():
644 Package = self.DecDatabase[Dec].Package
645
646 for Arch in self.SupArchList:
647 Pb = PackageBuildClassObject()
648
649 #
650 # Defines
651 #
652 Pb.DescFilePath = Dec
653 Pb.PackageName = Package.Header[Arch].Name
654 if Pb.PackageName == '':
655 EdkLogger.error("AutoGen", PARSER_ERROR, "The BaseName of package %s is not defined for arch %s" % (Dec, Arch))
656
657 Pb.Guid = Package.Header[Arch].Guid
658 Pb.Version = Package.Header[Arch].Version
659
660 #
661 # Protocols
662 #
663 for Item in Package.ProtocolDeclarations:
664 if Arch in Item.SupArchList:
665 Pb.Protocols[Item.CName] = Item.Guid
666
667 #
668 # Ppis
669 #
670 for Item in Package.PpiDeclarations:
671 if Arch in Item.SupArchList:
672 Pb.Ppis[Item.CName] = Item.Guid
673
674 #
675 # Guids
676 #
677 for Item in Package.GuidDeclarations:
678 if Arch in Item.SupArchList:
679 Pb.Guids[Item.CName] = Item.Guid
680
681 #
682 # Includes
683 #
684 for Item in Package.Includes:
685 if Arch in Item.SupArchList:
686 Pb.Includes.append(Item.FilePath)
687
688 #
689 # LibraryClasses
690 #
691 for Item in Package.LibraryClassDeclarations:
692 if Arch in Item.SupArchList:
693 Pb.LibraryClasses[Item.LibraryClass] = Item.RecommendedInstance
694
695 #
696 # Pcds
697 #
698 for Item in Package.PcdDeclarations:
699 if Arch in Item.SupArchList:
700 Name = Item.CName
701 Guid = Item.TokenSpaceGuidCName
702 Type = Item.ItemType
703 DatumType = Item.DatumType
704 Value = Item.DefaultValue
705 Token = Item.Token
706 MaxDatumSize = Item.MaxDatumSize
707 SkuInfoList = Item.SkuInfoList
708 Pb.Pcds[(Name, Guid, Type)] = PcdClassObject(Name, Guid, Type, DatumType, Value, Token, MaxDatumSize, SkuInfoList, False)
709
710 #
711 # Add to database
712 #
713 self.Build[Arch].PackageDatabase[Dec] = Pb
714 Pb = None
715
716 ## Generate ModuleDatabase
717 #
718 # Go through each arch to get all items in InfDatabase to ModuleDatabase
719 #
720 def GenModuleDatabase(self, InfList = []):
721 for Inf in self.InfDatabase.keys():
722 Module = self.InfDatabase[Inf].Module
723
724 for Arch in self.SupArchList:
725 if not self.IsModuleDefinedInPlatform(Inf, Arch, InfList) or Arch not in Module.Header:
726 continue
727
728 ModuleHeader = Module.Header[Arch]
729 Pb = ModuleBuildClassObject()
730
731 #
732 # Defines
733 #
734 Pb.DescFilePath = Inf
735 Pb.BaseName = ModuleHeader.Name
736 if Pb.BaseName == '':
737 EdkLogger.error("AutoGen", PARSER_ERROR, "The BaseName of module %s is not defined for arch %s" % (Inf, Arch))
738 Pb.Guid = ModuleHeader.Guid
739 Pb.Version = ModuleHeader.Version
740 Pb.ModuleType = ModuleHeader.ModuleType
741 Pb.PcdIsDriver = ModuleHeader.PcdIsDriver
742 Pb.BinaryModule = ModuleHeader.BinaryModule
743 Pb.CustomMakefile = ModuleHeader.CustomMakefile
744 Pb.Shadow = ModuleHeader.Shadow
745
746 #
747 # Specs os Defines
748 #
749 Pb.Specification = ModuleHeader.Specification
750 Pb.Specification[TAB_INF_DEFINES_EDK_RELEASE_VERSION] = ModuleHeader.EdkReleaseVersion
751 Pb.Specification[TAB_INF_DEFINES_EFI_SPECIFICATION_VERSION] = ModuleHeader.UefiSpecificationVersion
752 Pb.Specification[TAB_INF_DEFINES_UEFI_SPECIFICATION_VERSION] = ModuleHeader.UefiSpecificationVersion
753 Pb.AutoGenVersion = int(ModuleHeader.InfVersion, 0)
754
755 #
756 # LibraryClass of Defines
757 #
758 for Item in ModuleHeader.LibraryClass:
759 Pb.LibraryClass.append(LibraryClassObject(Item.LibraryClass, Item.SupModuleList, None))
760
761 #
762 # Module image and library of Defines
763 #
764 for Item in Module.ExternImages:
765 if Item.ModuleEntryPoint != '' and Item.ModuleEntryPoint not in Pb.ModuleEntryPointList:
766 Pb.ModuleEntryPointList.append(Item.ModuleEntryPoint)
767 if Item.ModuleUnloadImage != '' and Item.ModuleUnloadImage not in Pb.ModuleUnloadImageList:
768 Pb.ModuleUnloadImageList.append(Item.ModuleUnloadImage)
769 for Item in Module.ExternLibraries:
770 if Item.Constructor != '' and Item.Constructor not in Pb.ConstructorList:
771 Pb.ConstructorList.append(Item.Constructor)
772 if Item.Destructor != '' and Item.Destructor not in Pb.DestructorList:
773 Pb.DestructorList.append(Item.Destructor)
774
775 #
776 # Binaries
777 #
778 for Item in Module.Binaries:
779 if Arch in Item.SupArchList:
780 FileName = Item.BinaryFile
781 FileType = Item.FileType
782 Target = Item.Target
783 FeatureFlag = Item.FeatureFlag
784 Pb.Binaries.append(ModuleBinaryFileClass(FileName, FileType, Target, FeatureFlag, Arch.split()))
785
786 #
787 # Sources
788 #
789 for Item in Module.Sources:
790 if Arch in Item.SupArchList:
791 SourceFile = Item.SourceFile
792 TagName = Item.TagName
793 ToolCode = Item.ToolCode
794 ToolChainFamily = Item.ToolChainFamily
795 FeatureFlag = Item.FeatureFlag
796 Pb.Sources.append(ModuleSourceFileClass(SourceFile, TagName, ToolCode, ToolChainFamily, FeatureFlag))
797
798 #
799 # Protocols
800 #
801 for Item in Module.Protocols:
802 if Arch in Item.SupArchList:
803 Pb.Protocols.append(Item.CName)
804
805 #
806 # Ppis
807 #
808 for Item in Module.Ppis:
809 if Arch in Item.SupArchList:
810 Pb.Ppis.append(Item.CName)
811
812 #
813 # Guids
814 #
815 for Item in Module.Guids:
816 if Arch in Item.SupArchList:
817 Pb.Ppis.append(Item.CName)
818
819 #
820 # Includes
821 #
822 for Item in Module.Includes:
823 if Arch in Item.SupArchList:
824 Pb.Includes.append(Item.FilePath)
825
826 #
827 # Packages
828 #
829 for Item in Module.PackageDependencies:
830 if Arch in Item.SupArchList:
831 Pb.Packages.append(Item.FilePath)
832
833 #
834 # BuildOptions
835 #
836 for Item in Module.BuildOptions:
837 if Arch in Item.SupArchList:
838 if (Item.ToolChainFamily, Item.ToolChain) not in Pb.BuildOptions:
839 Pb.BuildOptions[(Item.ToolChainFamily, Item.ToolChain)] = Item.Option
840 else:
841 OptionString = Pb.BuildOptions[(Item.ToolChainFamily, Item.ToolChain)]
842 Pb.BuildOptions[(Item.ToolChainFamily, Item.ToolChain)] = OptionString + " " + Item.Option
843 self.FindBuildOptions(Arch, Inf, Pb.BuildOptions)
844
845 #
846 # Depex
847 #
848 for Item in Module.Depex:
849 if Arch in Item.SupArchList:
850 Pb.Depex = Pb.Depex + Item.Depex + ' '
851 Pb.Depex = Pb.Depex.strip()
852
853 #
854 # LibraryClasses
855 #
856 for Item in Module.LibraryClasses:
857 if Arch in Item.SupArchList:
858 Lib = Item.LibraryClass
859 RecommendedInstance = Item.RecommendedInstance
860 if Pb.LibraryClass != []:
861 #
862 # For Library
863 #
864 for Libs in Pb.LibraryClass:
865 for Type in Libs.SupModList:
866 Instance = self.FindLibraryClassInstanceOfLibrary(Lib, Arch, Type)
867 if Instance is None:
868 Instance = RecommendedInstance
869 Pb.LibraryClasses[(Lib, Type)] = Instance
870 else:
871 #
872 # For Module
873 #
874 Instance = self.FindLibraryClassInstanceOfModule(Lib, Arch, Pb.ModuleType, Inf)
875 if Instance is None:
876 Instance = RecommendedInstance
877 Pb.LibraryClasses[(Lib, Pb.ModuleType)] = Instance
878
879 #
880 # Libraries
881 #
882 for Item in Module.Libraries:
883 if Arch in Item.SupArchList:
884 Pb.Libraries.append(Item.Library)
885
886 #
887 # Pcds
888 #
889 for Item in Module.PcdCodes:
890 if Arch in Item.SupArchList:
891 Name = Item.CName
892 Guid = Item.TokenSpaceGuidCName
893 Type = Item.ItemType
894 Pb.Pcds[(Name, Guid)] = self.FindPcd(Arch, Inf, Name, Guid, Type)
895
896 #
897 # Add to database
898 #
899 self.Build[Arch].ModuleDatabase[Inf] = Pb
900 Pb = None
901
902 ## Update Libraries Of Platform Database
903 #
904 # @param InfList: A list for all inf files
905 #
906 def UpdateLibrariesOfPlatform(self, InfList = []):
907 for Arch in self.SupArchList:
908 PlatformDatabase = self.Build[Arch].PlatformDatabase
909 for Dsc in PlatformDatabase:
910 Platform = PlatformDatabase[Dsc]
911 for Inf in Platform.Modules:
912 if not self.IsModuleDefinedInPlatform(Inf, Arch, InfList):
913 continue
914 Module = self.Build[Arch].ModuleDatabase[Inf]
915 if Module.LibraryClass is None or Module.LibraryClass == []:
916 self.UpdateLibrariesOfModule(Platform, Module, Arch)
917 for Key in Module.LibraryClasses:
918 Lib = Module.LibraryClasses[Key]
919 if Lib not in Platform.LibraryInstances:
920 Platform.LibraryInstances.append(Lib)
921
922
923 ## Update Libraries Of Module Database
924 #
925 # @param Module: The module need to be updated libraries
926 # @param Arch: The supportted arch of the module
927 #
928 def UpdateLibrariesOfModule(self, Platform, Module, Arch):
929 ModuleDatabase = self.Build[Arch].ModuleDatabase
930 ModuleType = Module.ModuleType
931
932 # check Edk module
933 if Module.AutoGenVersion < 0x00010005:
934 EdkLogger.verbose("")
935 EdkLogger.verbose("Library instances of module [%s] [%s]:" % (str(Module), Arch))
936 LibraryConsumerList = [Module]
937
938 # "CompilerStub" is a must for Edk modules
939 Module.Libraries.append("CompilerStub")
940 while len(LibraryConsumerList) > 0:
941 M = LibraryConsumerList.pop()
942 for LibraryName in M.Libraries:
943 if LibraryName not in Platform.Libraries:
944 EdkLogger.warn("AutoGen", "Library [%s] is not found" % LibraryName,
945 ExtraData="\t%s [%s]" % (str(Module), Arch))
946 continue
947
948 LibraryFile = Platform.Libraries[LibraryName]
949 if (LibraryName, ModuleType) not in Module.LibraryClasses:
950 Module.LibraryClasses[LibraryName, ModuleType] = LibraryFile
951 LibraryConsumerList.append(ModuleDatabase[LibraryFile])
952 EdkLogger.verbose("\t" + LibraryName + " : " + LibraryFile)
953 return
954
955 # EdkII module
956 LibraryConsumerList = [Module]
957 Constructor = []
958 ConsumedByList = OrderedDict()
959 LibraryInstance = OrderedDict()
960
961 EdkLogger.verbose("")
962 EdkLogger.verbose("Library instances of module [%s] [%s]:" % (str(Module), Arch))
963 while len(LibraryConsumerList) > 0:
964 M = LibraryConsumerList.pop()
965 for Key, LibraryPath in M.LibraryClasses.iteritems():
966 # The "Key" is in format of (library_class_name, supported_module_type)
967 if ModuleType != "USER_DEFINED" and ModuleType not in Key:
968 EdkLogger.debug(EdkLogger.DEBUG_3, "%s for module type %s is not supported (%s)" % (Key + (LibraryPath,)))
969 continue
970
971 LibraryClassName = Key[0]
972 if LibraryClassName not in LibraryInstance or LibraryInstance[LibraryClassName] is None:
973 if LibraryPath is None or LibraryPath == "":
974 LibraryInstance[LibraryClassName] = None
975 continue
976 LibraryModule = ModuleDatabase[LibraryPath]
977 LibraryInstance[LibraryClassName] = LibraryModule
978 LibraryConsumerList.append(LibraryModule)
979 EdkLogger.verbose("\t" + LibraryClassName + " : " + str(LibraryModule))
980 elif LibraryPath is None or LibraryPath == "":
981 continue
982 else:
983 LibraryModule = LibraryInstance[LibraryClassName]
984
985 if LibraryModule.ConstructorList != [] and LibraryModule not in Constructor:
986 Constructor.append(LibraryModule)
987
988 if LibraryModule not in ConsumedByList:
989 ConsumedByList[LibraryModule] = []
990 if M != Module:
991 if M in ConsumedByList[LibraryModule]:
992 continue
993 ConsumedByList[LibraryModule].append(M)
994 #
995 # Initialize the sorted output list to the empty set
996 #
997 SortedLibraryList = []
998 #
999 # Q <- Set of all nodes with no incoming edges
1000 #
1001 LibraryList = [] #LibraryInstance.values()
1002 Q = []
1003 for LibraryClassName in LibraryInstance:
1004 M = LibraryInstance[LibraryClassName]
1005 if M is None:
1006 EdkLogger.error("AutoGen", AUTOGEN_ERROR,
1007 "Library instance for library class [%s] is not found" % LibraryClassName,
1008 ExtraData="\t%s [%s]" % (str(Module), Arch))
1009 LibraryList.append(M)
1010 #
1011 # check if there're duplicate library classes
1012 #
1013 for Lc in M.LibraryClass:
1014 if Lc.SupModList is not None and ModuleType not in Lc.SupModList:
1015 EdkLogger.error("AutoGen", AUTOGEN_ERROR,
1016 "Module type [%s] is not supported by library instance [%s]" % (ModuleType, str(M)),
1017 ExtraData="\t%s" % str(Module))
1018
1019 if Lc.LibraryClass in LibraryInstance and str(M) != str(LibraryInstance[Lc.LibraryClass]):
1020 EdkLogger.error("AutoGen", AUTOGEN_ERROR,
1021 "More than one library instance found for library class [%s] in module [%s]" % (Lc.LibraryClass, Module),
1022 ExtraData="\t%s\n\t%s" % (LibraryInstance[Lc.LibraryClass], str(M))
1023 )
1024 if ConsumedByList[M] == []:
1025 Q.insert(0, M)
1026 #
1027 # while Q is not empty do
1028 #
1029 while Q != []:
1030 #
1031 # remove node from Q
1032 #
1033 Node = Q.pop()
1034 #
1035 # output Node
1036 #
1037 SortedLibraryList.append(Node)
1038 #
1039 # for each node Item with an edge e from Node to Item do
1040 #
1041 for Item in LibraryList:
1042 if Node not in ConsumedByList[Item]:
1043 continue
1044 #
1045 # remove edge e from the graph
1046 #
1047 ConsumedByList[Item].remove(Node)
1048 #
1049 # If Item has no other incoming edges then
1050 #
1051 if ConsumedByList[Item] == []:
1052 #
1053 # insert Item into Q
1054 #
1055 Q.insert(0, Item)
1056
1057 EdgeRemoved = True
1058 while Q == [] and EdgeRemoved:
1059 EdgeRemoved = False
1060 #
1061 # for each node Item with a Constructor
1062 #
1063 for Item in LibraryList:
1064 if Item in Constructor:
1065 #
1066 # for each Node without a constructor with an edge e from Item to Node
1067 #
1068 for Node in ConsumedByList[Item]:
1069 if Node not in Constructor:
1070 #
1071 # remove edge e from the graph
1072 #
1073 ConsumedByList[Item].remove(Node)
1074 EdgeRemoved = True
1075 if ConsumedByList[Item] == []:
1076 #
1077 # insert Item into Q
1078 #
1079 Q.insert(0, Item)
1080 break
1081 if Q != []:
1082 break
1083
1084 #
1085 # if any remaining node Item in the graph has a constructor and an incoming edge, then the graph has a cycle
1086 #
1087 for Item in LibraryList:
1088 if ConsumedByList[Item] != [] and Item in Constructor and len(Constructor) > 1:
1089 ErrorMessage = 'Library [%s] with constructors has a cycle' % str(Item)
1090 EdkLogger.error("AutoGen", AUTOGEN_ERROR, ErrorMessage,
1091 "\tconsumed by " + "\n\tconsumed by ".join([str(L) for L in ConsumedByList[Item]]))
1092 if Item not in SortedLibraryList:
1093 SortedLibraryList.append(Item)
1094
1095 #
1096 # Build the list of constructor and destructir names
1097 # The DAG Topo sort produces the destructor order, so the list of constructors must generated in the reverse order
1098 #
1099 SortedLibraryList.reverse()
1100 Module.LibraryClasses = OrderedDict()
1101 for L in SortedLibraryList:
1102 for Lc in L.LibraryClass:
1103 Module.LibraryClasses[Lc.LibraryClass, ModuleType] = str(L)
1104 #
1105 # Merge PCDs from library instance
1106 #
1107 for Key in L.Pcds:
1108 if Key not in Module.Pcds:
1109 LibPcd = L.Pcds[Key]
1110 Module.Pcds[Key] = self.FindPcd(Arch, str(Module), LibPcd.TokenCName, LibPcd.TokenSpaceGuidCName, LibPcd.Type)
1111 #
1112 # Merge GUIDs from library instance
1113 #
1114 for CName in L.Guids:
1115 if CName not in Module.Guids:
1116 Module.Guids.append(CName)
1117 #
1118 # Merge Protocols from library instance
1119 #
1120 for CName in L.Protocols:
1121 if CName not in Module.Protocols:
1122 Module.Protocols.append(CName)
1123 #
1124 # Merge Ppis from library instance
1125 #
1126 for CName in L.Ppis:
1127 if CName not in Module.Ppis:
1128 Module.Ppis.append(CName)
1129
1130 ## GenBuildDatabase
1131 #
1132 # Generate build database for all arches
1133 #
1134 # @param PcdsSet: Pcd list for override from Fdf parse result
1135 # @param InfList: Inf list for override from Fdf parse result
1136 #
1137 def GenBuildDatabase(self, PcdsSet = {}, InfList = []):
1138 #
1139 # Add additional inf file defined in Fdf file
1140 #
1141 for InfFile in InfList:
1142 self.AddToInfDatabase(NormPath(InfFile))
1143
1144 #
1145 # Generate PlatformDatabase, PackageDatabase and ModuleDatabase
1146 #
1147 self.GenPackageDatabase()
1148 self.GenPlatformDatabase(PcdsSet)
1149 self.GenModuleDatabase(InfList)
1150
1151 self.Db.Close()
1152
1153 #
1154 # Update Libraries Of Platform
1155 #
1156 self.UpdateLibrariesOfPlatform(InfList)
1157
1158 #
1159 # Output used Pcds not found in DSC file
1160 #
1161 self.ShowUnFoundPcds()
1162
1163 ## ShowUnFoundPcds()
1164 #
1165 # If there is any pcd used but not defined in DSC
1166 # Print warning message on screen and output a list of pcds
1167 #
1168 def ShowUnFoundPcds(self):
1169 if self.UnFoundPcdInDsc != {}:
1170 WrnMessage = '**** WARNING ****\n'
1171 WrnMessage += 'The following Pcds were not defined in the DSC file: %s\n' % self.DscFileName
1172 WrnMessage += 'The default values were obtained from the DEC file that declares the PCD and the PCD default value\n'
1173 for (Guid, Name, Type, Arch) in self.UnFoundPcdInDsc:
1174 Dec = self.UnFoundPcdInDsc[(Guid, Name, Type, Arch)]
1175 Pcds = self.Build[Arch].PackageDatabase[Dec].Pcds
1176 if (Name, Guid, Type) in Pcds:
1177 Pcd = Pcds[(Name, Guid, Type)]
1178 PcdItemTypeUsed = Pcd.Type
1179 DefaultValue = Pcd.DefaultValue
1180 WrnMessage += '%s.%s: Defined in file %s, PcdItemType is Pcds%s, DefaultValue is %s\n' % (Guid, Name, Dec, PcdItemTypeUsed, DefaultValue)
1181 EdkLogger.verbose(WrnMessage)
1182
1183 ## Create a full path with workspace dir
1184 #
1185 # Convert Filename with workspace dir to create a full path
1186 #
1187 # @param Filename: The filename need to be added workspace dir
1188 #
1189 # @retval string Full path
1190 #
1191 def WorkspaceFile(self, Filename):
1192 return WorkspaceFile(self.WorkspaceDir, Filename)
1193
1194 ## Update LibraryClass of Module
1195 #
1196 # If a module of a platform has its own override libraryclass but the libraryclass not defined in the module
1197 # Add this libraryclass to the module
1198 #
1199 # @param InfFileName: InfFileName specificed in platform
1200 # @param LibraryClass: LibraryClass specificed in platform
1201 # @param Arch: Supportted Arch
1202 # @param InstanceFilePath: InstanceFilePath specificed in platform
1203 #
1204 def UpdateLibraryClassOfModule(self, InfFileName, LibraryClass, Arch, InstanceFilePath):
1205 #
1206 # Update the library instance itself to add this libraryclass name
1207 #
1208 LibraryModule = self.InfDatabase[InstanceFilePath].Module
1209 LibList = LibraryModule.Header[Arch].LibraryClass
1210 NotFound = True
1211 for Lib in LibList:
1212 #
1213 # Find this LibraryClass
1214 #
1215 if Lib.LibraryClass == LibraryClass:
1216 NotFound = False;
1217 break;
1218 if NotFound:
1219 NewLib = LibraryClassClass()
1220 NewLib.LibraryClass = LibraryClass
1221 NewLib.SupModuleList = DataType.SUP_MODULE_LIST # LibraryModule.Header[Arch].ModuleType.split()
1222 LibraryModule.Header[Arch].LibraryClass.append(NewLib)
1223
1224 #
1225 # Add it to LibraryClasses Section for the module which is using the library
1226 #
1227 Module = self.InfDatabase[InfFileName].Module
1228 LibList = Module.LibraryClasses
1229 NotFound = True
1230 for Lib in LibList:
1231 #
1232 # Find this LibraryClass
1233 #
1234 if Lib.LibraryClass == LibraryClass:
1235 if Arch in Lib.SupArchList:
1236 return
1237 else:
1238 Lib.SupArchList.append(Arch)
1239 return
1240 if NotFound:
1241 Lib = LibraryClassClass()
1242 Lib.LibraryClass = LibraryClass
1243 Lib.SupArchList = [Arch]
1244 Module.LibraryClasses.append(Lib)
1245
1246 ## Add Inf file to InfDatabase
1247 #
1248 # Create a Inf instance for input inf file and add it to InfDatabase
1249 #
1250 # @param InfFileName: The InfFileName need to be added to database
1251 #
1252 def AddToInfDatabase(self, InfFileName):
1253 File = self.WorkspaceFile(InfFileName)
1254 if os.path.exists(File) and os.path.isfile(File):
1255 if InfFileName not in self.InfDatabase:
1256 self.InfDatabase[InfFileName] = Inf(File, False, True, self.WorkspaceDir, self.Db, self.SupArchList)
1257 else:
1258 EdkLogger.error("AutoGen", FILE_NOT_FOUND, ExtraData=File)
1259
1260 ## Add Dec file to DecDatabase
1261 #
1262 # Create a Dec instance for input dec file and add it to DecDatabase
1263 #
1264 # @param DecFileName: The DecFileName need to be added to database
1265 #
1266 def AddToDecDatabase(self, DecFileName):
1267 File = self.WorkspaceFile(DecFileName)
1268 if os.path.exists(File) and os.path.isfile(File):
1269 if DecFileName not in self.DecDatabase:
1270 self.DecDatabase[DecFileName] = Dec(File, False, True, self.WorkspaceDir, self.Db, self.SupArchList)
1271 else:
1272 EdkLogger.error("AutoGen", FILE_NOT_FOUND, ExtraData=File)
1273
1274 ## Search LibraryClass Instance for Module
1275 #
1276 # Search PlatformBuildDatabase to find LibraryClass Instance for Module
1277 # Return the instance if found
1278 #
1279 # @param Lib: Input value for Library Class Name
1280 # @param Arch: Supportted Arch
1281 # @param ModuleType: Supportted ModuleType
1282 # @param ModuleName: Input value for Module Name
1283 #
1284 # @retval string Found LibraryClass Instance file path
1285 #
1286 def FindLibraryClassInstanceOfModule(self, Lib, Arch, ModuleType, ModuleName):
1287 #
1288 # First find if exist in <LibraryClass> of <Components> from dsc file
1289 #
1290 for Dsc in self.DscDatabase.keys():
1291 Platform = self.DscDatabase[Dsc].Platform
1292 for Module in Platform.Modules.ModuleList:
1293 if Arch in Module.SupArchList:
1294 if Module.FilePath == ModuleName:
1295 for LibraryClass in Module.LibraryClasses.LibraryList:
1296 if LibraryClass.Name == Lib:
1297 return LibraryClass.FilePath
1298 #
1299 #Second find if exist in <LibraryClass> of <LibraryClasses> from dsc file
1300 #
1301 return self.FindLibraryClassInstanceOfLibrary(Lib, Arch, ModuleType)
1302
1303 ## Search LibraryClass Instance for Library
1304 #
1305 # Search PlatformBuildDatabase to find LibraryClass Instance for Library
1306 # Return the instance if found
1307 #
1308 # @param Lib: Input value for Library Class Name
1309 # @param Arch: Supportted Arch
1310 # @param Type: Supportted Library Usage Type
1311 #
1312 # @retval string Found LibraryClass Instance file path
1313 # @retval None Not Found
1314 #
1315 def FindLibraryClassInstanceOfLibrary(self, Lib, Arch, Type):
1316 for Dsc in self.DscDatabase.keys():
1317 Platform = self.DscDatabase[Dsc].Platform
1318 if (Lib, Type) in self.Build[Arch].PlatformDatabase[Dsc].LibraryClasses:
1319 return self.Build[Arch].PlatformDatabase[Dsc].LibraryClasses[(Lib, Type)]
1320 elif (Lib, '') in self.Build[Arch].PlatformDatabase[Dsc].LibraryClasses:
1321 return self.Build[Arch].PlatformDatabase[Dsc].LibraryClasses[(Lib, '')]
1322 return None
1323
1324 ## Find BuildOptions
1325 #
1326 # Search DscDatabase to find component definition of ModuleName
1327 # Override BuildOption if it is defined in component
1328 #
1329 # @param Arch: Supportted Arch
1330 # @param ModuleName: The module which has buildoption definition in component of platform
1331 # @param BuildOptions: The set of all buildopitons
1332 #
1333 def FindBuildOptions(self, Arch, ModuleName, BuildOptions):
1334 for Dsc in self.DscDatabase.keys():
1335 #
1336 # First find if exist in <BuildOptions> of <Components> from dsc file
1337 # if find, use that override the one defined in inf file
1338 #
1339 Platform = self.DscDatabase[Dsc].Platform
1340 for Module in Platform.Modules.ModuleList:
1341 if Arch in Module.SupArchList:
1342 if Module.FilePath == ModuleName:
1343 for BuildOption in Module.ModuleSaBuildOption.BuildOptionList:
1344 #
1345 # Add to BuildOptions
1346 #
1347 BuildOptions[(BuildOption.ToolChainFamily, BuildOption.ToolChain)] = BuildOption.Option
1348
1349 ## Find Pcd
1350 #
1351 # Search platform database, package database, module database and PcdsSet from Fdf
1352 # Return found Pcd
1353 #
1354 # @param Arch: Supportted Arch
1355 # @param ModuleName: The module which has pcd definition in component of platform
1356 # @param Name: Name of Pcd
1357 # @param Guid: Guid of Pcd
1358 # @param Type: Type of Pcd
1359 #
1360 # @retval PcdClassObject An instance for PcdClassObject with all members filled
1361 #
1362 def FindPcd(self, Arch, ModuleName, Name, Guid, Type):
1363 NewType = ''
1364 DatumType = ''
1365 Value = ''
1366 Token = ''
1367 MaxDatumSize = ''
1368 SkuInfoList = {}
1369 IsOverrided = False
1370 IsFoundInDsc = False
1371 IsFoundInDec = False
1372 FoundInDecFile = ''
1373
1374 #
1375 # Second get information from platform database
1376 #
1377 OwnerPlatform = ''
1378 for Dsc in self.Build[Arch].PlatformDatabase.keys():
1379 Pcds = self.Build[Arch].PlatformDatabase[Dsc].Pcds
1380 if (Name, Guid) in Pcds:
1381 OwnerPlatform = Dsc
1382 Pcd = Pcds[(Name, Guid)]
1383 if Pcd.Type != '' and Pcd.Type is not None:
1384 NewType = Pcd.Type
1385 if NewType in DataType.PCD_DYNAMIC_TYPE_LIST:
1386 NewType = DataType.TAB_PCDS_DYNAMIC
1387 elif NewType in DataType.PCD_DYNAMIC_EX_TYPE_LIST:
1388 NewType = DataType.TAB_PCDS_DYNAMIC_EX
1389 else:
1390 NewType = Type
1391
1392 if Type != '' and Type != NewType:
1393 ErrorMsg = "PCD %s.%s is declared as [%s] in module\n\t%s\n\n"\
1394 " But it's used as [%s] in platform\n\t%s"\
1395 % (Guid, Name, Type, ModuleName, NewType, OwnerPlatform)
1396 EdkLogger.error("AutoGen", PARSER_ERROR, ErrorMsg)
1397
1398
1399 if Pcd.DatumType != '' and Pcd.DatumType is not None:
1400 DatumType = Pcd.DatumType
1401 if Pcd.TokenValue != '' and Pcd.TokenValue is not None:
1402 Token = Pcd.TokenValue
1403 if Pcd.DefaultValue != '' and Pcd.DefaultValue is not None:
1404 Value = Pcd.DefaultValue
1405 if Pcd.MaxDatumSize != '' and Pcd.MaxDatumSize is not None:
1406 MaxDatumSize = Pcd.MaxDatumSize
1407 SkuInfoList = Pcd.SkuInfoList
1408
1409 IsOverrided = True
1410 IsFoundInDsc = True
1411 break
1412
1413 #
1414 # Third get information from <Pcd> of <Compontents> from module database
1415 #
1416 for Dsc in self.DscDatabase.keys():
1417 for Module in self.DscDatabase[Dsc].Platform.Modules.ModuleList:
1418 if Arch in Module.SupArchList:
1419 if Module.FilePath == ModuleName:
1420 for Pcd in Module.PcdBuildDefinitions:
1421 if (Name, Guid) == (Pcd.CName, Pcd.TokenSpaceGuidCName):
1422 if Pcd.DefaultValue != '':
1423 Value = Pcd.DefaultValue
1424 if Pcd.MaxDatumSize != '':
1425 MaxDatumSize = Pcd.MaxDatumSize
1426
1427 IsFoundInDsc = True
1428 IsOverrided = True
1429 break
1430
1431 #
1432 # First get information from package database
1433 #
1434 Pcd = None
1435 if NewType == '':
1436 if Type != '':
1437 PcdTypeList = [Type]
1438 else:
1439 PcdTypeList = ["FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"]
1440
1441 for Dec in self.Build[Arch].PackageDatabase.keys():
1442 Pcds = self.Build[Arch].PackageDatabase[Dec].Pcds
1443 for PcdType in PcdTypeList:
1444 if (Name, Guid, PcdType) in Pcds:
1445 Pcd = Pcds[(Name, Guid, PcdType)]
1446 NewType = PcdType
1447 IsOverrided = True
1448 IsFoundInDec = True
1449 FoundInDecFile = Dec
1450 break
1451 else:
1452 continue
1453 break
1454 else:
1455 for Dec in self.Build[Arch].PackageDatabase.keys():
1456 Pcds = self.Build[Arch].PackageDatabase[Dec].Pcds
1457 if (Name, Guid, NewType) in Pcds:
1458 Pcd = Pcds[(Name, Guid, NewType)]
1459 IsOverrided = True
1460 IsFoundInDec = True
1461 FoundInDecFile = Dec
1462 break
1463
1464 if not IsFoundInDec:
1465 ErrorMsg = "Pcd '%s.%s [%s]' defined in module '%s' is not found in any package for Arch '%s'" % (Guid, Name, NewType, ModuleName, Arch)
1466 EdkLogger.error("AutoGen", PARSER_ERROR, ErrorMsg)
1467
1468 #
1469 # Not found in any platform and fdf
1470 #
1471 if not IsFoundInDsc:
1472 Value = Pcd.DefaultValue
1473 if NewType.startswith("Dynamic") and SkuInfoList == {}:
1474 SkuIds = self.Build[Arch].PlatformDatabase.values()[0].SkuIds
1475 SkuInfoList['DEFAULT'] = SkuInfoClass(SkuIdName='DEFAULT', SkuId=SkuIds['DEFAULT'], DefaultValue=Value)
1476 self.UnFoundPcdInDsc[(Guid, Name, NewType, Arch)] = FoundInDecFile
1477 #elif Type != '' and NewType.startswith("Dynamic"):
1478 # NewType = Pcd.Type
1479 DatumType = Pcd.DatumType
1480 if Token in [None, '']:
1481 Token = Pcd.TokenValue
1482 if DatumType == "VOID*" and MaxDatumSize in ['', None]:
1483 EdkLogger.verbose("No MaxDatumSize specified for PCD %s.%s in module [%s]" % (Guid, Name, ModuleName))
1484 if Value[0] == 'L':
1485 MaxDatumSize = str(len(Value) * 2)
1486 elif Value[0] == '{':
1487 MaxDatumSize = str(len(Value.split(',')))
1488 else:
1489 MaxDatumSize = str(len(Value))
1490
1491 return PcdClassObject(Name, Guid, NewType, DatumType, Value, Token, MaxDatumSize, SkuInfoList, IsOverrided)
1492
1493 ## Find Supportted Module List Of LibraryClass
1494 #
1495 # Search in InfDatabase, find the supmodulelist of the libraryclass
1496 #
1497 # @param LibraryClass: LibraryClass name for search
1498 # @param OverridedLibraryClassList: A list of all LibraryClass
1499 # @param Arch: Supportted Arch
1500 #
1501 # @retval list SupModuleList
1502 #
1503 def FindSupModuleListOfLibraryClass(self, LibraryClass, OverridedLibraryClassList, Arch):
1504 Name = LibraryClass.Name
1505 FilePath = LibraryClass.FilePath
1506 SupModuleList = copy.copy(LibraryClass.SupModuleList)
1507
1508 #
1509 # If the SupModuleList means all, remove overrided module types of platform
1510 #
1511 if SupModuleList == DataType.SUP_MODULE_LIST:
1512 EdkLogger.debug(EdkLogger.DEBUG_3, "\tLibraryClass %s supports all module types" % Name)
1513 for Item in OverridedLibraryClassList:
1514 #
1515 # Find a library class (Item) with the same name
1516 #
1517 if Item.Name == Name:
1518 #
1519 # Do nothing if it is itself
1520 #
1521 if Item.SupModuleList == DataType.SUP_MODULE_LIST:
1522 continue
1523 #
1524 # If not itself, check arch first
1525 #
1526 if Arch in LibraryClass.SupArchList:
1527 #
1528 # If arch is supportted, remove all related module type
1529 #
1530 if Arch in Item.SupArchList:
1531 for ModuleType in Item.SupModuleList:
1532 EdkLogger.debug(EdkLogger.DEBUG_3, "\tLibraryClass %s has specific defined module types" % Name)
1533 if ModuleType in SupModuleList:
1534 SupModuleList.remove(ModuleType)
1535
1536 return SupModuleList
1537
1538 ## Find Module inf Platform
1539 #
1540 # Check if the module is defined in <Compentent> of <Platform>
1541 #
1542 # @param Inf: Inf file (Module) need to be searched
1543 # @param Arch: Supportted Arch
1544 # @param InfList: A list for all Inf file
1545 #
1546 # @retval True Mudule Found
1547 # @retval Flase Module Not Found
1548 #
1549 def IsModuleDefinedInPlatform(self, Inf, Arch, InfList):
1550 for Dsc in self.DscDatabase.values():
1551 for LibraryClass in Dsc.Platform.LibraryClasses.LibraryList:
1552 if Inf == LibraryClass.FilePath and Arch in LibraryClass.SupArchList:
1553 return True
1554 for Module in Dsc.Platform.Modules.ModuleList:
1555 if Inf == Module.FilePath and Arch in Module.SupArchList:
1556 return True
1557 for Item in Module.LibraryClasses.LibraryList:
1558 if Inf == Item.FilePath:
1559 return True
1560 for Library in Dsc.Platform.Libraries.LibraryList:
1561 if Inf == Library.FilePath and Arch in Library.SupArchList:
1562 return True
1563
1564 return False
1565
1566 ## Show all content of the workspacebuild
1567 #
1568 # Print each item of the workspacebuild with (Key = Value) pair
1569 #
1570 def ShowWorkspaceBuild(self):
1571 print self.DscDatabase
1572 print self.InfDatabase
1573 print self.DecDatabase
1574 print 'SupArchList', self.SupArchList
1575 print 'BuildTarget', self.BuildTarget
1576 print 'SkuId', self.SkuId
1577
1578 for Arch in self.SupArchList:
1579 print Arch
1580 print 'Platform'
1581 for Platform in self.Build[Arch].PlatformDatabase.keys():
1582 P = self.Build[Arch].PlatformDatabase[Platform]
1583 print 'DescFilePath = ', P.DescFilePath
1584 print 'PlatformName = ', P.PlatformName
1585 print 'Guid = ', P.Guid
1586 print 'Version = ', P.Version
1587 print 'OutputDirectory = ', P.OutputDirectory
1588 print 'FlashDefinition = ', P.FlashDefinition
1589 print 'SkuIds = ', P.SkuIds
1590 print 'Modules = ', P.Modules
1591 print 'LibraryClasses = ', P.LibraryClasses
1592 print 'Pcds = ', P.Pcds
1593 for item in P.Pcds.keys():
1594 print P.Pcds[item]
1595 print 'BuildOptions = ', P.BuildOptions
1596 print ''
1597 # End of Platform
1598
1599 print 'package'
1600 for Package in self.Build[Arch].PackageDatabase.keys():
1601 P = self.Build[Arch].PackageDatabase[Package]
1602 print 'DescFilePath = ', P.DescFilePath
1603 print 'PackageName = ', P.PackageName
1604 print 'Guid = ', P.Guid
1605 print 'Version = ', P.Version
1606 print 'Protocols = ', P.Protocols
1607 print 'Ppis = ', P.Ppis
1608 print 'Guids = ', P.Guids
1609 print 'Includes = ', P.Includes
1610 print 'LibraryClasses = ', P.LibraryClasses
1611 print 'Pcds = ', P.Pcds
1612 for item in P.Pcds.keys():
1613 print P.Pcds[item]
1614 print ''
1615 # End of Package
1616
1617 print 'module'
1618 for Module in self.Build[Arch].ModuleDatabase.keys():
1619 P = self.Build[Arch].ModuleDatabase[Module]
1620 print 'DescFilePath = ', P.DescFilePath
1621 print 'BaseName = ', P.BaseName
1622 print 'ModuleType = ', P.ModuleType
1623 print 'Guid = ', P.Guid
1624 print 'Version = ', P.Version
1625 print 'CustomMakefile = ', P.CustomMakefile
1626 print 'Specification = ', P.Specification
1627 print 'Shadow = ', P.Shadow
1628 print 'PcdIsDriver = ', P.PcdIsDriver
1629 for Lib in P.LibraryClass:
1630 print 'LibraryClassDefinition = ', Lib.LibraryClass, 'SupModList = ', Lib.SupModList
1631 print 'ModuleEntryPointList = ', P.ModuleEntryPointList
1632 print 'ModuleUnloadImageList = ', P.ModuleUnloadImageList
1633 print 'ConstructorList = ', P.ConstructorList
1634 print 'DestructorList = ', P.DestructorList
1635
1636 print 'Binaries = '
1637 for item in P.Binaries:
1638 print item.BinaryFile, item.FeatureFlag, item.SupArchList
1639 print 'Sources = '
1640 for item in P.Sources:
1641 print item.SourceFile
1642 print 'LibraryClasses = ', P.LibraryClasses
1643 print 'Protocols = ', P.Protocols
1644 print 'Ppis = ', P.Ppis
1645 print 'Guids = ', P.Guids
1646 print 'Includes = ', P.Includes
1647 print 'Packages = ', P.Packages
1648 print 'Pcds = ', P.Pcds
1649 for item in P.Pcds.keys():
1650 print P.Pcds[item]
1651 print 'BuildOptions = ', P.BuildOptions
1652 print 'Depex = ', P.Depex
1653 print ''
1654 # End of Module
1655
1656 ##
1657 #
1658 # This acts like the main() function for the script, unless it is 'import'ed into another
1659 # script.
1660 #
1661 if __name__ == '__main__':
1662 print 'Start!', time.strftime('%H:%M:%S', time.localtime())
1663 EdkLogger.Initialize()
1664 EdkLogger.SetLevel(EdkLogger.QUIET)
1665
1666 W = os.getenv('WORKSPACE')
1667 Ewb = WorkspaceBuild('Nt32Pkg/Nt32Pkg.dsc', W)
1668 Ewb.GenBuildDatabase({('PcdDevicePathSupportDevicePathFromText', 'gEfiMdeModulePkgTokenSpaceGuid') : 'KKKKKKKKKKKKKKKKKKKKK'}, ['Test.Inf'])
1669 print 'Done!', time.strftime('%H:%M:%S', time.localtime())
1670 Ewb.ShowWorkspaceBuild()