]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/Workspace/DecBuildData.py
BaseTools: remove unused setter functions
[mirror_edk2.git] / BaseTools / Source / Python / Workspace / DecBuildData.py
1 ## @file
2 # This file is used to create a database used by build tool
3 #
4 # Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR>
5 # (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
6 # This program and the accompanying materials
7 # are licensed and made available under the terms and conditions of the BSD License
8 # which accompanies this distribution. The full text of the license may be found at
9 # http://opensource.org/licenses/bsd-license.php
10 #
11 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13 #
14 from Common.StringUtils import *
15 from Common.DataType import *
16 from Common.Misc import *
17 from types import *
18 from collections import OrderedDict
19
20 from Workspace.BuildClassObject import PackageBuildClassObject, StructurePcd, PcdClassObject
21
22 ## Platform build information from DEC file
23 #
24 # This class is used to retrieve information stored in database and convert them
25 # into PackageBuildClassObject form for easier use for AutoGen.
26 #
27 class DecBuildData(PackageBuildClassObject):
28 # dict used to convert PCD type in database to string used by build tool
29 _PCD_TYPE_STRING_ = {
30 MODEL_PCD_FIXED_AT_BUILD : TAB_PCDS_FIXED_AT_BUILD,
31 MODEL_PCD_PATCHABLE_IN_MODULE : TAB_PCDS_PATCHABLE_IN_MODULE,
32 MODEL_PCD_FEATURE_FLAG : TAB_PCDS_FEATURE_FLAG,
33 MODEL_PCD_DYNAMIC : TAB_PCDS_DYNAMIC,
34 MODEL_PCD_DYNAMIC_DEFAULT : TAB_PCDS_DYNAMIC,
35 MODEL_PCD_DYNAMIC_HII : TAB_PCDS_DYNAMIC_HII,
36 MODEL_PCD_DYNAMIC_VPD : TAB_PCDS_DYNAMIC_VPD,
37 MODEL_PCD_DYNAMIC_EX : TAB_PCDS_DYNAMIC_EX,
38 MODEL_PCD_DYNAMIC_EX_DEFAULT : TAB_PCDS_DYNAMIC_EX,
39 MODEL_PCD_DYNAMIC_EX_HII : TAB_PCDS_DYNAMIC_EX_HII,
40 MODEL_PCD_DYNAMIC_EX_VPD : TAB_PCDS_DYNAMIC_EX_VPD,
41 }
42
43 # dict used to convert part of [Defines] to members of DecBuildData directly
44 _PROPERTY_ = {
45 #
46 # Required Fields
47 #
48 TAB_DEC_DEFINES_PACKAGE_NAME : "_PackageName",
49 TAB_DEC_DEFINES_PACKAGE_GUID : "_Guid",
50 TAB_DEC_DEFINES_PACKAGE_VERSION : "_Version",
51 TAB_DEC_DEFINES_PKG_UNI_FILE : "_PkgUniFile",
52 }
53
54
55 ## Constructor of DecBuildData
56 #
57 # Initialize object of DecBuildData
58 #
59 # @param FilePath The path of package description file
60 # @param RawData The raw data of DEC file
61 # @param BuildDataBase Database used to retrieve module information
62 # @param Arch The target architecture
63 # @param Platform (not used for DecBuildData)
64 # @param Macros Macros used for replacement in DSC file
65 #
66 def __init__(self, File, RawData, BuildDataBase, Arch=TAB_ARCH_COMMON, Target=None, Toolchain=None):
67 self.MetaFile = File
68 self._PackageDir = File.Dir
69 self._RawData = RawData
70 self._Bdb = BuildDataBase
71 self._Arch = Arch
72 self._Target = Target
73 self._Toolchain = Toolchain
74 self._Clear()
75
76 ## XXX[key] = value
77 def __setitem__(self, key, value):
78 self.__dict__[self._PROPERTY_[key]] = value
79
80 ## value = XXX[key]
81 def __getitem__(self, key):
82 return self.__dict__[self._PROPERTY_[key]]
83
84 ## "in" test support
85 def __contains__(self, key):
86 return key in self._PROPERTY_
87
88 ## Set all internal used members of DecBuildData to None
89 def _Clear(self):
90 self._Header = None
91 self._PackageName = None
92 self._Guid = None
93 self._Version = None
94 self._PkgUniFile = None
95 self._Protocols = None
96 self._Ppis = None
97 self._Guids = None
98 self._Includes = None
99 self._CommonIncludes = None
100 self._LibraryClasses = None
101 self._Pcds = None
102 self.__Macros = None
103 self._PrivateProtocols = None
104 self._PrivatePpis = None
105 self._PrivateGuids = None
106 self._PrivateIncludes = None
107
108 ## Get current effective macros
109 def _GetMacros(self):
110 if self.__Macros is None:
111 self.__Macros = {}
112 self.__Macros.update(GlobalData.gGlobalDefines)
113 return self.__Macros
114
115 ## Get architecture
116 def _GetArch(self):
117 return self._Arch
118
119 ## Retrieve all information in [Defines] section
120 #
121 # (Retriving all [Defines] information in one-shot is just to save time.)
122 #
123 def _GetHeaderInfo(self):
124 RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch]
125 for Record in RecordList:
126 Name = Record[1]
127 if Name in self:
128 self[Name] = Record[2]
129 self._Header = 'DUMMY'
130
131 ## Retrieve package name
132 def _GetPackageName(self):
133 if self._PackageName is None:
134 if self._Header is None:
135 self._GetHeaderInfo()
136 if self._PackageName is None:
137 EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, "No PACKAGE_NAME", File=self.MetaFile)
138 return self._PackageName
139
140 ## Retrieve file guid
141 def _GetFileGuid(self):
142 if self._Guid is None:
143 if self._Header is None:
144 self._GetHeaderInfo()
145 if self._Guid is None:
146 EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, "No PACKAGE_GUID", File=self.MetaFile)
147 return self._Guid
148
149 ## Retrieve package version
150 def _GetVersion(self):
151 if self._Version is None:
152 if self._Header is None:
153 self._GetHeaderInfo()
154 if self._Version is None:
155 self._Version = ''
156 return self._Version
157
158 ## Retrieve protocol definitions (name/value pairs)
159 def _GetProtocol(self):
160 if self._Protocols is None:
161 #
162 # tdict is a special kind of dict, used for selecting correct
163 # protocol defition for given ARCH
164 #
165 ProtocolDict = tdict(True)
166 PrivateProtocolDict = tdict(True)
167 NameList = []
168 PrivateNameList = []
169 PublicNameList = []
170 # find out all protocol definitions for specific and 'common' arch
171 RecordList = self._RawData[MODEL_EFI_PROTOCOL, self._Arch]
172 for Name, Guid, Dummy, Arch, PrivateFlag, ID, LineNo in RecordList:
173 if PrivateFlag == 'PRIVATE':
174 if Name not in PrivateNameList:
175 PrivateNameList.append(Name)
176 PrivateProtocolDict[Arch, Name] = Guid
177 if Name in PublicNameList:
178 EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name, File=self.MetaFile, Line=LineNo)
179 else:
180 if Name not in PublicNameList:
181 PublicNameList.append(Name)
182 if Name in PrivateNameList:
183 EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name, File=self.MetaFile, Line=LineNo)
184 if Name not in NameList:
185 NameList.append(Name)
186 ProtocolDict[Arch, Name] = Guid
187 # use OrderedDict to keep the order
188 self._Protocols = OrderedDict()
189 self._PrivateProtocols = OrderedDict()
190 for Name in NameList:
191 #
192 # limit the ARCH to self._Arch, if no self._Arch found, tdict
193 # will automatically turn to 'common' ARCH for trying
194 #
195 self._Protocols[Name] = ProtocolDict[self._Arch, Name]
196 for Name in PrivateNameList:
197 self._PrivateProtocols[Name] = PrivateProtocolDict[self._Arch, Name]
198 return self._Protocols
199
200 ## Retrieve PPI definitions (name/value pairs)
201 def _GetPpi(self):
202 if self._Ppis is None:
203 #
204 # tdict is a special kind of dict, used for selecting correct
205 # PPI defition for given ARCH
206 #
207 PpiDict = tdict(True)
208 PrivatePpiDict = tdict(True)
209 NameList = []
210 PrivateNameList = []
211 PublicNameList = []
212 # find out all PPI definitions for specific arch and 'common' arch
213 RecordList = self._RawData[MODEL_EFI_PPI, self._Arch]
214 for Name, Guid, Dummy, Arch, PrivateFlag, ID, LineNo in RecordList:
215 if PrivateFlag == 'PRIVATE':
216 if Name not in PrivateNameList:
217 PrivateNameList.append(Name)
218 PrivatePpiDict[Arch, Name] = Guid
219 if Name in PublicNameList:
220 EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name, File=self.MetaFile, Line=LineNo)
221 else:
222 if Name not in PublicNameList:
223 PublicNameList.append(Name)
224 if Name in PrivateNameList:
225 EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name, File=self.MetaFile, Line=LineNo)
226 if Name not in NameList:
227 NameList.append(Name)
228 PpiDict[Arch, Name] = Guid
229 # use OrderedDict to keep the order
230 self._Ppis = OrderedDict()
231 self._PrivatePpis = OrderedDict()
232 for Name in NameList:
233 #
234 # limit the ARCH to self._Arch, if no self._Arch found, tdict
235 # will automatically turn to 'common' ARCH for trying
236 #
237 self._Ppis[Name] = PpiDict[self._Arch, Name]
238 for Name in PrivateNameList:
239 self._PrivatePpis[Name] = PrivatePpiDict[self._Arch, Name]
240 return self._Ppis
241
242 ## Retrieve GUID definitions (name/value pairs)
243 def _GetGuid(self):
244 if self._Guids is None:
245 #
246 # tdict is a special kind of dict, used for selecting correct
247 # GUID defition for given ARCH
248 #
249 GuidDict = tdict(True)
250 PrivateGuidDict = tdict(True)
251 NameList = []
252 PrivateNameList = []
253 PublicNameList = []
254 # find out all protocol definitions for specific and 'common' arch
255 RecordList = self._RawData[MODEL_EFI_GUID, self._Arch]
256 for Name, Guid, Dummy, Arch, PrivateFlag, ID, LineNo in RecordList:
257 if PrivateFlag == 'PRIVATE':
258 if Name not in PrivateNameList:
259 PrivateNameList.append(Name)
260 PrivateGuidDict[Arch, Name] = Guid
261 if Name in PublicNameList:
262 EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name, File=self.MetaFile, Line=LineNo)
263 else:
264 if Name not in PublicNameList:
265 PublicNameList.append(Name)
266 if Name in PrivateNameList:
267 EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name, File=self.MetaFile, Line=LineNo)
268 if Name not in NameList:
269 NameList.append(Name)
270 GuidDict[Arch, Name] = Guid
271 # use OrderedDict to keep the order
272 self._Guids = OrderedDict()
273 self._PrivateGuids = OrderedDict()
274 for Name in NameList:
275 #
276 # limit the ARCH to self._Arch, if no self._Arch found, tdict
277 # will automatically turn to 'common' ARCH for trying
278 #
279 self._Guids[Name] = GuidDict[self._Arch, Name]
280 for Name in PrivateNameList:
281 self._PrivateGuids[Name] = PrivateGuidDict[self._Arch, Name]
282 return self._Guids
283
284 ## Retrieve public include paths declared in this package
285 def _GetInclude(self):
286 if self._Includes is None or self._CommonIncludes is None:
287 self._CommonIncludes = []
288 self._Includes = []
289 self._PrivateIncludes = []
290 PublicInclues = []
291 RecordList = self._RawData[MODEL_EFI_INCLUDE, self._Arch]
292 Macros = self._Macros
293 Macros["EDK_SOURCE"] = GlobalData.gEcpSource
294 for Record in RecordList:
295 File = PathClass(NormPath(Record[0], Macros), self._PackageDir, Arch=self._Arch)
296 LineNo = Record[-1]
297 # validate the path
298 ErrorCode, ErrorInfo = File.Validate()
299 if ErrorCode != 0:
300 EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)
301
302 # avoid duplicate include path
303 if File not in self._Includes:
304 self._Includes.append(File)
305 if Record[4] == 'PRIVATE':
306 if File not in self._PrivateIncludes:
307 self._PrivateIncludes.append(File)
308 if File in PublicInclues:
309 EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % File, File=self.MetaFile, Line=LineNo)
310 else:
311 if File not in PublicInclues:
312 PublicInclues.append(File)
313 if File in self._PrivateIncludes:
314 EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % File, File=self.MetaFile, Line=LineNo)
315 if Record[3] == TAB_COMMON:
316 self._CommonIncludes.append(File)
317 return self._Includes
318
319 ## Retrieve library class declarations (not used in build at present)
320 def _GetLibraryClass(self):
321 if self._LibraryClasses is None:
322 #
323 # tdict is a special kind of dict, used for selecting correct
324 # library class declaration for given ARCH
325 #
326 LibraryClassDict = tdict(True)
327 LibraryClassSet = set()
328 RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch]
329 Macros = self._Macros
330 for LibraryClass, File, Dummy, Arch, PrivateFlag, ID, LineNo in RecordList:
331 File = PathClass(NormPath(File, Macros), self._PackageDir, Arch=self._Arch)
332 # check the file validation
333 ErrorCode, ErrorInfo = File.Validate()
334 if ErrorCode != 0:
335 EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)
336 LibraryClassSet.add(LibraryClass)
337 LibraryClassDict[Arch, LibraryClass] = File
338 self._LibraryClasses = OrderedDict()
339 for LibraryClass in LibraryClassSet:
340 self._LibraryClasses[LibraryClass] = LibraryClassDict[self._Arch, LibraryClass]
341 return self._LibraryClasses
342
343 ## Retrieve PCD declarations
344 def _GetPcds(self):
345 if self._Pcds is None:
346 self._Pcds = OrderedDict()
347 self._Pcds.update(self._GetPcd(MODEL_PCD_FIXED_AT_BUILD))
348 self._Pcds.update(self._GetPcd(MODEL_PCD_PATCHABLE_IN_MODULE))
349 self._Pcds.update(self._GetPcd(MODEL_PCD_FEATURE_FLAG))
350 self._Pcds.update(self._GetPcd(MODEL_PCD_DYNAMIC))
351 self._Pcds.update(self._GetPcd(MODEL_PCD_DYNAMIC_EX))
352 return self._Pcds
353
354
355 def ProcessStructurePcd(self, StructurePcdRawDataSet):
356 s_pcd_set = OrderedDict()
357 for s_pcd, LineNo in StructurePcdRawDataSet:
358 if s_pcd.TokenSpaceGuidCName not in s_pcd_set:
359 s_pcd_set[s_pcd.TokenSpaceGuidCName] = []
360 s_pcd_set[s_pcd.TokenSpaceGuidCName].append((s_pcd, LineNo))
361
362 str_pcd_set = []
363 for pcdname in s_pcd_set:
364 dep_pkgs = []
365 struct_pcd = StructurePcd()
366 for item, LineNo in s_pcd_set[pcdname]:
367 if "<HeaderFiles>" in item.TokenCName:
368 struct_pcd.StructuredPcdIncludeFile.append(item.DefaultValue)
369 elif "<Packages>" in item.TokenCName:
370 dep_pkgs.append(item.DefaultValue)
371 elif item.DatumType == item.TokenCName:
372 struct_pcd.copy(item)
373 struct_pcd.TokenValue = struct_pcd.TokenValue.strip("{").strip()
374 struct_pcd.TokenSpaceGuidCName, struct_pcd.TokenCName = pcdname.split(".")
375 struct_pcd.PcdDefineLineNo = LineNo
376 struct_pcd.PkgPath = self.MetaFile.File
377 struct_pcd.SetDecDefaultValue(item.DefaultValue)
378 else:
379 struct_pcd.AddDefaultValue(item.TokenCName, item.DefaultValue, self.MetaFile.File, LineNo)
380
381 struct_pcd.PackageDecs = dep_pkgs
382 str_pcd_set.append(struct_pcd)
383 return str_pcd_set
384
385 ## Retrieve PCD declarations for given type
386 def _GetPcd(self, Type):
387 Pcds = OrderedDict()
388 #
389 # tdict is a special kind of dict, used for selecting correct
390 # PCD declaration for given ARCH
391 #
392 PcdDict = tdict(True, 3)
393 # for summarizing PCD
394 PcdSet = []
395 # find out all PCDs of the 'type'
396
397 StrPcdSet = []
398 RecordList = self._RawData[Type, self._Arch]
399 for TokenSpaceGuid, PcdCName, Setting, Arch, PrivateFlag, Dummy1, Dummy2 in RecordList:
400 PcdDict[Arch, PcdCName, TokenSpaceGuid] = (Setting, Dummy2)
401 if not (PcdCName, TokenSpaceGuid) in PcdSet:
402 PcdSet.append((PcdCName, TokenSpaceGuid))
403
404 for PcdCName, TokenSpaceGuid in PcdSet:
405 #
406 # limit the ARCH to self._Arch, if no self._Arch found, tdict
407 # will automatically turn to 'common' ARCH and try again
408 #
409 Setting, LineNo = PcdDict[self._Arch, PcdCName, TokenSpaceGuid]
410 if Setting is None:
411 continue
412
413 DefaultValue, DatumType, TokenNumber = AnalyzePcdData(Setting)
414 validateranges, validlists, expressions = self._RawData.GetValidExpression(TokenSpaceGuid, PcdCName)
415 PcdObj = PcdClassObject(
416 PcdCName,
417 TokenSpaceGuid,
418 self._PCD_TYPE_STRING_[Type],
419 DatumType,
420 DefaultValue,
421 TokenNumber,
422 '',
423 {},
424 False,
425 None,
426 list(validateranges),
427 list(validlists),
428 list(expressions)
429 )
430 PcdObj.DefinitionPosition = (self.MetaFile.File, LineNo)
431 if "." in TokenSpaceGuid:
432 StrPcdSet.append((PcdObj, LineNo))
433 else:
434 Pcds[PcdCName, TokenSpaceGuid, self._PCD_TYPE_STRING_[Type]] = PcdObj
435
436 StructurePcds = self.ProcessStructurePcd(StrPcdSet)
437 for pcd in StructurePcds:
438 Pcds[pcd.TokenCName, pcd.TokenSpaceGuidCName, self._PCD_TYPE_STRING_[Type]] = pcd
439 StructPattern = re.compile(r'[_a-zA-Z][0-9A-Za-z_]*$')
440 for pcd in Pcds.values():
441 if pcd.DatumType not in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64, TAB_VOID, "BOOLEAN"]:
442 if StructPattern.match(pcd.DatumType) is None:
443 EdkLogger.error('build', FORMAT_INVALID, "DatumType only support BOOLEAN, UINT8, UINT16, UINT32, UINT64, VOID* or a valid struct name.", pcd.DefinitionPosition[0], pcd.DefinitionPosition[1])
444 for struct_pcd in Pcds.values():
445 if isinstance(struct_pcd, StructurePcd) and not struct_pcd.StructuredPcdIncludeFile:
446 EdkLogger.error("build", PCD_STRUCTURE_PCD_ERROR, "The structure Pcd %s.%s header file is not found in %s line %s \n" % (struct_pcd.TokenSpaceGuidCName, struct_pcd.TokenCName, struct_pcd.DefinitionPosition[0], struct_pcd.DefinitionPosition[1] ))
447
448 return Pcds
449 @property
450 def CommonIncludes(self):
451 if self._CommonIncludes is None:
452 self.Includes
453 return self._CommonIncludes
454
455
456 _Macros = property(_GetMacros)
457 Arch = property(_GetArch)
458 PackageName = property(_GetPackageName)
459 Guid = property(_GetFileGuid)
460 Version = property(_GetVersion)
461
462 Protocols = property(_GetProtocol)
463 Ppis = property(_GetPpi)
464 Guids = property(_GetGuid)
465 Includes = property(_GetInclude)
466 LibraryClasses = property(_GetLibraryClass)
467 Pcds = property(_GetPcds)