]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/Common/EdkIIWorkspaceBuild.py
Sync tool code to BuildTools project r1783.
[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 ~ 2008, Intel Corporation
5 # All rights reserved. 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 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 Misc import sdict
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 != 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 != 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 = sdict()
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
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.EfiSpecificationVersion
752 Pb.AutoGenVersion = int(ModuleHeader.InfVersion, 0)
753
754 #
755 # LibraryClass of Defines
756 #
757 for Item in ModuleHeader.LibraryClass:
758 Pb.LibraryClass.append(LibraryClassObject(Item.LibraryClass, Item.SupModuleList, None))
759
760 #
761 # Module image and library of Defines
762 #
763 for Item in Module.ExternImages:
764 if Item.ModuleEntryPoint != '' and Item.ModuleEntryPoint not in Pb.ModuleEntryPointList:
765 Pb.ModuleEntryPointList.append(Item.ModuleEntryPoint)
766 if Item.ModuleUnloadImage != '' and Item.ModuleUnloadImage not in Pb.ModuleUnloadImageList:
767 Pb.ModuleUnloadImageList.append(Item.ModuleUnloadImage)
768 for Item in Module.ExternLibraries:
769 if Item.Constructor != '' and Item.Constructor not in Pb.ConstructorList:
770 Pb.ConstructorList.append(Item.Constructor)
771 if Item.Destructor != '' and Item.Destructor not in Pb.DestructorList:
772 Pb.DestructorList.append(Item.Destructor)
773
774 #
775 # Binaries
776 #
777 for Item in Module.Binaries:
778 if Arch in Item.SupArchList:
779 FileName = Item.BinaryFile
780 FileType = Item.FileType
781 Target = Item.Target
782 FeatureFlag = Item.FeatureFlag
783 Pb.Binaries.append(ModuleBinaryFileClass(FileName, FileType, Target, FeatureFlag, Arch.split()))
784
785 #
786 # Sources
787 #
788 for Item in Module.Sources:
789 if Arch in Item.SupArchList:
790 SourceFile = Item.SourceFile
791 TagName = Item.TagName
792 ToolCode = Item.ToolCode
793 ToolChainFamily = Item.ToolChainFamily
794 FeatureFlag = Item.FeatureFlag
795 Pb.Sources.append(ModuleSourceFileClass(SourceFile, TagName, ToolCode, ToolChainFamily, FeatureFlag))
796
797 #
798 # Protocols
799 #
800 for Item in Module.Protocols:
801 if Arch in Item.SupArchList:
802 Pb.Protocols.append(Item.CName)
803
804 #
805 # Ppis
806 #
807 for Item in Module.Ppis:
808 if Arch in Item.SupArchList:
809 Pb.Ppis.append(Item.CName)
810
811 #
812 # Guids
813 #
814 for Item in Module.Guids:
815 if Arch in Item.SupArchList:
816 Pb.Ppis.append(Item.CName)
817
818 #
819 # Includes
820 #
821 for Item in Module.Includes:
822 if Arch in Item.SupArchList:
823 Pb.Includes.append(Item.FilePath)
824
825 #
826 # Packages
827 #
828 for Item in Module.PackageDependencies:
829 if Arch in Item.SupArchList:
830 Pb.Packages.append(Item.FilePath)
831
832 #
833 # BuildOptions
834 #
835 for Item in Module.BuildOptions:
836 if Arch in Item.SupArchList:
837 if (Item.ToolChainFamily, Item.ToolChain) not in Pb.BuildOptions:
838 Pb.BuildOptions[(Item.ToolChainFamily, Item.ToolChain)] = Item.Option
839 else:
840 OptionString = Pb.BuildOptions[(Item.ToolChainFamily, Item.ToolChain)]
841 Pb.BuildOptions[(Item.ToolChainFamily, Item.ToolChain)] = OptionString + " " + Item.Option
842 self.FindBuildOptions(Arch, Inf, Pb.BuildOptions)
843
844 #
845 # Depex
846 #
847 for Item in Module.Depex:
848 if Arch in Item.SupArchList:
849 Pb.Depex = Pb.Depex + Item.Depex + ' '
850 Pb.Depex = Pb.Depex.strip()
851
852 #
853 # LibraryClasses
854 #
855 for Item in Module.LibraryClasses:
856 if Arch in Item.SupArchList:
857 Lib = Item.LibraryClass
858 RecommendedInstance = Item.RecommendedInstance
859 if Pb.LibraryClass != []:
860 #
861 # For Library
862 #
863 for Libs in Pb.LibraryClass:
864 for Type in Libs.SupModList:
865 Instance = self.FindLibraryClassInstanceOfLibrary(Lib, Arch, Type)
866 if Instance == None:
867 Instance = RecommendedInstance
868 Pb.LibraryClasses[(Lib, Type)] = Instance
869 else:
870 #
871 # For Module
872 #
873 Instance = self.FindLibraryClassInstanceOfModule(Lib, Arch, Pb.ModuleType, Inf)
874 if Instance == None:
875 Instance = RecommendedInstance
876 Pb.LibraryClasses[(Lib, Pb.ModuleType)] = Instance
877
878 #
879 # Libraries
880 #
881 for Item in Module.Libraries:
882 if Arch in Item.SupArchList:
883 Pb.Libraries.append(Item.Library)
884
885 #
886 # Pcds
887 #
888 for Item in Module.PcdCodes:
889 if Arch in Item.SupArchList:
890 Name = Item.CName
891 Guid = Item.TokenSpaceGuidCName
892 Type = Item.ItemType
893 Pb.Pcds[(Name, Guid)] = self.FindPcd(Arch, Inf, Name, Guid, Type)
894
895 #
896 # Add to database
897 #
898 self.Build[Arch].ModuleDatabase[Inf] = Pb
899 Pb = None
900
901 ## Update Libraries Of Platform Database
902 #
903 # @param InfList: A list for all inf files
904 #
905 def UpdateLibrariesOfPlatform(self, InfList = []):
906 for Arch in self.SupArchList:
907 PlatformDatabase = self.Build[Arch].PlatformDatabase
908 for Dsc in PlatformDatabase:
909 Platform = PlatformDatabase[Dsc]
910 for Inf in Platform.Modules:
911 if not self.IsModuleDefinedInPlatform(Inf, Arch, InfList):
912 continue
913 Module = self.Build[Arch].ModuleDatabase[Inf]
914 if Module.LibraryClass == None or Module.LibraryClass == []:
915 self.UpdateLibrariesOfModule(Platform, Module, Arch)
916 for Key in Module.LibraryClasses:
917 Lib = Module.LibraryClasses[Key]
918 if Lib not in Platform.LibraryInstances:
919 Platform.LibraryInstances.append(Lib)
920
921
922 ## Update Libraries Of Module Database
923 #
924 # @param Module: The module need to be updated libraries
925 # @param Arch: The supportted arch of the module
926 #
927 def UpdateLibrariesOfModule(self, Platform, Module, Arch):
928 ModuleDatabase = self.Build[Arch].ModuleDatabase
929 ModuleType = Module.ModuleType
930
931 # check R8 module
932 if Module.AutoGenVersion < 0x00010005:
933 EdkLogger.verbose("")
934 EdkLogger.verbose("Library instances of module [%s] [%s]:" % (str(Module), Arch))
935 LibraryConsumerList = [Module]
936
937 # "CompilerStub" is a must for R8 modules
938 Module.Libraries.append("CompilerStub")
939 while len(LibraryConsumerList) > 0:
940 M = LibraryConsumerList.pop()
941 for LibraryName in M.Libraries:
942 if LibraryName not in Platform.Libraries:
943 EdkLogger.warn("AutoGen", "Library [%s] is not found" % LibraryName,
944 ExtraData="\t%s [%s]" % (str(Module), Arch))
945 continue
946
947 LibraryFile = Platform.Libraries[LibraryName]
948 if (LibraryName, ModuleType) not in Module.LibraryClasses:
949 Module.LibraryClasses[LibraryName, ModuleType] = LibraryFile
950 LibraryConsumerList.append(ModuleDatabase[LibraryFile])
951 EdkLogger.verbose("\t" + LibraryName + " : " + LibraryFile)
952 return
953
954 # R9 module
955 LibraryConsumerList = [Module]
956 Constructor = []
957 ConsumedByList = sdict()
958 LibraryInstance = sdict()
959
960 EdkLogger.verbose("")
961 EdkLogger.verbose("Library instances of module [%s] [%s]:" % (str(Module), Arch))
962 while len(LibraryConsumerList) > 0:
963 M = LibraryConsumerList.pop()
964 for Key, LibraryPath in M.LibraryClasses.iteritems():
965 # The "Key" is in format of (library_class_name, supported_module_type)
966 if ModuleType != "USER_DEFINED" and ModuleType not in Key:
967 EdkLogger.debug(EdkLogger.DEBUG_3, "%s for module type %s is not supported (%s)" % (Key + (LibraryPath,)))
968 continue
969
970 LibraryClassName = Key[0]
971 if LibraryClassName not in LibraryInstance or LibraryInstance[LibraryClassName] == None:
972 if LibraryPath == None or LibraryPath == "":
973 LibraryInstance[LibraryClassName] = None
974 continue
975 LibraryModule = ModuleDatabase[LibraryPath]
976 LibraryInstance[LibraryClassName] = LibraryModule
977 LibraryConsumerList.append(LibraryModule)
978 EdkLogger.verbose("\t" + LibraryClassName + " : " + str(LibraryModule))
979 elif LibraryPath == None or LibraryPath == "":
980 continue
981 else:
982 LibraryModule = LibraryInstance[LibraryClassName]
983
984 if LibraryModule.ConstructorList != [] and LibraryModule not in Constructor:
985 Constructor.append(LibraryModule)
986
987 if LibraryModule not in ConsumedByList:
988 ConsumedByList[LibraryModule] = []
989 if M != Module:
990 if M in ConsumedByList[LibraryModule]:
991 continue
992 ConsumedByList[LibraryModule].append(M)
993 #
994 # Initialize the sorted output list to the empty set
995 #
996 SortedLibraryList = []
997 #
998 # Q <- Set of all nodes with no incoming edges
999 #
1000 LibraryList = [] #LibraryInstance.values()
1001 Q = []
1002 for LibraryClassName in LibraryInstance:
1003 M = LibraryInstance[LibraryClassName]
1004 if M == None:
1005 EdkLogger.error("AutoGen", AUTOGEN_ERROR,
1006 "Library instance for library class [%s] is not found" % LibraryClassName,
1007 ExtraData="\t%s [%s]" % (str(Module), Arch))
1008 LibraryList.append(M)
1009 #
1010 # check if there're duplicate library classes
1011 #
1012 for Lc in M.LibraryClass:
1013 if Lc.SupModList != None and ModuleType not in Lc.SupModList:
1014 EdkLogger.error("AutoGen", AUTOGEN_ERROR,
1015 "Module type [%s] is not supported by library instance [%s]" % (ModuleType, str(M)),
1016 ExtraData="\t%s" % str(Module))
1017
1018 if Lc.LibraryClass in LibraryInstance and str(M) != str(LibraryInstance[Lc.LibraryClass]):
1019 EdkLogger.error("AutoGen", AUTOGEN_ERROR,
1020 "More than one library instance found for library class [%s] in module [%s]" % (Lc.LibraryClass, Module),
1021 ExtraData="\t%s\n\t%s" % (LibraryInstance[Lc.LibraryClass], str(M))
1022 )
1023 if ConsumedByList[M] == []:
1024 Q.insert(0, M)
1025 #
1026 # while Q is not empty do
1027 #
1028 while Q != []:
1029 #
1030 # remove node from Q
1031 #
1032 Node = Q.pop()
1033 #
1034 # output Node
1035 #
1036 SortedLibraryList.append(Node)
1037 #
1038 # for each node Item with an edge e from Node to Item do
1039 #
1040 for Item in LibraryList:
1041 if Node not in ConsumedByList[Item]:
1042 continue
1043 #
1044 # remove edge e from the graph
1045 #
1046 ConsumedByList[Item].remove(Node)
1047 #
1048 # If Item has no other incoming edges then
1049 #
1050 if ConsumedByList[Item] == []:
1051 #
1052 # insert Item into Q
1053 #
1054 Q.insert(0, Item)
1055
1056 EdgeRemoved = True
1057 while Q == [] and EdgeRemoved:
1058 EdgeRemoved = False
1059 #
1060 # for each node Item with a Constructor
1061 #
1062 for Item in LibraryList:
1063 if Item in Constructor:
1064 #
1065 # for each Node without a constructor with an edge e from Item to Node
1066 #
1067 for Node in ConsumedByList[Item]:
1068 if Node not in Constructor:
1069 #
1070 # remove edge e from the graph
1071 #
1072 ConsumedByList[Item].remove(Node)
1073 EdgeRemoved = True
1074 if ConsumedByList[Item] == []:
1075 #
1076 # insert Item into Q
1077 #
1078 Q.insert(0, Item)
1079 break
1080 if Q != []:
1081 break
1082
1083 #
1084 # if any remaining node Item in the graph has a constructor and an incoming edge, then the graph has a cycle
1085 #
1086 for Item in LibraryList:
1087 if ConsumedByList[Item] != [] and Item in Constructor and len(Constructor) > 1:
1088 ErrorMessage = 'Library [%s] with constructors has a cycle' % str(Item)
1089 EdkLogger.error("AutoGen", AUTOGEN_ERROR, ErrorMessage,
1090 "\tconsumed by " + "\n\tconsumed by ".join([str(L) for L in ConsumedByList[Item]]))
1091 if Item not in SortedLibraryList:
1092 SortedLibraryList.append(Item)
1093
1094 #
1095 # Build the list of constructor and destructir names
1096 # The DAG Topo sort produces the destructor order, so the list of constructors must generated in the reverse order
1097 #
1098 SortedLibraryList.reverse()
1099 Module.LibraryClasses = sdict()
1100 for L in SortedLibraryList:
1101 for Lc in L.LibraryClass:
1102 Module.LibraryClasses[Lc.LibraryClass, ModuleType] = str(L)
1103 #
1104 # Merge PCDs from library instance
1105 #
1106 for Key in L.Pcds:
1107 if Key not in Module.Pcds:
1108 LibPcd = L.Pcds[Key]
1109 Module.Pcds[Key] = self.FindPcd(Arch, str(Module), LibPcd.TokenCName, LibPcd.TokenSpaceGuidCName, LibPcd.Type)
1110 #
1111 # Merge GUIDs from library instance
1112 #
1113 for CName in L.Guids:
1114 if CName not in Module.Guids:
1115 Module.Guids.append(CName)
1116 #
1117 # Merge Protocols from library instance
1118 #
1119 for CName in L.Protocols:
1120 if CName not in Module.Protocols:
1121 Module.Protocols.append(CName)
1122 #
1123 # Merge Ppis from library instance
1124 #
1125 for CName in L.Ppis:
1126 if CName not in Module.Ppis:
1127 Module.Ppis.append(CName)
1128
1129 ## GenBuildDatabase
1130 #
1131 # Generate build database for all arches
1132 #
1133 # @param PcdsSet: Pcd list for override from Fdf parse result
1134 # @param InfList: Inf list for override from Fdf parse result
1135 #
1136 def GenBuildDatabase(self, PcdsSet = {}, InfList = []):
1137 #
1138 # Add additional inf file defined in Fdf file
1139 #
1140 for InfFile in InfList:
1141 self.AddToInfDatabase(NormPath(InfFile))
1142
1143 #
1144 # Generate PlatformDatabase, PackageDatabase and ModuleDatabase
1145 #
1146 self.GenPackageDatabase()
1147 self.GenPlatformDatabase(PcdsSet)
1148 self.GenModuleDatabase(InfList)
1149
1150 self.Db.Close()
1151
1152 #
1153 # Update Libraries Of Platform
1154 #
1155 self.UpdateLibrariesOfPlatform(InfList)
1156
1157 #
1158 # Output used Pcds not found in DSC file
1159 #
1160 self.ShowUnFoundPcds()
1161
1162 ## ShowUnFoundPcds()
1163 #
1164 # If there is any pcd used but not defined in DSC
1165 # Print warning message on screen and output a list of pcds
1166 #
1167 def ShowUnFoundPcds(self):
1168 if self.UnFoundPcdInDsc != {}:
1169 WrnMessage = '**** WARNING ****\n'
1170 WrnMessage += 'The following Pcds were not defined in the DSC file: %s\n' % self.DscFileName
1171 WrnMessage += 'The default values were obtained from the DEC file that declares the PCD and the PCD default value\n'
1172 for (Guid, Name, Type, Arch) in self.UnFoundPcdInDsc:
1173 Dec = self.UnFoundPcdInDsc[(Guid, Name, Type, Arch)]
1174 Pcds = self.Build[Arch].PackageDatabase[Dec].Pcds
1175 if (Name, Guid, Type) in Pcds:
1176 Pcd = Pcds[(Name, Guid, Type)]
1177 PcdItemTypeUsed = Pcd.Type
1178 DefaultValue = Pcd.DefaultValue
1179 WrnMessage += '%s.%s: Defined in file %s, PcdItemType is Pcds%s, DefaultValue is %s\n' % (Guid, Name, Dec, PcdItemTypeUsed, DefaultValue)
1180 EdkLogger.verbose(WrnMessage)
1181
1182 ## Create a full path with workspace dir
1183 #
1184 # Convert Filename with workspace dir to create a full path
1185 #
1186 # @param Filename: The filename need to be added workspace dir
1187 #
1188 # @retval string Full path
1189 #
1190 def WorkspaceFile(self, Filename):
1191 return WorkspaceFile(self.WorkspaceDir, Filename)
1192
1193 ## Update LibraryClass of Module
1194 #
1195 # If a module of a platform has its own override libraryclass but the libraryclass not defined in the module
1196 # Add this libraryclass to the module
1197 #
1198 # @param InfFileName: InfFileName specificed in platform
1199 # @param LibraryClass: LibraryClass specificed in platform
1200 # @param Arch: Supportted Arch
1201 # @param InstanceFilePath: InstanceFilePath specificed in platform
1202 #
1203 def UpdateLibraryClassOfModule(self, InfFileName, LibraryClass, Arch, InstanceFilePath):
1204 #
1205 # Update the library instance itself to add this libraryclass name
1206 #
1207 LibraryModule = self.InfDatabase[InstanceFilePath].Module
1208 LibList = LibraryModule.Header[Arch].LibraryClass
1209 NotFound = True
1210 for Lib in LibList:
1211 #
1212 # Find this LibraryClass
1213 #
1214 if Lib.LibraryClass == LibraryClass:
1215 NotFound = False;
1216 break;
1217 if NotFound:
1218 NewLib = LibraryClassClass()
1219 NewLib.LibraryClass = LibraryClass
1220 NewLib.SupModuleList = DataType.SUP_MODULE_LIST # LibraryModule.Header[Arch].ModuleType.split()
1221 LibraryModule.Header[Arch].LibraryClass.append(NewLib)
1222
1223 #
1224 # Add it to LibraryClasses Section for the module which is using the library
1225 #
1226 Module = self.InfDatabase[InfFileName].Module
1227 LibList = Module.LibraryClasses
1228 NotFound = True
1229 for Lib in LibList:
1230 #
1231 # Find this LibraryClass
1232 #
1233 if Lib.LibraryClass == LibraryClass:
1234 if Arch in Lib.SupArchList:
1235 return
1236 else:
1237 Lib.SupArchList.append(Arch)
1238 return
1239 if NotFound:
1240 Lib = LibraryClassClass()
1241 Lib.LibraryClass = LibraryClass
1242 Lib.SupArchList = [Arch]
1243 Module.LibraryClasses.append(Lib)
1244
1245 ## Add Inf file to InfDatabase
1246 #
1247 # Create a Inf instance for input inf file and add it to InfDatabase
1248 #
1249 # @param InfFileName: The InfFileName need to be added to database
1250 #
1251 def AddToInfDatabase(self, InfFileName):
1252 File = self.WorkspaceFile(InfFileName)
1253 if os.path.exists(File) and os.path.isfile(File):
1254 if InfFileName not in self.InfDatabase:
1255 self.InfDatabase[InfFileName] = Inf(File, False, True, self.WorkspaceDir, self.Db, self.SupArchList)
1256 else:
1257 EdkLogger.error("AutoGen", FILE_NOT_FOUND, ExtraData=File)
1258
1259 ## Add Dec file to DecDatabase
1260 #
1261 # Create a Dec instance for input dec file and add it to DecDatabase
1262 #
1263 # @param DecFileName: The DecFileName need to be added to database
1264 #
1265 def AddToDecDatabase(self, DecFileName):
1266 File = self.WorkspaceFile(DecFileName)
1267 if os.path.exists(File) and os.path.isfile(File):
1268 if DecFileName not in self.DecDatabase:
1269 self.DecDatabase[DecFileName] = Dec(File, False, True, self.WorkspaceDir, self.Db, self.SupArchList)
1270 else:
1271 EdkLogger.error("AutoGen", FILE_NOT_FOUND, ExtraData=File)
1272
1273 ## Search LibraryClass Instance for Module
1274 #
1275 # Search PlatformBuildDatabase to find LibraryClass Instance for Module
1276 # Return the instance if found
1277 #
1278 # @param Lib: Input value for Library Class Name
1279 # @param Arch: Supportted Arch
1280 # @param ModuleType: Supportted ModuleType
1281 # @param ModuleName: Input value for Module Name
1282 #
1283 # @retval string Found LibraryClass Instance file path
1284 #
1285 def FindLibraryClassInstanceOfModule(self, Lib, Arch, ModuleType, ModuleName):
1286 #
1287 # First find if exist in <LibraryClass> of <Components> from dsc file
1288 #
1289 for Dsc in self.DscDatabase.keys():
1290 Platform = self.DscDatabase[Dsc].Platform
1291 for Module in Platform.Modules.ModuleList:
1292 if Arch in Module.SupArchList:
1293 if Module.FilePath == ModuleName:
1294 for LibraryClass in Module.LibraryClasses.LibraryList:
1295 if LibraryClass.Name == Lib:
1296 return LibraryClass.FilePath
1297 #
1298 #Second find if exist in <LibraryClass> of <LibraryClasses> from dsc file
1299 #
1300 return self.FindLibraryClassInstanceOfLibrary(Lib, Arch, ModuleType)
1301
1302 ## Search LibraryClass Instance for Library
1303 #
1304 # Search PlatformBuildDatabase to find LibraryClass Instance for Library
1305 # Return the instance if found
1306 #
1307 # @param Lib: Input value for Library Class Name
1308 # @param Arch: Supportted Arch
1309 # @param Type: Supportted Library Usage Type
1310 #
1311 # @retval string Found LibraryClass Instance file path
1312 # @retval None Not Found
1313 #
1314 def FindLibraryClassInstanceOfLibrary(self, Lib, Arch, Type):
1315 for Dsc in self.DscDatabase.keys():
1316 Platform = self.DscDatabase[Dsc].Platform
1317 if (Lib, Type) in self.Build[Arch].PlatformDatabase[Dsc].LibraryClasses:
1318 return self.Build[Arch].PlatformDatabase[Dsc].LibraryClasses[(Lib, Type)]
1319 elif (Lib, '') in self.Build[Arch].PlatformDatabase[Dsc].LibraryClasses:
1320 return self.Build[Arch].PlatformDatabase[Dsc].LibraryClasses[(Lib, '')]
1321 return None
1322
1323 ## Find BuildOptions
1324 #
1325 # Search DscDatabase to find component definition of ModuleName
1326 # Override BuildOption if it is defined in component
1327 #
1328 # @param Arch: Supportted Arch
1329 # @param ModuleName: The module which has buildoption definition in component of platform
1330 # @param BuildOptions: The set of all buildopitons
1331 #
1332 def FindBuildOptions(self, Arch, ModuleName, BuildOptions):
1333 for Dsc in self.DscDatabase.keys():
1334 #
1335 # First find if exist in <BuildOptions> of <Components> from dsc file
1336 # if find, use that override the one defined in inf file
1337 #
1338 Platform = self.DscDatabase[Dsc].Platform
1339 for Module in Platform.Modules.ModuleList:
1340 if Arch in Module.SupArchList:
1341 if Module.FilePath == ModuleName:
1342 for BuildOption in Module.ModuleSaBuildOption.BuildOptionList:
1343 #
1344 # Add to BuildOptions
1345 #
1346 BuildOptions[(BuildOption.ToolChainFamily, BuildOption.ToolChain)] = BuildOption.Option
1347
1348 ## Find Pcd
1349 #
1350 # Search platform database, package database, module database and PcdsSet from Fdf
1351 # Return found Pcd
1352 #
1353 # @param Arch: Supportted Arch
1354 # @param ModuleName: The module which has pcd definition in component of platform
1355 # @param Name: Name of Pcd
1356 # @param Guid: Guid of Pcd
1357 # @param Type: Type of Pcd
1358 #
1359 # @retval PcdClassObject An instance for PcdClassObject with all members filled
1360 #
1361 def FindPcd(self, Arch, ModuleName, Name, Guid, Type):
1362 NewType = ''
1363 DatumType = ''
1364 Value = ''
1365 Token = ''
1366 MaxDatumSize = ''
1367 SkuInfoList = {}
1368 IsOverrided = False
1369 IsFoundInDsc = False
1370 IsFoundInDec = False
1371 FoundInDecFile = ''
1372
1373 #
1374 # Second get information from platform database
1375 #
1376 OwnerPlatform = ''
1377 for Dsc in self.Build[Arch].PlatformDatabase.keys():
1378 Pcds = self.Build[Arch].PlatformDatabase[Dsc].Pcds
1379 if (Name, Guid) in Pcds:
1380 OwnerPlatform = Dsc
1381 Pcd = Pcds[(Name, Guid)]
1382 if Pcd.Type != '' and Pcd.Type != None:
1383 NewType = Pcd.Type
1384 if NewType in DataType.PCD_DYNAMIC_TYPE_LIST:
1385 NewType = DataType.TAB_PCDS_DYNAMIC
1386 elif NewType in DataType.PCD_DYNAMIC_EX_TYPE_LIST:
1387 NewType = DataType.TAB_PCDS_DYNAMIC_EX
1388 else:
1389 NewType = Type
1390
1391 if Type != '' and Type != NewType:
1392 ErrorMsg = "PCD %s.%s is declared as [%s] in module\n\t%s\n\n"\
1393 " But it's used as [%s] in platform\n\t%s"\
1394 % (Guid, Name, Type, ModuleName, NewType, OwnerPlatform)
1395 EdkLogger.error("AutoGen", PARSER_ERROR, ErrorMsg)
1396
1397
1398 if Pcd.DatumType != '' and Pcd.DatumType != None:
1399 DatumType = Pcd.DatumType
1400 if Pcd.TokenValue != '' and Pcd.TokenValue != None:
1401 Token = Pcd.TokenValue
1402 if Pcd.DefaultValue != '' and Pcd.DefaultValue != None:
1403 Value = Pcd.DefaultValue
1404 if Pcd.MaxDatumSize != '' and Pcd.MaxDatumSize != None:
1405 MaxDatumSize = Pcd.MaxDatumSize
1406 SkuInfoList = Pcd.SkuInfoList
1407
1408 IsOverrided = True
1409 IsFoundInDsc = True
1410 break
1411
1412 #
1413 # Third get information from <Pcd> of <Compontents> from module database
1414 #
1415 for Dsc in self.DscDatabase.keys():
1416 for Module in self.DscDatabase[Dsc].Platform.Modules.ModuleList:
1417 if Arch in Module.SupArchList:
1418 if Module.FilePath == ModuleName:
1419 for Pcd in Module.PcdBuildDefinitions:
1420 if (Name, Guid) == (Pcd.CName, Pcd.TokenSpaceGuidCName):
1421 if Pcd.DefaultValue != '':
1422 Value = Pcd.DefaultValue
1423 if Pcd.MaxDatumSize != '':
1424 MaxDatumSize = Pcd.MaxDatumSize
1425
1426 IsFoundInDsc = True
1427 IsOverrided = True
1428 break
1429
1430 #
1431 # First get information from package database
1432 #
1433 Pcd = None
1434 if NewType == '':
1435 if Type != '':
1436 PcdTypeList = [Type]
1437 else:
1438 PcdTypeList = ["FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"]
1439
1440 for Dec in self.Build[Arch].PackageDatabase.keys():
1441 Pcds = self.Build[Arch].PackageDatabase[Dec].Pcds
1442 for PcdType in PcdTypeList:
1443 if (Name, Guid, PcdType) in Pcds:
1444 Pcd = Pcds[(Name, Guid, PcdType)]
1445 NewType = PcdType
1446 IsOverrided = True
1447 IsFoundInDec = True
1448 FoundInDecFile = Dec
1449 break
1450 else:
1451 continue
1452 break
1453 else:
1454 for Dec in self.Build[Arch].PackageDatabase.keys():
1455 Pcds = self.Build[Arch].PackageDatabase[Dec].Pcds
1456 if (Name, Guid, NewType) in Pcds:
1457 Pcd = Pcds[(Name, Guid, NewType)]
1458 IsOverrided = True
1459 IsFoundInDec = True
1460 FoundInDecFile = Dec
1461 break
1462
1463 if not IsFoundInDec:
1464 ErrorMsg = "Pcd '%s.%s [%s]' defined in module '%s' is not found in any package for Arch '%s'" % (Guid, Name, NewType, ModuleName, Arch)
1465 EdkLogger.error("AutoGen", PARSER_ERROR, ErrorMsg)
1466
1467 #
1468 # Not found in any platform and fdf
1469 #
1470 if not IsFoundInDsc:
1471 Value = Pcd.DefaultValue
1472 if NewType.startswith("Dynamic") and SkuInfoList == {}:
1473 SkuIds = self.Build[Arch].PlatformDatabase.values()[0].SkuIds
1474 SkuInfoList['DEFAULT'] = SkuInfoClass(SkuIdName='DEFAULT', SkuId=SkuIds['DEFAULT'], DefaultValue=Value)
1475 self.UnFoundPcdInDsc[(Guid, Name, NewType, Arch)] = FoundInDecFile
1476 #elif Type != '' and NewType.startswith("Dynamic"):
1477 # NewType = Pcd.Type
1478 DatumType = Pcd.DatumType
1479 if Token in [None, '']:
1480 Token = Pcd.TokenValue
1481 if DatumType == "VOID*" and MaxDatumSize in ['', None]:
1482 EdkLogger.verbose("No MaxDatumSize specified for PCD %s.%s in module [%s]" % (Guid, Name, ModuleName))
1483 if Value[0] == 'L':
1484 MaxDatumSize = str(len(Value) * 2)
1485 elif Value[0] == '{':
1486 MaxDatumSize = str(len(Value.split(',')))
1487 else:
1488 MaxDatumSize = str(len(Value))
1489
1490 return PcdClassObject(Name, Guid, NewType, DatumType, Value, Token, MaxDatumSize, SkuInfoList, IsOverrided)
1491
1492 ## Find Supportted Module List Of LibraryClass
1493 #
1494 # Search in InfDatabase, find the supmodulelist of the libraryclass
1495 #
1496 # @param LibraryClass: LibraryClass name for search
1497 # @param OverridedLibraryClassList: A list of all LibraryClass
1498 # @param Arch: Supportted Arch
1499 #
1500 # @retval list SupModuleList
1501 #
1502 def FindSupModuleListOfLibraryClass(self, LibraryClass, OverridedLibraryClassList, Arch):
1503 Name = LibraryClass.Name
1504 FilePath = LibraryClass.FilePath
1505 SupModuleList = copy.copy(LibraryClass.SupModuleList)
1506
1507 #
1508 # If the SupModuleList means all, remove overrided module types of platform
1509 #
1510 if SupModuleList == DataType.SUP_MODULE_LIST:
1511 EdkLogger.debug(EdkLogger.DEBUG_3, "\tLibraryClass %s supports all module types" % Name)
1512 for Item in OverridedLibraryClassList:
1513 #
1514 # Find a library class (Item) with the same name
1515 #
1516 if Item.Name == Name:
1517 #
1518 # Do nothing if it is itself
1519 #
1520 if Item.SupModuleList == DataType.SUP_MODULE_LIST:
1521 continue
1522 #
1523 # If not itself, check arch first
1524 #
1525 if Arch in LibraryClass.SupArchList:
1526 #
1527 # If arch is supportted, remove all related module type
1528 #
1529 if Arch in Item.SupArchList:
1530 for ModuleType in Item.SupModuleList:
1531 EdkLogger.debug(EdkLogger.DEBUG_3, "\tLibraryClass %s has specific defined module types" % Name)
1532 if ModuleType in SupModuleList:
1533 SupModuleList.remove(ModuleType)
1534
1535 return SupModuleList
1536
1537 ## Find Module inf Platform
1538 #
1539 # Check if the module is defined in <Compentent> of <Platform>
1540 #
1541 # @param Inf: Inf file (Module) need to be searched
1542 # @param Arch: Supportted Arch
1543 # @param InfList: A list for all Inf file
1544 #
1545 # @retval True Mudule Found
1546 # @retval Flase Module Not Found
1547 #
1548 def IsModuleDefinedInPlatform(self, Inf, Arch, InfList):
1549 for Dsc in self.DscDatabase.values():
1550 for LibraryClass in Dsc.Platform.LibraryClasses.LibraryList:
1551 if Inf == LibraryClass.FilePath and Arch in LibraryClass.SupArchList:
1552 return True
1553 for Module in Dsc.Platform.Modules.ModuleList:
1554 if Inf == Module.FilePath and Arch in Module.SupArchList:
1555 return True
1556 for Item in Module.LibraryClasses.LibraryList:
1557 if Inf == Item.FilePath:
1558 return True
1559 for Library in Dsc.Platform.Libraries.LibraryList:
1560 if Inf == Library.FilePath and Arch in Library.SupArchList:
1561 return True
1562
1563 return False
1564
1565 ## Show all content of the workspacebuild
1566 #
1567 # Print each item of the workspacebuild with (Key = Value) pair
1568 #
1569 def ShowWorkspaceBuild(self):
1570 print self.DscDatabase
1571 print self.InfDatabase
1572 print self.DecDatabase
1573 print 'SupArchList', self.SupArchList
1574 print 'BuildTarget', self.BuildTarget
1575 print 'SkuId', self.SkuId
1576
1577 for Arch in self.SupArchList:
1578 print Arch
1579 print 'Platform'
1580 for Platform in self.Build[Arch].PlatformDatabase.keys():
1581 P = self.Build[Arch].PlatformDatabase[Platform]
1582 print 'DescFilePath = ', P.DescFilePath
1583 print 'PlatformName = ', P.PlatformName
1584 print 'Guid = ', P.Guid
1585 print 'Version = ', P.Version
1586 print 'OutputDirectory = ', P.OutputDirectory
1587 print 'FlashDefinition = ', P.FlashDefinition
1588 print 'SkuIds = ', P.SkuIds
1589 print 'Modules = ', P.Modules
1590 print 'LibraryClasses = ', P.LibraryClasses
1591 print 'Pcds = ', P.Pcds
1592 for item in P.Pcds.keys():
1593 print P.Pcds[item]
1594 print 'BuildOptions = ', P.BuildOptions
1595 print ''
1596 # End of Platform
1597
1598 print 'package'
1599 for Package in self.Build[Arch].PackageDatabase.keys():
1600 P = self.Build[Arch].PackageDatabase[Package]
1601 print 'DescFilePath = ', P.DescFilePath
1602 print 'PackageName = ', P.PackageName
1603 print 'Guid = ', P.Guid
1604 print 'Version = ', P.Version
1605 print 'Protocols = ', P.Protocols
1606 print 'Ppis = ', P.Ppis
1607 print 'Guids = ', P.Guids
1608 print 'Includes = ', P.Includes
1609 print 'LibraryClasses = ', P.LibraryClasses
1610 print 'Pcds = ', P.Pcds
1611 for item in P.Pcds.keys():
1612 print P.Pcds[item]
1613 print ''
1614 # End of Package
1615
1616 print 'module'
1617 for Module in self.Build[Arch].ModuleDatabase.keys():
1618 P = self.Build[Arch].ModuleDatabase[Module]
1619 print 'DescFilePath = ', P.DescFilePath
1620 print 'BaseName = ', P.BaseName
1621 print 'ModuleType = ', P.ModuleType
1622 print 'Guid = ', P.Guid
1623 print 'Version = ', P.Version
1624 print 'CustomMakefile = ', P.CustomMakefile
1625 print 'Specification = ', P.Specification
1626 print 'Shadow = ', P.Shadow
1627 print 'PcdIsDriver = ', P.PcdIsDriver
1628 for Lib in P.LibraryClass:
1629 print 'LibraryClassDefinition = ', Lib.LibraryClass, 'SupModList = ', Lib.SupModList
1630 print 'ModuleEntryPointList = ', P.ModuleEntryPointList
1631 print 'ModuleUnloadImageList = ', P.ModuleUnloadImageList
1632 print 'ConstructorList = ', P.ConstructorList
1633 print 'DestructorList = ', P.DestructorList
1634
1635 print 'Binaries = '
1636 for item in P.Binaries:
1637 print item.BinaryFile, item.FeatureFlag, item.SupArchList
1638 print 'Sources = '
1639 for item in P.Sources:
1640 print item.SourceFile
1641 print 'LibraryClasses = ', P.LibraryClasses
1642 print 'Protocols = ', P.Protocols
1643 print 'Ppis = ', P.Ppis
1644 print 'Guids = ', P.Guids
1645 print 'Includes = ', P.Includes
1646 print 'Packages = ', P.Packages
1647 print 'Pcds = ', P.Pcds
1648 for item in P.Pcds.keys():
1649 print P.Pcds[item]
1650 print 'BuildOptions = ', P.BuildOptions
1651 print 'Depex = ', P.Depex
1652 print ''
1653 # End of Module
1654
1655 ##
1656 #
1657 # This acts like the main() function for the script, unless it is 'import'ed into another
1658 # script.
1659 #
1660 if __name__ == '__main__':
1661 print 'Start!', time.strftime('%H:%M:%S', time.localtime())
1662 EdkLogger.Initialize()
1663 EdkLogger.SetLevel(EdkLogger.QUIET)
1664
1665 W = os.getenv('WORKSPACE')
1666 Ewb = WorkspaceBuild('Nt32Pkg/Nt32Pkg.dsc', W)
1667 Ewb.GenBuildDatabase({('PcdDevicePathSupportDevicePathFromText', 'gEfiMdeModulePkgTokenSpaceGuid') : 'KKKKKKKKKKKKKKKKKKKKK'}, ['Test.Inf'])
1668 print 'Done!', time.strftime('%H:%M:%S', time.localtime())
1669 Ewb.ShowWorkspaceBuild()