UefiCpuPkg/CpuCommonFeaturesLib: Add check for input parameter.
[mirror_edk2.git] / BaseTools / Source / Python / AutoGen / AutoGen.py
CommitLineData
52302d4d
LG
1## @file\r
2# Generate AutoGen.h, AutoGen.c and *.depex files\r
3#\r
5b97eb4c 4# Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.<BR>\r
40d841f6 5# This program and the accompanying materials\r
52302d4d
LG
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## Import Modules\r
15#\r
1be2ed90 16import Common.LongFilePathOs as os\r
52302d4d
LG
17import re\r
18import os.path as path\r
19import copy\r
867d1cd4 20import uuid\r
52302d4d
LG
21\r
22import GenC\r
23import GenMake\r
24import GenDepex\r
25from StringIO import StringIO\r
26\r
27from StrGather import *\r
28from BuildEngine import BuildRule\r
29\r
1be2ed90 30from Common.LongFilePathSupport import CopyLongFilePath\r
52302d4d
LG
31from Common.BuildToolError import *\r
32from Common.DataType import *\r
33from Common.Misc import *\r
34from Common.String import *\r
35import Common.GlobalData as GlobalData\r
36from GenFds.FdfParser import *\r
37from CommonDataClass.CommonClass import SkuInfoClass\r
38from Workspace.BuildClassObject import *\r
e8a47801 39from GenPatchPcdTable.GenPatchPcdTable import parsePcdInfoFromMapFile\r
e56468c0 40import Common.VpdInfoFile as VpdInfoFile\r
e8a47801
LG
41from GenPcdDb import CreatePcdDatabaseCode\r
42from Workspace.MetaFileCommentParser import UsageList\r
05cc51ad 43from Common.MultipleWorkspace import MultipleWorkspace as mws\r
97fa0ee9 44import InfSectionParser\r
c17956e0 45import datetime\r
97fa0ee9 46\r
e8a47801 47## Regular expression for splitting Dependency Expression string into tokens\r
52302d4d
LG
48gDepexTokenPattern = re.compile("(\(|\)|\w+| \S+\.inf)")\r
49\r
97fa0ee9
YL
50#\r
51# Match name = variable\r
52#\r
53gEfiVarStoreNamePattern = re.compile("\s*name\s*=\s*(\w+)")\r
54#\r
55# The format of guid in efivarstore statement likes following and must be correct:\r
56# guid = {0xA04A27f4, 0xDF00, 0x4D42, {0xB5, 0x52, 0x39, 0x51, 0x13, 0x02, 0x11, 0x3D}}\r
57#\r
58gEfiVarStoreGuidPattern = re.compile("\s*guid\s*=\s*({.*?{.*?}\s*})")\r
59\r
52302d4d
LG
60## Mapping Makefile type\r
61gMakeTypeMap = {"MSFT":"nmake", "GCC":"gmake"}\r
62\r
63\r
64## Build rule configuration file\r
51de5c30 65gDefaultBuildRuleFile = 'build_rule.txt'\r
52302d4d 66\r
86601b78 67## Tools definition configuration file\r
51de5c30 68gDefaultToolsDefFile = 'tools_def.txt'\r
86601b78 69\r
64b2609f
LG
70## Build rule default version\r
71AutoGenReqBuildRuleVerNum = "0.1"\r
72\r
52302d4d
LG
73## default file name for AutoGen\r
74gAutoGenCodeFileName = "AutoGen.c"\r
75gAutoGenHeaderFileName = "AutoGen.h"\r
76gAutoGenStringFileName = "%(module_name)sStrDefs.h"\r
77gAutoGenStringFormFileName = "%(module_name)sStrDefs.hpk"\r
78gAutoGenDepexFileName = "%(module_name)s.depex"\r
333ba578
YZ
79gAutoGenImageDefFileName = "%(module_name)sImgDefs.h"\r
80gAutoGenIdfFileName = "%(module_name)sIdf.hpk"\r
97fa0ee9
YL
81gInfSpecVersion = "0x00010017"\r
82\r
da92f276
LG
83#\r
84# Template string to generic AsBuilt INF\r
85#\r
e8a47801 86gAsBuiltInfHeaderString = TemplateString("""${header_comments}\r
da92f276 87\r
97fa0ee9
YL
88# DO NOT EDIT\r
89# FILE auto-generated\r
90\r
da92f276 91[Defines]\r
97fa0ee9 92 INF_VERSION = ${module_inf_version}\r
da92f276
LG
93 BASE_NAME = ${module_name}\r
94 FILE_GUID = ${module_guid}\r
97fa0ee9
YL
95 MODULE_TYPE = ${module_module_type}${BEGIN}\r
96 VERSION_STRING = ${module_version_string}${END}${BEGIN}\r
e8a47801 97 PCD_IS_DRIVER = ${pcd_is_driver_string}${END}${BEGIN}\r
da92f276 98 UEFI_SPECIFICATION_VERSION = ${module_uefi_specification_version}${END}${BEGIN}\r
97fa0ee9
YL
99 PI_SPECIFICATION_VERSION = ${module_pi_specification_version}${END}${BEGIN}\r
100 ENTRY_POINT = ${module_entry_point}${END}${BEGIN}\r
101 UNLOAD_IMAGE = ${module_unload_image}${END}${BEGIN}\r
102 CONSTRUCTOR = ${module_constructor}${END}${BEGIN}\r
103 DESTRUCTOR = ${module_destructor}${END}${BEGIN}\r
104 SHADOW = ${module_shadow}${END}${BEGIN}\r
105 PCI_VENDOR_ID = ${module_pci_vendor_id}${END}${BEGIN}\r
106 PCI_DEVICE_ID = ${module_pci_device_id}${END}${BEGIN}\r
107 PCI_CLASS_CODE = ${module_pci_class_code}${END}${BEGIN}\r
108 PCI_REVISION = ${module_pci_revision}${END}${BEGIN}\r
109 BUILD_NUMBER = ${module_build_number}${END}${BEGIN}\r
110 SPEC = ${module_spec}${END}${BEGIN}\r
111 UEFI_HII_RESOURCE_SECTION = ${module_uefi_hii_resource_section}${END}${BEGIN}\r
112 MODULE_UNI_FILE = ${module_uni_file}${END}\r
113\r
114[Packages.${module_arch}]${BEGIN}\r
da92f276
LG
115 ${package_item}${END}\r
116\r
117[Binaries.${module_arch}]${BEGIN}\r
118 ${binary_item}${END}\r
119\r
e8a47801
LG
120[PatchPcd.${module_arch}]${BEGIN}\r
121 ${patchablepcd_item}\r
122${END}\r
97fa0ee9 123\r
e8a47801
LG
124[Protocols.${module_arch}]${BEGIN}\r
125 ${protocol_item}\r
126${END}\r
97fa0ee9 127\r
e8a47801
LG
128[Ppis.${module_arch}]${BEGIN}\r
129 ${ppi_item}\r
130${END}\r
97fa0ee9 131\r
e8a47801
LG
132[Guids.${module_arch}]${BEGIN}\r
133 ${guid_item}\r
134${END}\r
97fa0ee9 135\r
e8a47801
LG
136[PcdEx.${module_arch}]${BEGIN}\r
137 ${pcd_item}\r
138${END}\r
da92f276 139\r
97fa0ee9
YL
140[LibraryClasses.${module_arch}]\r
141## @LIB_INSTANCES${BEGIN}\r
142# ${libraryclasses_item}${END}\r
143\r
144${depexsection_item}\r
145\r
dfa41b4a
YZ
146${userextension_tianocore_item}\r
147\r
97fa0ee9
YL
148${tail_comments}\r
149\r
150[BuildOptions.${module_arch}]\r
da92f276
LG
151## @AsBuilt${BEGIN}\r
152## ${flags_item}${END}\r
153""")\r
154\r
52302d4d
LG
155## Base class for AutoGen\r
156#\r
157# This class just implements the cache mechanism of AutoGen objects.\r
158#\r
159class AutoGen(object):\r
160 # database to maintain the objects of xxxAutoGen\r
161 _CACHE_ = {} # (BuildTarget, ToolChain) : {ARCH : {platform file: AutoGen object}}}\r
162\r
163 ## Factory method\r
164 #\r
165 # @param Class class object of real AutoGen class\r
166 # (WorkspaceAutoGen, ModuleAutoGen or PlatformAutoGen)\r
167 # @param Workspace Workspace directory or WorkspaceAutoGen object\r
168 # @param MetaFile The path of meta file\r
169 # @param Target Build target\r
170 # @param Toolchain Tool chain name\r
171 # @param Arch Target arch\r
172 # @param *args The specific class related parameters\r
173 # @param **kwargs The specific class related dict parameters\r
174 #\r
175 def __new__(Class, Workspace, MetaFile, Target, Toolchain, Arch, *args, **kwargs):\r
176 # check if the object has been created\r
177 Key = (Target, Toolchain)\r
178 if Key not in Class._CACHE_ or Arch not in Class._CACHE_[Key] \\r
179 or MetaFile not in Class._CACHE_[Key][Arch]:\r
180 AutoGenObject = super(AutoGen, Class).__new__(Class)\r
181 # call real constructor\r
182 if not AutoGenObject._Init(Workspace, MetaFile, Target, Toolchain, Arch, *args, **kwargs):\r
183 return None\r
184 if Key not in Class._CACHE_:\r
185 Class._CACHE_[Key] = {}\r
186 if Arch not in Class._CACHE_[Key]:\r
187 Class._CACHE_[Key][Arch] = {}\r
188 Class._CACHE_[Key][Arch][MetaFile] = AutoGenObject\r
189 else:\r
190 AutoGenObject = Class._CACHE_[Key][Arch][MetaFile]\r
191\r
192 return AutoGenObject\r
193\r
194 ## hash() operator\r
195 #\r
196 # The file path of platform file will be used to represent hash value of this object\r
197 #\r
198 # @retval int Hash value of the file path of platform file\r
199 #\r
200 def __hash__(self):\r
201 return hash(self.MetaFile)\r
202\r
203 ## str() operator\r
204 #\r
205 # The file path of platform file will be used to represent this object\r
206 #\r
207 # @retval string String of platform file path\r
208 #\r
209 def __str__(self):\r
210 return str(self.MetaFile)\r
211\r
212 ## "==" operator\r
213 def __eq__(self, Other):\r
214 return Other and self.MetaFile == Other\r
215\r
216## Workspace AutoGen class\r
217#\r
218# This class is used mainly to control the whole platform build for different\r
219# architecture. This class will generate top level makefile.\r
220#\r
221class WorkspaceAutoGen(AutoGen):\r
222 ## Real constructor of WorkspaceAutoGen\r
223 #\r
79b74a03 224 # This method behaves the same as __init__ except that it needs explicit invoke\r
52302d4d
LG
225 # (in super class's __new__ method)\r
226 #\r
227 # @param WorkspaceDir Root directory of workspace\r
228 # @param ActivePlatform Meta-file of active platform\r
229 # @param Target Build target\r
230 # @param Toolchain Tool chain name\r
231 # @param ArchList List of architecture of current build\r
232 # @param MetaFileDb Database containing meta-files\r
233 # @param BuildConfig Configuration of build\r
234 # @param ToolDefinition Tool chain definitions\r
235 # @param FlashDefinitionFile File of flash definition\r
236 # @param Fds FD list to be generated\r
237 # @param Fvs FV list to be generated\r
4234283c 238 # @param Caps Capsule list to be generated\r
52302d4d
LG
239 # @param SkuId SKU id from command line\r
240 #\r
241 def _Init(self, WorkspaceDir, ActivePlatform, Target, Toolchain, ArchList, MetaFileDb,\r
47fea6af 242 BuildConfig, ToolDefinition, FlashDefinitionFile='', Fds=None, Fvs=None, Caps=None, SkuId='', UniFlag=None,\r
9508d0fa 243 Progress=None, BuildModule=None):\r
4234283c
LG
244 if Fds is None:\r
245 Fds = []\r
246 if Fvs is None:\r
247 Fvs = []\r
248 if Caps is None:\r
249 Caps = []\r
0d2711a6
LG
250 self.BuildDatabase = MetaFileDb\r
251 self.MetaFile = ActivePlatform\r
52302d4d 252 self.WorkspaceDir = WorkspaceDir\r
0d2711a6 253 self.Platform = self.BuildDatabase[self.MetaFile, 'COMMON', Target, Toolchain]\r
d0acc87a 254 GlobalData.gActivePlatform = self.Platform\r
52302d4d
LG
255 self.BuildTarget = Target\r
256 self.ToolChain = Toolchain\r
257 self.ArchList = ArchList\r
258 self.SkuId = SkuId\r
f3decdc3 259 self.UniFlag = UniFlag\r
52302d4d 260\r
52302d4d
LG
261 self.TargetTxt = BuildConfig\r
262 self.ToolDef = ToolDefinition\r
263 self.FdfFile = FlashDefinitionFile\r
264 self.FdTargetList = Fds\r
265 self.FvTargetList = Fvs\r
4234283c 266 self.CapTargetList = Caps\r
52302d4d
LG
267 self.AutoGenObjectList = []\r
268\r
269 # there's many relative directory operations, so ...\r
270 os.chdir(self.WorkspaceDir)\r
271\r
0d2711a6
LG
272 #\r
273 # Merge Arch\r
274 #\r
275 if not self.ArchList:\r
276 ArchList = set(self.Platform.SupArchList)\r
277 else:\r
278 ArchList = set(self.ArchList) & set(self.Platform.SupArchList)\r
279 if not ArchList:\r
280 EdkLogger.error("build", PARAMETER_INVALID,\r
281 ExtraData = "Invalid ARCH specified. [Valid ARCH: %s]" % (" ".join(self.Platform.SupArchList)))\r
282 elif self.ArchList and len(ArchList) != len(self.ArchList):\r
283 SkippedArchList = set(self.ArchList).symmetric_difference(set(self.Platform.SupArchList))\r
284 EdkLogger.verbose("\nArch [%s] is ignored because the platform supports [%s] only!"\r
285 % (" ".join(SkippedArchList), " ".join(self.Platform.SupArchList)))\r
286 self.ArchList = tuple(ArchList)\r
287\r
288 # Validate build target\r
289 if self.BuildTarget not in self.Platform.BuildTargets:\r
47fea6af 290 EdkLogger.error("build", PARAMETER_INVALID,\r
0d2711a6
LG
291 ExtraData="Build target [%s] is not supported by the platform. [Valid target: %s]"\r
292 % (self.BuildTarget, " ".join(self.Platform.BuildTargets)))\r
293\r
12d37ace 294 \r
52302d4d 295 # parse FDF file to get PCDs in it, if any\r
0d2711a6
LG
296 if not self.FdfFile:\r
297 self.FdfFile = self.Platform.FlashDefinition\r
47fea6af 298\r
9508d0fa
LG
299 EdkLogger.info("")\r
300 if self.ArchList:\r
301 EdkLogger.info('%-16s = %s' % ("Architecture(s)", ' '.join(self.ArchList)))\r
302 EdkLogger.info('%-16s = %s' % ("Build target", self.BuildTarget))\r
47fea6af
YZ
303 EdkLogger.info('%-16s = %s' % ("Toolchain", self.ToolChain))\r
304\r
9508d0fa
LG
305 EdkLogger.info('\n%-24s = %s' % ("Active Platform", self.Platform))\r
306 if BuildModule:\r
307 EdkLogger.info('%-24s = %s' % ("Active Module", BuildModule))\r
47fea6af 308\r
9508d0fa
LG
309 if self.FdfFile:\r
310 EdkLogger.info('%-24s = %s' % ("Flash Image Definition", self.FdfFile))\r
0d2711a6 311\r
9508d0fa 312 EdkLogger.verbose("\nFLASH_DEFINITION = %s" % self.FdfFile)\r
47fea6af 313\r
9508d0fa
LG
314 if Progress:\r
315 Progress.Start("\nProcessing meta-data")\r
47fea6af 316\r
0d2711a6 317 if self.FdfFile:\r
df692f02
LG
318 #\r
319 # Mark now build in AutoGen Phase\r
320 #\r
47fea6af 321 GlobalData.gAutoGenPhase = True\r
52302d4d
LG
322 Fdf = FdfParser(self.FdfFile.Path)\r
323 Fdf.ParseFile()\r
a0a2cd1e 324 GlobalData.gFdfParser = Fdf\r
0d2711a6 325 GlobalData.gAutoGenPhase = False\r
52302d4d 326 PcdSet = Fdf.Profile.PcdDict\r
cb04330e
YZ
327 if Fdf.CurrentFdName and Fdf.CurrentFdName in Fdf.Profile.FdDict:\r
328 FdDict = Fdf.Profile.FdDict[Fdf.CurrentFdName]\r
329 for FdRegion in FdDict.RegionList:\r
330 if str(FdRegion.RegionType) is 'FILE' and self.Platform.VpdToolGuid in str(FdRegion.RegionDataList):\r
331 if int(FdRegion.Offset) % 8 != 0:\r
332 EdkLogger.error("build", FORMAT_INVALID, 'The VPD Base Address %s must be 8-byte aligned.' % (FdRegion.Offset))\r
52302d4d
LG
333 ModuleList = Fdf.Profile.InfList\r
334 self.FdfProfile = Fdf.Profile\r
0d2711a6
LG
335 for fvname in self.FvTargetList:\r
336 if fvname.upper() not in self.FdfProfile.FvDict:\r
337 EdkLogger.error("build", OPTION_VALUE_INVALID,\r
338 "No such an FV in FDF file: %s" % fvname)\r
2502b735 339\r
622b1758
YZ
340 # In DSC file may use FILE_GUID to override the module, then in the Platform.Modules use FILE_GUIDmodule.inf as key,\r
341 # but the path (self.MetaFile.Path) is the real path\r
2502b735
YZ
342 for key in self.FdfProfile.InfDict:\r
343 if key == 'ArchTBD':\r
344 Platform_cache = {}\r
622b1758 345 MetaFile_cache = {}\r
2502b735
YZ
346 for Arch in self.ArchList:\r
347 Platform_cache[Arch] = self.BuildDatabase[self.MetaFile, Arch, Target, Toolchain]\r
622b1758
YZ
348 MetaFile_cache[Arch] = []\r
349 for Pkey in Platform_cache[Arch].Modules.keys():\r
350 MetaFile_cache[Arch].append(Platform_cache[Arch].Modules[Pkey].MetaFile)\r
2502b735
YZ
351 for Inf in self.FdfProfile.InfDict[key]:\r
352 ModuleFile = PathClass(NormPath(Inf), GlobalData.gWorkspace, Arch)\r
353 for Arch in self.ArchList:\r
622b1758 354 if ModuleFile in MetaFile_cache[Arch]:\r
2502b735
YZ
355 break\r
356 else:\r
357 ModuleData = self.BuildDatabase[ModuleFile, Arch, Target, Toolchain]\r
358 if not ModuleData.IsBinaryModule:\r
359 EdkLogger.error('build', PARSER_ERROR, "Module %s NOT found in DSC file; Is it really a binary module?" % ModuleFile)\r
360\r
361 else:\r
362 for Arch in self.ArchList:\r
363 if Arch == key:\r
364 Platform = self.BuildDatabase[self.MetaFile, Arch, Target, Toolchain]\r
622b1758
YZ
365 MetaFileList = []\r
366 for Pkey in Platform.Modules.keys():\r
367 MetaFileList.append(Platform.Modules[Pkey].MetaFile)\r
2502b735
YZ
368 for Inf in self.FdfProfile.InfDict[key]:\r
369 ModuleFile = PathClass(NormPath(Inf), GlobalData.gWorkspace, Arch)\r
622b1758 370 if ModuleFile in MetaFileList:\r
2502b735
YZ
371 continue\r
372 ModuleData = self.BuildDatabase[ModuleFile, Arch, Target, Toolchain]\r
373 if not ModuleData.IsBinaryModule:\r
374 EdkLogger.error('build', PARSER_ERROR, "Module %s NOT found in DSC file; Is it really a binary module?" % ModuleFile)\r
375\r
52302d4d
LG
376 else:\r
377 PcdSet = {}\r
378 ModuleList = []\r
379 self.FdfProfile = None\r
0d2711a6
LG
380 if self.FdTargetList:\r
381 EdkLogger.info("No flash definition file found. FD [%s] will be ignored." % " ".join(self.FdTargetList))\r
382 self.FdTargetList = []\r
383 if self.FvTargetList:\r
384 EdkLogger.info("No flash definition file found. FV [%s] will be ignored." % " ".join(self.FvTargetList))\r
385 self.FvTargetList = []\r
386 if self.CapTargetList:\r
387 EdkLogger.info("No flash definition file found. Capsule [%s] will be ignored." % " ".join(self.CapTargetList))\r
388 self.CapTargetList = []\r
47fea6af 389\r
52302d4d
LG
390 # apply SKU and inject PCDs from Flash Definition file\r
391 for Arch in self.ArchList:\r
0d2711a6 392 Platform = self.BuildDatabase[self.MetaFile, Arch, Target, Toolchain]\r
64b2609f 393\r
25918452 394 DecPcds = {}\r
4afd3d04 395 DecPcdsKey = set()\r
64b2609f 396 PGen = PlatformAutoGen(self, self.MetaFile, Target, Toolchain, Arch)\r
763e8edf
YZ
397 if GlobalData.BuildOptionPcd:\r
398 for i, pcd in enumerate(GlobalData.BuildOptionPcd):\r
d7cd3356
YZ
399 if type(pcd) is tuple:\r
400 continue\r
763e8edf
YZ
401 (pcdname, pcdvalue) = pcd.split('=')\r
402 if not pcdvalue:\r
403 EdkLogger.error('build', AUTOGEN_ERROR, "No Value specified for the PCD %s." % (pcdname))\r
404 if '.' in pcdname:\r
405 (TokenSpaceGuidCName, TokenCName) = pcdname.split('.')\r
406 HasTokenSpace = True\r
407 else:\r
408 TokenCName = pcdname\r
409 TokenSpaceGuidCName = ''\r
410 HasTokenSpace = False\r
411 TokenSpaceGuidCNameList = []\r
412 FoundFlag = False\r
413 PcdDatumType = ''\r
414 NewValue = ''\r
415 for package in PGen.PackageList:\r
416 for key in package.Pcds:\r
417 PcdItem = package.Pcds[key]\r
418 if HasTokenSpace:\r
419 if (PcdItem.TokenCName, PcdItem.TokenSpaceGuidCName) == (TokenCName, TokenSpaceGuidCName):\r
420 PcdDatumType = PcdItem.DatumType\r
db55dac7 421 NewValue = BuildOptionPcdValueFormat(TokenSpaceGuidCName, TokenCName, PcdDatumType, pcdvalue)\r
763e8edf
YZ
422 FoundFlag = True\r
423 else:\r
424 if PcdItem.TokenCName == TokenCName:\r
425 if not PcdItem.TokenSpaceGuidCName in TokenSpaceGuidCNameList:\r
426 if len (TokenSpaceGuidCNameList) < 1:\r
427 TokenSpaceGuidCNameList.append(PcdItem.TokenSpaceGuidCName)\r
428 PcdDatumType = PcdItem.DatumType\r
429 TokenSpaceGuidCName = PcdItem.TokenSpaceGuidCName\r
db55dac7 430 NewValue = BuildOptionPcdValueFormat(TokenSpaceGuidCName, TokenCName, PcdDatumType, pcdvalue)\r
763e8edf
YZ
431 FoundFlag = True\r
432 else:\r
433 EdkLogger.error(\r
434 'build',\r
435 AUTOGEN_ERROR,\r
436 "The Pcd %s is found under multiple different TokenSpaceGuid: %s and %s." % (TokenCName, PcdItem.TokenSpaceGuidCName, TokenSpaceGuidCNameList[0])\r
437 )\r
438\r
439 GlobalData.BuildOptionPcd[i] = (TokenSpaceGuidCName, TokenCName, NewValue)\r
440\r
441 if not FoundFlag:\r
442 if HasTokenSpace:\r
443 EdkLogger.error('build', AUTOGEN_ERROR, "The Pcd %s.%s is not found in the DEC file." % (TokenSpaceGuidCName, TokenCName))\r
444 else:\r
445 EdkLogger.error('build', AUTOGEN_ERROR, "The Pcd %s is not found in the DEC file." % (TokenCName))\r
446\r
447 for BuildData in PGen.BuildDatabase._CACHE_.values():\r
448 if BuildData.Arch != Arch:\r
449 continue\r
450 if BuildData.MetaFile.Ext == '.dec':\r
451 continue\r
452 for key in BuildData.Pcds:\r
453 PcdItem = BuildData.Pcds[key]\r
454 if (TokenSpaceGuidCName, TokenCName) == (PcdItem.TokenSpaceGuidCName, PcdItem.TokenCName):\r
455 PcdItem.DefaultValue = NewValue\r
456\r
457 if (TokenCName, TokenSpaceGuidCName) in PcdSet:\r
458 PcdSet[(TokenCName, TokenSpaceGuidCName)] = NewValue\r
459\r
2a29017e
YZ
460 SourcePcdDict = {'DynamicEx':[], 'PatchableInModule':[],'Dynamic':[],'FixedAtBuild':[]}\r
461 BinaryPcdDict = {'DynamicEx':[], 'PatchableInModule':[]}\r
462 SourcePcdDict_Keys = SourcePcdDict.keys()\r
463 BinaryPcdDict_Keys = BinaryPcdDict.keys()\r
464\r
465 # generate the SourcePcdDict and BinaryPcdDict\r
466 for BuildData in PGen.BuildDatabase._CACHE_.values():\r
467 if BuildData.Arch != Arch:\r
468 continue\r
469 if BuildData.MetaFile.Ext == '.inf':\r
470 for key in BuildData.Pcds:\r
471 if BuildData.Pcds[key].Pending:\r
472 if key in Platform.Pcds:\r
473 PcdInPlatform = Platform.Pcds[key]\r
474 if PcdInPlatform.Type not in [None, '']:\r
475 BuildData.Pcds[key].Type = PcdInPlatform.Type\r
476\r
477 if BuildData.MetaFile in Platform.Modules:\r
478 PlatformModule = Platform.Modules[str(BuildData.MetaFile)]\r
479 if key in PlatformModule.Pcds:\r
480 PcdInPlatform = PlatformModule.Pcds[key]\r
481 if PcdInPlatform.Type not in [None, '']:\r
482 BuildData.Pcds[key].Type = PcdInPlatform.Type\r
483\r
484 if 'DynamicEx' in BuildData.Pcds[key].Type:\r
485 if BuildData.IsBinaryModule:\r
486 if (BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName) not in BinaryPcdDict['DynamicEx']:\r
487 BinaryPcdDict['DynamicEx'].append((BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName))\r
488 else:\r
489 if (BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName) not in SourcePcdDict['DynamicEx']:\r
490 SourcePcdDict['DynamicEx'].append((BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName))\r
491\r
492 elif 'PatchableInModule' in BuildData.Pcds[key].Type:\r
493 if BuildData.MetaFile.Ext == '.inf':\r
494 if BuildData.IsBinaryModule:\r
495 if (BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName) not in BinaryPcdDict['PatchableInModule']:\r
496 BinaryPcdDict['PatchableInModule'].append((BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName))\r
497 else:\r
498 if (BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName) not in SourcePcdDict['PatchableInModule']:\r
499 SourcePcdDict['PatchableInModule'].append((BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName))\r
500\r
501 elif 'Dynamic' in BuildData.Pcds[key].Type:\r
502 if (BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName) not in SourcePcdDict['Dynamic']:\r
503 SourcePcdDict['Dynamic'].append((BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName))\r
504 elif 'FixedAtBuild' in BuildData.Pcds[key].Type:\r
505 if (BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName) not in SourcePcdDict['FixedAtBuild']:\r
506 SourcePcdDict['FixedAtBuild'].append((BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName))\r
507 else:\r
508 pass\r
97cdb33b
YZ
509 #\r
510 # A PCD can only use one type for all source modules\r
511 #\r
512 for i in SourcePcdDict_Keys:\r
513 for j in SourcePcdDict_Keys:\r
514 if i != j:\r
515 IntersectionList = list(set(SourcePcdDict[i]).intersection(set(SourcePcdDict[j])))\r
516 if len(IntersectionList) > 0:\r
517 EdkLogger.error(\r
518 'build',\r
519 FORMAT_INVALID,\r
520 "Building modules from source INFs, following PCD use %s and %s access method. It must be corrected to use only one access method." % (i, j),\r
521 ExtraData="%s" % '\n\t'.join([str(P[1]+'.'+P[0]) for P in IntersectionList])\r
522 )\r
523 else:\r
524 pass\r
2a29017e
YZ
525\r
526 #\r
527 # intersection the BinaryPCD for Mixed PCD\r
528 #\r
529 for i in BinaryPcdDict_Keys:\r
530 for j in BinaryPcdDict_Keys:\r
531 if i != j:\r
532 IntersectionList = list(set(BinaryPcdDict[i]).intersection(set(BinaryPcdDict[j])))\r
533 for item in IntersectionList:\r
534 NewPcd1 = (item[0] + '_' + i, item[1])\r
535 NewPcd2 = (item[0] + '_' + j, item[1])\r
536 if item not in GlobalData.MixedPcd:\r
537 GlobalData.MixedPcd[item] = [NewPcd1, NewPcd2]\r
538 else:\r
539 if NewPcd1 not in GlobalData.MixedPcd[item]:\r
540 GlobalData.MixedPcd[item].append(NewPcd1)\r
541 if NewPcd2 not in GlobalData.MixedPcd[item]:\r
542 GlobalData.MixedPcd[item].append(NewPcd2)\r
543 else:\r
544 pass\r
545\r
546 #\r
547 # intersection the SourcePCD and BinaryPCD for Mixed PCD\r
548 #\r
549 for i in SourcePcdDict_Keys:\r
550 for j in BinaryPcdDict_Keys:\r
551 if i != j:\r
552 IntersectionList = list(set(SourcePcdDict[i]).intersection(set(BinaryPcdDict[j])))\r
553 for item in IntersectionList:\r
554 NewPcd1 = (item[0] + '_' + i, item[1])\r
555 NewPcd2 = (item[0] + '_' + j, item[1])\r
556 if item not in GlobalData.MixedPcd:\r
557 GlobalData.MixedPcd[item] = [NewPcd1, NewPcd2]\r
558 else:\r
559 if NewPcd1 not in GlobalData.MixedPcd[item]:\r
560 GlobalData.MixedPcd[item].append(NewPcd1)\r
561 if NewPcd2 not in GlobalData.MixedPcd[item]:\r
562 GlobalData.MixedPcd[item].append(NewPcd2)\r
563 else:\r
564 pass\r
565\r
566 for BuildData in PGen.BuildDatabase._CACHE_.values():\r
567 if BuildData.Arch != Arch:\r
568 continue\r
569 for key in BuildData.Pcds:\r
570 for SinglePcd in GlobalData.MixedPcd:\r
571 if (BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName) == SinglePcd:\r
572 for item in GlobalData.MixedPcd[SinglePcd]:\r
573 Pcd_Type = item[0].split('_')[-1]\r
574 if (Pcd_Type == BuildData.Pcds[key].Type) or (Pcd_Type == TAB_PCDS_DYNAMIC_EX and BuildData.Pcds[key].Type in GenC.gDynamicExPcd) or \\r
575 (Pcd_Type == TAB_PCDS_DYNAMIC and BuildData.Pcds[key].Type in GenC.gDynamicPcd):\r
576 Value = BuildData.Pcds[key]\r
577 Value.TokenCName = BuildData.Pcds[key].TokenCName + '_' + Pcd_Type\r
578 if len(key) == 2:\r
579 newkey = (Value.TokenCName, key[1])\r
580 elif len(key) == 3:\r
581 newkey = (Value.TokenCName, key[1], key[2])\r
582 del BuildData.Pcds[key]\r
583 BuildData.Pcds[newkey] = Value\r
584 break\r
585 else:\r
586 pass\r
587 break\r
588 else:\r
589 pass\r
590\r
591 # handle the mixed pcd in FDF file\r
592 for key in PcdSet:\r
593 if key in GlobalData.MixedPcd:\r
594 Value = PcdSet[key]\r
595 del PcdSet[key]\r
596 for item in GlobalData.MixedPcd[key]:\r
597 PcdSet[item] = Value\r
598\r
97fa0ee9 599 #Collect package set information from INF of FDF\r
a0a2cd1e
FB
600 PkgSet = set()\r
601 for Inf in ModuleList:\r
602 ModuleFile = PathClass(NormPath(Inf), GlobalData.gWorkspace, Arch)\r
603 if ModuleFile in Platform.Modules:\r
604 continue\r
605 ModuleData = self.BuildDatabase[ModuleFile, Arch, Target, Toolchain]\r
606 PkgSet.update(ModuleData.Packages)\r
607 Pkgs = list(PkgSet) + list(PGen.PackageList)\r
64b2609f 608 for Pkg in Pkgs:\r
25918452
LG
609 for Pcd in Pkg.Pcds:\r
610 DecPcds[Pcd[0], Pcd[1]] = Pkg.Pcds[Pcd]\r
4afd3d04 611 DecPcdsKey.add((Pcd[0], Pcd[1], Pcd[2]))\r
64b2609f 612\r
52302d4d
LG
613 Platform.SkuName = self.SkuId\r
614 for Name, Guid in PcdSet:\r
64b2609f
LG
615 if (Name, Guid) not in DecPcds:\r
616 EdkLogger.error(\r
617 'build',\r
618 PARSER_ERROR,\r
619 "PCD (%s.%s) used in FDF is not declared in DEC files." % (Guid, Name),\r
620 File = self.FdfProfile.PcdFileLineDict[Name, Guid][0],\r
621 Line = self.FdfProfile.PcdFileLineDict[Name, Guid][1]\r
622 )\r
4afd3d04
LG
623 else:\r
624 # Check whether Dynamic or DynamicEx PCD used in FDF file. If used, build break and give a error message.\r
625 if (Name, Guid, TAB_PCDS_FIXED_AT_BUILD) in DecPcdsKey \\r
626 or (Name, Guid, TAB_PCDS_PATCHABLE_IN_MODULE) in DecPcdsKey \\r
627 or (Name, Guid, TAB_PCDS_FEATURE_FLAG) in DecPcdsKey:\r
628 Platform.AddPcd(Name, Guid, PcdSet[Name, Guid])\r
629 continue\r
630 elif (Name, Guid, TAB_PCDS_DYNAMIC) in DecPcdsKey or (Name, Guid, TAB_PCDS_DYNAMIC_EX) in DecPcdsKey:\r
631 EdkLogger.error(\r
632 'build',\r
633 PARSER_ERROR,\r
634 "Using Dynamic or DynamicEx type of PCD [%s.%s] in FDF file is not allowed." % (Guid, Name),\r
635 File = self.FdfProfile.PcdFileLineDict[Name, Guid][0],\r
636 Line = self.FdfProfile.PcdFileLineDict[Name, Guid][1]\r
637 )\r
52302d4d
LG
638\r
639 Pa = PlatformAutoGen(self, self.MetaFile, Target, Toolchain, Arch)\r
640 #\r
641 # Explicitly collect platform's dynamic PCDs\r
642 #\r
643 Pa.CollectPlatformDynamicPcds()\r
2bc3256c 644 Pa.CollectFixedAtBuildPcds()\r
52302d4d 645 self.AutoGenObjectList.append(Pa)\r
47fea6af 646\r
6780eef1
LG
647 #\r
648 # Check PCDs token value conflict in each DEC file.\r
649 #\r
650 self._CheckAllPcdsTokenValueConflict()\r
47fea6af 651\r
4234283c
LG
652 #\r
653 # Check PCD type and definition between DSC and DEC\r
654 #\r
655 self._CheckPcdDefineAndType()\r
97fa0ee9
YL
656\r
657# if self.FdfFile:\r
658# self._CheckDuplicateInFV(Fdf)\r
659\r
52302d4d
LG
660 self._BuildDir = None\r
661 self._FvDir = None\r
662 self._MakeFileDir = None\r
663 self._BuildCommand = None\r
664\r
c17956e0 665 #\r
2d499388 666 # Create BuildOptions Macro & PCD metafile, also add the Active Platform and FDF file.\r
c17956e0
DL
667 #\r
668 content = 'gCommandLineDefines: '\r
669 content += str(GlobalData.gCommandLineDefines)\r
670 content += os.linesep\r
671 content += 'BuildOptionPcd: '\r
672 content += str(GlobalData.BuildOptionPcd)\r
2d499388
YZ
673 content += os.linesep\r
674 content += 'Active Platform: '\r
675 content += str(self.Platform)\r
676 content += os.linesep\r
677 if self.FdfFile:\r
678 content += 'Flash Image Definition: '\r
679 content += str(self.FdfFile)\r
c17956e0
DL
680 SaveFileOnChange(os.path.join(self.BuildDir, 'BuildOptions'), content, False)\r
681\r
99adfe9f
YZ
682 #\r
683 # Create PcdToken Number file for Dynamic/DynamicEx Pcd.\r
684 #\r
685 PcdTokenNumber = 'PcdTokenNumber: '\r
686 if Pa.PcdTokenNumber:\r
687 if Pa.DynamicPcdList:\r
688 for Pcd in Pa.DynamicPcdList:\r
689 PcdTokenNumber += os.linesep\r
690 PcdTokenNumber += str((Pcd.TokenCName, Pcd.TokenSpaceGuidCName))\r
691 PcdTokenNumber += ' : '\r
692 PcdTokenNumber += str(Pa.PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName])\r
693 SaveFileOnChange(os.path.join(self.BuildDir, 'PcdTokenNumber'), PcdTokenNumber, False)\r
694\r
c17956e0
DL
695 #\r
696 # Get set of workspace metafiles\r
697 #\r
698 AllWorkSpaceMetaFiles = self._GetMetaFiles(Target, Toolchain, Arch)\r
699\r
700 #\r
701 # Retrieve latest modified time of all metafiles\r
702 #\r
703 SrcTimeStamp = 0\r
704 for f in AllWorkSpaceMetaFiles:\r
705 if os.stat(f)[8] > SrcTimeStamp:\r
706 SrcTimeStamp = os.stat(f)[8]\r
707 self._SrcTimeStamp = SrcTimeStamp\r
708\r
709 #\r
710 # Write metafile list to build directory\r
711 #\r
712 AutoGenFilePath = os.path.join(self.BuildDir, 'AutoGen')\r
713 if os.path.exists (AutoGenFilePath):\r
714 os.remove(AutoGenFilePath)\r
715 if not os.path.exists(self.BuildDir):\r
716 os.makedirs(self.BuildDir)\r
717 with open(os.path.join(self.BuildDir, 'AutoGen'), 'w+') as file:\r
718 for f in AllWorkSpaceMetaFiles:\r
719 print >> file, f\r
52302d4d
LG
720 return True\r
721\r
763e8edf 722\r
c17956e0
DL
723 def _GetMetaFiles(self, Target, Toolchain, Arch):\r
724 AllWorkSpaceMetaFiles = set()\r
725 #\r
726 # add fdf\r
727 #\r
728 if self.FdfFile:\r
729 AllWorkSpaceMetaFiles.add (self.FdfFile.Path)\r
730 if self.FdfFile:\r
731 FdfFiles = GlobalData.gFdfParser.GetAllIncludedFile()\r
732 for f in FdfFiles:\r
733 AllWorkSpaceMetaFiles.add (f.FileName)\r
734 #\r
735 # add dsc\r
736 #\r
737 AllWorkSpaceMetaFiles.add(self.MetaFile.Path)\r
738\r
739 #\r
86601b78
DL
740 # add build_rule.txt & tools_def.txt\r
741 #\r
51de5c30
YZ
742 AllWorkSpaceMetaFiles.add(os.path.join(GlobalData.gConfDirectory, gDefaultBuildRuleFile))\r
743 AllWorkSpaceMetaFiles.add(os.path.join(GlobalData.gConfDirectory, gDefaultToolsDefFile))\r
86601b78 744\r
c17956e0
DL
745 # add BuildOption metafile\r
746 #\r
747 AllWorkSpaceMetaFiles.add(os.path.join(self.BuildDir, 'BuildOptions'))\r
748\r
99adfe9f
YZ
749 # add PcdToken Number file for Dynamic/DynamicEx Pcd\r
750 #\r
751 AllWorkSpaceMetaFiles.add(os.path.join(self.BuildDir, 'PcdTokenNumber'))\r
752\r
c17956e0
DL
753 for Arch in self.ArchList:\r
754 Platform = self.BuildDatabase[self.MetaFile, Arch, Target, Toolchain]\r
755 PGen = PlatformAutoGen(self, self.MetaFile, Target, Toolchain, Arch)\r
756\r
757 #\r
758 # add dec\r
759 #\r
760 for Package in PGen.PackageList:\r
761 AllWorkSpaceMetaFiles.add(Package.MetaFile.Path)\r
762\r
763 #\r
764 # add included dsc\r
765 #\r
766 for filePath in Platform._RawData.IncludedFiles:\r
767 AllWorkSpaceMetaFiles.add(filePath.Path)\r
768\r
769 return AllWorkSpaceMetaFiles\r
770\r
79b74a03
LG
771 ## _CheckDuplicateInFV() method\r
772 #\r
773 # Check whether there is duplicate modules/files exist in FV section. \r
774 # The check base on the file GUID;\r
775 #\r
776 def _CheckDuplicateInFV(self, Fdf):\r
777 for Fv in Fdf.Profile.FvDict:\r
778 _GuidDict = {}\r
779 for FfsFile in Fdf.Profile.FvDict[Fv].FfsList:\r
780 if FfsFile.InfFileName and FfsFile.NameGuid == None:\r
781 #\r
782 # Get INF file GUID\r
783 #\r
47fea6af 784 InfFoundFlag = False\r
79b74a03 785 for Pa in self.AutoGenObjectList:\r
64b2609f
LG
786 if InfFoundFlag:\r
787 break\r
79b74a03
LG
788 for Module in Pa.ModuleAutoGenList:\r
789 if path.normpath(Module.MetaFile.File) == path.normpath(FfsFile.InfFileName):\r
790 InfFoundFlag = True\r
791 if not Module.Guid.upper() in _GuidDict.keys():\r
792 _GuidDict[Module.Guid.upper()] = FfsFile\r
64b2609f 793 break\r
79b74a03 794 else:\r
47fea6af 795 EdkLogger.error("build",\r
79b74a03 796 FORMAT_INVALID,\r
47fea6af 797 "Duplicate GUID found for these lines: Line %d: %s and Line %d: %s. GUID: %s" % (FfsFile.CurrentLineNum,\r
79b74a03
LG
798 FfsFile.CurrentLineContent,\r
799 _GuidDict[Module.Guid.upper()].CurrentLineNum,\r
800 _GuidDict[Module.Guid.upper()].CurrentLineContent,\r
801 Module.Guid.upper()),\r
802 ExtraData=self.FdfFile)\r
803 #\r
804 # Some INF files not have entity in DSC file. \r
805 #\r
806 if not InfFoundFlag:\r
807 if FfsFile.InfFileName.find('$') == -1:\r
808 InfPath = NormPath(FfsFile.InfFileName)\r
809 if not os.path.exists(InfPath):\r
810 EdkLogger.error('build', GENFDS_ERROR, "Non-existant Module %s !" % (FfsFile.InfFileName))\r
47fea6af 811\r
79b74a03
LG
812 PathClassObj = PathClass(FfsFile.InfFileName, self.WorkspaceDir)\r
813 #\r
814 # Here we just need to get FILE_GUID from INF file, use 'COMMON' as ARCH attribute. and use \r
815 # BuildObject from one of AutoGenObjectList is enough.\r
816 #\r
817 InfObj = self.AutoGenObjectList[0].BuildDatabase.WorkspaceDb.BuildObject[PathClassObj, 'COMMON', self.BuildTarget, self.ToolChain]\r
818 if not InfObj.Guid.upper() in _GuidDict.keys():\r
819 _GuidDict[InfObj.Guid.upper()] = FfsFile\r
820 else:\r
47fea6af 821 EdkLogger.error("build",\r
79b74a03 822 FORMAT_INVALID,\r
47fea6af 823 "Duplicate GUID found for these lines: Line %d: %s and Line %d: %s. GUID: %s" % (FfsFile.CurrentLineNum,\r
79b74a03
LG
824 FfsFile.CurrentLineContent,\r
825 _GuidDict[InfObj.Guid.upper()].CurrentLineNum,\r
826 _GuidDict[InfObj.Guid.upper()].CurrentLineContent,\r
827 InfObj.Guid.upper()),\r
828 ExtraData=self.FdfFile)\r
829 InfFoundFlag = False\r
47fea6af 830\r
79b74a03
LG
831 if FfsFile.NameGuid != None:\r
832 _CheckPCDAsGuidPattern = re.compile("^PCD\(.+\..+\)$")\r
47fea6af 833\r
79b74a03
LG
834 #\r
835 # If the NameGuid reference a PCD name. \r
836 # The style must match: PCD(xxxx.yyy)\r
837 #\r
838 if _CheckPCDAsGuidPattern.match(FfsFile.NameGuid):\r
839 #\r
840 # Replace the PCD value.\r
841 #\r
842 _PcdName = FfsFile.NameGuid.lstrip("PCD(").rstrip(")")\r
843 PcdFoundFlag = False\r
844 for Pa in self.AutoGenObjectList:\r
845 if not PcdFoundFlag:\r
846 for PcdItem in Pa.AllPcdList:\r
847 if (PcdItem.TokenSpaceGuidCName + "." + PcdItem.TokenCName) == _PcdName:\r
848 #\r
849 # First convert from CFormatGuid to GUID string\r
850 #\r
851 _PcdGuidString = GuidStructureStringToGuidString(PcdItem.DefaultValue)\r
47fea6af 852\r
79b74a03
LG
853 if not _PcdGuidString:\r
854 #\r
855 # Then try Byte array.\r
856 #\r
857 _PcdGuidString = GuidStructureByteArrayToGuidString(PcdItem.DefaultValue)\r
47fea6af 858\r
79b74a03
LG
859 if not _PcdGuidString:\r
860 #\r
861 # Not Byte array or CFormat GUID, raise error.\r
862 #\r
863 EdkLogger.error("build",\r
864 FORMAT_INVALID,\r
47fea6af 865 "The format of PCD value is incorrect. PCD: %s , Value: %s\n" % (_PcdName, PcdItem.DefaultValue),\r
79b74a03 866 ExtraData=self.FdfFile)\r
47fea6af
YZ
867\r
868 if not _PcdGuidString.upper() in _GuidDict.keys():\r
79b74a03
LG
869 _GuidDict[_PcdGuidString.upper()] = FfsFile\r
870 PcdFoundFlag = True\r
871 break\r
872 else:\r
47fea6af 873 EdkLogger.error("build",\r
79b74a03 874 FORMAT_INVALID,\r
47fea6af 875 "Duplicate GUID found for these lines: Line %d: %s and Line %d: %s. GUID: %s" % (FfsFile.CurrentLineNum,\r
79b74a03
LG
876 FfsFile.CurrentLineContent,\r
877 _GuidDict[_PcdGuidString.upper()].CurrentLineNum,\r
878 _GuidDict[_PcdGuidString.upper()].CurrentLineContent,\r
879 FfsFile.NameGuid.upper()),\r
47fea6af
YZ
880 ExtraData=self.FdfFile)\r
881\r
79b74a03
LG
882 if not FfsFile.NameGuid.upper() in _GuidDict.keys():\r
883 _GuidDict[FfsFile.NameGuid.upper()] = FfsFile\r
884 else:\r
885 #\r
886 # Two raw file GUID conflict.\r
887 #\r
47fea6af 888 EdkLogger.error("build",\r
79b74a03 889 FORMAT_INVALID,\r
47fea6af 890 "Duplicate GUID found for these lines: Line %d: %s and Line %d: %s. GUID: %s" % (FfsFile.CurrentLineNum,\r
79b74a03
LG
891 FfsFile.CurrentLineContent,\r
892 _GuidDict[FfsFile.NameGuid.upper()].CurrentLineNum,\r
893 _GuidDict[FfsFile.NameGuid.upper()].CurrentLineContent,\r
894 FfsFile.NameGuid.upper()),\r
895 ExtraData=self.FdfFile)\r
47fea6af 896\r
79b74a03 897\r
4234283c
LG
898 def _CheckPcdDefineAndType(self):\r
899 PcdTypeList = [\r
900 "FixedAtBuild", "PatchableInModule", "FeatureFlag",\r
901 "Dynamic", #"DynamicHii", "DynamicVpd",\r
902 "DynamicEx", # "DynamicExHii", "DynamicExVpd"\r
903 ]\r
904\r
905 # This dict store PCDs which are not used by any modules with specified arches\r
906 UnusedPcd = sdict()\r
907 for Pa in self.AutoGenObjectList:\r
908 # Key of DSC's Pcds dictionary is PcdCName, TokenSpaceGuid\r
909 for Pcd in Pa.Platform.Pcds:\r
910 PcdType = Pa.Platform.Pcds[Pcd].Type\r
47fea6af 911\r
4234283c
LG
912 # If no PCD type, this PCD comes from FDF \r
913 if not PcdType:\r
914 continue\r
47fea6af 915\r
4234283c
LG
916 # Try to remove Hii and Vpd suffix\r
917 if PcdType.startswith("DynamicEx"):\r
918 PcdType = "DynamicEx"\r
919 elif PcdType.startswith("Dynamic"):\r
920 PcdType = "Dynamic"\r
47fea6af 921\r
4234283c
LG
922 for Package in Pa.PackageList:\r
923 # Key of DEC's Pcds dictionary is PcdCName, TokenSpaceGuid, PcdType\r
924 if (Pcd[0], Pcd[1], PcdType) in Package.Pcds:\r
925 break\r
926 for Type in PcdTypeList:\r
927 if (Pcd[0], Pcd[1], Type) in Package.Pcds:\r
928 EdkLogger.error(\r
929 'build',\r
930 FORMAT_INVALID,\r
931 "Type [%s] of PCD [%s.%s] in DSC file doesn't match the type [%s] defined in DEC file." \\r
932 % (Pa.Platform.Pcds[Pcd].Type, Pcd[1], Pcd[0], Type),\r
933 ExtraData=None\r
934 )\r
935 return\r
936 else:\r
937 UnusedPcd.setdefault(Pcd, []).append(Pa.Arch)\r
938\r
939 for Pcd in UnusedPcd:\r
940 EdkLogger.warn(\r
941 'build',\r
942 "The PCD was not specified by any INF module in the platform for the given architecture.\n"\r
943 "\tPCD: [%s.%s]\n\tPlatform: [%s]\n\tArch: %s"\r
944 % (Pcd[1], Pcd[0], os.path.basename(str(self.MetaFile)), str(UnusedPcd[Pcd])),\r
945 ExtraData=None\r
946 )\r
947\r
52302d4d
LG
948 def __repr__(self):\r
949 return "%s [%s]" % (self.MetaFile, ", ".join(self.ArchList))\r
950\r
951 ## Return the directory to store FV files\r
952 def _GetFvDir(self):\r
953 if self._FvDir == None:\r
954 self._FvDir = path.join(self.BuildDir, 'FV')\r
955 return self._FvDir\r
956\r
957 ## Return the directory to store all intermediate and final files built\r
958 def _GetBuildDir(self):\r
959 return self.AutoGenObjectList[0].BuildDir\r
960\r
961 ## Return the build output directory platform specifies\r
962 def _GetOutputDir(self):\r
963 return self.Platform.OutputDirectory\r
964\r
965 ## Return platform name\r
966 def _GetName(self):\r
967 return self.Platform.PlatformName\r
968\r
969 ## Return meta-file GUID\r
970 def _GetGuid(self):\r
971 return self.Platform.Guid\r
972\r
973 ## Return platform version\r
974 def _GetVersion(self):\r
975 return self.Platform.Version\r
976\r
977 ## Return paths of tools\r
978 def _GetToolDefinition(self):\r
979 return self.AutoGenObjectList[0].ToolDefinition\r
980\r
981 ## Return directory of platform makefile\r
982 #\r
983 # @retval string Makefile directory\r
984 #\r
985 def _GetMakeFileDir(self):\r
986 if self._MakeFileDir == None:\r
987 self._MakeFileDir = self.BuildDir\r
988 return self._MakeFileDir\r
989\r
990 ## Return build command string\r
991 #\r
992 # @retval string Build command string\r
993 #\r
994 def _GetBuildCommand(self):\r
995 if self._BuildCommand == None:\r
996 # BuildCommand should be all the same. So just get one from platform AutoGen\r
997 self._BuildCommand = self.AutoGenObjectList[0].BuildCommand\r
998 return self._BuildCommand\r
47fea6af 999\r
6780eef1
LG
1000 ## Check the PCDs token value conflict in each DEC file.\r
1001 #\r
1002 # Will cause build break and raise error message while two PCDs conflict.\r
1003 # \r
1004 # @return None\r
1005 #\r
1006 def _CheckAllPcdsTokenValueConflict(self):\r
b36d134f
LG
1007 for Pa in self.AutoGenObjectList:\r
1008 for Package in Pa.PackageList:\r
6780eef1 1009 PcdList = Package.Pcds.values()\r
f827cd07 1010 PcdList.sort(lambda x, y: cmp(int(x.TokenValue, 0), int(y.TokenValue, 0))) \r
6780eef1
LG
1011 Count = 0\r
1012 while (Count < len(PcdList) - 1) :\r
1013 Item = PcdList[Count]\r
1014 ItemNext = PcdList[Count + 1]\r
1015 #\r
1016 # Make sure in the same token space the TokenValue should be unique\r
1017 #\r
f827cd07 1018 if (int(Item.TokenValue, 0) == int(ItemNext.TokenValue, 0)):\r
6780eef1
LG
1019 SameTokenValuePcdList = []\r
1020 SameTokenValuePcdList.append(Item)\r
1021 SameTokenValuePcdList.append(ItemNext)\r
1022 RemainPcdListLength = len(PcdList) - Count - 2\r
1023 for ValueSameCount in range(RemainPcdListLength):\r
f827cd07 1024 if int(PcdList[len(PcdList) - RemainPcdListLength + ValueSameCount].TokenValue, 0) == int(Item.TokenValue, 0):\r
6780eef1
LG
1025 SameTokenValuePcdList.append(PcdList[len(PcdList) - RemainPcdListLength + ValueSameCount])\r
1026 else:\r
1027 break;\r
1028 #\r
1029 # Sort same token value PCD list with TokenGuid and TokenCName\r
1030 #\r
47fea6af
YZ
1031 SameTokenValuePcdList.sort(lambda x, y: cmp("%s.%s" % (x.TokenSpaceGuidCName, x.TokenCName), "%s.%s" % (y.TokenSpaceGuidCName, y.TokenCName)))\r
1032 SameTokenValuePcdListCount = 0\r
6780eef1 1033 while (SameTokenValuePcdListCount < len(SameTokenValuePcdList) - 1):\r
2a29017e 1034 Flag = False\r
47fea6af
YZ
1035 TemListItem = SameTokenValuePcdList[SameTokenValuePcdListCount]\r
1036 TemListItemNext = SameTokenValuePcdList[SameTokenValuePcdListCount + 1]\r
1037\r
6780eef1 1038 if (TemListItem.TokenSpaceGuidCName == TemListItemNext.TokenSpaceGuidCName) and (TemListItem.TokenCName != TemListItemNext.TokenCName):\r
2a29017e
YZ
1039 for PcdItem in GlobalData.MixedPcd:\r
1040 if (TemListItem.TokenCName, TemListItem.TokenSpaceGuidCName) in GlobalData.MixedPcd[PcdItem] or \\r
1041 (TemListItemNext.TokenCName, TemListItemNext.TokenSpaceGuidCName) in GlobalData.MixedPcd[PcdItem]:\r
1042 Flag = True\r
1043 if not Flag:\r
1044 EdkLogger.error(\r
1045 'build',\r
1046 FORMAT_INVALID,\r
1047 "The TokenValue [%s] of PCD [%s.%s] is conflict with: [%s.%s] in %s"\\r
1048 % (TemListItem.TokenValue, TemListItem.TokenSpaceGuidCName, TemListItem.TokenCName, TemListItemNext.TokenSpaceGuidCName, TemListItemNext.TokenCName, Package),\r
1049 ExtraData=None\r
1050 )\r
6780eef1
LG
1051 SameTokenValuePcdListCount += 1\r
1052 Count += SameTokenValuePcdListCount\r
1053 Count += 1\r
47fea6af 1054\r
6780eef1 1055 PcdList = Package.Pcds.values()\r
47fea6af 1056 PcdList.sort(lambda x, y: cmp("%s.%s" % (x.TokenSpaceGuidCName, x.TokenCName), "%s.%s" % (y.TokenSpaceGuidCName, y.TokenCName)))\r
6780eef1
LG
1057 Count = 0\r
1058 while (Count < len(PcdList) - 1) :\r
1059 Item = PcdList[Count]\r
47fea6af 1060 ItemNext = PcdList[Count + 1]\r
6780eef1
LG
1061 #\r
1062 # Check PCDs with same TokenSpaceGuidCName.TokenCName have same token value as well.\r
1063 #\r
f827cd07 1064 if (Item.TokenSpaceGuidCName == ItemNext.TokenSpaceGuidCName) and (Item.TokenCName == ItemNext.TokenCName) and (int(Item.TokenValue, 0) != int(ItemNext.TokenValue, 0)):\r
6780eef1
LG
1065 EdkLogger.error(\r
1066 'build',\r
1067 FORMAT_INVALID,\r
1068 "The TokenValue [%s] of PCD [%s.%s] in %s defined in two places should be same as well."\\r
1069 % (Item.TokenValue, Item.TokenSpaceGuidCName, Item.TokenCName, Package),\r
1070 ExtraData=None\r
1071 )\r
1072 Count += 1\r
97fa0ee9 1073 ## Generate fds command\r
03af2753
HC
1074 def _GenFdsCommand(self):\r
1075 return (GenMake.TopLevelMakefile(self)._TEMPLATE_.Replace(GenMake.TopLevelMakefile(self)._TemplateDict)).strip()\r
52302d4d 1076\r
e56468c0 1077 ## Create makefile for the platform and modules in it\r
52302d4d
LG
1078 #\r
1079 # @param CreateDepsMakeFile Flag indicating if the makefile for\r
1080 # modules will be created as well\r
1081 #\r
1082 def CreateMakeFile(self, CreateDepsMakeFile=False):\r
52302d4d
LG
1083 if CreateDepsMakeFile:\r
1084 for Pa in self.AutoGenObjectList:\r
1085 Pa.CreateMakeFile(CreateDepsMakeFile)\r
1086\r
1087 ## Create autogen code for platform and modules\r
1088 #\r
1089 # Since there's no autogen code for platform, this method will do nothing\r
1090 # if CreateModuleCodeFile is set to False.\r
1091 #\r
1092 # @param CreateDepsCodeFile Flag indicating if creating module's\r
1093 # autogen code file or not\r
1094 #\r
1095 def CreateCodeFile(self, CreateDepsCodeFile=False):\r
1096 if not CreateDepsCodeFile:\r
1097 return\r
1098 for Pa in self.AutoGenObjectList:\r
1099 Pa.CreateCodeFile(CreateDepsCodeFile)\r
1100\r
7c1fd323
LG
1101 ## Create AsBuilt INF file the platform\r
1102 #\r
1103 def CreateAsBuiltInf(self):\r
1104 return\r
1105\r
52302d4d
LG
1106 Name = property(_GetName)\r
1107 Guid = property(_GetGuid)\r
1108 Version = property(_GetVersion)\r
1109 OutputDir = property(_GetOutputDir)\r
1110\r
1111 ToolDefinition = property(_GetToolDefinition) # toolcode : tool path\r
1112\r
1113 BuildDir = property(_GetBuildDir)\r
1114 FvDir = property(_GetFvDir)\r
1115 MakeFileDir = property(_GetMakeFileDir)\r
1116 BuildCommand = property(_GetBuildCommand)\r
03af2753 1117 GenFdsCommand = property(_GenFdsCommand)\r
52302d4d
LG
1118\r
1119## AutoGen class for platform\r
1120#\r
1121# PlatformAutoGen class will process the original information in platform\r
1122# file in order to generate makefile for platform.\r
1123#\r
1124class PlatformAutoGen(AutoGen):\r
1125 #\r
1126 # Used to store all PCDs for both PEI and DXE phase, in order to generate \r
1127 # correct PCD database\r
1128 # \r
1129 _DynaPcdList_ = []\r
1130 _NonDynaPcdList_ = []\r
61ee1dff 1131 _PlatformPcds = {}\r
6780eef1
LG
1132 \r
1133 #\r
1134 # The priority list while override build option \r
1135 #\r
1136 PrioList = {"0x11111" : 16, # TARGET_TOOLCHAIN_ARCH_COMMANDTYPE_ATTRIBUTE (Highest)\r
1137 "0x01111" : 15, # ******_TOOLCHAIN_ARCH_COMMANDTYPE_ATTRIBUTE\r
1138 "0x10111" : 14, # TARGET_*********_ARCH_COMMANDTYPE_ATTRIBUTE\r
1139 "0x00111" : 13, # ******_*********_ARCH_COMMANDTYPE_ATTRIBUTE \r
1140 "0x11011" : 12, # TARGET_TOOLCHAIN_****_COMMANDTYPE_ATTRIBUTE\r
1141 "0x01011" : 11, # ******_TOOLCHAIN_****_COMMANDTYPE_ATTRIBUTE\r
1142 "0x10011" : 10, # TARGET_*********_****_COMMANDTYPE_ATTRIBUTE\r
1143 "0x00011" : 9, # ******_*********_****_COMMANDTYPE_ATTRIBUTE\r
1144 "0x11101" : 8, # TARGET_TOOLCHAIN_ARCH_***********_ATTRIBUTE\r
1145 "0x01101" : 7, # ******_TOOLCHAIN_ARCH_***********_ATTRIBUTE\r
1146 "0x10101" : 6, # TARGET_*********_ARCH_***********_ATTRIBUTE\r
1147 "0x00101" : 5, # ******_*********_ARCH_***********_ATTRIBUTE\r
1148 "0x11001" : 4, # TARGET_TOOLCHAIN_****_***********_ATTRIBUTE\r
1149 "0x01001" : 3, # ******_TOOLCHAIN_****_***********_ATTRIBUTE\r
1150 "0x10001" : 2, # TARGET_*********_****_***********_ATTRIBUTE\r
1151 "0x00001" : 1} # ******_*********_****_***********_ATTRIBUTE (Lowest)\r
47fea6af 1152\r
52302d4d
LG
1153 ## The real constructor of PlatformAutoGen\r
1154 #\r
1155 # This method is not supposed to be called by users of PlatformAutoGen. It's\r
1156 # only used by factory method __new__() to do real initialization work for an\r
1157 # object of PlatformAutoGen\r
1158 #\r
1159 # @param Workspace WorkspaceAutoGen object\r
1160 # @param PlatformFile Platform file (DSC file)\r
1161 # @param Target Build target (DEBUG, RELEASE)\r
1162 # @param Toolchain Name of tool chain\r
1163 # @param Arch arch of the platform supports\r
1164 #\r
1165 def _Init(self, Workspace, PlatformFile, Target, Toolchain, Arch):\r
1166 EdkLogger.debug(EdkLogger.DEBUG_9, "AutoGen platform [%s] [%s]" % (PlatformFile, Arch))\r
1167 GlobalData.gProcessingFile = "%s [%s, %s, %s]" % (PlatformFile, Arch, Toolchain, Target)\r
1168\r
1169 self.MetaFile = PlatformFile\r
1170 self.Workspace = Workspace\r
1171 self.WorkspaceDir = Workspace.WorkspaceDir\r
1172 self.ToolChain = Toolchain\r
1173 self.BuildTarget = Target\r
1174 self.Arch = Arch\r
1175 self.SourceDir = PlatformFile.SubDir\r
1176 self.SourceOverrideDir = None\r
1177 self.FdTargetList = self.Workspace.FdTargetList\r
1178 self.FvTargetList = self.Workspace.FvTargetList\r
1179 self.AllPcdList = []\r
a0a2cd1e
FB
1180 # get the original module/package/platform objects\r
1181 self.BuildDatabase = Workspace.BuildDatabase\r
52302d4d
LG
1182\r
1183 # flag indicating if the makefile/C-code file has been created or not\r
1184 self.IsMakeFileCreated = False\r
1185 self.IsCodeFileCreated = False\r
1186\r
1187 self._Platform = None\r
1188 self._Name = None\r
1189 self._Guid = None\r
1190 self._Version = None\r
1191\r
1192 self._BuildRule = None\r
1193 self._SourceDir = None\r
1194 self._BuildDir = None\r
1195 self._OutputDir = None\r
1196 self._FvDir = None\r
1197 self._MakeFileDir = None\r
1198 self._FdfFile = None\r
1199\r
1200 self._PcdTokenNumber = None # (TokenCName, TokenSpaceGuidCName) : GeneratedTokenNumber\r
1201 self._DynamicPcdList = None # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]\r
1202 self._NonDynamicPcdList = None # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]\r
2bc3256c 1203 self._NonDynamicPcdDict = {}\r
52302d4d
LG
1204\r
1205 self._ToolDefinitions = None\r
1206 self._ToolDefFile = None # toolcode : tool path\r
1207 self._ToolChainFamily = None\r
1208 self._BuildRuleFamily = None\r
1209 self._BuildOption = None # toolcode : option\r
1210 self._EdkBuildOption = None # edktoolcode : option\r
1211 self._EdkIIBuildOption = None # edkiitoolcode : option\r
1212 self._PackageList = None\r
1213 self._ModuleAutoGenList = None\r
1214 self._LibraryAutoGenList = None\r
1215 self._BuildCommand = None\r
a0a2cd1e
FB
1216 self._AsBuildInfList = []\r
1217 self._AsBuildModuleList = []\r
1218 if GlobalData.gFdfParser != None:\r
1219 self._AsBuildInfList = GlobalData.gFdfParser.Profile.InfList\r
1220 for Inf in self._AsBuildInfList:\r
1221 InfClass = PathClass(NormPath(Inf), GlobalData.gWorkspace, self.Arch)\r
1222 M = self.BuildDatabase[InfClass, self.Arch, self.BuildTarget, self.ToolChain]\r
1223 if not M.IsSupportedArch:\r
1224 continue\r
1225 self._AsBuildModuleList.append(InfClass)\r
03af2753
HC
1226 # get library/modules for build\r
1227 self.LibraryBuildDirectoryList = []\r
1228 self.ModuleBuildDirectoryList = []\r
52302d4d
LG
1229 return True\r
1230\r
1231 def __repr__(self):\r
1232 return "%s [%s]" % (self.MetaFile, self.Arch)\r
1233\r
1234 ## Create autogen code for platform and modules\r
1235 #\r
1236 # Since there's no autogen code for platform, this method will do nothing\r
1237 # if CreateModuleCodeFile is set to False.\r
1238 #\r
1239 # @param CreateModuleCodeFile Flag indicating if creating module's\r
1240 # autogen code file or not\r
1241 #\r
1242 def CreateCodeFile(self, CreateModuleCodeFile=False):\r
1243 # only module has code to be greated, so do nothing if CreateModuleCodeFile is False\r
1244 if self.IsCodeFileCreated or not CreateModuleCodeFile:\r
1245 return\r
1246\r
1247 for Ma in self.ModuleAutoGenList:\r
1248 Ma.CreateCodeFile(True)\r
1249\r
1250 # don't do this twice\r
1251 self.IsCodeFileCreated = True\r
1252\r
03af2753
HC
1253 ## Generate Fds Command\r
1254 def _GenFdsCommand(self):\r
1255 return self.Workspace.GenFdsCommand\r
481252bb 1256\r
52302d4d
LG
1257 ## Create makefile for the platform and mdoules in it\r
1258 #\r
1259 # @param CreateModuleMakeFile Flag indicating if the makefile for\r
1260 # modules will be created as well\r
1261 #\r
1262 def CreateMakeFile(self, CreateModuleMakeFile=False):\r
1263 if CreateModuleMakeFile:\r
1264 for ModuleFile in self.Platform.Modules:\r
1265 Ma = ModuleAutoGen(self.Workspace, ModuleFile, self.BuildTarget,\r
1266 self.ToolChain, self.Arch, self.MetaFile)\r
1267 Ma.CreateMakeFile(True)\r
97fa0ee9 1268 #Ma.CreateAsBuiltInf()\r
52302d4d
LG
1269\r
1270 # no need to create makefile for the platform more than once\r
1271 if self.IsMakeFileCreated:\r
1272 return\r
1273\r
03af2753 1274 # create library/module build dirs for platform\r
52302d4d 1275 Makefile = GenMake.PlatformMakefile(self)\r
03af2753
HC
1276 self.LibraryBuildDirectoryList = Makefile.GetLibraryBuildDirectoryList()\r
1277 self.ModuleBuildDirectoryList = Makefile.GetModuleBuildDirectoryList()\r
1278\r
52302d4d
LG
1279 self.IsMakeFileCreated = True\r
1280\r
2bc3256c
LG
1281 ## Deal with Shared FixedAtBuild Pcds\r
1282 #\r
1283 def CollectFixedAtBuildPcds(self):\r
1284 for LibAuto in self.LibraryAutoGenList:\r
1285 FixedAtBuildPcds = {} \r
1286 ShareFixedAtBuildPcdsSameValue = {} \r
1287 for Module in LibAuto._ReferenceModules: \r
1288 for Pcd in Module.FixedAtBuildPcds + LibAuto.FixedAtBuildPcds:\r
1289 key = ".".join((Pcd.TokenSpaceGuidCName,Pcd.TokenCName)) \r
1290 if key not in FixedAtBuildPcds:\r
1291 ShareFixedAtBuildPcdsSameValue[key] = True\r
1292 FixedAtBuildPcds[key] = Pcd.DefaultValue\r
1293 else:\r
1294 if FixedAtBuildPcds[key] != Pcd.DefaultValue:\r
1295 ShareFixedAtBuildPcdsSameValue[key] = False \r
1296 for Pcd in LibAuto.FixedAtBuildPcds:\r
1297 key = ".".join((Pcd.TokenSpaceGuidCName,Pcd.TokenCName))\r
1298 if (Pcd.TokenCName,Pcd.TokenSpaceGuidCName) not in self.NonDynamicPcdDict:\r
1299 continue\r
1300 else:\r
1301 DscPcd = self.NonDynamicPcdDict[(Pcd.TokenCName,Pcd.TokenSpaceGuidCName)]\r
1302 if DscPcd.Type != "FixedAtBuild":\r
1303 continue\r
1304 if key in ShareFixedAtBuildPcdsSameValue and ShareFixedAtBuildPcdsSameValue[key]: \r
1305 LibAuto.ConstPcd[key] = Pcd.DefaultValue\r
1306\r
52302d4d
LG
1307 ## Collect dynamic PCDs\r
1308 #\r
1309 # Gather dynamic PCDs list from each module and their settings from platform\r
1310 # This interface should be invoked explicitly when platform action is created.\r
1311 #\r
1312 def CollectPlatformDynamicPcds(self):\r
763e8edf
YZ
1313 # Override the platform Pcd's value by build option\r
1314 if GlobalData.BuildOptionPcd:\r
1315 for key in self.Platform.Pcds:\r
1316 PlatformPcd = self.Platform.Pcds[key]\r
1317 for PcdItem in GlobalData.BuildOptionPcd:\r
1318 if (PlatformPcd.TokenSpaceGuidCName, PlatformPcd.TokenCName) == (PcdItem[0], PcdItem[1]):\r
1319 PlatformPcd.DefaultValue = PcdItem[2]\r
1320 if PlatformPcd.SkuInfoList:\r
1321 Sku = PlatformPcd.SkuInfoList[PlatformPcd.SkuInfoList.keys()[0]]\r
1322 Sku.DefaultValue = PcdItem[2]\r
1323 break\r
1324\r
2a29017e
YZ
1325 for key in self.Platform.Pcds:\r
1326 for SinglePcd in GlobalData.MixedPcd:\r
1327 if (self.Platform.Pcds[key].TokenCName, self.Platform.Pcds[key].TokenSpaceGuidCName) == SinglePcd:\r
1328 for item in GlobalData.MixedPcd[SinglePcd]:\r
1329 Pcd_Type = item[0].split('_')[-1]\r
1330 if (Pcd_Type == self.Platform.Pcds[key].Type) or (Pcd_Type == TAB_PCDS_DYNAMIC_EX and self.Platform.Pcds[key].Type in GenC.gDynamicExPcd) or \\r
1331 (Pcd_Type == TAB_PCDS_DYNAMIC and self.Platform.Pcds[key].Type in GenC.gDynamicPcd):\r
1332 Value = self.Platform.Pcds[key]\r
1333 Value.TokenCName = self.Platform.Pcds[key].TokenCName + '_' + Pcd_Type\r
1334 if len(key) == 2:\r
1335 newkey = (Value.TokenCName, key[1])\r
1336 elif len(key) == 3:\r
1337 newkey = (Value.TokenCName, key[1], key[2])\r
1338 del self.Platform.Pcds[key]\r
1339 self.Platform.Pcds[newkey] = Value\r
1340 break\r
1341 else:\r
1342 pass\r
1343 break\r
1344 else:\r
1345 pass\r
1346\r
52302d4d
LG
1347 # for gathering error information\r
1348 NoDatumTypePcdList = set()\r
a0a2cd1e 1349 PcdNotInDb = []\r
52302d4d 1350 self._GuidValue = {}\r
a0a2cd1e
FB
1351 FdfModuleList = []\r
1352 for InfName in self._AsBuildInfList:\r
05cc51ad 1353 InfName = mws.join(self.WorkspaceDir, InfName)\r
a0a2cd1e 1354 FdfModuleList.append(os.path.normpath(InfName))\r
52302d4d
LG
1355 for F in self.Platform.Modules.keys():\r
1356 M = ModuleAutoGen(self.Workspace, F, self.BuildTarget, self.ToolChain, self.Arch, self.MetaFile)\r
1357 #GuidValue.update(M.Guids)\r
1358 \r
1359 self.Platform.Modules[F].M = M\r
47fea6af
YZ
1360\r
1361 for PcdFromModule in M.ModulePcdList + M.LibraryPcdList:\r
52302d4d 1362 # make sure that the "VOID*" kind of datum has MaxDatumSize set\r
e8a47801 1363 if PcdFromModule.DatumType == "VOID*" and PcdFromModule.MaxDatumSize in [None, '']:\r
52302d4d
LG
1364 NoDatumTypePcdList.add("%s.%s [%s]" % (PcdFromModule.TokenSpaceGuidCName, PcdFromModule.TokenCName, F))\r
1365\r
97fa0ee9 1366 # Check the PCD from Binary INF or Source INF\r
a0a2cd1e
FB
1367 if M.IsBinaryModule == True:\r
1368 PcdFromModule.IsFromBinaryInf = True\r
97fa0ee9
YL
1369\r
1370 # Check the PCD from DSC or not \r
a0a2cd1e
FB
1371 if (PcdFromModule.TokenCName, PcdFromModule.TokenSpaceGuidCName) in self.Platform.Pcds.keys():\r
1372 PcdFromModule.IsFromDsc = True\r
1373 else:\r
1374 PcdFromModule.IsFromDsc = False\r
52302d4d 1375 if PcdFromModule.Type in GenC.gDynamicPcd or PcdFromModule.Type in GenC.gDynamicExPcd:\r
a0a2cd1e
FB
1376 if F.Path not in FdfModuleList:\r
1377 # If one of the Source built modules listed in the DSC is not listed \r
1378 # in FDF modules, and the INF lists a PCD can only use the PcdsDynamic \r
1379 # access method (it is only listed in the DEC file that declares the \r
1380 # PCD as PcdsDynamic), then build tool will report warning message\r
1381 # notify the PI that they are attempting to build a module that must \r
1382 # be included in a flash image in order to be functional. These Dynamic \r
1383 # PCD will not be added into the Database unless it is used by other \r
1384 # modules that are included in the FDF file.\r
1385 if PcdFromModule.Type in GenC.gDynamicPcd and \\r
1386 PcdFromModule.IsFromBinaryInf == False:\r
1387 # Print warning message to let the developer make a determine.\r
1388 if PcdFromModule not in PcdNotInDb:\r
a0a2cd1e
FB
1389 PcdNotInDb.append(PcdFromModule)\r
1390 continue\r
1391 # If one of the Source built modules listed in the DSC is not listed in \r
1392 # FDF modules, and the INF lists a PCD can only use the PcdsDynamicEx \r
1393 # access method (it is only listed in the DEC file that declares the \r
1394 # PCD as PcdsDynamicEx), then DO NOT break the build; DO NOT add the \r
1395 # PCD to the Platform's PCD Database.\r
1396 if PcdFromModule.Type in GenC.gDynamicExPcd:\r
1397 if PcdFromModule not in PcdNotInDb:\r
1398 PcdNotInDb.append(PcdFromModule)\r
1399 continue\r
52302d4d
LG
1400 #\r
1401 # If a dynamic PCD used by a PEM module/PEI module & DXE module,\r
1402 # it should be stored in Pcd PEI database, If a dynamic only\r
1403 # used by DXE module, it should be stored in DXE PCD database.\r
1404 # The default Phase is DXE\r
1405 #\r
1406 if M.ModuleType in ["PEIM", "PEI_CORE"]:\r
1407 PcdFromModule.Phase = "PEI"\r
1408 if PcdFromModule not in self._DynaPcdList_:\r
1409 self._DynaPcdList_.append(PcdFromModule)\r
1410 elif PcdFromModule.Phase == 'PEI':\r
1411 # overwrite any the same PCD existing, if Phase is PEI\r
1412 Index = self._DynaPcdList_.index(PcdFromModule)\r
1413 self._DynaPcdList_[Index] = PcdFromModule\r
1414 elif PcdFromModule not in self._NonDynaPcdList_:\r
1415 self._NonDynaPcdList_.append(PcdFromModule)\r
a0a2cd1e
FB
1416 elif PcdFromModule in self._NonDynaPcdList_ and PcdFromModule.IsFromBinaryInf == True:\r
1417 Index = self._NonDynaPcdList_.index(PcdFromModule)\r
1418 if self._NonDynaPcdList_[Index].IsFromBinaryInf == False:\r
1419 #The PCD from Binary INF will override the same one from source INF\r
1420 self._NonDynaPcdList_.remove (self._NonDynaPcdList_[Index])\r
1421 PcdFromModule.Pending = False\r
1422 self._NonDynaPcdList_.append (PcdFromModule)\r
1423 # Parse the DynamicEx PCD from the AsBuild INF module list of FDF.\r
1424 DscModuleList = []\r
1425 for ModuleInf in self.Platform.Modules.keys():\r
1426 DscModuleList.append (os.path.normpath(ModuleInf.Path))\r
1427 # add the PCD from modules that listed in FDF but not in DSC to Database \r
1428 for InfName in FdfModuleList:\r
1429 if InfName not in DscModuleList:\r
1430 InfClass = PathClass(InfName)\r
1431 M = self.BuildDatabase[InfClass, self.Arch, self.BuildTarget, self.ToolChain]\r
1432 # If a module INF in FDF but not in current arch's DSC module list, it must be module (either binary or source) \r
1433 # for different Arch. PCDs in source module for different Arch is already added before, so skip the source module here. \r
1434 # For binary module, if in current arch, we need to list the PCDs into database. \r
1435 if not M.IsSupportedArch:\r
1436 continue\r
1437 # Override the module PCD setting by platform setting\r
1438 ModulePcdList = self.ApplyPcdSetting(M, M.Pcds)\r
1439 for PcdFromModule in ModulePcdList:\r
1440 PcdFromModule.IsFromBinaryInf = True\r
1441 PcdFromModule.IsFromDsc = False\r
1442 # Only allow the DynamicEx and Patchable PCD in AsBuild INF\r
1443 if PcdFromModule.Type not in GenC.gDynamicExPcd and PcdFromModule.Type not in TAB_PCDS_PATCHABLE_IN_MODULE:\r
1444 EdkLogger.error("build", AUTOGEN_ERROR, "PCD setting error",\r
1445 File=self.MetaFile,\r
1446 ExtraData="\n\tExisted %s PCD %s in:\n\t\t%s\n"\r
1447 % (PcdFromModule.Type, PcdFromModule.TokenCName, InfName))\r
1448 # make sure that the "VOID*" kind of datum has MaxDatumSize set\r
1449 if PcdFromModule.DatumType == "VOID*" and PcdFromModule.MaxDatumSize in [None, '']:\r
1450 NoDatumTypePcdList.add("%s.%s [%s]" % (PcdFromModule.TokenSpaceGuidCName, PcdFromModule.TokenCName, InfName))\r
1451 if M.ModuleType in ["PEIM", "PEI_CORE"]:\r
1452 PcdFromModule.Phase = "PEI"\r
1453 if PcdFromModule not in self._DynaPcdList_ and PcdFromModule.Type in GenC.gDynamicExPcd:\r
1454 self._DynaPcdList_.append(PcdFromModule)\r
1455 elif PcdFromModule not in self._NonDynaPcdList_ and PcdFromModule.Type in TAB_PCDS_PATCHABLE_IN_MODULE:\r
1456 self._NonDynaPcdList_.append(PcdFromModule)\r
1457 if PcdFromModule in self._DynaPcdList_ and PcdFromModule.Phase == 'PEI' and PcdFromModule.Type in GenC.gDynamicExPcd:\r
97fa0ee9
YL
1458 # Overwrite the phase of any the same PCD existing, if Phase is PEI.\r
1459 # It is to solve the case that a dynamic PCD used by a PEM module/PEI \r
1460 # module & DXE module at a same time.\r
1461 # Overwrite the type of the PCDs in source INF by the type of AsBuild\r
1462 # INF file as DynamicEx. \r
a0a2cd1e
FB
1463 Index = self._DynaPcdList_.index(PcdFromModule)\r
1464 self._DynaPcdList_[Index].Phase = PcdFromModule.Phase\r
1465 self._DynaPcdList_[Index].Type = PcdFromModule.Type\r
1466 for PcdFromModule in self._NonDynaPcdList_:\r
1467 # If a PCD is not listed in the DSC file, but binary INF files used by \r
1468 # this platform all (that use this PCD) list the PCD in a [PatchPcds] \r
1469 # section, AND all source INF files used by this platform the build \r
1470 # that use the PCD list the PCD in either a [Pcds] or [PatchPcds] \r
1471 # section, then the tools must NOT add the PCD to the Platform's PCD\r
1472 # Database; the build must assign the access method for this PCD as \r
1473 # PcdsPatchableInModule.\r
1474 if PcdFromModule not in self._DynaPcdList_:\r
1475 continue\r
1476 Index = self._DynaPcdList_.index(PcdFromModule)\r
1477 if PcdFromModule.IsFromDsc == False and \\r
1478 PcdFromModule.Type in TAB_PCDS_PATCHABLE_IN_MODULE and \\r
1479 PcdFromModule.IsFromBinaryInf == True and \\r
1480 self._DynaPcdList_[Index].IsFromBinaryInf == False:\r
1481 Index = self._DynaPcdList_.index(PcdFromModule)\r
1482 self._DynaPcdList_.remove (self._DynaPcdList_[Index])\r
52302d4d
LG
1483\r
1484 # print out error information and break the build, if error found\r
1485 if len(NoDatumTypePcdList) > 0:\r
1486 NoDatumTypePcdListString = "\n\t\t".join(NoDatumTypePcdList)\r
1487 EdkLogger.error("build", AUTOGEN_ERROR, "PCD setting error",\r
1488 File=self.MetaFile,\r
1489 ExtraData="\n\tPCD(s) without MaxDatumSize:\n\t\t%s\n"\r
1490 % NoDatumTypePcdListString)\r
1491 self._NonDynamicPcdList = self._NonDynaPcdList_\r
1492 self._DynamicPcdList = self._DynaPcdList_\r
52302d4d
LG
1493 #\r
1494 # Sort dynamic PCD list to:\r
1495 # 1) If PCD's datum type is VOID* and value is unicode string which starts with L, the PCD item should \r
1496 # try to be put header of dynamicd List\r
1497 # 2) If PCD is HII type, the PCD item should be put after unicode type PCD\r
1498 #\r
1499 # The reason of sorting is make sure the unicode string is in double-byte alignment in string table.\r
1500 #\r
1501 UnicodePcdArray = []\r
1502 HiiPcdArray = []\r
1503 OtherPcdArray = []\r
6780eef1 1504 VpdPcdDict = {}\r
e56468c0 1505 VpdFile = VpdInfoFile.VpdInfoFile()\r
61ee1dff
YZ
1506 NeedProcessVpdMapFile = False\r
1507\r
1508 for pcd in self.Platform.Pcds.keys():\r
1509 if pcd not in self._PlatformPcds.keys():\r
1510 self._PlatformPcds[pcd] = self.Platform.Pcds[pcd]\r
1511\r
e56468c0 1512 if (self.Workspace.ArchList[-1] == self.Arch): \r
1513 for Pcd in self._DynamicPcdList:\r
e56468c0 1514 # just pick the a value to determine whether is unicode string type\r
47fea6af 1515 Sku = Pcd.SkuInfoList[Pcd.SkuInfoList.keys()[0]]\r
e56468c0 1516 Sku.VpdOffset = Sku.VpdOffset.strip()\r
47fea6af 1517\r
e56468c0 1518 PcdValue = Sku.DefaultValue\r
1519 if Pcd.DatumType == 'VOID*' and PcdValue.startswith("L"):\r
1520 # if found PCD which datum value is unicode string the insert to left size of UnicodeIndex\r
1521 UnicodePcdArray.append(Pcd)\r
1522 elif len(Sku.VariableName) > 0:\r
1523 # if found HII type PCD then insert to right of UnicodeIndex\r
1524 HiiPcdArray.append(Pcd)\r
1525 else:\r
1526 OtherPcdArray.append(Pcd)\r
e56468c0 1527 if Pcd.Type in [TAB_PCDS_DYNAMIC_VPD, TAB_PCDS_DYNAMIC_EX_VPD]:\r
47fea6af
YZ
1528 VpdPcdDict[(Pcd.TokenCName, Pcd.TokenSpaceGuidCName)] = Pcd\r
1529\r
61ee1dff 1530 PlatformPcds = self._PlatformPcds.keys()\r
47fea6af 1531 PlatformPcds.sort()\r
6780eef1
LG
1532 #\r
1533 # Add VPD type PCD into VpdFile and determine whether the VPD PCD need to be fixed up.\r
1534 #\r
1535 for PcdKey in PlatformPcds:\r
61ee1dff 1536 Pcd = self._PlatformPcds[PcdKey]\r
e8a47801
LG
1537 if Pcd.Type in [TAB_PCDS_DYNAMIC_VPD, TAB_PCDS_DYNAMIC_EX_VPD] and \\r
1538 PcdKey in VpdPcdDict:\r
1539 Pcd = VpdPcdDict[PcdKey]\r
1540 for (SkuName,Sku) in Pcd.SkuInfoList.items():\r
1541 Sku.VpdOffset = Sku.VpdOffset.strip()\r
5a13737a
YZ
1542 PcdValue = Sku.DefaultValue\r
1543 if PcdValue == "":\r
1544 PcdValue = Pcd.DefaultValue\r
1545 if Sku.VpdOffset != '*':\r
1546 if PcdValue.startswith("{"):\r
1547 Alignment = 8\r
1548 elif PcdValue.startswith("L"):\r
1549 Alignment = 2\r
1550 else:\r
1551 Alignment = 1\r
ca85291f
YZ
1552 try:\r
1553 VpdOffset = int(Sku.VpdOffset)\r
1554 except:\r
1555 try:\r
1556 VpdOffset = int(Sku.VpdOffset, 16)\r
1557 except:\r
1558 EdkLogger.error("build", FORMAT_INVALID, "Invalid offset value %s for PCD %s.%s." % (Sku.VpdOffset, Pcd.TokenSpaceGuidCName, Pcd.TokenCName))\r
1559 if VpdOffset % Alignment != 0:\r
815ada26
YZ
1560 if PcdValue.startswith("{"):\r
1561 EdkLogger.warn("build", "The offset value of PCD %s.%s is not 8-byte aligned!" %(Pcd.TokenSpaceGuidCName, Pcd.TokenCName), File=self.MetaFile)\r
1562 else:\r
1563 EdkLogger.error("build", FORMAT_INVALID, 'The offset value of PCD %s.%s should be %s-byte aligned.' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Alignment))\r
e8a47801
LG
1564 VpdFile.Add(Pcd, Sku.VpdOffset)\r
1565 # if the offset of a VPD is *, then it need to be fixed up by third party tool.\r
1566 if not NeedProcessVpdMapFile and Sku.VpdOffset == "*":\r
1567 NeedProcessVpdMapFile = True\r
1568 if self.Platform.VpdToolGuid == None or self.Platform.VpdToolGuid == '':\r
1569 EdkLogger.error("Build", FILE_NOT_FOUND, \\r
1570 "Fail to find third-party BPDG tool to process VPD PCDs. BPDG Guid tool need to be defined in tools_def.txt and VPD_TOOL_GUID need to be provided in DSC file.")\r
47fea6af
YZ
1571\r
1572\r
e56468c0 1573 #\r
1574 # Fix the PCDs define in VPD PCD section that never referenced by module.\r
1575 # An example is PCD for signature usage.\r
6780eef1
LG
1576 # \r
1577 for DscPcd in PlatformPcds:\r
61ee1dff 1578 DscPcdEntry = self._PlatformPcds[DscPcd]\r
e56468c0 1579 if DscPcdEntry.Type in [TAB_PCDS_DYNAMIC_VPD, TAB_PCDS_DYNAMIC_EX_VPD]:\r
1580 if not (self.Platform.VpdToolGuid == None or self.Platform.VpdToolGuid == ''):\r
1581 FoundFlag = False\r
1582 for VpdPcd in VpdFile._VpdArray.keys():\r
1583 # This PCD has been referenced by module\r
1584 if (VpdPcd.TokenSpaceGuidCName == DscPcdEntry.TokenSpaceGuidCName) and \\r
1585 (VpdPcd.TokenCName == DscPcdEntry.TokenCName):\r
1586 FoundFlag = True\r
47fea6af 1587\r
e56468c0 1588 # Not found, it should be signature\r
1589 if not FoundFlag :\r
1590 # just pick the a value to determine whether is unicode string type\r
e8a47801
LG
1591 for (SkuName,Sku) in DscPcdEntry.SkuInfoList.items():\r
1592 Sku.VpdOffset = Sku.VpdOffset.strip() \r
1593 \r
1594 # Need to iterate DEC pcd information to get the value & datumtype\r
1595 for eachDec in self.PackageList:\r
1596 for DecPcd in eachDec.Pcds:\r
1597 DecPcdEntry = eachDec.Pcds[DecPcd]\r
1598 if (DecPcdEntry.TokenSpaceGuidCName == DscPcdEntry.TokenSpaceGuidCName) and \\r
1599 (DecPcdEntry.TokenCName == DscPcdEntry.TokenCName):\r
1600 # Print warning message to let the developer make a determine.\r
1601 EdkLogger.warn("build", "Unreferenced vpd pcd used!",\r
1602 File=self.MetaFile, \\r
1603 ExtraData = "PCD: %s.%s used in the DSC file %s is unreferenced." \\r
1604 %(DscPcdEntry.TokenSpaceGuidCName, DscPcdEntry.TokenCName, self.Platform.MetaFile.Path)) \r
1605 \r
1606 DscPcdEntry.DatumType = DecPcdEntry.DatumType\r
1607 DscPcdEntry.DefaultValue = DecPcdEntry.DefaultValue\r
1608 DscPcdEntry.TokenValue = DecPcdEntry.TokenValue\r
1609 DscPcdEntry.TokenSpaceGuidValue = eachDec.Guids[DecPcdEntry.TokenSpaceGuidCName]\r
1610 # Only fix the value while no value provided in DSC file.\r
1611 if (Sku.DefaultValue == "" or Sku.DefaultValue==None):\r
1612 DscPcdEntry.SkuInfoList[DscPcdEntry.SkuInfoList.keys()[0]].DefaultValue = DecPcdEntry.DefaultValue\r
1613 \r
1614 if DscPcdEntry not in self._DynamicPcdList:\r
1615 self._DynamicPcdList.append(DscPcdEntry)\r
1616# Sku = DscPcdEntry.SkuInfoList[DscPcdEntry.SkuInfoList.keys()[0]]\r
1617 Sku.VpdOffset = Sku.VpdOffset.strip()\r
1618 PcdValue = Sku.DefaultValue\r
5a13737a
YZ
1619 if PcdValue == "":\r
1620 PcdValue = DscPcdEntry.DefaultValue\r
1621 if Sku.VpdOffset != '*':\r
1622 if PcdValue.startswith("{"):\r
1623 Alignment = 8\r
1624 elif PcdValue.startswith("L"):\r
1625 Alignment = 2\r
1626 else:\r
1627 Alignment = 1\r
ca85291f
YZ
1628 try:\r
1629 VpdOffset = int(Sku.VpdOffset)\r
1630 except:\r
1631 try:\r
1632 VpdOffset = int(Sku.VpdOffset, 16)\r
1633 except:\r
1634 EdkLogger.error("build", FORMAT_INVALID, "Invalid offset value %s for PCD %s.%s." % (Sku.VpdOffset, DscPcdEntry.TokenSpaceGuidCName, DscPcdEntry.TokenCName))\r
1635 if VpdOffset % Alignment != 0:\r
815ada26
YZ
1636 if PcdValue.startswith("{"):\r
1637 EdkLogger.warn("build", "The offset value of PCD %s.%s is not 8-byte aligned!" %(DscPcdEntry.TokenSpaceGuidCName, DscPcdEntry.TokenCName), File=self.MetaFile)\r
1638 else:\r
1639 EdkLogger.error("build", FORMAT_INVALID, 'The offset value of PCD %s.%s should be %s-byte aligned.' % (DscPcdEntry.TokenSpaceGuidCName, DscPcdEntry.TokenCName, Alignment))\r
e8a47801
LG
1640 VpdFile.Add(DscPcdEntry, Sku.VpdOffset)\r
1641 if not NeedProcessVpdMapFile and Sku.VpdOffset == "*":\r
1642 NeedProcessVpdMapFile = True \r
1643 if DscPcdEntry.DatumType == 'VOID*' and PcdValue.startswith("L"):\r
1644 UnicodePcdArray.append(DscPcdEntry)\r
1645 elif len(Sku.VariableName) > 0:\r
1646 HiiPcdArray.append(DscPcdEntry)\r
1647 else:\r
1648 OtherPcdArray.append(DscPcdEntry)\r
1649 \r
1650 # if the offset of a VPD is *, then it need to be fixed up by third party tool.\r
e56468c0 1651 \r
e56468c0 1652 \r
1653 \r
1654 if (self.Platform.FlashDefinition == None or self.Platform.FlashDefinition == '') and \\r
1655 VpdFile.GetCount() != 0:\r
1656 EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, \r
1657 "Fail to get FLASH_DEFINITION definition in DSC file %s which is required when DSC contains VPD PCD." % str(self.Platform.MetaFile))\r
47fea6af 1658\r
e56468c0 1659 if VpdFile.GetCount() != 0:\r
e56468c0 1660 FvPath = os.path.join(self.BuildDir, "FV")\r
1661 if not os.path.exists(FvPath):\r
1662 try:\r
1663 os.makedirs(FvPath)\r
1664 except:\r
1665 EdkLogger.error("build", FILE_WRITE_FAILURE, "Fail to create FV folder under %s" % self.BuildDir)\r
47fea6af 1666\r
08dd311f
LG
1667 VpdFilePath = os.path.join(FvPath, "%s.txt" % self.Platform.VpdToolGuid)\r
1668\r
e459de78 1669 if VpdFile.Write(VpdFilePath):\r
e56468c0 1670 # retrieve BPDG tool's path from tool_def.txt according to VPD_TOOL_GUID defined in DSC file.\r
1671 BPDGToolName = None\r
1672 for ToolDef in self.ToolDefinition.values():\r
1673 if ToolDef.has_key("GUID") and ToolDef["GUID"] == self.Platform.VpdToolGuid:\r
1674 if not ToolDef.has_key("PATH"):\r
1675 EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, "PATH attribute was not provided for BPDG guid tool %s in tools_def.txt" % self.Platform.VpdToolGuid)\r
1676 BPDGToolName = ToolDef["PATH"]\r
1677 break\r
1678 # Call third party GUID BPDG tool.\r
1679 if BPDGToolName != None:\r
08dd311f 1680 VpdInfoFile.CallExtenalBPDGTool(BPDGToolName, VpdFilePath)\r
e56468c0 1681 else:\r
1682 EdkLogger.error("Build", FILE_NOT_FOUND, "Fail to find third-party BPDG tool to process VPD PCDs. BPDG Guid tool need to be defined in tools_def.txt and VPD_TOOL_GUID need to be provided in DSC file.")\r
47fea6af 1683\r
e56468c0 1684 # Process VPD map file generated by third party BPDG tool\r
1685 if NeedProcessVpdMapFile:\r
08dd311f 1686 VpdMapFilePath = os.path.join(self.BuildDir, "FV", "%s.map" % self.Platform.VpdToolGuid)\r
e56468c0 1687 if os.path.exists(VpdMapFilePath):\r
1688 VpdFile.Read(VpdMapFilePath)\r
47fea6af 1689\r
e56468c0 1690 # Fixup "*" offset\r
1691 for Pcd in self._DynamicPcdList:\r
1692 # just pick the a value to determine whether is unicode string type\r
e8a47801
LG
1693 i = 0\r
1694 for (SkuName,Sku) in Pcd.SkuInfoList.items(): \r
1695 if Sku.VpdOffset == "*":\r
1696 Sku.VpdOffset = VpdFile.GetOffset(Pcd)[i].strip()\r
1697 i += 1\r
e56468c0 1698 else:\r
1699 EdkLogger.error("build", FILE_READ_FAILURE, "Can not find VPD map file %s to fix up VPD offset." % VpdMapFilePath)\r
47fea6af 1700\r
e56468c0 1701 # Delete the DynamicPcdList At the last time enter into this function \r
47fea6af 1702 del self._DynamicPcdList[:]\r
52302d4d
LG
1703 self._DynamicPcdList.extend(UnicodePcdArray)\r
1704 self._DynamicPcdList.extend(HiiPcdArray)\r
1705 self._DynamicPcdList.extend(OtherPcdArray)\r
a0a2cd1e 1706 self.AllPcdList = self._NonDynamicPcdList + self._DynamicPcdList\r
52302d4d
LG
1707 \r
1708 ## Return the platform build data object\r
1709 def _GetPlatform(self):\r
1710 if self._Platform == None:\r
0d2711a6 1711 self._Platform = self.BuildDatabase[self.MetaFile, self.Arch, self.BuildTarget, self.ToolChain]\r
52302d4d
LG
1712 return self._Platform\r
1713\r
1714 ## Return platform name\r
1715 def _GetName(self):\r
1716 return self.Platform.PlatformName\r
1717\r
1718 ## Return the meta file GUID\r
1719 def _GetGuid(self):\r
1720 return self.Platform.Guid\r
1721\r
1722 ## Return the platform version\r
1723 def _GetVersion(self):\r
1724 return self.Platform.Version\r
1725\r
1726 ## Return the FDF file name\r
1727 def _GetFdfFile(self):\r
1728 if self._FdfFile == None:\r
1729 if self.Workspace.FdfFile != "":\r
05cc51ad 1730 self._FdfFile= mws.join(self.WorkspaceDir, self.Workspace.FdfFile)\r
52302d4d
LG
1731 else:\r
1732 self._FdfFile = ''\r
1733 return self._FdfFile\r
1734\r
1735 ## Return the build output directory platform specifies\r
1736 def _GetOutputDir(self):\r
1737 return self.Platform.OutputDirectory\r
1738\r
1739 ## Return the directory to store all intermediate and final files built\r
1740 def _GetBuildDir(self):\r
1741 if self._BuildDir == None:\r
1742 if os.path.isabs(self.OutputDir):\r
1743 self._BuildDir = path.join(\r
1744 path.abspath(self.OutputDir),\r
1745 self.BuildTarget + "_" + self.ToolChain,\r
1746 )\r
1747 else:\r
1748 self._BuildDir = path.join(\r
1749 self.WorkspaceDir,\r
1750 self.OutputDir,\r
1751 self.BuildTarget + "_" + self.ToolChain,\r
1752 )\r
1753 return self._BuildDir\r
1754\r
1755 ## Return directory of platform makefile\r
1756 #\r
1757 # @retval string Makefile directory\r
1758 #\r
1759 def _GetMakeFileDir(self):\r
1760 if self._MakeFileDir == None:\r
1761 self._MakeFileDir = path.join(self.BuildDir, self.Arch)\r
1762 return self._MakeFileDir\r
1763\r
1764 ## Return build command string\r
1765 #\r
1766 # @retval string Build command string\r
1767 #\r
1768 def _GetBuildCommand(self):\r
1769 if self._BuildCommand == None:\r
1770 self._BuildCommand = []\r
1771 if "MAKE" in self.ToolDefinition and "PATH" in self.ToolDefinition["MAKE"]:\r
1772 self._BuildCommand += SplitOption(self.ToolDefinition["MAKE"]["PATH"])\r
1773 if "FLAGS" in self.ToolDefinition["MAKE"]:\r
1774 NewOption = self.ToolDefinition["MAKE"]["FLAGS"].strip()\r
1775 if NewOption != '':\r
6780eef1 1776 self._BuildCommand += SplitOption(NewOption)\r
52302d4d
LG
1777 return self._BuildCommand\r
1778\r
1779 ## Get tool chain definition\r
1780 #\r
1781 # Get each tool defition for given tool chain from tools_def.txt and platform\r
1782 #\r
1783 def _GetToolDefinition(self):\r
1784 if self._ToolDefinitions == None:\r
1785 ToolDefinition = self.Workspace.ToolDef.ToolsDefTxtDictionary\r
1786 if TAB_TOD_DEFINES_COMMAND_TYPE not in self.Workspace.ToolDef.ToolsDefTxtDatabase:\r
1787 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, "No tools found in configuration",\r
1788 ExtraData="[%s]" % self.MetaFile)\r
1789 self._ToolDefinitions = {}\r
1790 DllPathList = set()\r
1791 for Def in ToolDefinition:\r
1792 Target, Tag, Arch, Tool, Attr = Def.split("_")\r
1793 if Target != self.BuildTarget or Tag != self.ToolChain or Arch != self.Arch:\r
1794 continue\r
1795\r
1796 Value = ToolDefinition[Def]\r
1797 # don't record the DLL\r
1798 if Attr == "DLL":\r
1799 DllPathList.add(Value)\r
1800 continue\r
1801\r
1802 if Tool not in self._ToolDefinitions:\r
1803 self._ToolDefinitions[Tool] = {}\r
1804 self._ToolDefinitions[Tool][Attr] = Value\r
1805\r
1806 ToolsDef = ''\r
1807 MakePath = ''\r
1808 if GlobalData.gOptions.SilentMode and "MAKE" in self._ToolDefinitions:\r
1809 if "FLAGS" not in self._ToolDefinitions["MAKE"]:\r
1810 self._ToolDefinitions["MAKE"]["FLAGS"] = ""\r
1811 self._ToolDefinitions["MAKE"]["FLAGS"] += " -s"\r
1812 MakeFlags = ''\r
1813 for Tool in self._ToolDefinitions:\r
1814 for Attr in self._ToolDefinitions[Tool]:\r
1815 Value = self._ToolDefinitions[Tool][Attr]\r
1816 if Tool in self.BuildOption and Attr in self.BuildOption[Tool]:\r
1817 # check if override is indicated\r
1818 if self.BuildOption[Tool][Attr].startswith('='):\r
1819 Value = self.BuildOption[Tool][Attr][1:]\r
1820 else:\r
95816356
YZ
1821 if Attr != 'PATH':\r
1822 Value += " " + self.BuildOption[Tool][Attr]\r
1823 else:\r
1824 Value = self.BuildOption[Tool][Attr]\r
52302d4d
LG
1825\r
1826 if Attr == "PATH":\r
1827 # Don't put MAKE definition in the file\r
1828 if Tool == "MAKE":\r
1829 MakePath = Value\r
1830 else:\r
1831 ToolsDef += "%s = %s\n" % (Tool, Value)\r
1832 elif Attr != "DLL":\r
1833 # Don't put MAKE definition in the file\r
1834 if Tool == "MAKE":\r
1835 if Attr == "FLAGS":\r
1836 MakeFlags = Value\r
1837 else:\r
1838 ToolsDef += "%s_%s = %s\n" % (Tool, Attr, Value)\r
1839 ToolsDef += "\n"\r
1840\r
1841 SaveFileOnChange(self.ToolDefinitionFile, ToolsDef)\r
1842 for DllPath in DllPathList:\r
1843 os.environ["PATH"] = DllPath + os.pathsep + os.environ["PATH"]\r
1844 os.environ["MAKE_FLAGS"] = MakeFlags\r
1845\r
1846 return self._ToolDefinitions\r
1847\r
1848 ## Return the paths of tools\r
1849 def _GetToolDefFile(self):\r
1850 if self._ToolDefFile == None:\r
1851 self._ToolDefFile = os.path.join(self.MakeFileDir, "TOOLS_DEF." + self.Arch)\r
1852 return self._ToolDefFile\r
1853\r
1854 ## Retrieve the toolchain family of given toolchain tag. Default to 'MSFT'.\r
1855 def _GetToolChainFamily(self):\r
1856 if self._ToolChainFamily == None:\r
1857 ToolDefinition = self.Workspace.ToolDef.ToolsDefTxtDatabase\r
1858 if TAB_TOD_DEFINES_FAMILY not in ToolDefinition \\r
1859 or self.ToolChain not in ToolDefinition[TAB_TOD_DEFINES_FAMILY] \\r
1860 or not ToolDefinition[TAB_TOD_DEFINES_FAMILY][self.ToolChain]:\r
1861 EdkLogger.verbose("No tool chain family found in configuration for %s. Default to MSFT." \\r
1862 % self.ToolChain)\r
1863 self._ToolChainFamily = "MSFT"\r
1864 else:\r
1865 self._ToolChainFamily = ToolDefinition[TAB_TOD_DEFINES_FAMILY][self.ToolChain]\r
1866 return self._ToolChainFamily\r
1867\r
1868 def _GetBuildRuleFamily(self):\r
1869 if self._BuildRuleFamily == None:\r
1870 ToolDefinition = self.Workspace.ToolDef.ToolsDefTxtDatabase\r
1871 if TAB_TOD_DEFINES_BUILDRULEFAMILY not in ToolDefinition \\r
1872 or self.ToolChain not in ToolDefinition[TAB_TOD_DEFINES_BUILDRULEFAMILY] \\r
1873 or not ToolDefinition[TAB_TOD_DEFINES_BUILDRULEFAMILY][self.ToolChain]:\r
1874 EdkLogger.verbose("No tool chain family found in configuration for %s. Default to MSFT." \\r
1875 % self.ToolChain)\r
1876 self._BuildRuleFamily = "MSFT"\r
1877 else:\r
1878 self._BuildRuleFamily = ToolDefinition[TAB_TOD_DEFINES_BUILDRULEFAMILY][self.ToolChain]\r
1879 return self._BuildRuleFamily\r
1880\r
1881 ## Return the build options specific for all modules in this platform\r
1882 def _GetBuildOptions(self):\r
1883 if self._BuildOption == None:\r
1884 self._BuildOption = self._ExpandBuildOption(self.Platform.BuildOptions)\r
1885 return self._BuildOption\r
1886\r
1887 ## Return the build options specific for EDK modules in this platform\r
1888 def _GetEdkBuildOptions(self):\r
1889 if self._EdkBuildOption == None:\r
1890 self._EdkBuildOption = self._ExpandBuildOption(self.Platform.BuildOptions, EDK_NAME)\r
1891 return self._EdkBuildOption\r
1892\r
1893 ## Return the build options specific for EDKII modules in this platform\r
1894 def _GetEdkIIBuildOptions(self):\r
1895 if self._EdkIIBuildOption == None:\r
1896 self._EdkIIBuildOption = self._ExpandBuildOption(self.Platform.BuildOptions, EDKII_NAME)\r
1897 return self._EdkIIBuildOption\r
1898\r
97fa0ee9 1899 ## Parse build_rule.txt in Conf Directory.\r
52302d4d
LG
1900 #\r
1901 # @retval BuildRule object\r
1902 #\r
1903 def _GetBuildRule(self):\r
1904 if self._BuildRule == None:\r
1905 BuildRuleFile = None\r
1906 if TAB_TAT_DEFINES_BUILD_RULE_CONF in self.Workspace.TargetTxt.TargetTxtDictionary:\r
1907 BuildRuleFile = self.Workspace.TargetTxt.TargetTxtDictionary[TAB_TAT_DEFINES_BUILD_RULE_CONF]\r
1908 if BuildRuleFile in [None, '']:\r
97fa0ee9 1909 BuildRuleFile = gDefaultBuildRuleFile\r
52302d4d 1910 self._BuildRule = BuildRule(BuildRuleFile)\r
64b2609f
LG
1911 if self._BuildRule._FileVersion == "":\r
1912 self._BuildRule._FileVersion = AutoGenReqBuildRuleVerNum\r
1913 else:\r
1914 if self._BuildRule._FileVersion < AutoGenReqBuildRuleVerNum :\r
1915 # If Build Rule's version is less than the version number required by the tools, halting the build.\r
47fea6af 1916 EdkLogger.error("build", AUTOGEN_ERROR,\r
64b2609f
LG
1917 ExtraData="The version number [%s] of build_rule.txt is less than the version number required by the AutoGen.(the minimum required version number is [%s])"\\r
1918 % (self._BuildRule._FileVersion, AutoGenReqBuildRuleVerNum))\r
47fea6af 1919\r
52302d4d
LG
1920 return self._BuildRule\r
1921\r
1922 ## Summarize the packages used by modules in this platform\r
1923 def _GetPackageList(self):\r
1924 if self._PackageList == None:\r
1925 self._PackageList = set()\r
1926 for La in self.LibraryAutoGenList:\r
1927 self._PackageList.update(La.DependentPackageList)\r
1928 for Ma in self.ModuleAutoGenList:\r
1929 self._PackageList.update(Ma.DependentPackageList)\r
a0a2cd1e
FB
1930 #Collect package set information from INF of FDF\r
1931 PkgSet = set()\r
1932 for ModuleFile in self._AsBuildModuleList:\r
1933 if ModuleFile in self.Platform.Modules:\r
1934 continue\r
1935 ModuleData = self.BuildDatabase[ModuleFile, self.Arch, self.BuildTarget, self.ToolChain]\r
1936 PkgSet.update(ModuleData.Packages)\r
1937 self._PackageList = list(self._PackageList) + list (PkgSet)\r
52302d4d
LG
1938 return self._PackageList\r
1939\r
2bc3256c
LG
1940 def _GetNonDynamicPcdDict(self):\r
1941 if self._NonDynamicPcdDict:\r
1942 return self._NonDynamicPcdDict\r
1943 for Pcd in self.NonDynamicPcdList:\r
1944 self._NonDynamicPcdDict[(Pcd.TokenCName,Pcd.TokenSpaceGuidCName)] = Pcd\r
1945 return self._NonDynamicPcdDict\r
1946\r
52302d4d
LG
1947 ## Get list of non-dynamic PCDs\r
1948 def _GetNonDynamicPcdList(self):\r
e56468c0 1949 if self._NonDynamicPcdList == None:\r
1950 self.CollectPlatformDynamicPcds()\r
52302d4d
LG
1951 return self._NonDynamicPcdList\r
1952\r
1953 ## Get list of dynamic PCDs\r
1954 def _GetDynamicPcdList(self):\r
e56468c0 1955 if self._DynamicPcdList == None:\r
1956 self.CollectPlatformDynamicPcds()\r
52302d4d
LG
1957 return self._DynamicPcdList\r
1958\r
1959 ## Generate Token Number for all PCD\r
1960 def _GetPcdTokenNumbers(self):\r
1961 if self._PcdTokenNumber == None:\r
1962 self._PcdTokenNumber = sdict()\r
1963 TokenNumber = 1\r
d0acc87a
LG
1964 #\r
1965 # Make the Dynamic and DynamicEx PCD use within different TokenNumber area. \r
1966 # Such as:\r
1967 # \r
1968 # Dynamic PCD:\r
1969 # TokenNumber 0 ~ 10\r
1970 # DynamicEx PCD:\r
1971 # TokeNumber 11 ~ 20\r
1972 #\r
52302d4d
LG
1973 for Pcd in self.DynamicPcdList:\r
1974 if Pcd.Phase == "PEI":\r
d0acc87a
LG
1975 if Pcd.Type in ["Dynamic", "DynamicDefault", "DynamicVpd", "DynamicHii"]:\r
1976 EdkLogger.debug(EdkLogger.DEBUG_5, "%s %s (%s) -> %d" % (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Pcd.Phase, TokenNumber))\r
1977 self._PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber\r
1978 TokenNumber += 1\r
47fea6af 1979\r
d0acc87a
LG
1980 for Pcd in self.DynamicPcdList:\r
1981 if Pcd.Phase == "PEI":\r
1982 if Pcd.Type in ["DynamicEx", "DynamicExDefault", "DynamicExVpd", "DynamicExHii"]:\r
1983 EdkLogger.debug(EdkLogger.DEBUG_5, "%s %s (%s) -> %d" % (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Pcd.Phase, TokenNumber))\r
1984 self._PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber\r
1985 TokenNumber += 1\r
47fea6af 1986\r
52302d4d
LG
1987 for Pcd in self.DynamicPcdList:\r
1988 if Pcd.Phase == "DXE":\r
d0acc87a
LG
1989 if Pcd.Type in ["Dynamic", "DynamicDefault", "DynamicVpd", "DynamicHii"]:\r
1990 EdkLogger.debug(EdkLogger.DEBUG_5, "%s %s (%s) -> %d" % (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Pcd.Phase, TokenNumber))\r
1991 self._PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber\r
1992 TokenNumber += 1\r
47fea6af 1993\r
d0acc87a
LG
1994 for Pcd in self.DynamicPcdList:\r
1995 if Pcd.Phase == "DXE":\r
1996 if Pcd.Type in ["DynamicEx", "DynamicExDefault", "DynamicExVpd", "DynamicExHii"]:\r
1997 EdkLogger.debug(EdkLogger.DEBUG_5, "%s %s (%s) -> %d" % (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Pcd.Phase, TokenNumber))\r
1998 self._PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber\r
1999 TokenNumber += 1\r
47fea6af 2000\r
52302d4d
LG
2001 for Pcd in self.NonDynamicPcdList:\r
2002 self._PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber\r
2003 TokenNumber += 1\r
2004 return self._PcdTokenNumber\r
2005\r
2006 ## Summarize ModuleAutoGen objects of all modules/libraries to be built for this platform\r
2007 def _GetAutoGenObjectList(self):\r
2008 self._ModuleAutoGenList = []\r
2009 self._LibraryAutoGenList = []\r
2010 for ModuleFile in self.Platform.Modules:\r
2011 Ma = ModuleAutoGen(\r
2012 self.Workspace,\r
2013 ModuleFile,\r
2014 self.BuildTarget,\r
2015 self.ToolChain,\r
2016 self.Arch,\r
2017 self.MetaFile\r
2018 )\r
2019 if Ma not in self._ModuleAutoGenList:\r
2020 self._ModuleAutoGenList.append(Ma)\r
2021 for La in Ma.LibraryAutoGenList:\r
2022 if La not in self._LibraryAutoGenList:\r
2023 self._LibraryAutoGenList.append(La)\r
2bc3256c
LG
2024 if Ma not in La._ReferenceModules:\r
2025 La._ReferenceModules.append(Ma)\r
52302d4d
LG
2026\r
2027 ## Summarize ModuleAutoGen objects of all modules to be built for this platform\r
2028 def _GetModuleAutoGenList(self):\r
2029 if self._ModuleAutoGenList == None:\r
2030 self._GetAutoGenObjectList()\r
2031 return self._ModuleAutoGenList\r
2032\r
2033 ## Summarize ModuleAutoGen objects of all libraries to be built for this platform\r
2034 def _GetLibraryAutoGenList(self):\r
2035 if self._LibraryAutoGenList == None:\r
2036 self._GetAutoGenObjectList()\r
2037 return self._LibraryAutoGenList\r
2038\r
2039 ## Test if a module is supported by the platform\r
2040 #\r
2041 # An error will be raised directly if the module or its arch is not supported\r
2042 # by the platform or current configuration\r
2043 #\r
2044 def ValidModule(self, Module):\r
a0a2cd1e
FB
2045 return Module in self.Platform.Modules or Module in self.Platform.LibraryInstances \\r
2046 or Module in self._AsBuildModuleList\r
52302d4d
LG
2047\r
2048 ## Resolve the library classes in a module to library instances\r
2049 #\r
2050 # This method will not only resolve library classes but also sort the library\r
2051 # instances according to the dependency-ship.\r
2052 #\r
2053 # @param Module The module from which the library classes will be resolved\r
2054 #\r
2055 # @retval library_list List of library instances sorted\r
2056 #\r
2057 def ApplyLibraryInstance(self, Module):\r
25193a33
YZ
2058 # Cover the case that the binary INF file is list in the FDF file but not DSC file, return empty list directly\r
2059 if str(Module) not in self.Platform.Modules:\r
2060 return []\r
2061\r
52302d4d
LG
2062 ModuleType = Module.ModuleType\r
2063\r
2064 # for overridding library instances with module specific setting\r
2065 PlatformModule = self.Platform.Modules[str(Module)]\r
2066\r
2067 # add forced library instances (specified under LibraryClasses sections)\r
da92f276
LG
2068 #\r
2069 # If a module has a MODULE_TYPE of USER_DEFINED,\r
2070 # do not link in NULL library class instances from the global [LibraryClasses.*] sections.\r
2071 #\r
2072 if Module.ModuleType != SUP_MODULE_USER_DEFINED:\r
2073 for LibraryClass in self.Platform.LibraryClasses.GetKeys():\r
2074 if LibraryClass.startswith("NULL") and self.Platform.LibraryClasses[LibraryClass, Module.ModuleType]:\r
2075 Module.LibraryClasses[LibraryClass] = self.Platform.LibraryClasses[LibraryClass, Module.ModuleType]\r
52302d4d
LG
2076\r
2077 # add forced library instances (specified in module overrides)\r
2078 for LibraryClass in PlatformModule.LibraryClasses:\r
2079 if LibraryClass.startswith("NULL"):\r
2080 Module.LibraryClasses[LibraryClass] = PlatformModule.LibraryClasses[LibraryClass]\r
2081\r
b36d134f 2082 # EdkII module\r
52302d4d
LG
2083 LibraryConsumerList = [Module]\r
2084 Constructor = []\r
2085 ConsumedByList = sdict()\r
2086 LibraryInstance = sdict()\r
2087\r
2088 EdkLogger.verbose("")\r
2089 EdkLogger.verbose("Library instances of module [%s] [%s]:" % (str(Module), self.Arch))\r
2090 while len(LibraryConsumerList) > 0:\r
2091 M = LibraryConsumerList.pop()\r
2092 for LibraryClassName in M.LibraryClasses:\r
2093 if LibraryClassName not in LibraryInstance:\r
2094 # override library instance for this module\r
2095 if LibraryClassName in PlatformModule.LibraryClasses:\r
2096 LibraryPath = PlatformModule.LibraryClasses[LibraryClassName]\r
2097 else:\r
2098 LibraryPath = self.Platform.LibraryClasses[LibraryClassName, ModuleType]\r
2099 if LibraryPath == None or LibraryPath == "":\r
2100 LibraryPath = M.LibraryClasses[LibraryClassName]\r
2101 if LibraryPath == None or LibraryPath == "":\r
2102 EdkLogger.error("build", RESOURCE_NOT_AVAILABLE,\r
2103 "Instance of library class [%s] is not found" % LibraryClassName,\r
2104 File=self.MetaFile,\r
2105 ExtraData="in [%s] [%s]\n\tconsumed by module [%s]" % (str(M), self.Arch, str(Module)))\r
2106\r
0d2711a6 2107 LibraryModule = self.BuildDatabase[LibraryPath, self.Arch, self.BuildTarget, self.ToolChain]\r
52302d4d
LG
2108 # for those forced library instance (NULL library), add a fake library class\r
2109 if LibraryClassName.startswith("NULL"):\r
2110 LibraryModule.LibraryClass.append(LibraryClassObject(LibraryClassName, [ModuleType]))\r
2111 elif LibraryModule.LibraryClass == None \\r
2112 or len(LibraryModule.LibraryClass) == 0 \\r
2113 or (ModuleType != 'USER_DEFINED'\r
2114 and ModuleType not in LibraryModule.LibraryClass[0].SupModList):\r
2115 # only USER_DEFINED can link against any library instance despite of its SupModList\r
2116 EdkLogger.error("build", OPTION_MISSING,\r
2117 "Module type [%s] is not supported by library instance [%s]" \\r
2118 % (ModuleType, LibraryPath), File=self.MetaFile,\r
2119 ExtraData="consumed by [%s]" % str(Module))\r
2120\r
2121 LibraryInstance[LibraryClassName] = LibraryModule\r
2122 LibraryConsumerList.append(LibraryModule)\r
2123 EdkLogger.verbose("\t" + str(LibraryClassName) + " : " + str(LibraryModule))\r
2124 else:\r
2125 LibraryModule = LibraryInstance[LibraryClassName]\r
2126\r
2127 if LibraryModule == None:\r
2128 continue\r
2129\r
2130 if LibraryModule.ConstructorList != [] and LibraryModule not in Constructor:\r
2131 Constructor.append(LibraryModule)\r
2132\r
2133 if LibraryModule not in ConsumedByList:\r
2134 ConsumedByList[LibraryModule] = []\r
2135 # don't add current module itself to consumer list\r
2136 if M != Module:\r
2137 if M in ConsumedByList[LibraryModule]:\r
2138 continue\r
2139 ConsumedByList[LibraryModule].append(M)\r
2140 #\r
2141 # Initialize the sorted output list to the empty set\r
2142 #\r
2143 SortedLibraryList = []\r
2144 #\r
2145 # Q <- Set of all nodes with no incoming edges\r
2146 #\r
2147 LibraryList = [] #LibraryInstance.values()\r
2148 Q = []\r
2149 for LibraryClassName in LibraryInstance:\r
2150 M = LibraryInstance[LibraryClassName]\r
2151 LibraryList.append(M)\r
2152 if ConsumedByList[M] == []:\r
2153 Q.append(M)\r
2154\r
2155 #\r
2156 # start the DAG algorithm\r
2157 #\r
2158 while True:\r
2159 EdgeRemoved = True\r
2160 while Q == [] and EdgeRemoved:\r
2161 EdgeRemoved = False\r
2162 # for each node Item with a Constructor\r
2163 for Item in LibraryList:\r
2164 if Item not in Constructor:\r
2165 continue\r
2166 # for each Node without a constructor with an edge e from Item to Node\r
2167 for Node in ConsumedByList[Item]:\r
2168 if Node in Constructor:\r
2169 continue\r
2170 # remove edge e from the graph if Node has no constructor\r
2171 ConsumedByList[Item].remove(Node)\r
2172 EdgeRemoved = True\r
2173 if ConsumedByList[Item] == []:\r
2174 # insert Item into Q\r
2175 Q.insert(0, Item)\r
2176 break\r
2177 if Q != []:\r
2178 break\r
2179 # DAG is done if there's no more incoming edge for all nodes\r
2180 if Q == []:\r
2181 break\r
2182\r
2183 # remove node from Q\r
2184 Node = Q.pop()\r
2185 # output Node\r
2186 SortedLibraryList.append(Node)\r
2187\r
2188 # for each node Item with an edge e from Node to Item do\r
2189 for Item in LibraryList:\r
2190 if Node not in ConsumedByList[Item]:\r
2191 continue\r
2192 # remove edge e from the graph\r
2193 ConsumedByList[Item].remove(Node)\r
2194\r
2195 if ConsumedByList[Item] != []:\r
2196 continue\r
2197 # insert Item into Q, if Item has no other incoming edges\r
2198 Q.insert(0, Item)\r
2199\r
2200 #\r
2201 # if any remaining node Item in the graph has a constructor and an incoming edge, then the graph has a cycle\r
2202 #\r
2203 for Item in LibraryList:\r
2204 if ConsumedByList[Item] != [] and Item in Constructor and len(Constructor) > 1:\r
2205 ErrorMessage = "\tconsumed by " + "\n\tconsumed by ".join([str(L) for L in ConsumedByList[Item]])\r
2206 EdkLogger.error("build", BUILD_ERROR, 'Library [%s] with constructors has a cycle' % str(Item),\r
2207 ExtraData=ErrorMessage, File=self.MetaFile)\r
2208 if Item not in SortedLibraryList:\r
2209 SortedLibraryList.append(Item)\r
2210\r
2211 #\r
2212 # Build the list of constructor and destructir names\r
2213 # The DAG Topo sort produces the destructor order, so the list of constructors must generated in the reverse order\r
2214 #\r
2215 SortedLibraryList.reverse()\r
2216 return SortedLibraryList\r
2217\r
2218\r
2219 ## Override PCD setting (type, value, ...)\r
2220 #\r
2221 # @param ToPcd The PCD to be overrided\r
2222 # @param FromPcd The PCD overrideing from\r
2223 #\r
2224 def _OverridePcd(self, ToPcd, FromPcd, Module=""):\r
2225 #\r
2226 # in case there's PCDs coming from FDF file, which have no type given.\r
2227 # at this point, ToPcd.Type has the type found from dependent\r
2228 # package\r
2229 #\r
2a29017e
YZ
2230 TokenCName = ToPcd.TokenCName\r
2231 for PcdItem in GlobalData.MixedPcd:\r
2232 if (ToPcd.TokenCName, ToPcd.TokenSpaceGuidCName) in GlobalData.MixedPcd[PcdItem]:\r
2233 TokenCName = PcdItem[0]\r
2234 break\r
52302d4d 2235 if FromPcd != None:\r
2a29017e
YZ
2236 if GlobalData.BuildOptionPcd:\r
2237 for pcd in GlobalData.BuildOptionPcd:\r
2238 if (FromPcd.TokenSpaceGuidCName, FromPcd.TokenCName) == (pcd[0], pcd[1]):\r
2239 FromPcd.DefaultValue = pcd[2]\r
2240 break\r
52302d4d
LG
2241 if ToPcd.Pending and FromPcd.Type not in [None, '']:\r
2242 ToPcd.Type = FromPcd.Type\r
e56468c0 2243 elif (ToPcd.Type not in [None, '']) and (FromPcd.Type not in [None, ''])\\r
2244 and (ToPcd.Type != FromPcd.Type) and (ToPcd.Type in FromPcd.Type):\r
2245 if ToPcd.Type.strip() == "DynamicEx":\r
47fea6af 2246 ToPcd.Type = FromPcd.Type\r
52302d4d
LG
2247 elif ToPcd.Type not in [None, ''] and FromPcd.Type not in [None, ''] \\r
2248 and ToPcd.Type != FromPcd.Type:\r
2249 EdkLogger.error("build", OPTION_CONFLICT, "Mismatched PCD type",\r
2250 ExtraData="%s.%s is defined as [%s] in module %s, but as [%s] in platform."\\r
2a29017e 2251 % (ToPcd.TokenSpaceGuidCName, TokenCName,\r
52302d4d
LG
2252 ToPcd.Type, Module, FromPcd.Type),\r
2253 File=self.MetaFile)\r
2254\r
2255 if FromPcd.MaxDatumSize not in [None, '']:\r
2256 ToPcd.MaxDatumSize = FromPcd.MaxDatumSize\r
2257 if FromPcd.DefaultValue not in [None, '']:\r
2258 ToPcd.DefaultValue = FromPcd.DefaultValue\r
2259 if FromPcd.TokenValue not in [None, '']:\r
2260 ToPcd.TokenValue = FromPcd.TokenValue\r
2261 if FromPcd.MaxDatumSize not in [None, '']:\r
2262 ToPcd.MaxDatumSize = FromPcd.MaxDatumSize\r
2263 if FromPcd.DatumType not in [None, '']:\r
2264 ToPcd.DatumType = FromPcd.DatumType\r
2265 if FromPcd.SkuInfoList not in [None, '', []]:\r
2266 ToPcd.SkuInfoList = FromPcd.SkuInfoList\r
2267\r
2268 # check the validation of datum\r
2269 IsValid, Cause = CheckPcdDatum(ToPcd.DatumType, ToPcd.DefaultValue)\r
2270 if not IsValid:\r
2271 EdkLogger.error('build', FORMAT_INVALID, Cause, File=self.MetaFile,\r
2a29017e 2272 ExtraData="%s.%s" % (ToPcd.TokenSpaceGuidCName, TokenCName))\r
82a6a960
BF
2273 ToPcd.validateranges = FromPcd.validateranges\r
2274 ToPcd.validlists = FromPcd.validlists\r
2275 ToPcd.expressions = FromPcd.expressions\r
52302d4d
LG
2276\r
2277 if ToPcd.DatumType == "VOID*" and ToPcd.MaxDatumSize in ['', None]:\r
2278 EdkLogger.debug(EdkLogger.DEBUG_9, "No MaxDatumSize specified for PCD %s.%s" \\r
2a29017e 2279 % (ToPcd.TokenSpaceGuidCName, TokenCName))\r
52302d4d
LG
2280 Value = ToPcd.DefaultValue\r
2281 if Value in [None, '']:\r
e8a47801 2282 ToPcd.MaxDatumSize = '1'\r
52302d4d 2283 elif Value[0] == 'L':\r
e8a47801 2284 ToPcd.MaxDatumSize = str((len(Value) - 2) * 2)\r
52302d4d
LG
2285 elif Value[0] == '{':\r
2286 ToPcd.MaxDatumSize = str(len(Value.split(',')))\r
2287 else:\r
e8a47801 2288 ToPcd.MaxDatumSize = str(len(Value) - 1)\r
52302d4d
LG
2289\r
2290 # apply default SKU for dynamic PCDS if specified one is not available\r
2291 if (ToPcd.Type in PCD_DYNAMIC_TYPE_LIST or ToPcd.Type in PCD_DYNAMIC_EX_TYPE_LIST) \\r
2292 and ToPcd.SkuInfoList in [None, {}, '']:\r
2293 if self.Platform.SkuName in self.Platform.SkuIds:\r
2294 SkuName = self.Platform.SkuName\r
2295 else:\r
2296 SkuName = 'DEFAULT'\r
2297 ToPcd.SkuInfoList = {\r
2298 SkuName : SkuInfoClass(SkuName, self.Platform.SkuIds[SkuName], '', '', '', '', '', ToPcd.DefaultValue)\r
2299 }\r
2300\r
2301 ## Apply PCD setting defined platform to a module\r
2302 #\r
2303 # @param Module The module from which the PCD setting will be overrided\r
2304 #\r
2305 # @retval PCD_list The list PCDs with settings from platform\r
2306 #\r
2307 def ApplyPcdSetting(self, Module, Pcds):\r
2308 # for each PCD in module\r
47fea6af
YZ
2309 for Name, Guid in Pcds:\r
2310 PcdInModule = Pcds[Name, Guid]\r
52302d4d 2311 # find out the PCD setting in platform\r
47fea6af
YZ
2312 if (Name, Guid) in self.Platform.Pcds:\r
2313 PcdInPlatform = self.Platform.Pcds[Name, Guid]\r
52302d4d
LG
2314 else:\r
2315 PcdInPlatform = None\r
2316 # then override the settings if any\r
2317 self._OverridePcd(PcdInModule, PcdInPlatform, Module)\r
2318 # resolve the VariableGuid value\r
2319 for SkuId in PcdInModule.SkuInfoList:\r
2320 Sku = PcdInModule.SkuInfoList[SkuId]\r
2321 if Sku.VariableGuid == '': continue\r
c28d2e10 2322 Sku.VariableGuidValue = GuidValue(Sku.VariableGuid, self.PackageList, self.MetaFile.Path)\r
52302d4d
LG
2323 if Sku.VariableGuidValue == None:\r
2324 PackageList = "\n\t".join([str(P) for P in self.PackageList])\r
2325 EdkLogger.error(\r
2326 'build',\r
2327 RESOURCE_NOT_AVAILABLE,\r
2328 "Value of GUID [%s] is not found in" % Sku.VariableGuid,\r
2329 ExtraData=PackageList + "\n\t(used with %s.%s from module %s)" \\r
2330 % (Guid, Name, str(Module)),\r
2331 File=self.MetaFile\r
2332 )\r
2333\r
2334 # override PCD settings with module specific setting\r
2335 if Module in self.Platform.Modules:\r
2336 PlatformModule = self.Platform.Modules[str(Module)]\r
2337 for Key in PlatformModule.Pcds:\r
aa9aa47e 2338 Flag = False\r
52302d4d 2339 if Key in Pcds:\r
aa9aa47e
YZ
2340 ToPcd = Pcds[Key]\r
2341 Flag = True\r
2342 elif Key in GlobalData.MixedPcd:\r
2343 for PcdItem in GlobalData.MixedPcd[Key]:\r
2344 if PcdItem in Pcds:\r
2345 ToPcd = Pcds[PcdItem]\r
2346 Flag = True\r
2347 break\r
2348 if Flag:\r
2349 self._OverridePcd(ToPcd, PlatformModule.Pcds[Key], Module)\r
52302d4d
LG
2350 return Pcds.values()\r
2351\r
2352 ## Resolve library names to library modules\r
2353 #\r
b36d134f 2354 # (for Edk.x modules)\r
52302d4d
LG
2355 #\r
2356 # @param Module The module from which the library names will be resolved\r
2357 #\r
2358 # @retval library_list The list of library modules\r
2359 #\r
2360 def ResolveLibraryReference(self, Module):\r
2361 EdkLogger.verbose("")\r
2362 EdkLogger.verbose("Library instances of module [%s] [%s]:" % (str(Module), self.Arch))\r
2363 LibraryConsumerList = [Module]\r
2364\r
b36d134f 2365 # "CompilerStub" is a must for Edk modules\r
52302d4d
LG
2366 if Module.Libraries:\r
2367 Module.Libraries.append("CompilerStub")\r
2368 LibraryList = []\r
2369 while len(LibraryConsumerList) > 0:\r
2370 M = LibraryConsumerList.pop()\r
2371 for LibraryName in M.Libraries:\r
2372 Library = self.Platform.LibraryClasses[LibraryName, ':dummy:']\r
2373 if Library == None:\r
2374 for Key in self.Platform.LibraryClasses.data.keys():\r
2375 if LibraryName.upper() == Key.upper():\r
2376 Library = self.Platform.LibraryClasses[Key, ':dummy:']\r
2377 break\r
2378 if Library == None:\r
2379 EdkLogger.warn("build", "Library [%s] is not found" % LibraryName, File=str(M),\r
2380 ExtraData="\t%s [%s]" % (str(Module), self.Arch))\r
2381 continue\r
2382\r
2383 if Library not in LibraryList:\r
2384 LibraryList.append(Library)\r
2385 LibraryConsumerList.append(Library)\r
2386 EdkLogger.verbose("\t" + LibraryName + " : " + str(Library) + ' ' + str(type(Library)))\r
2387 return LibraryList\r
2388\r
6780eef1
LG
2389 ## Calculate the priority value of the build option\r
2390 #\r
2391 # @param Key Build option definition contain: TARGET_TOOLCHAIN_ARCH_COMMANDTYPE_ATTRIBUTE\r
2392 #\r
2393 # @retval Value Priority value based on the priority list.\r
2394 #\r
2395 def CalculatePriorityValue(self, Key):\r
47fea6af
YZ
2396 Target, ToolChain, Arch, CommandType, Attr = Key.split('_')\r
2397 PriorityValue = 0x11111\r
6780eef1
LG
2398 if Target == "*":\r
2399 PriorityValue &= 0x01111\r
2400 if ToolChain == "*":\r
2401 PriorityValue &= 0x10111\r
2402 if Arch == "*":\r
2403 PriorityValue &= 0x11011\r
2404 if CommandType == "*":\r
2405 PriorityValue &= 0x11101\r
2406 if Attr == "*":\r
2407 PriorityValue &= 0x11110\r
47fea6af
YZ
2408\r
2409 return self.PrioList["0x%0.5x" % PriorityValue]\r
2410\r
6780eef1 2411\r
52302d4d
LG
2412 ## Expand * in build option key\r
2413 #\r
2414 # @param Options Options to be expanded\r
2415 #\r
2416 # @retval options Options expanded\r
6780eef1 2417 # \r
52302d4d
LG
2418 def _ExpandBuildOption(self, Options, ModuleStyle=None):\r
2419 BuildOptions = {}\r
2420 FamilyMatch = False\r
2421 FamilyIsNull = True\r
47fea6af 2422\r
6780eef1
LG
2423 OverrideList = {}\r
2424 #\r
2425 # Construct a list contain the build options which need override.\r
2426 #\r
2427 for Key in Options:\r
2428 #\r
2429 # Key[0] -- tool family\r
2430 # Key[1] -- TARGET_TOOLCHAIN_ARCH_COMMANDTYPE_ATTRIBUTE\r
2431 #\r
1ba5124e
YL
2432 if (Key[0] == self.BuildRuleFamily and\r
2433 (ModuleStyle == None or len(Key) < 3 or (len(Key) > 2 and Key[2] == ModuleStyle))):\r
6780eef1
LG
2434 Target, ToolChain, Arch, CommandType, Attr = Key[1].split('_')\r
2435 if Target == self.BuildTarget or Target == "*":\r
2436 if ToolChain == self.ToolChain or ToolChain == "*":\r
2437 if Arch == self.Arch or Arch == "*":\r
2438 if Options[Key].startswith("="):\r
47fea6af 2439 if OverrideList.get(Key[1]) != None:\r
6780eef1
LG
2440 OverrideList.pop(Key[1])\r
2441 OverrideList[Key[1]] = Options[Key]\r
2442 \r
2443 #\r
2444 # Use the highest priority value. \r
2445 #\r
2446 if (len(OverrideList) >= 2):\r
47fea6af 2447 KeyList = OverrideList.keys()\r
6780eef1 2448 for Index in range(len(KeyList)):\r
47fea6af 2449 NowKey = KeyList[Index]\r
6780eef1
LG
2450 Target1, ToolChain1, Arch1, CommandType1, Attr1 = NowKey.split("_")\r
2451 for Index1 in range(len(KeyList) - Index - 1):\r
2452 NextKey = KeyList[Index1 + Index + 1]\r
2453 #\r
2454 # Compare two Key, if one is included by another, choose the higher priority one\r
2455 # \r
2456 Target2, ToolChain2, Arch2, CommandType2, Attr2 = NextKey.split("_")\r
2457 if Target1 == Target2 or Target1 == "*" or Target2 == "*":\r
2458 if ToolChain1 == ToolChain2 or ToolChain1 == "*" or ToolChain2 == "*":\r
2459 if Arch1 == Arch2 or Arch1 == "*" or Arch2 == "*":\r
2460 if CommandType1 == CommandType2 or CommandType1 == "*" or CommandType2 == "*":\r
2461 if Attr1 == Attr2 or Attr1 == "*" or Attr2 == "*":\r
2462 if self.CalculatePriorityValue(NowKey) > self.CalculatePriorityValue(NextKey):\r
47fea6af 2463 if Options.get((self.BuildRuleFamily, NextKey)) != None:\r
6780eef1
LG
2464 Options.pop((self.BuildRuleFamily, NextKey))\r
2465 else:\r
47fea6af 2466 if Options.get((self.BuildRuleFamily, NowKey)) != None:\r
6780eef1
LG
2467 Options.pop((self.BuildRuleFamily, NowKey))\r
2468 \r
52302d4d
LG
2469 for Key in Options:\r
2470 if ModuleStyle != None and len (Key) > 2:\r
2471 # Check Module style is EDK or EDKII.\r
2472 # Only append build option for the matched style module.\r
2473 if ModuleStyle == EDK_NAME and Key[2] != EDK_NAME:\r
2474 continue\r
2475 elif ModuleStyle == EDKII_NAME and Key[2] != EDKII_NAME:\r
2476 continue\r
2477 Family = Key[0]\r
2478 Target, Tag, Arch, Tool, Attr = Key[1].split("_")\r
2479 # if tool chain family doesn't match, skip it\r
2480 if Tool in self.ToolDefinition and Family != "":\r
2481 FamilyIsNull = False\r
2482 if self.ToolDefinition[Tool].get(TAB_TOD_DEFINES_BUILDRULEFAMILY, "") != "":\r
2483 if Family != self.ToolDefinition[Tool][TAB_TOD_DEFINES_BUILDRULEFAMILY]:\r
2484 continue\r
2485 elif Family != self.ToolDefinition[Tool][TAB_TOD_DEFINES_FAMILY]:\r
2486 continue\r
2487 FamilyMatch = True\r
2488 # expand any wildcard\r
2489 if Target == "*" or Target == self.BuildTarget:\r
2490 if Tag == "*" or Tag == self.ToolChain:\r
2491 if Arch == "*" or Arch == self.Arch:\r
2492 if Tool not in BuildOptions:\r
2493 BuildOptions[Tool] = {}\r
5015bee2 2494 if Attr != "FLAGS" or Attr not in BuildOptions[Tool] or Options[Key].startswith('='):\r
52302d4d
LG
2495 BuildOptions[Tool][Attr] = Options[Key]\r
2496 else:\r
95816356
YZ
2497 # append options for the same tool except PATH\r
2498 if Attr != 'PATH':\r
2499 BuildOptions[Tool][Attr] += " " + Options[Key]\r
2500 else:\r
2501 BuildOptions[Tool][Attr] = Options[Key]\r
52302d4d
LG
2502 # Build Option Family has been checked, which need't to be checked again for family.\r
2503 if FamilyMatch or FamilyIsNull:\r
2504 return BuildOptions\r
1ba5124e 2505\r
52302d4d
LG
2506 for Key in Options:\r
2507 if ModuleStyle != None and len (Key) > 2:\r
2508 # Check Module style is EDK or EDKII.\r
2509 # Only append build option for the matched style module.\r
2510 if ModuleStyle == EDK_NAME and Key[2] != EDK_NAME:\r
2511 continue\r
2512 elif ModuleStyle == EDKII_NAME and Key[2] != EDKII_NAME:\r
2513 continue\r
2514 Family = Key[0]\r
2515 Target, Tag, Arch, Tool, Attr = Key[1].split("_")\r
2516 # if tool chain family doesn't match, skip it\r
47fea6af 2517 if Tool not in self.ToolDefinition or Family == "":\r
52302d4d
LG
2518 continue\r
2519 # option has been added before\r
2520 if Family != self.ToolDefinition[Tool][TAB_TOD_DEFINES_FAMILY]:\r
2521 continue\r
2522\r
2523 # expand any wildcard\r
2524 if Target == "*" or Target == self.BuildTarget:\r
2525 if Tag == "*" or Tag == self.ToolChain:\r
2526 if Arch == "*" or Arch == self.Arch:\r
2527 if Tool not in BuildOptions:\r
2528 BuildOptions[Tool] = {}\r
5015bee2 2529 if Attr != "FLAGS" or Attr not in BuildOptions[Tool] or Options[Key].startswith('='):\r
52302d4d
LG
2530 BuildOptions[Tool][Attr] = Options[Key]\r
2531 else:\r
95816356
YZ
2532 # append options for the same tool except PATH\r
2533 if Attr != 'PATH':\r
2534 BuildOptions[Tool][Attr] += " " + Options[Key]\r
2535 else:\r
2536 BuildOptions[Tool][Attr] = Options[Key]\r
52302d4d
LG
2537 return BuildOptions\r
2538\r
2539 ## Append build options in platform to a module\r
2540 #\r
2541 # @param Module The module to which the build options will be appened\r
2542 #\r
2543 # @retval options The options appended with build options in platform\r
2544 #\r
2545 def ApplyBuildOption(self, Module):\r
2546 # Get the different options for the different style module\r
2547 if Module.AutoGenVersion < 0x00010005:\r
2548 PlatformOptions = self.EdkBuildOption\r
35f69db9 2549 ModuleTypeOptions = self.Platform.GetBuildOptionsByModuleType(EDK_NAME, Module.ModuleType)\r
52302d4d
LG
2550 else:\r
2551 PlatformOptions = self.EdkIIBuildOption\r
35f69db9
YL
2552 ModuleTypeOptions = self.Platform.GetBuildOptionsByModuleType(EDKII_NAME, Module.ModuleType)\r
2553 ModuleTypeOptions = self._ExpandBuildOption(ModuleTypeOptions)\r
52302d4d
LG
2554 ModuleOptions = self._ExpandBuildOption(Module.BuildOptions)\r
2555 if Module in self.Platform.Modules:\r
2556 PlatformModule = self.Platform.Modules[str(Module)]\r
2557 PlatformModuleOptions = self._ExpandBuildOption(PlatformModule.BuildOptions)\r
2558 else:\r
2559 PlatformModuleOptions = {}\r
2560\r
fe4bf2f9 2561 BuildRuleOrder = None\r
35f69db9 2562 for Options in [self.ToolDefinition, ModuleOptions, PlatformOptions, ModuleTypeOptions, PlatformModuleOptions]:\r
fe4bf2f9
YL
2563 for Tool in Options:\r
2564 for Attr in Options[Tool]:\r
2565 if Attr == TAB_TOD_DEFINES_BUILDRULEORDER:\r
2566 BuildRuleOrder = Options[Tool][Attr]\r
2567\r
35f69db9
YL
2568 AllTools = set(ModuleOptions.keys() + PlatformOptions.keys() +\r
2569 PlatformModuleOptions.keys() + ModuleTypeOptions.keys() +\r
2570 self.ToolDefinition.keys())\r
52302d4d
LG
2571 BuildOptions = {}\r
2572 for Tool in AllTools:\r
2573 if Tool not in BuildOptions:\r
2574 BuildOptions[Tool] = {}\r
2575\r
35f69db9 2576 for Options in [self.ToolDefinition, ModuleOptions, PlatformOptions, ModuleTypeOptions, PlatformModuleOptions]:\r
52302d4d
LG
2577 if Tool not in Options:\r
2578 continue\r
2579 for Attr in Options[Tool]:\r
2580 Value = Options[Tool][Attr]\r
fe4bf2f9
YL
2581 #\r
2582 # Do not generate it in Makefile\r
2583 #\r
2584 if Attr == TAB_TOD_DEFINES_BUILDRULEORDER:\r
2585 continue\r
52302d4d
LG
2586 if Attr not in BuildOptions[Tool]:\r
2587 BuildOptions[Tool][Attr] = ""\r
2588 # check if override is indicated\r
2589 if Value.startswith('='):\r
05cc51ad
LY
2590 ToolPath = Value[1:]\r
2591 ToolPath = mws.handleWsMacro(ToolPath)\r
2592 BuildOptions[Tool][Attr] = ToolPath\r
5015bee2 2593 else:\r
05cc51ad 2594 Value = mws.handleWsMacro(Value)\r
95816356
YZ
2595 if Attr != 'PATH':\r
2596 BuildOptions[Tool][Attr] += " " + Value\r
2597 else:\r
2598 BuildOptions[Tool][Attr] = Value\r
f3decdc3
LG
2599 if Module.AutoGenVersion < 0x00010005 and self.Workspace.UniFlag != None:\r
2600 #\r
2601 # Override UNI flag only for EDK module.\r
2602 #\r
2603 if 'BUILD' not in BuildOptions:\r
2604 BuildOptions['BUILD'] = {}\r
2605 BuildOptions['BUILD']['FLAGS'] = self.Workspace.UniFlag\r
fe4bf2f9 2606 return BuildOptions, BuildRuleOrder\r
52302d4d
LG
2607\r
2608 Platform = property(_GetPlatform)\r
2609 Name = property(_GetName)\r
2610 Guid = property(_GetGuid)\r
2611 Version = property(_GetVersion)\r
2612\r
2613 OutputDir = property(_GetOutputDir)\r
2614 BuildDir = property(_GetBuildDir)\r
2615 MakeFileDir = property(_GetMakeFileDir)\r
2616 FdfFile = property(_GetFdfFile)\r
2617\r
2618 PcdTokenNumber = property(_GetPcdTokenNumbers) # (TokenCName, TokenSpaceGuidCName) : GeneratedTokenNumber\r
2619 DynamicPcdList = property(_GetDynamicPcdList) # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]\r
2620 NonDynamicPcdList = property(_GetNonDynamicPcdList) # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]\r
2bc3256c 2621 NonDynamicPcdDict = property(_GetNonDynamicPcdDict)\r
52302d4d
LG
2622 PackageList = property(_GetPackageList)\r
2623\r
2624 ToolDefinition = property(_GetToolDefinition) # toolcode : tool path\r
2625 ToolDefinitionFile = property(_GetToolDefFile) # toolcode : lib path\r
2626 ToolChainFamily = property(_GetToolChainFamily)\r
2627 BuildRuleFamily = property(_GetBuildRuleFamily)\r
2628 BuildOption = property(_GetBuildOptions) # toolcode : option\r
2629 EdkBuildOption = property(_GetEdkBuildOptions) # edktoolcode : option\r
2630 EdkIIBuildOption = property(_GetEdkIIBuildOptions) # edkiitoolcode : option\r
2631\r
2632 BuildCommand = property(_GetBuildCommand)\r
2633 BuildRule = property(_GetBuildRule)\r
2634 ModuleAutoGenList = property(_GetModuleAutoGenList)\r
2635 LibraryAutoGenList = property(_GetLibraryAutoGenList)\r
0923aa1c 2636 GenFdsCommand = property(_GenFdsCommand)\r
52302d4d
LG
2637\r
2638## ModuleAutoGen class\r
2639#\r
2640# This class encapsules the AutoGen behaviors for the build tools. In addition to\r
2641# the generation of AutoGen.h and AutoGen.c, it will generate *.depex file according\r
2642# to the [depex] section in module's inf file.\r
2643#\r
2644class ModuleAutoGen(AutoGen):\r
c17956e0
DL
2645 ## Cache the timestamps of metafiles of every module in a class variable\r
2646 #\r
2647 TimeDict = {}\r
2648\r
52302d4d
LG
2649 ## The real constructor of ModuleAutoGen\r
2650 #\r
2651 # This method is not supposed to be called by users of ModuleAutoGen. It's\r
2652 # only used by factory method __new__() to do real initialization work for an\r
2653 # object of ModuleAutoGen\r
2654 #\r
2655 # @param Workspace EdkIIWorkspaceBuild object\r
2656 # @param ModuleFile The path of module file\r
2657 # @param Target Build target (DEBUG, RELEASE)\r
2658 # @param Toolchain Name of tool chain\r
2659 # @param Arch The arch the module supports\r
2660 # @param PlatformFile Platform meta-file\r
2661 #\r
2662 def _Init(self, Workspace, ModuleFile, Target, Toolchain, Arch, PlatformFile):\r
2663 EdkLogger.debug(EdkLogger.DEBUG_9, "AutoGen module [%s] [%s]" % (ModuleFile, Arch))\r
2664 GlobalData.gProcessingFile = "%s [%s, %s, %s]" % (ModuleFile, Arch, Toolchain, Target)\r
2665\r
2666 self.Workspace = Workspace\r
2667 self.WorkspaceDir = Workspace.WorkspaceDir\r
2668\r
2669 self.MetaFile = ModuleFile\r
2670 self.PlatformInfo = PlatformAutoGen(Workspace, PlatformFile, Target, Toolchain, Arch)\r
2671 # check if this module is employed by active platform\r
2672 if not self.PlatformInfo.ValidModule(self.MetaFile):\r
2673 EdkLogger.verbose("Module [%s] for [%s] is not employed by active platform\n" \\r
2674 % (self.MetaFile, Arch))\r
2675 return False\r
2676\r
2677 self.SourceDir = self.MetaFile.SubDir\r
05cc51ad 2678 self.SourceDir = mws.relpath(self.SourceDir, self.WorkspaceDir)\r
97fa0ee9 2679\r
52302d4d
LG
2680 self.SourceOverrideDir = None\r
2681 # use overrided path defined in DSC file\r
2682 if self.MetaFile.Key in GlobalData.gOverrideDir:\r
2683 self.SourceOverrideDir = GlobalData.gOverrideDir[self.MetaFile.Key]\r
2684\r
2685 self.ToolChain = Toolchain\r
2686 self.BuildTarget = Target\r
2687 self.Arch = Arch\r
2688 self.ToolChainFamily = self.PlatformInfo.ToolChainFamily\r
2689 self.BuildRuleFamily = self.PlatformInfo.BuildRuleFamily\r
2690\r
2691 self.IsMakeFileCreated = False\r
2692 self.IsCodeFileCreated = False\r
da92f276
LG
2693 self.IsAsBuiltInfCreated = False\r
2694 self.DepexGenerated = False\r
52302d4d
LG
2695\r
2696 self.BuildDatabase = self.Workspace.BuildDatabase\r
fe4bf2f9 2697 self.BuildRuleOrder = None\r
1b8eca8b 2698 self.BuildTime = 0\r
52302d4d
LG
2699\r
2700 self._Module = None\r
2701 self._Name = None\r
2702 self._Guid = None\r
2703 self._Version = None\r
2704 self._ModuleType = None\r
2705 self._ComponentType = None\r
2706 self._PcdIsDriver = None\r
2707 self._AutoGenVersion = None\r
2708 self._LibraryFlag = None\r
2709 self._CustomMakefile = None\r
2710 self._Macro = None\r
2711\r
2712 self._BuildDir = None\r
2713 self._OutputDir = None\r
2714 self._DebugDir = None\r
2715 self._MakeFileDir = None\r
2716\r
2717 self._IncludePathList = None\r
725cdb8f 2718 self._IncludePathLength = 0\r
52302d4d
LG
2719 self._AutoGenFileList = None\r
2720 self._UnicodeFileList = None\r
5b97eb4c 2721 self._VfrFileList = None\r
333ba578 2722 self._IdfFileList = None\r
52302d4d
LG
2723 self._SourceFileList = None\r
2724 self._ObjectFileList = None\r
2725 self._BinaryFileList = None\r
2726\r
2727 self._DependentPackageList = None\r
2728 self._DependentLibraryList = None\r
2729 self._LibraryAutoGenList = None\r
2730 self._DerivedPackageList = None\r
2731 self._ModulePcdList = None\r
2732 self._LibraryPcdList = None\r
e8a47801 2733 self._PcdComments = sdict()\r
52302d4d 2734 self._GuidList = None\r
e8a47801
LG
2735 self._GuidsUsedByPcd = None\r
2736 self._GuidComments = sdict()\r
52302d4d 2737 self._ProtocolList = None\r
e8a47801 2738 self._ProtocolComments = sdict()\r
52302d4d 2739 self._PpiList = None\r
e8a47801 2740 self._PpiComments = sdict()\r
52302d4d
LG
2741 self._DepexList = None\r
2742 self._DepexExpressionList = None\r
2743 self._BuildOption = None\r
79b74a03 2744 self._BuildOptionIncPathList = None\r
52302d4d
LG
2745 self._BuildTargets = None\r
2746 self._IntroBuildTargetList = None\r
2747 self._FinalBuildTargetList = None\r
2748 self._FileTypes = None\r
2749 self._BuildRules = None\r
c17956e0
DL
2750\r
2751 self._TimeStampPath = None\r
2752\r
2753 self.AutoGenDepSet = set()\r
2754\r
2bc3256c
LG
2755 \r
2756 ## The Modules referenced to this Library\r
2757 # Only Library has this attribute\r
2758 self._ReferenceModules = [] \r
2759 \r
2760 ## Store the FixedAtBuild Pcds\r
2761 # \r
2762 self._FixedAtBuildPcds = []\r
2763 self.ConstPcd = {}\r
52302d4d
LG
2764 return True\r
2765\r
2766 def __repr__(self):\r
2767 return "%s [%s]" % (self.MetaFile, self.Arch)\r
2768\r
2bc3256c
LG
2769 # Get FixedAtBuild Pcds of this Module\r
2770 def _GetFixedAtBuildPcds(self):\r
2771 if self._FixedAtBuildPcds:\r
2772 return self._FixedAtBuildPcds\r
2773 for Pcd in self.ModulePcdList:\r
7256bd55 2774 if Pcd.Type != "FixedAtBuild":\r
2bc3256c
LG
2775 continue\r
2776 if Pcd not in self._FixedAtBuildPcds:\r
2777 self._FixedAtBuildPcds.append(Pcd)\r
2778 \r
2779 return self._FixedAtBuildPcds \r
2780\r
867d1cd4
YL
2781 def _GetUniqueBaseName(self):\r
2782 BaseName = self.Name\r
2783 for Module in self.PlatformInfo.ModuleAutoGenList:\r
2784 if Module.MetaFile == self.MetaFile:\r
2785 continue\r
2786 if Module.Name == self.Name:\r
867d1cd4
YL
2787 if uuid.UUID(Module.Guid) == uuid.UUID(self.Guid):\r
2788 EdkLogger.error("build", FILE_DUPLICATED, 'Modules have same BaseName and FILE_GUID:\n'\r
2789 ' %s\n %s' % (Module.MetaFile, self.MetaFile))\r
2790 BaseName = '%s_%s' % (self.Name, self.Guid)\r
2791 return BaseName\r
2792\r
52302d4d
LG
2793 # Macros could be used in build_rule.txt (also Makefile)\r
2794 def _GetMacros(self):\r
2795 if self._Macro == None:\r
2796 self._Macro = sdict()\r
2797 self._Macro["WORKSPACE" ] = self.WorkspaceDir\r
2798 self._Macro["MODULE_NAME" ] = self.Name\r
867d1cd4 2799 self._Macro["MODULE_NAME_GUID" ] = self._GetUniqueBaseName()\r
52302d4d
LG
2800 self._Macro["MODULE_GUID" ] = self.Guid\r
2801 self._Macro["MODULE_VERSION" ] = self.Version\r
2802 self._Macro["MODULE_TYPE" ] = self.ModuleType\r
2803 self._Macro["MODULE_FILE" ] = str(self.MetaFile)\r
2804 self._Macro["MODULE_FILE_BASE_NAME" ] = self.MetaFile.BaseName\r
2805 self._Macro["MODULE_RELATIVE_DIR" ] = self.SourceDir\r
2806 self._Macro["MODULE_DIR" ] = self.SourceDir\r
2807\r
2808 self._Macro["BASE_NAME" ] = self.Name\r
2809\r
2810 self._Macro["ARCH" ] = self.Arch\r
2811 self._Macro["TOOLCHAIN" ] = self.ToolChain\r
2812 self._Macro["TOOLCHAIN_TAG" ] = self.ToolChain\r
0d2711a6 2813 self._Macro["TOOL_CHAIN_TAG" ] = self.ToolChain\r
52302d4d
LG
2814 self._Macro["TARGET" ] = self.BuildTarget\r
2815\r
2816 self._Macro["BUILD_DIR" ] = self.PlatformInfo.BuildDir\r
2817 self._Macro["BIN_DIR" ] = os.path.join(self.PlatformInfo.BuildDir, self.Arch)\r
2818 self._Macro["LIB_DIR" ] = os.path.join(self.PlatformInfo.BuildDir, self.Arch)\r
2819 self._Macro["MODULE_BUILD_DIR" ] = self.BuildDir\r
2820 self._Macro["OUTPUT_DIR" ] = self.OutputDir\r
2821 self._Macro["DEBUG_DIR" ] = self.DebugDir\r
df1e1b63
YZ
2822 self._Macro["DEST_DIR_OUTPUT" ] = self.OutputDir\r
2823 self._Macro["DEST_DIR_DEBUG" ] = self.DebugDir\r
3570e332
YZ
2824 self._Macro["PLATFORM_NAME" ] = self.PlatformInfo.Name\r
2825 self._Macro["PLATFORM_GUID" ] = self.PlatformInfo.Guid\r
2826 self._Macro["PLATFORM_VERSION" ] = self.PlatformInfo.Version\r
2827 self._Macro["PLATFORM_RELATIVE_DIR" ] = self.PlatformInfo.SourceDir\r
2828 self._Macro["PLATFORM_DIR" ] = mws.join(self.WorkspaceDir, self.PlatformInfo.SourceDir)\r
2829 self._Macro["PLATFORM_OUTPUT_DIR" ] = self.PlatformInfo.OutputDir\r
52302d4d
LG
2830 return self._Macro\r
2831\r
2832 ## Return the module build data object\r
2833 def _GetModule(self):\r
2834 if self._Module == None:\r
0d2711a6 2835 self._Module = self.Workspace.BuildDatabase[self.MetaFile, self.Arch, self.BuildTarget, self.ToolChain]\r
52302d4d
LG
2836 return self._Module\r
2837\r
2838 ## Return the module name\r
2839 def _GetBaseName(self):\r
2840 return self.Module.BaseName\r
2841\r
b36d134f
LG
2842 ## Return the module DxsFile if exist\r
2843 def _GetDxsFile(self):\r
2844 return self.Module.DxsFile\r
2845\r
52302d4d
LG
2846 ## Return the module SourceOverridePath\r
2847 def _GetSourceOverridePath(self):\r
2848 return self.Module.SourceOverridePath\r
2849\r
2850 ## Return the module meta-file GUID\r
2851 def _GetGuid(self):\r
97fa0ee9
YL
2852 #\r
2853 # To build same module more than once, the module path with FILE_GUID overridden has\r
2854 # the file name FILE_GUIDmodule.inf, but the relative path (self.MetaFile.File) is the realy path\r
2855 # in DSC. The overridden GUID can be retrieved from file name\r
2856 #\r
2857 if os.path.basename(self.MetaFile.File) != os.path.basename(self.MetaFile.Path):\r
2858 #\r
2859 # Length of GUID is 36\r
2860 #\r
2861 return os.path.basename(self.MetaFile.Path)[:36]\r
52302d4d
LG
2862 return self.Module.Guid\r
2863\r
2864 ## Return the module version\r
2865 def _GetVersion(self):\r
2866 return self.Module.Version\r
2867\r
2868 ## Return the module type\r
2869 def _GetModuleType(self):\r
2870 return self.Module.ModuleType\r
2871\r
b36d134f 2872 ## Return the component type (for Edk.x style of module)\r
52302d4d
LG
2873 def _GetComponentType(self):\r
2874 return self.Module.ComponentType\r
2875\r
2876 ## Return the build type\r
2877 def _GetBuildType(self):\r
2878 return self.Module.BuildType\r
2879\r
2880 ## Return the PCD_IS_DRIVER setting\r
2881 def _GetPcdIsDriver(self):\r
2882 return self.Module.PcdIsDriver\r
2883\r
2884 ## Return the autogen version, i.e. module meta-file version\r
2885 def _GetAutoGenVersion(self):\r
2886 return self.Module.AutoGenVersion\r
2887\r
2888 ## Check if the module is library or not\r
2889 def _IsLibrary(self):\r
2890 if self._LibraryFlag == None:\r
2891 if self.Module.LibraryClass != None and self.Module.LibraryClass != []:\r
2892 self._LibraryFlag = True\r
2893 else:\r
2894 self._LibraryFlag = False\r
2895 return self._LibraryFlag\r
2896\r
e8a47801
LG
2897 ## Check if the module is binary module or not\r
2898 def _IsBinaryModule(self):\r
2899 return self.Module.IsBinaryModule\r
2900\r
52302d4d
LG
2901 ## Return the directory to store intermediate files of the module\r
2902 def _GetBuildDir(self):\r
2903 if self._BuildDir == None:\r
2904 self._BuildDir = path.join(\r
2905 self.PlatformInfo.BuildDir,\r
2906 self.Arch,\r
2907 self.SourceDir,\r
2908 self.MetaFile.BaseName\r
2909 )\r
2910 CreateDirectory(self._BuildDir)\r
2911 return self._BuildDir\r
2912\r
2913 ## Return the directory to store the intermediate object files of the mdoule\r
2914 def _GetOutputDir(self):\r
2915 if self._OutputDir == None:\r
2916 self._OutputDir = path.join(self.BuildDir, "OUTPUT")\r
2917 CreateDirectory(self._OutputDir)\r
2918 return self._OutputDir\r
2919\r
2920 ## Return the directory to store auto-gened source files of the mdoule\r
2921 def _GetDebugDir(self):\r
2922 if self._DebugDir == None:\r