git-svn-id: https://buildtools.tianocore.org/svn/buildtools/trunk/BaseTools@466 7335b...
[people/mcb30/basetools.git] / Source / Python / Common / EdkIIWorkspaceBuild.py
1 # Copyright (c) 2007, Intel Corporation\r
2 # All rights reserved. This program and the accompanying materials\r
3 # are licensed and made available under the terms and conditions of the BSD License\r
4 # which accompanies this distribution.    The full text of the license may be found at\r
5 # http://opensource.org/licenses/bsd-license.php\r
6 #\r
7 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
8 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
9 \r
10 #\r
11 # This file is used to define each component of the build database\r
12 #\r
13 \r
14 #\r
15 # Import Modules\r
16 #\r
17 import os, string, copy, pdb\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 CommonDataClass.CommonClass import *\r
26 \r
27 #\r
28 # This Class is used for PcdObject \r
29 #\r
30 class PcdClassObject(object):\r
31     def __init__(self, Name = None, Guid = None, Type = None, DatumType = None, Value = None, Token = None, MaxDatumSize = None, SkuInfoList = {}):\r
32         self.TokenCName = Name\r
33         self.TokenSpaceGuidCName = Guid\r
34         self.Type = Type\r
35         self.DatumType = DatumType\r
36         self.DefaultValue = Value\r
37         self.TokenValue = Token\r
38         self.MaxDatumSize = MaxDatumSize\r
39         self.SkuInfoList = SkuInfoList\r
40         self.Phase = "DXE"\r
41         \r
42     def __str__(self):\r
43         rtn = str(self.TokenCName) + DataType.TAB_VALUE_SPLIT + \\r
44               str(self.TokenSpaceGuidCName) + DataType.TAB_VALUE_SPLIT + \\r
45               str(self.Type) + DataType.TAB_VALUE_SPLIT + \\r
46               str(self.DatumType) + DataType.TAB_VALUE_SPLIT + \\r
47               str(self.DefaultValue) + DataType.TAB_VALUE_SPLIT + \\r
48               str(self.TokenValue) + DataType.TAB_VALUE_SPLIT + \\r
49               str(self.MaxDatumSize) + DataType.TAB_VALUE_SPLIT\r
50         for Item in self.SkuInfoList.values():\r
51             rtn = rtn + Item.SkuId + DataType.TAB_VALUE_SPLIT + Item.SkuIdName\r
52         return rtn\r
53 \r
54     def __eq__(self, other):\r
55         return other != None and self.TokenCName == other.TokenCName and self.TokenSpaceGuidCName == other.TokenSpaceGuidCName\r
56 \r
57     def __hash__(self):\r
58         return hash((self.TokenCName, self.TokenSpaceGuidCName))\r
59 \r
60 #\r
61 # This Class is used for LibraryClassObject\r
62 #\r
63 class LibraryClassObject(object):\r
64     def __init__(self, Name = None, SupModList = [], Type = None):\r
65         self.LibraryClass = Name\r
66         self.SupModList = SupModList\r
67         if Type != None:\r
68             self.SupModList = CleanString(Type).split(DataType.TAB_SPACE_SPLIT)\r
69         \r
70 class ModuleBuildClassObject(object):\r
71     def __init__(self):\r
72         self.DescFilePath            = ''\r
73         self.BaseName                = ''\r
74         self.ModuleType              = ''\r
75         self.Guid                    = ''\r
76         self.Version                 = ''\r
77         self.PcdIsDriver             = ''\r
78         self.BinaryModule            = ''\r
79         self.CustomMakefile          = {}\r
80         self.Specification           = {}\r
81         self.LibraryClass            = None      # LibraryClassObject\r
82         self.ModuleEntryPointList    = []\r
83         self.ModuleUnloadImageList   = []\r
84         self.ConstructorList         = []\r
85         self.DestructorList          = []\r
86         \r
87         self.Binaries                = []        #[ ModuleBinaryClassObject, ...]\r
88         self.Sources                 = []        #[ ModuleSourceFilesClassObject, ... ]\r
89         self.LibraryClasses          = {}        #{ [LibraryClassName, ModuleType] : LibraryClassInfFile }\r
90         self.Protocols               = []        #[ ProtocolName, ... ]\r
91         self.Ppis                    = []        #[ PpiName, ... ]\r
92         self.Guids                   = []        #[ GuidName, ... ]\r
93         self.Includes                = []        #[ IncludePath, ... ]\r
94         self.Packages                = []        #[ DecFileName, ... ]\r
95         self.Pcds                    = {}        #{ [(PcdCName, PcdGuidCName)] : PcdClassObject}\r
96         self.BuildOptions            = {}        #{ [BuildOptionKey] : BuildOptionValue}\r
97         self.Depex                   = ''\r
98 \r
99     def __str__(self):\r
100         return self.DescFilePath\r
101 \r
102     def __eq__(self, other):\r
103         return self.DescFilePath == str(other)\r
104 \r
105     def __hash__(self):\r
106         return hash(self.DescFilePath)\r
107 \r
108 class PackageBuildClassObject(object):\r
109     def __init__(self):\r
110         self.DescFilePath            = ''\r
111         self.PackageName             = ''\r
112         self.Guid                    = ''\r
113         self.Version                 = ''\r
114         \r
115         self.Protocols               = {}       #{ [ProtocolName] : Protocol Guid, ... }\r
116         self.Ppis                    = {}       #{ [PpiName] : Ppi Guid, ... }\r
117         self.Guids                   = {}       #{ [GuidName] : Guid, ... }\r
118         self.Includes                = []       #[ IncludePath, ... ]        \r
119         self.LibraryClasses          = {}       #{ [LibraryClassName] : LibraryClassInfFile }\r
120         self.Pcds                    = {}       #{ [(PcdCName, PcdGuidCName)] : PcdClassObject}\r
121         \r
122     def __str__(self):\r
123         return self.DescFilePath\r
124 \r
125     def __eq__(self, other):\r
126         return self.DescFilePath == str(other)\r
127 \r
128     def __hash__(self):\r
129         return hash(self.DescFilePath)\r
130 \r
131 class PlatformBuildClassObject(object):\r
132     def __init__(self):\r
133         self.DescFilePath            = ''\r
134         self.PlatformName            = ''\r
135         self.Guid                    = ''\r
136         self.Version                 = ''\r
137         self.DscSpecification        = ''\r
138         self.OutputDirectory         = ''\r
139         self.FlashDefinition         = ''\r
140         self.BuildNumber             = ''\r
141         self.MakefileName            = ''\r
142                 \r
143         self.SkuIds                  = {}       #{ 'SkuName' : SkuId, '!include' : includefilename, ...}\r
144         self.Modules                 = []       #[ InfFileName, ... ]\r
145         self.Libraries               = []       #[ InfFileName, ... ]\r
146         self.LibraryClasses          = {}       #{ (LibraryClassName, ModuleType) : LibraryClassInfFile }\r
147         self.Pcds                    = {}       #{ [(PcdCName, PcdGuidCName)] : PcdClassObject }\r
148         self.BuildOptions            = {}       #{ [BuildOptionKey] : BuildOptionValue }    \r
149 \r
150     def __str__(self):\r
151         return self.DescFilePath\r
152 \r
153     def __eq__(self, other):\r
154         return self.DescFilePath == str(other)\r
155 \r
156     def __hash__(self):\r
157         return hash(self.DescFilePath)\r
158 \r
159 class ItemBuild(object):\r
160     def __init__(self, Arch, Platform = None, Package = None, Module = None):\r
161         self.Arch                    = Arch\r
162         self.PlatformDatabase        = {}        #{ [DscFileName] : PlatformBuildClassObject, ...}\r
163         self.PackageDatabase         = {}        #{ [DecFileName] : PacakgeBuildClassObject, ...}\r
164         self.ModuleDatabase          = {}        #{ [InfFileName] : ModuleBuildClassObject, ...}\r
165         \r
166 #\r
167 # This class is used to parse active platform to init all inf/dec/dsc files\r
168 # Generate module/package/platform databases for build\r
169 #\r
170 class WorkspaceBuild(object):\r
171     def __init__(self, ActivePlatform, WorkspaceDir):\r
172         self.WorkspaceDir            = NormPath(WorkspaceDir)\r
173         self.SupArchList             = []        #[ 'IA32', 'X64', ...]\r
174         self.BuildTarget             = []        #[ 'RELEASE', 'DEBUG']\r
175         self.SkuId                   = ''\r
176         self.Fdf                     = ''\r
177         self.TargetTxt               = None\r
178         self.ToolDef                 = None\r
179         \r
180         self.InfDatabase             = {}        #{ [InfFileName] : InfClassObject}\r
181         self.DecDatabase             = {}        #{ [DecFileName] : DecClassObject}\r
182         self.DscDatabase             = {}        #{ [DscFileName] : DscClassObject}\r
183         \r
184         #\r
185         # Init build for all arches\r
186         #\r
187         self.Build                   = {}\r
188         for Arch in DataType.ARCH_LIST:\r
189             self.Build[Arch] = ItemBuild(Arch)\r
190         \r
191         #\r
192         # Get active platform\r
193         #\r
194         DscFileName = ActivePlatform\r
195         File = self.WorkspaceFile(NormPath(DscFileName))\r
196         if os.path.exists(File) and os.path.isfile(File):\r
197             self.DscDatabase[DscFileName] = Dsc(File, True, True)\r
198         else:\r
199             raise ParserError(FILE_NOT_FOUND, name = File)\r
200         \r
201         #\r
202         # Parse platform to get module\r
203         #\r
204         for DscFile in self.DscDatabase.keys():\r
205             Platform = self.DscDatabase[DscFile].Platform\r
206             \r
207             #\r
208             # Get global information\r
209             #\r
210             self.SupArchList = Platform.Header.SupArchList\r
211             self.BuildTarget = Platform.Header.BuildTargets\r
212             self.SkuId = Platform.Header.SkuIdName\r
213             self.Fdf = Platform.FlashDefinitionFile.FilePath\r
214             \r
215             #\r
216             # Get all inf files\r
217             #\r
218             for Item in Platform.LibraryClasses.LibraryList:\r
219                 for Arch in Item.SupArchList:\r
220                     self.AddToInfDatabase(Item.FilePath)\r
221             \r
222             for Item in Platform.Modules.ModuleList:\r
223                 for Arch in Item.SupArchList:\r
224                     #\r
225                     # Add modules\r
226                     #\r
227                     Module = Item.FilePath\r
228                     self.AddToInfDatabase(Module)\r
229                     #\r
230                     # Add library used in modules\r
231                     #\r
232                     for Lib in Item.LibraryClasses.LibraryList:\r
233                         self.AddToInfDatabase(Lib.FilePath)\r
234                         self.UpdateLibraryClassOfModule(Module, Lib.Name, Arch)\r
235         \r
236         #\r
237         # Parse module to get package\r
238         #\r
239         for InfFile in self.InfDatabase.keys():\r
240             Module = self.InfDatabase[InfFile].Module\r
241             #\r
242             # Get all dec\r
243             #\r
244             for Item in Module.PackageDependencies:\r
245                 for Arch in Item.SupArchList:\r
246                     self.AddToDecDatabase(Item.FilePath)\r
247     # End of self.Init()\r
248     \r
249     #\r
250     # Generate PlatformDatabase\r
251     #\r
252     def GenPlatformDatabase(self):\r
253         for Dsc in self.DscDatabase.keys():\r
254             Platform = self.DscDatabase[Dsc].Platform\r
255             \r
256             for Arch in self.SupArchList:\r
257                 pb = PlatformBuildClassObject()\r
258                 \r
259                 # Defines\r
260                 pb.DescFilePath = Dsc\r
261                 pb.PlatformName = Platform.Header.Name\r
262                 pb.Guid = Platform.Header.Guid\r
263                 pb.Version = Platform.Header.Version\r
264                 pb.DscSpecification = Platform.Header.DscSpecification\r
265                 pb.OutputDirectory = NormPath(Platform.Header.OutputDirectory)\r
266                 pb.FlashDefinition = NormPath(Platform.FlashDefinitionFile.FilePath)\r
267                 pb.BuildNumber = Platform.Header.BuildNumber\r
268             \r
269                 # SkuId\r
270                 for Key in Platform.SkuInfos.SkuInfoList.keys():\r
271                     pb.SkuIds[Key] = Platform.SkuInfos.SkuInfoList[Key]\r
272                 \r
273                 # Module\r
274                 for Item in Platform.Modules.ModuleList:\r
275                     if Arch in Item.SupArchList:\r
276                         pb.Modules.append(NormPath(Item.FilePath))\r
277                     \r
278                 # BuildOptions\r
279                 for Item in Platform.BuildOptions.BuildOptionList:\r
280                     if Arch in Item.SupArchList:\r
281                         pb.BuildOptions[(Item.ToolChainFamily, Item.ToolChain)] = Item.Option\r
282                   \r
283                 # LibraryClass\r
284                 for Item in Platform.LibraryClasses.LibraryList:\r
285                     if Arch in Item.SupArchList:\r
286                         for ModuleType in Item.ModuleType:\r
287                             pb.LibraryClasses[(Item.Name, ModuleType)] = NormPath(Item.FilePath)\r
288                     \r
289                 # Pcds\r
290                 for Item in Platform.DynamicPcdBuildDefinitions:\r
291                     if Arch in Item.SupArchList:\r
292                         Name = Item.CName\r
293                         Guid = Item.TokenSpaceGuidCName\r
294                         Type = Item.ItemType\r
295                         DatumType = Item.DatumType\r
296                         Value = Item.DefaultValue\r
297                         Token = Item.Token\r
298                         MaxDatumSize = Item.MaxDatumSize\r
299                         SkuInfoList = Item.SkuInfoList\r
300                         pb.Pcds[(Name, Guid)] = PcdClassObject(Name, Guid, Type, DatumType, Value, Token, MaxDatumSize, SkuInfoList)\r
301                 \r
302                 # Add to database\r
303                 self.Build[Arch].PlatformDatabase[Dsc] = pb\r
304                 pb = None\r
305     \r
306     #\r
307     # Generate PackageDatabase\r
308     #    \r
309     def GenPackageDatabase(self):\r
310         for Dec in self.DecDatabase.keys():\r
311             Package = self.DecDatabase[Dec].Package\r
312         \r
313             for Arch in self.SupArchList:\r
314                 pb = PackageBuildClassObject()\r
315                 \r
316                 # Defines\r
317                 pb.DescFilePath = Dec\r
318                 pb.PackageName = Package.Header.Name\r
319                 pb.Guid = Package.Header.Guid\r
320                 pb.Version = Package.Header.Version\r
321                 \r
322                 # Protocols\r
323                 for Item in Package.ProtocolDeclarations:\r
324                     if Arch in Item.SupArchList:\r
325                         pb.Protocols[Item.CName] = Item.Guid\r
326                         \r
327                 # Ppis\r
328                 for Item in Package.PpiDeclarations:\r
329                     if Arch in Item.SupArchList:\r
330                         pb.Ppis[Item.CName] = Item.Guid\r
331                 \r
332                 # Guids\r
333                 for Item in Package.GuidDeclarations:\r
334                     if Arch in Item.SupArchList:\r
335                         pb.Ppis[Item.CName] = Item.Guid\r
336                 \r
337                 # Includes\r
338                 for Item in Package.Includes:\r
339                     if Arch in Item.SupArchList:\r
340                         pb.Includes.append(NormPath(Item.FilePath))\r
341                         \r
342                 # LibraryClasses\r
343                 for Item in Package.LibraryClassDeclarations:\r
344                     if Arch in Item.SupArchList:\r
345                         pb.LibraryClasses[Item.LibraryClass] = NormPath(Item.RecommendedInstance)\r
346                 \r
347                 # Pcds\r
348                 for Item in Package.PcdDeclarations:\r
349                     if Arch in Item.SupArchList:\r
350                         Name = Item.CName\r
351                         Guid = Item.TokenSpaceGuidCName\r
352                         Type = Item.ItemType\r
353                         DatumType = Item.DatumType\r
354                         Value = Item.DefaultValue\r
355                         Token = Item.Token\r
356                         MaxDatumSize = Item.MaxDatumSize\r
357                         SkuInfoList = Item.SkuInfoList\r
358                         pb.Pcds[(Name, Guid)] = PcdClassObject(Name, Guid, Type, DatumType, Value, Token, MaxDatumSize, SkuInfoList)\r
359                 \r
360                 # Add to database\r
361                 self.Build[Arch].PackageDatabase[Dec] = pb\r
362                 pb = None\r
363     \r
364     #\r
365     # Generate ModuleDatabase\r
366     #\r
367     def GenModuleDatabase(self, PcdsSet = {}):\r
368         for Inf in self.InfDatabase.keys():\r
369             Module = self.InfDatabase[Inf].Module\r
370             \r
371             for Arch in self.SupArchList:\r
372                 pb = ModuleBuildClassObject()\r
373                 \r
374                 # Defines\r
375                 pb.DescFilePath = Inf\r
376                 pb.BaseName = Module.Header.Name\r
377                 pb.Guid = Module.Header.Guid\r
378                 pb.Version = Module.Header.Version\r
379                 pb.ModuleType = Module.Header.ModuleType\r
380                 pb.PcdIsDriver = Module.Header.PcdIsDriver\r
381                 pb.BinaryModule = Module.Header.BinaryModule\r
382                 pb.CustomMakefile = Module.Header.CustomMakefile\r
383                 \r
384                 # Specs os Defines\r
385                 pb.Specification = Module.Header.Specification\r
386                 pb.Specification[TAB_INF_DEFINES_EDK_RELEASE_VERSION] = Module.Header.EdkReleaseVersion\r
387                 pb.Specification[TAB_INF_DEFINES_EFI_SPECIFICATION_VERSION] = Module.Header.EfiSpecificationVersion\r
388                 \r
389                 # LibraryClass of Defines\r
390                 for Item in Module.Header.LibraryClass:\r
391                     pb.LibraryClass = LibraryClassObject(Item.LibraryClass, Item.SupModuleList, None)\r
392 \r
393                 # Module image and library of Defines\r
394                 for Item in Module.ExternImages:\r
395                     if Item.ModuleEntryPoint != '':\r
396                         pb.ModuleEntryPointList.append(Item.ModuleEntryPoint)\r
397                     if Item.ModuleUnloadImage != '':\r
398                         pb.ModuleUnloadImageList.append(Item.ModuleUnloadImage)\r
399                 for Item in Module.ExternLibraries:\r
400                     if Item.Constructor != '':\r
401                         pb.ConstructorList.append(Item.Constructor)\r
402                     if Item.Destructor != '':\r
403                         pb.DestructorList.append(Item.Destructor)\r
404                 \r
405                 # Binaries\r
406                 for Item in Module.Binaries:\r
407                     if Arch in Item.SupArchList:\r
408                         FileName = NormPath(Item.BinaryFile)\r
409                         FileType = Item.FileType\r
410                         Target = Item.Target\r
411                         FeatureFlag = Item.FeatureFlag\r
412                         pb.Binaries.append(ModuleBinaryFileClass(FileName, FileType, Target, FeatureFlag))\r
413                 \r
414                 #Sources\r
415                 for Item in Module.Sources:\r
416                     if Arch in Item.SupArchList:\r
417                         SourceFile = NormPath(Item.SourceFile)\r
418                         TagName = Item.TagName\r
419                         ToolCode = Item.ToolCode\r
420                         ToolChainFamily = Item.ToolChainFamily\r
421                         FeatureFlag = Item.FeatureFlag\r
422                         pb.Sources.append(ModuleSourceFileClass(SourceFile, TagName, ToolCode, ToolChainFamily, FeatureFlag))\r
423                 \r
424                 # Protocols\r
425                 for Item in Module.Protocols:\r
426                     if Arch in Item.SupArchList:\r
427                         pb.Protocols.append(Item.CName)\r
428                         \r
429                 # Ppis\r
430                 for Item in Module.Ppis:\r
431                     if Arch in Item.SupArchList:\r
432                         pb.Ppis.append(Item.CName)\r
433                 \r
434                 # Guids\r
435                 for Item in Module.Guids:\r
436                     if Arch in Item.SupArchList:\r
437                         pb.Ppis.append(Item.CName)\r
438                 \r
439                 # Includes\r
440                 for Item in Module.Includes:\r
441                     if Arch in Item.SupArchList:\r
442                         pb.Includes.append(NormPath(Item.FilePath))                \r
443                 \r
444                 # Packages\r
445                 for Item in Module.PackageDependencies:\r
446                     if Arch in Item.SupArchList:\r
447                         pb.Packages.append(NormPath(Item.FilePath))                        \r
448 \r
449                 # BuildOptions\r
450                 for Item in Module.BuildOptions:\r
451                     if Arch in Item.SupArchList:\r
452                         pb.BuildOptions[(Item.ToolChainFamily, Item.ToolChain)] = Item.Option\r
453                 self.FindBuildOptions(Arch, Inf, pb.BuildOptions)\r
454                 \r
455                 # Depex\r
456                 for Item in Module.Depex:\r
457                     if Arch in Item.SupArchList:\r
458                         pb.Depex = pb.Depex + Item.Depex + ' '\r
459                 pb.Depex = pb.Depex.strip()\r
460                 \r
461                 # LibraryClasses\r
462                 for Item in Module.LibraryClasses:\r
463                     if Arch in Item.SupArchList:\r
464                         Lib = Item.LibraryClass\r
465                         RecommendedInstance = Item.RecommendedInstance\r
466                         if pb.LibraryClass != None:\r
467                             # For Library\r
468                             for Type in pb.LibraryClass.SupModList:\r
469                                 Instance = self.FindLibraryClassInstanceOfLibrary(Lib, Arch, Type)\r
470                                 if Instance == None:\r
471                                     Instance = RecommendedInstance\r
472                                 pb.LibraryClasses[(Lib, Type)] = NormPath(Instance)\r
473                         else:\r
474                             # For Module\r
475                             Instance = self.FindLibraryClassInstanceOfModule(Lib, Arch, pb.ModuleType, Inf) \r
476                             if Instance == None:\r
477                                 Instance = RecommendedInstance\r
478                             pb.LibraryClasses[(Lib, pb.ModuleType)] = NormPath(Instance)\r
479                 \r
480                 # Pcds\r
481                 for Item in Module.PcdCodes:\r
482                     if Arch in Item.SupArchList:\r
483                         Name = Item.CName\r
484                         Guid = Item.TokenSpaceGuidCName\r
485                         Type = Item.ItemType\r
486                         pb.Pcds[(Name, Guid)] = self.FindPcd(Arch, Inf, Name, Guid, Type, PcdsSet)\r
487                 \r
488                 # Add to database\r
489                 self.Build[Arch].ModuleDatabase[Inf] = pb\r
490                 pb = None\r
491     \r
492     #\r
493     # Update Libraries Of Platform Database\r
494     #\r
495     def UpdateLibrariesOfPlatform(self):\r
496         for Arch in self.SupArchList:\r
497             PlatformDatabase = self.Build[Arch].PlatformDatabase\r
498             for Dsc in PlatformDatabase:\r
499                 Platform = PlatformDatabase[Dsc]\r
500                 for Inf in Platform.Modules:\r
501                     Module = self.Build[Arch].ModuleDatabase[NormPath(Inf)]\r
502                     Stack = [NormPath(str(Module))]\r
503                     while len(Stack) > 0:\r
504                         M = self.Build[Arch].ModuleDatabase[Stack.pop()]\r
505                         if M != Module:\r
506                             Platform.Libraries.append(M)\r
507                         for Lib in M.LibraryClasses.values():\r
508                             if Lib not in Platform.Libraries and Lib != '':\r
509                                 Platform.Libraries.append(NormPath(Lib))\r
510                                 Stack.append(NormPath(Lib))\r
511     \r
512     #\r
513     # Generate build database for all arches\r
514     #\r
515     def GenBuildDatabase(self, PcdsSet = {}):\r
516         self.GenPlatformDatabase()\r
517         self.GenPackageDatabase()\r
518         self.GenModuleDatabase(PcdsSet)\r
519         self.UpdateLibrariesOfPlatform()\r
520 \r
521     #\r
522     # Return a full path with workspace dir\r
523     #\r
524     def WorkspaceFile(self, Filename):\r
525         return os.path.join(os.path.normpath(self.WorkspaceDir), os.path.normpath(Filename))\r
526     \r
527     #\r
528     # If a module of a platform has its own override libraryclass but the libraryclass not defined in the module\r
529     # Add this libraryclass to the module\r
530     #\r
531     def UpdateLibraryClassOfModule(self, InfFileName, LibraryClass, Arch):\r
532         LibList = self.InfDatabase[NormPath(InfFileName)].Module.LibraryClasses\r
533         NotFound = True\r
534         for Lib in LibList:\r
535             #\r
536             # Find this LibraryClass\r
537             #\r
538             if Lib.LibraryClass == LibraryClass:\r
539                 if Arch in Lib.SupArchList:\r
540                     return\r
541                 else:\r
542                     Lib.SupArchList.append(Arch)\r
543                     return\r
544         if NotFound:\r
545             Lib = LibraryClassClass()\r
546             Lib.LibraryClass = LibraryClass\r
547             Lib.SupArchList = [Arch]\r
548             self.InfDatabase[NormPath(InfFileName)].Module.LibraryClasses.append(Lib)\r
549             \r
550     #\r
551     # Create a Inf instance for input inf file and add it to InfDatabase\r
552     #\r
553     def AddToInfDatabase(self, InfFileName):\r
554         InfFileName = NormPath(InfFileName)\r
555         File = self.WorkspaceFile(InfFileName)\r
556         if os.path.exists(File) and os.path.isfile(File):\r
557             if InfFileName not in self.InfDatabase:\r
558                 self.InfDatabase[InfFileName] = Inf(File, True, True)\r
559         else:\r
560             raise ParserError(FILE_NOT_FOUND, name = File)\r
561     \r
562     #\r
563     # Create a Dec instance for input dec file and add it to DecDatabase\r
564     #                \r
565     def AddToDecDatabase(self, DecFileName):\r
566         DecFileName = NormPath(DecFileName)\r
567         File = self.WorkspaceFile(DecFileName)\r
568         if os.path.exists(File) and os.path.isfile(File):\r
569             if DecFileName not in self.DecDatabase:\r
570                 self.DecDatabase[DecFileName] = Dec(File, True, True)\r
571         else:\r
572             raise ParserError(FILE_NOT_FOUND, name = File)\r
573                 \r
574     #\r
575     # Search PlatformBuildDatabase to find LibraryClass Instance for Module\r
576     # Return the instance if found\r
577     #\r
578     def FindLibraryClassInstanceOfModule(self, Lib, Arch, ModuleType, ModuleName):\r
579         #\r
580         # First find if exist in <LibraryClass> of <Components> from dsc file\r
581         #\r
582         for Dsc in self.DscDatabase.keys():\r
583             Platform = self.DscDatabase[Dsc].Platform\r
584             for Module in Platform.Modules.ModuleList:\r
585                 if Arch in Module.SupArchList:\r
586                     if NormPath(Module.FilePath) == ModuleName:\r
587                         for LibraryClass in Module.LibraryClasses.LibraryList:\r
588                             if LibraryClass.Name == Lib:\r
589                                 return NormPath(LibraryClass.FilePath)\r
590         #\r
591         #Second find if exist in <LibraryClass> of <LibraryClasses> from dsc file            \r
592         #\r
593         return self.FindLibraryClassInstanceOfLibrary(Lib, Arch, ModuleType)\r
594             \r
595     #\r
596     # Search PlatformBuildDatabase to find LibraryClass Instance for Library\r
597     # Return the instance if found\r
598     #\r
599     def FindLibraryClassInstanceOfLibrary(self, Lib, Arch, Type):\r
600         for Dsc in self.DscDatabase.keys():\r
601             Platform  = self.DscDatabase[Dsc].Platform\r
602             if (Lib, Type) in self.Build[Arch].PlatformDatabase[Dsc].LibraryClasses:\r
603                 return self.Build[Arch].PlatformDatabase[Dsc].LibraryClasses[(Lib, Type)]\r
604             elif (Lib, '') in self.Build[Arch].PlatformDatabase[Dsc].LibraryClasses:\r
605                 return self.Build[Arch].PlatformDatabase[Dsc].LibraryClasses[(Lib, '')]\r
606         return None\r
607             \r
608     #\r
609     # Search DscDatabase to find component definition of ModuleName\r
610     # Override BuildOption if it is defined in component\r
611     #\r
612     def FindBuildOptions(self, Arch, ModuleName, BuildOptions):\r
613         for Dsc in self.DscDatabase.keys():\r
614             #\r
615             # First find if exist in <BuildOptions> of <Components> from dsc file\r
616             # if find, use that override the one defined in inf file\r
617             #\r
618             Platform = self.DscDatabase[Dsc].Platform\r
619             for Module in Platform.Modules.ModuleList:\r
620                 if Arch in Module.SupArchList:\r
621                     if NormPath(Module.FilePath) == ModuleName:\r
622                         for BuildOption in Module.ModuleSaBuildOption.BuildOptionList:\r
623                             BuildOptions[(BuildOption.ToolChainFamily, BuildOption.ToolChain)] = BuildOption.Option\r
624                         \r
625     #\r
626     # Search platform database, package database, module database and PcdsSet from Fdf\r
627     # Return found Pcd\r
628     #\r
629     def FindPcd(self, Arch, ModuleName, Name, Guid, Type, PcdsSet):\r
630         DatumType = ''\r
631         Value = ''\r
632         Token = ''\r
633         MaxDatumSize = ''\r
634         SkuInfoList = {}\r
635         #\r
636         # First get information from platform database\r
637         #\r
638         for Dsc in self.Build[Arch].PlatformDatabase.keys():\r
639             Pcds = self.Build[Arch].PlatformDatabase[Dsc].Pcds\r
640             if (Name, Guid) in Pcds:\r
641                 Type = Pcds[(Name, Guid)].Type\r
642                 DatumType = Pcds[(Name, Guid)].DatumType\r
643                 Value = Pcds[(Name, Guid)].DefaultValue\r
644                 Token = Pcds[(Name, Guid)].TokenValue\r
645                 MaxDatumSize = Pcds[(Name, Guid)].MaxDatumSize\r
646                 SkuInfoList =  Pcds[(Name, Guid)].SkuInfoList\r
647                 break\r
648 \r
649         #\r
650         # Second get information from package database\r
651         #\r
652         for Dec in self.Build[Arch].PackageDatabase.keys():\r
653             Pcds = self.Build[Arch].PackageDatabase[Dec].Pcds\r
654             if (Name, Guid) in Pcds:\r
655                 DatumType = Pcds[(Name, Guid)].DatumType\r
656                 Token = Pcds[(Name, Guid)].TokenValue\r
657                 break\r
658         \r
659         #\r
660         # Third get information from <Pcd> of <Compontents> from module database\r
661         #\r
662         for Dsc in self.DscDatabase.keys():\r
663             for Module in self.DscDatabase[Dsc].Platform.Modules.ModuleList:\r
664                 if Arch in Module.SupArchList:\r
665                     if NormPath(Module.FilePath) == ModuleName:\r
666                         for Pcd in Module.PcdBuildDefinitions:\r
667                             if (Name, Guid) == (Pcd.CName, Pcd.TokenSpaceGuidCName):\r
668                                 if Pcd.DefaultValue != '':\r
669                                     Value = Pcd.DefaultValue\r
670                                 if Pcd.MaxDatumSize != '':\r
671                                     MaxDatumSize = Pcd.MaxDatumSize\r
672         \r
673         #\r
674         # Last get information from PcdsSet defined by FDF\r
675         #\r
676         if Guid in PcdsSet.keys():\r
677             Value = PcdsSet[Guid]\r
678         \r
679         return PcdClassObject(Name, Guid, Type, DatumType, Value, Token, MaxDatumSize, SkuInfoList)   \r
680 \r
681     #\r
682     # Show all content of the workspacebuild\r
683     #\r
684     def ShowWorkspaceBuild(self):\r
685         print ewb.DscDatabase\r
686         print ewb.InfDatabase\r
687         print ewb.DecDatabase\r
688         print 'SupArchList', ewb.SupArchList\r
689         print 'BuildTarget', ewb.BuildTarget\r
690         print 'SkuId', ewb.SkuId\r
691         \r
692         for arch in ewb.SupArchList:\r
693             print arch\r
694             print 'Platform'\r
695             for platform in ewb.Build[arch].PlatformDatabase.keys():\r
696                 p = ewb.Build[arch].PlatformDatabase[platform]\r
697                 print 'DescFilePath = ', p.DescFilePath     \r
698                 print 'PlatformName = ', p.PlatformName     \r
699                 print 'Guid = ', p.Guid                     \r
700                 print 'Version = ', p.Version\r
701                 print 'OutputDirectory = ', p.OutputDirectory                \r
702                 print 'FlashDefinition = ', p.FlashDefinition\r
703                 print 'SkuIds = ', p.SkuIds\r
704                 print 'Modules = ', p.Modules\r
705                 print 'LibraryClasses = ', p.LibraryClasses \r
706                 print 'Pcds = ', p.Pcds\r
707                 for item in p.Pcds.keys():\r
708                     print p.Pcds[item]\r
709                 print 'BuildOptions = ', p.BuildOptions\r
710                 print ''   \r
711             # End of Platform\r
712         \r
713             print 'package'\r
714             for package in ewb.Build[arch].PackageDatabase.keys():\r
715                 p = ewb.Build[arch].PackageDatabase[package]\r
716                 print 'DescFilePath = ', p.DescFilePath    \r
717                 print 'PackageName = ', p.PackageName     \r
718                 print 'Guid = ', p.Guid                    \r
719                 print 'Version = ', p.Version             \r
720                 print 'Protocols = ', p.Protocols         \r
721                 print 'Ppis = ', p.Ppis                    \r
722                 print 'Guids = ', p.Guids                 \r
723                 print 'Includes = ', p.Includes            \r
724                 print 'LibraryClasses = ', p.LibraryClasses\r
725                 print 'Pcds = ', p.Pcds\r
726                 for item in p.Pcds.keys():\r
727                     print p.Pcds[item]\r
728                 print ''                    \r
729             # End of Package\r
730             \r
731             print 'module'\r
732             for module in ewb.Build[arch].ModuleDatabase.keys():\r
733                 p = ewb.Build[arch].ModuleDatabase[module]\r
734                 print 'DescFilePath = ', p.DescFilePath                    \r
735                 print 'BaseName = ', p.BaseName                         \r
736                 print 'ModuleType = ', p.ModuleType                     \r
737                 print 'Guid = ', p.Guid                                 \r
738                 print 'Version = ', p.Version\r
739                 print 'CustomMakefile = ', p.CustomMakefile\r
740                 print 'Specification = ', p.Specification\r
741                 print 'PcdIsDriver = ', p.PcdIsDriver\r
742                 if p.LibraryClass != None:\r
743                     print 'LibraryClass = ', p.LibraryClass.LibraryClass, 'SupModList = ', p.LibraryClass.SupModList\r
744                 print 'ModuleEntryPointList = ', p.ModuleEntryPointList \r
745                 print 'ModuleUnloadImageList = ', p.ModuleUnloadImageList\r
746                 print 'ConstructorList = ', p.ConstructorList            \r
747                 print 'DestructorList = ', p.DestructorList             \r
748                                                                          \r
749                 print 'Binaries = '\r
750                 for item in p.Binaries:\r
751                     print item.BinaryFile, item.FeatureFlag\r
752                 print 'Sources = '\r
753                 for item in p.Sources:\r
754                     print item.SourceFile\r
755                 print 'LibraryClasses = ', p.LibraryClasses             \r
756                 print 'Protocols = ', p.Protocols                        \r
757                 print 'Ppis = ', p.Ppis                                 \r
758                 print 'Guids = ', p.Guids                                \r
759                 print 'Includes = ', p.Includes                         \r
760                 print 'Packages = ', p.Packages                         \r
761                 print 'Pcds = ', p.Pcds\r
762                 for item in p.Pcds.keys():\r
763                     print p.Pcds[item]\r
764                 print 'BuildOptions = ', p.BuildOptions\r
765                 print 'Depex = ', p.Depex\r
766                 print ''\r
767             # End of Module    \r
768 \r
769 #\r
770 # This acts like the main() function for the script, unless it is 'import'ed into another\r
771 # script.\r
772 #\r
773 if __name__ == '__main__':\r
774     # Nothing to do here. Could do some unit tests.\r
775     w = os.getenv('WORKSPACE')\r
776     ewb = WorkspaceBuild('Nt32Pkg/Nt32Pkg.dsc', w)\r
777     ewb.GenBuildDatabase({'gEfiMdeModulePkgTokenSpaceGuid' : 'KKKKKKKKKKKKKKKKKKKKK'})\r
778     ewb.ShowWorkspaceBuild()\r