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