BaseTools: Enable structure pcd in FDF file
[mirror_edk2.git] / BaseTools / Source / Python / Workspace / BuildClassObject.py
1 ## @file
2 # This file is used to define each component of the build database
3 #
4 # Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
5 # This program and the accompanying materials
6 # are licensed and made available under the terms and conditions of the BSD License
7 # which accompanies this distribution. The full text of the license may be found at
8 # http://opensource.org/licenses/bsd-license.php
9 #
10 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12 #
13
14 import Common.LongFilePathOs as os
15
16 from collections import OrderedDict
17 from Common.Misc import RealPath2
18 from Common.BuildToolError import *
19 from Common.DataType import *
20 import collections
21
22 ## PcdClassObject
23 #
24 # This Class is used for PcdObject
25 #
26 # @param object: Inherited from object class
27 # @param Name: Input value for Name of Pcd, default is None
28 # @param Guid: Input value for Guid of Pcd, default is None
29 # @param Type: Input value for Type of Pcd, default is None
30 # @param DatumType: Input value for DatumType of Pcd, default is None
31 # @param Value: Input value for Value of Pcd, default is None
32 # @param Token: Input value for Token of Pcd, default is None
33 # @param MaxDatumSize: Input value for MaxDatumSize of Pcd, default is None
34 # @param SkuInfoList: Input value for SkuInfoList of Pcd, default is {}
35 # @param IsOverrided: Input value for IsOverrided of Pcd, default is False
36 # @param GuidValue: Input value for TokenSpaceGuidValue of Pcd, default is None
37 #
38 # @var TokenCName: To store value for TokenCName
39 # @var TokenSpaceGuidCName: To store value for TokenSpaceGuidCName
40 # @var Type: To store value for Type
41 # @var DatumType: To store value for DatumType
42 # @var TokenValue: To store value for TokenValue
43 # @var MaxDatumSize: To store value for MaxDatumSize
44 # @var SkuInfoList: To store value for SkuInfoList
45 # @var IsOverrided: To store value for IsOverrided
46 # @var Phase: To store value for Phase, default is "DXE"
47 #
48 class PcdClassObject(object):
49 def __init__(self, Name = None, Guid = None, Type = None, DatumType = None, Value = None, Token = None, MaxDatumSize = None, SkuInfoList = {}, IsOverrided = False, GuidValue = None, validateranges = [], validlists = [], expressions = [], IsDsc = False):
50 self.TokenCName = Name
51 self.TokenSpaceGuidCName = Guid
52 self.TokenSpaceGuidValue = GuidValue
53 self.Type = Type
54 self.DatumType = DatumType
55 self.DefaultValue = Value
56 self.TokenValue = Token
57 self.MaxDatumSize = MaxDatumSize
58 self.MaxSizeUserSet = None
59 self.SkuInfoList = SkuInfoList
60 self.Phase = "DXE"
61 self.Pending = False
62 self.IsOverrided = IsOverrided
63 self.IsFromBinaryInf = False
64 self.IsFromDsc = False
65 self.validateranges = validateranges
66 self.validlists = validlists
67 self.expressions = expressions
68 self.DscDefaultValue = None
69 self.DscRawValue = None
70 if IsDsc:
71 self.DscDefaultValue = Value
72 self.PcdValueFromComm = ""
73 self.PcdValueFromFdf = ""
74 self.DefinitionPosition = ("","")
75
76 ## Get the maximum number of bytes
77 def GetPcdMaxSize(self):
78 if self.DatumType in TAB_PCD_NUMERIC_TYPES:
79 return MAX_SIZE_TYPE[self.DatumType]
80
81 MaxSize = int(self.MaxDatumSize, 10) if self.MaxDatumSize else 0
82 if self.PcdValueFromFdf:
83 if self.PcdValueFromFdf.startswith("{") and self.PcdValueFromFdf.endswith("}"):
84 MaxSize = max([len(self.PcdValueFromFdf.split(",")),MaxSize])
85 elif self.PcdValueFromFdf.startswith("\"") or self.PcdValueFromFdf.startswith("\'"):
86 MaxSize = max([len(self.PcdValueFromFdf)-2+1,MaxSize])
87 elif self.PcdValueFromFdf.startswith("L\""):
88 MaxSize = max([2*(len(self.PcdValueFromFdf)-3+1),MaxSize])
89 else:
90 MaxSize = max([len(self.PcdValueFromFdf),MaxSize])
91
92 if self.PcdValueFromComm:
93 if self.PcdValueFromComm.startswith("{") and self.PcdValueFromComm.endswith("}"):
94 return max([len(self.PcdValueFromComm.split(",")), MaxSize])
95 elif self.PcdValueFromComm.startswith("\"") or self.PcdValueFromComm.startswith("\'"):
96 return max([len(self.PcdValueFromComm)-2+1, MaxSize])
97 elif self.PcdValueFromComm.startswith("L\""):
98 return max([2*(len(self.PcdValueFromComm)-3+1), MaxSize])
99 else:
100 return max([len(self.PcdValueFromComm), MaxSize])
101 return MaxSize
102
103 ## Get the number of bytes
104 def GetPcdSize(self):
105 if self.DatumType in TAB_PCD_NUMERIC_TYPES:
106 return MAX_SIZE_TYPE[self.DatumType]
107 if not self.DefaultValue:
108 return 1
109 elif self.DefaultValue[0] == 'L':
110 return (len(self.DefaultValue) - 2) * 2
111 elif self.DefaultValue[0] == '{':
112 return len(self.DefaultValue.split(','))
113 else:
114 return len(self.DefaultValue) - 1
115
116
117 ## Convert the class to a string
118 #
119 # Convert each member of the class to string
120 # Organize to a signle line format string
121 #
122 # @retval Rtn Formatted String
123 #
124 def __str__(self):
125 Rtn = '\tTokenCName=' + str(self.TokenCName) + ', ' + \
126 'TokenSpaceGuidCName=' + str(self.TokenSpaceGuidCName) + ', ' + \
127 'Type=' + str(self.Type) + ', ' + \
128 'DatumType=' + str(self.DatumType) + ', ' + \
129 'DefaultValue=' + str(self.DefaultValue) + ', ' + \
130 'TokenValue=' + str(self.TokenValue) + ', ' + \
131 'MaxDatumSize=' + str(self.MaxDatumSize) + ', '
132 for Item in self.SkuInfoList.values():
133 Rtn = Rtn + 'SkuId=' + Item.SkuId + ', ' + 'SkuIdName=' + Item.SkuIdName
134 Rtn = Rtn + ', IsOverrided=' + str(self.IsOverrided)
135
136 return Rtn
137
138 ## Override __eq__ function
139 #
140 # Check whether pcds are the same
141 #
142 # @retval False The two pcds are different
143 # @retval True The two pcds are the same
144 #
145 def __eq__(self, Other):
146 return Other and self.TokenCName == Other.TokenCName and self.TokenSpaceGuidCName == Other.TokenSpaceGuidCName
147
148 ## Override __hash__ function
149 #
150 # Use (TokenCName, TokenSpaceGuidCName) as key in hash table
151 #
152 # @retval truple() Key for hash table
153 #
154 def __hash__(self):
155 return hash((self.TokenCName, self.TokenSpaceGuidCName))
156
157 class StructurePcd(PcdClassObject):
158 def __init__(self, StructuredPcdIncludeFile=None, Packages=None, Name=None, Guid=None, Type=None, DatumType=None, Value=None, Token=None, MaxDatumSize=None, SkuInfoList=None, IsOverrided=False, GuidValue=None, validateranges=None, validlists=None, expressions=None,default_store = TAB_DEFAULT_STORES_DEFAULT):
159 if SkuInfoList is None:
160 SkuInfoList = {}
161 if validateranges is None:
162 validateranges = []
163 if validlists is None:
164 validlists = []
165 if expressions is None:
166 expressions = []
167 if Packages is None:
168 Packages = []
169 super(StructurePcd, self).__init__(Name, Guid, Type, DatumType, Value, Token, MaxDatumSize, SkuInfoList, IsOverrided, GuidValue, validateranges, validlists, expressions)
170 self.StructuredPcdIncludeFile = [] if StructuredPcdIncludeFile is None else StructuredPcdIncludeFile
171 self.PackageDecs = Packages
172 self.DefaultStoreName = [default_store]
173 self.DefaultValues = collections.OrderedDict()
174 self.PcdMode = None
175 self.SkuOverrideValues = collections.OrderedDict()
176 self.FlexibleFieldName = None
177 self.StructName = None
178 self.PcdDefineLineNo = 0
179 self.PkgPath = ""
180 self.DefaultValueFromDec = ""
181 self.ValueChain = set()
182 self.PcdFieldValueFromComm = collections.OrderedDict()
183 self.PcdFieldValueFromFdf = collections.OrderedDict()
184 def __repr__(self):
185 return self.TypeName
186
187 def AddDefaultValue (self, FieldName, Value, FileName="", LineNo=0):
188 if FieldName in self.DefaultValues:
189 del self.DefaultValues[FieldName]
190 self.DefaultValues[FieldName] = [Value.strip(), FileName, LineNo]
191 return self.DefaultValues[FieldName]
192
193 def SetDecDefaultValue(self, DefaultValue):
194 self.DefaultValueFromDec = DefaultValue
195 def AddOverrideValue (self, FieldName, Value, SkuName, DefaultStoreName, FileName="", LineNo=0):
196 if SkuName not in self.SkuOverrideValues:
197 self.SkuOverrideValues[SkuName] = collections.OrderedDict()
198 if DefaultStoreName not in self.SkuOverrideValues[SkuName]:
199 self.SkuOverrideValues[SkuName][DefaultStoreName] = collections.OrderedDict()
200 if FieldName in self.SkuOverrideValues[SkuName][DefaultStoreName]:
201 del self.SkuOverrideValues[SkuName][DefaultStoreName][FieldName]
202 self.SkuOverrideValues[SkuName][DefaultStoreName][FieldName] = [Value.strip(), FileName, LineNo]
203 return self.SkuOverrideValues[SkuName][DefaultStoreName][FieldName]
204
205 def SetPcdMode (self, PcdMode):
206 self.PcdMode = PcdMode
207
208 def SetFlexibleFieldName (self, FlexibleFieldName):
209 self.FlexibleFieldName = FlexibleFieldName
210
211 def copy(self, PcdObject):
212 self.TokenCName = PcdObject.TokenCName if PcdObject.TokenCName else self.TokenCName
213 self.TokenSpaceGuidCName = PcdObject.TokenSpaceGuidCName if PcdObject.TokenSpaceGuidCName else PcdObject.TokenSpaceGuidCName
214 self.TokenSpaceGuidValue = PcdObject.TokenSpaceGuidValue if PcdObject.TokenSpaceGuidValue else self.TokenSpaceGuidValue
215 self.Type = PcdObject.Type if PcdObject.Type else self.Type
216 self.DatumType = PcdObject.DatumType if PcdObject.DatumType else self.DatumType
217 self.DefaultValue = PcdObject.DefaultValue if PcdObject.DefaultValue else self.DefaultValue
218 self.TokenValue = PcdObject.TokenValue if PcdObject.TokenValue else self.TokenValue
219 self.MaxDatumSize = PcdObject.MaxDatumSize if PcdObject.MaxDatumSize else self.MaxDatumSize
220 self.SkuInfoList = PcdObject.SkuInfoList if PcdObject.SkuInfoList else self.SkuInfoList
221 self.Phase = PcdObject.Phase if PcdObject.Phase else self.Phase
222 self.Pending = PcdObject.Pending if PcdObject.Pending else self.Pending
223 self.IsOverrided = PcdObject.IsOverrided if PcdObject.IsOverrided else self.IsOverrided
224 self.IsFromBinaryInf = PcdObject.IsFromBinaryInf if PcdObject.IsFromBinaryInf else self.IsFromBinaryInf
225 self.IsFromDsc = PcdObject.IsFromDsc if PcdObject.IsFromDsc else self.IsFromDsc
226 self.validateranges = PcdObject.validateranges if PcdObject.validateranges else self.validateranges
227 self.validlists = PcdObject.validlists if PcdObject.validlists else self.validlists
228 self.expressions = PcdObject.expressions if PcdObject.expressions else self.expressions
229 self.DscRawValue = PcdObject.DscRawValue if PcdObject.DscRawValue else self.DscRawValue
230 self.PcdValueFromComm = PcdObject.PcdValueFromComm if PcdObject.PcdValueFromComm else self.PcdValueFromComm
231 self.PcdValueFromFdf = PcdObject.PcdValueFromFdf if PcdObject.PcdValueFromFdf else self.PcdValueFromFdf
232 self.DefinitionPosition = PcdObject.DefinitionPosition if PcdObject.DefinitionPosition else self.DefinitionPosition
233 if isinstance(PcdObject, StructurePcd):
234 self.StructuredPcdIncludeFile = PcdObject.StructuredPcdIncludeFile if PcdObject.StructuredPcdIncludeFile else self.StructuredPcdIncludeFile
235 self.PackageDecs = PcdObject.PackageDecs if PcdObject.PackageDecs else self.PackageDecs
236 self.DefaultValues = PcdObject.DefaultValues if PcdObject.DefaultValues else self.DefaultValues
237 self.PcdMode = PcdObject.PcdMode if PcdObject.PcdMode else self.PcdMode
238 self.DefaultFromDSC=None
239 self.DefaultValueFromDec = PcdObject.DefaultValueFromDec if PcdObject.DefaultValueFromDec else self.DefaultValueFromDec
240 self.SkuOverrideValues = PcdObject.SkuOverrideValues if PcdObject.SkuOverrideValues else self.SkuOverrideValues
241 self.FlexibleFieldName = PcdObject.FlexibleFieldName if PcdObject.FlexibleFieldName else self.FlexibleFieldName
242 self.StructName = PcdObject.DatumType if PcdObject.DatumType else self.StructName
243 self.PcdDefineLineNo = PcdObject.PcdDefineLineNo if PcdObject.PcdDefineLineNo else self.PcdDefineLineNo
244 self.PkgPath = PcdObject.PkgPath if PcdObject.PkgPath else self.PkgPath
245 self.ValueChain = PcdObject.ValueChain if PcdObject.ValueChain else self.ValueChain
246 self.PcdFieldValueFromComm = PcdObject.PcdFieldValueFromComm if PcdObject.PcdFieldValueFromComm else self.PcdFieldValueFromComm
247 self.PcdFieldValueFromFdf = PcdObject.PcdFieldValueFromFdf if PcdObject.PcdFieldValueFromFdf else self.PcdFieldValueFromFdf
248
249 ## LibraryClassObject
250 #
251 # This Class defines LibraryClassObject used in BuildDatabase
252 #
253 # @param object: Inherited from object class
254 # @param Name: Input value for LibraryClassName, default is None
255 # @param SupModList: Input value for SupModList, default is []
256 # @param Type: Input value for Type, default is None
257 #
258 # @var LibraryClass: To store value for LibraryClass
259 # @var SupModList: To store value for SupModList
260 # @var Type: To store value for Type
261 #
262 class LibraryClassObject(object):
263 def __init__(self, Name = None, SupModList = [], Type = None):
264 self.LibraryClass = Name
265 self.SupModList = SupModList
266 if Type is not None:
267 self.SupModList = CleanString(Type).split(DataType.TAB_SPACE_SPLIT)
268
269 ## ModuleBuildClassObject
270 #
271 # This Class defines ModuleBuildClass
272 #
273 # @param object: Inherited from object class
274 #
275 # @var MetaFile: To store value for module meta file path
276 # @var BaseName: To store value for BaseName
277 # @var ModuleType: To store value for ModuleType
278 # @var Guid: To store value for Guid
279 # @var Version: To store value for Version
280 # @var PcdIsDriver: To store value for PcdIsDriver
281 # @var BinaryModule: To store value for BinaryModule
282 # @var CustomMakefile: To store value for CustomMakefile
283 # @var Specification: To store value for Specification
284 # @var Shadow To store value for Shadow
285 # @var LibraryClass: To store value for LibraryClass, it is a list structure as
286 # [ LibraryClassObject, ...]
287 # @var ModuleEntryPointList: To store value for ModuleEntryPointList
288 # @var ModuleUnloadImageList: To store value for ModuleUnloadImageList
289 # @var ConstructorList: To store value for ConstructorList
290 # @var DestructorList: To store value for DestructorList
291 # @var Binaries: To store value for Binaries, it is a list structure as
292 # [ ModuleBinaryClassObject, ...]
293 # @var Sources: To store value for Sources, it is a list structure as
294 # [ ModuleSourceFilesClassObject, ... ]
295 # @var LibraryClasses: To store value for LibraryClasses, it is a set structure as
296 # { [LibraryClassName, ModuleType] : LibraryClassInfFile }
297 # @var Protocols: To store value for Protocols, it is a list structure as
298 # [ ProtocolName, ... ]
299 # @var Ppis: To store value for Ppis, it is a list structure as
300 # [ PpiName, ... ]
301 # @var Guids: To store value for Guids, it is a list structure as
302 # [ GuidName, ... ]
303 # @var Includes: To store value for Includes, it is a list structure as
304 # [ IncludePath, ... ]
305 # @var Packages: To store value for Packages, it is a list structure as
306 # [ DecFileName, ... ]
307 # @var Pcds: To store value for Pcds, it is a set structure as
308 # { [(PcdCName, PcdGuidCName)] : PcdClassObject}
309 # @var BuildOptions: To store value for BuildOptions, it is a set structure as
310 # { [BuildOptionKey] : BuildOptionValue}
311 # @var Depex: To store value for Depex
312 #
313 class ModuleBuildClassObject(object):
314 def __init__(self):
315 self.AutoGenVersion = 0
316 self.MetaFile = ''
317 self.BaseName = ''
318 self.ModuleType = ''
319 self.Guid = ''
320 self.Version = ''
321 self.PcdIsDriver = ''
322 self.BinaryModule = ''
323 self.Shadow = ''
324 self.SourceOverridePath = ''
325 self.CustomMakefile = {}
326 self.Specification = {}
327 self.LibraryClass = []
328 self.ModuleEntryPointList = []
329 self.ModuleUnloadImageList = []
330 self.ConstructorList = []
331 self.DestructorList = []
332
333 self.Binaries = []
334 self.Sources = []
335 self.LibraryClasses = OrderedDict()
336 self.Libraries = []
337 self.Protocols = []
338 self.Ppis = []
339 self.Guids = []
340 self.Includes = []
341 self.Packages = []
342 self.Pcds = {}
343 self.BuildOptions = {}
344 self.Depex = {}
345
346 ## Convert the class to a string
347 #
348 # Convert member MetaFile of the class to a string
349 #
350 # @retval string Formatted String
351 #
352 def __str__(self):
353 return str(self.MetaFile)
354
355 ## Override __eq__ function
356 #
357 # Check whether ModuleBuildClassObjects are the same
358 #
359 # @retval False The two ModuleBuildClassObjects are different
360 # @retval True The two ModuleBuildClassObjects are the same
361 #
362 def __eq__(self, Other):
363 return self.MetaFile == Other
364
365 ## Override __hash__ function
366 #
367 # Use MetaFile as key in hash table
368 #
369 # @retval string Key for hash table
370 #
371 def __hash__(self):
372 return hash(self.MetaFile)
373
374 ## PackageBuildClassObject
375 #
376 # This Class defines PackageBuildClass
377 #
378 # @param object: Inherited from object class
379 #
380 # @var MetaFile: To store value for package meta file path
381 # @var PackageName: To store value for PackageName
382 # @var Guid: To store value for Guid
383 # @var Version: To store value for Version
384 # @var Protocols: To store value for Protocols, it is a set structure as
385 # { [ProtocolName] : Protocol Guid, ... }
386 # @var Ppis: To store value for Ppis, it is a set structure as
387 # { [PpiName] : Ppi Guid, ... }
388 # @var Guids: To store value for Guids, it is a set structure as
389 # { [GuidName] : Guid, ... }
390 # @var Includes: To store value for Includes, it is a list structure as
391 # [ IncludePath, ... ]
392 # @var LibraryClasses: To store value for LibraryClasses, it is a set structure as
393 # { [LibraryClassName] : LibraryClassInfFile }
394 # @var Pcds: To store value for Pcds, it is a set structure as
395 # { [(PcdCName, PcdGuidCName)] : PcdClassObject}
396 #
397 class PackageBuildClassObject(object):
398 def __init__(self):
399 self.MetaFile = ''
400 self.PackageName = ''
401 self.Guid = ''
402 self.Version = ''
403
404 self.Protocols = {}
405 self.Ppis = {}
406 self.Guids = {}
407 self.Includes = []
408 self.LibraryClasses = {}
409 self.Pcds = {}
410
411 ## Convert the class to a string
412 #
413 # Convert member MetaFile of the class to a string
414 #
415 # @retval string Formatted String
416 #
417 def __str__(self):
418 return str(self.MetaFile)
419
420 ## Override __eq__ function
421 #
422 # Check whether PackageBuildClassObjects are the same
423 #
424 # @retval False The two PackageBuildClassObjects are different
425 # @retval True The two PackageBuildClassObjects are the same
426 #
427 def __eq__(self, Other):
428 return self.MetaFile == Other
429
430 ## Override __hash__ function
431 #
432 # Use MetaFile as key in hash table
433 #
434 # @retval string Key for hash table
435 #
436 def __hash__(self):
437 return hash(self.MetaFile)
438
439 ## PlatformBuildClassObject
440 #
441 # This Class defines PlatformBuildClass
442 #
443 # @param object: Inherited from object class
444 #
445 # @var MetaFile: To store value for platform meta-file path
446 # @var PlatformName: To store value for PlatformName
447 # @var Guid: To store value for Guid
448 # @var Version: To store value for Version
449 # @var DscSpecification: To store value for DscSpecification
450 # @var OutputDirectory: To store value for OutputDirectory
451 # @var FlashDefinition: To store value for FlashDefinition
452 # @var BuildNumber: To store value for BuildNumber
453 # @var MakefileName: To store value for MakefileName
454 # @var SkuIds: To store value for SkuIds, it is a set structure as
455 # { 'SkuName' : SkuId, '!include' : includefilename, ...}
456 # @var Modules: To store value for Modules, it is a list structure as
457 # [ InfFileName, ... ]
458 # @var Libraries: To store value for Libraries, it is a list structure as
459 # [ InfFileName, ... ]
460 # @var LibraryClasses: To store value for LibraryClasses, it is a set structure as
461 # { (LibraryClassName, ModuleType) : LibraryClassInfFile }
462 # @var Pcds: To store value for Pcds, it is a set structure as
463 # { [(PcdCName, PcdGuidCName)] : PcdClassObject }
464 # @var BuildOptions: To store value for BuildOptions, it is a set structure as
465 # { [BuildOptionKey] : BuildOptionValue }
466 #
467 class PlatformBuildClassObject(object):
468 def __init__(self):
469 self.MetaFile = ''
470 self.PlatformName = ''
471 self.Guid = ''
472 self.Version = ''
473 self.DscSpecification = ''
474 self.OutputDirectory = ''
475 self.FlashDefinition = ''
476 self.BuildNumber = ''
477 self.MakefileName = ''
478
479 self.SkuIds = {}
480 self.Modules = []
481 self.LibraryInstances = []
482 self.LibraryClasses = {}
483 self.Libraries = {}
484 self.Pcds = {}
485 self.BuildOptions = {}
486
487 ## Convert the class to a string
488 #
489 # Convert member MetaFile of the class to a string
490 #
491 # @retval string Formatted String
492 #
493 def __str__(self):
494 return str(self.MetaFile)
495
496 ## Override __eq__ function
497 #
498 # Check whether PlatformBuildClassObjects are the same
499 #
500 # @retval False The two PlatformBuildClassObjects are different
501 # @retval True The two PlatformBuildClassObjects are the same
502 #
503 def __eq__(self, Other):
504 return self.MetaFile == Other
505
506 ## Override __hash__ function
507 #
508 # Use MetaFile as key in hash table
509 #
510 # @retval string Key for hash table
511 #
512 def __hash__(self):
513 return hash(self.MetaFile)