]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/AutoGen/AutoGen.py
BaseTools: Update Gensec to set PROCESSING_REQUIRED value
[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
36d083ef 46import hashlib\r
97fa0ee9 47\r
e8a47801 48## Regular expression for splitting Dependency Expression string into tokens\r
52302d4d
LG
49gDepexTokenPattern = re.compile("(\(|\)|\w+| \S+\.inf)")\r
50\r
97fa0ee9
YL
51#\r
52# Match name = variable\r
53#\r
54gEfiVarStoreNamePattern = re.compile("\s*name\s*=\s*(\w+)")\r
55#\r
56# The format of guid in efivarstore statement likes following and must be correct:\r
57# guid = {0xA04A27f4, 0xDF00, 0x4D42, {0xB5, 0x52, 0x39, 0x51, 0x13, 0x02, 0x11, 0x3D}}\r
58#\r
59gEfiVarStoreGuidPattern = re.compile("\s*guid\s*=\s*({.*?{.*?}\s*})")\r
60\r
52302d4d
LG
61## Mapping Makefile type\r
62gMakeTypeMap = {"MSFT":"nmake", "GCC":"gmake"}\r
63\r
64\r
65## Build rule configuration file\r
51de5c30 66gDefaultBuildRuleFile = 'build_rule.txt'\r
52302d4d 67\r
86601b78 68## Tools definition configuration file\r
51de5c30 69gDefaultToolsDefFile = 'tools_def.txt'\r
86601b78 70\r
64b2609f
LG
71## Build rule default version\r
72AutoGenReqBuildRuleVerNum = "0.1"\r
73\r
52302d4d
LG
74## default file name for AutoGen\r
75gAutoGenCodeFileName = "AutoGen.c"\r
76gAutoGenHeaderFileName = "AutoGen.h"\r
77gAutoGenStringFileName = "%(module_name)sStrDefs.h"\r
78gAutoGenStringFormFileName = "%(module_name)sStrDefs.hpk"\r
79gAutoGenDepexFileName = "%(module_name)s.depex"\r
333ba578
YZ
80gAutoGenImageDefFileName = "%(module_name)sImgDefs.h"\r
81gAutoGenIdfFileName = "%(module_name)sIdf.hpk"\r
97fa0ee9
YL
82gInfSpecVersion = "0x00010017"\r
83\r
da92f276
LG
84#\r
85# Template string to generic AsBuilt INF\r
86#\r
e8a47801 87gAsBuiltInfHeaderString = TemplateString("""${header_comments}\r
da92f276 88\r
97fa0ee9
YL
89# DO NOT EDIT\r
90# FILE auto-generated\r
91\r
da92f276 92[Defines]\r
97fa0ee9 93 INF_VERSION = ${module_inf_version}\r
da92f276
LG
94 BASE_NAME = ${module_name}\r
95 FILE_GUID = ${module_guid}\r
97fa0ee9
YL
96 MODULE_TYPE = ${module_module_type}${BEGIN}\r
97 VERSION_STRING = ${module_version_string}${END}${BEGIN}\r
e8a47801 98 PCD_IS_DRIVER = ${pcd_is_driver_string}${END}${BEGIN}\r
da92f276 99 UEFI_SPECIFICATION_VERSION = ${module_uefi_specification_version}${END}${BEGIN}\r
97fa0ee9
YL
100 PI_SPECIFICATION_VERSION = ${module_pi_specification_version}${END}${BEGIN}\r
101 ENTRY_POINT = ${module_entry_point}${END}${BEGIN}\r
102 UNLOAD_IMAGE = ${module_unload_image}${END}${BEGIN}\r
103 CONSTRUCTOR = ${module_constructor}${END}${BEGIN}\r
104 DESTRUCTOR = ${module_destructor}${END}${BEGIN}\r
105 SHADOW = ${module_shadow}${END}${BEGIN}\r
106 PCI_VENDOR_ID = ${module_pci_vendor_id}${END}${BEGIN}\r
107 PCI_DEVICE_ID = ${module_pci_device_id}${END}${BEGIN}\r
108 PCI_CLASS_CODE = ${module_pci_class_code}${END}${BEGIN}\r
109 PCI_REVISION = ${module_pci_revision}${END}${BEGIN}\r
110 BUILD_NUMBER = ${module_build_number}${END}${BEGIN}\r
111 SPEC = ${module_spec}${END}${BEGIN}\r
112 UEFI_HII_RESOURCE_SECTION = ${module_uefi_hii_resource_section}${END}${BEGIN}\r
113 MODULE_UNI_FILE = ${module_uni_file}${END}\r
114\r
115[Packages.${module_arch}]${BEGIN}\r
da92f276
LG
116 ${package_item}${END}\r
117\r
118[Binaries.${module_arch}]${BEGIN}\r
119 ${binary_item}${END}\r
120\r
e8a47801
LG
121[PatchPcd.${module_arch}]${BEGIN}\r
122 ${patchablepcd_item}\r
123${END}\r
97fa0ee9 124\r
e8a47801
LG
125[Protocols.${module_arch}]${BEGIN}\r
126 ${protocol_item}\r
127${END}\r
97fa0ee9 128\r
e8a47801
LG
129[Ppis.${module_arch}]${BEGIN}\r
130 ${ppi_item}\r
131${END}\r
97fa0ee9 132\r
e8a47801
LG
133[Guids.${module_arch}]${BEGIN}\r
134 ${guid_item}\r
135${END}\r
97fa0ee9 136\r
e8a47801
LG
137[PcdEx.${module_arch}]${BEGIN}\r
138 ${pcd_item}\r
139${END}\r
da92f276 140\r
97fa0ee9
YL
141[LibraryClasses.${module_arch}]\r
142## @LIB_INSTANCES${BEGIN}\r
143# ${libraryclasses_item}${END}\r
144\r
145${depexsection_item}\r
146\r
dfa41b4a
YZ
147${userextension_tianocore_item}\r
148\r
97fa0ee9
YL
149${tail_comments}\r
150\r
151[BuildOptions.${module_arch}]\r
da92f276
LG
152## @AsBuilt${BEGIN}\r
153## ${flags_item}${END}\r
154""")\r
155\r
52302d4d
LG
156## Base class for AutoGen\r
157#\r
158# This class just implements the cache mechanism of AutoGen objects.\r
159#\r
160class AutoGen(object):\r
161 # database to maintain the objects of xxxAutoGen\r
162 _CACHE_ = {} # (BuildTarget, ToolChain) : {ARCH : {platform file: AutoGen object}}}\r
163\r
164 ## Factory method\r
165 #\r
166 # @param Class class object of real AutoGen class\r
167 # (WorkspaceAutoGen, ModuleAutoGen or PlatformAutoGen)\r
168 # @param Workspace Workspace directory or WorkspaceAutoGen object\r
169 # @param MetaFile The path of meta file\r
170 # @param Target Build target\r
171 # @param Toolchain Tool chain name\r
172 # @param Arch Target arch\r
173 # @param *args The specific class related parameters\r
174 # @param **kwargs The specific class related dict parameters\r
175 #\r
176 def __new__(Class, Workspace, MetaFile, Target, Toolchain, Arch, *args, **kwargs):\r
177 # check if the object has been created\r
178 Key = (Target, Toolchain)\r
179 if Key not in Class._CACHE_ or Arch not in Class._CACHE_[Key] \\r
180 or MetaFile not in Class._CACHE_[Key][Arch]:\r
181 AutoGenObject = super(AutoGen, Class).__new__(Class)\r
182 # call real constructor\r
183 if not AutoGenObject._Init(Workspace, MetaFile, Target, Toolchain, Arch, *args, **kwargs):\r
184 return None\r
185 if Key not in Class._CACHE_:\r
186 Class._CACHE_[Key] = {}\r
187 if Arch not in Class._CACHE_[Key]:\r
188 Class._CACHE_[Key][Arch] = {}\r
189 Class._CACHE_[Key][Arch][MetaFile] = AutoGenObject\r
190 else:\r
191 AutoGenObject = Class._CACHE_[Key][Arch][MetaFile]\r
192\r
193 return AutoGenObject\r
194\r
195 ## hash() operator\r
196 #\r
197 # The file path of platform file will be used to represent hash value of this object\r
198 #\r
199 # @retval int Hash value of the file path of platform file\r
200 #\r
201 def __hash__(self):\r
202 return hash(self.MetaFile)\r
203\r
204 ## str() operator\r
205 #\r
206 # The file path of platform file will be used to represent this object\r
207 #\r
208 # @retval string String of platform file path\r
209 #\r
210 def __str__(self):\r
211 return str(self.MetaFile)\r
212\r
213 ## "==" operator\r
214 def __eq__(self, Other):\r
215 return Other and self.MetaFile == Other\r
216\r
217## Workspace AutoGen class\r
218#\r
219# This class is used mainly to control the whole platform build for different\r
220# architecture. This class will generate top level makefile.\r
221#\r
222class WorkspaceAutoGen(AutoGen):\r
223 ## Real constructor of WorkspaceAutoGen\r
224 #\r
79b74a03 225 # This method behaves the same as __init__ except that it needs explicit invoke\r
52302d4d
LG
226 # (in super class's __new__ method)\r
227 #\r
228 # @param WorkspaceDir Root directory of workspace\r
229 # @param ActivePlatform Meta-file of active platform\r
230 # @param Target Build target\r
231 # @param Toolchain Tool chain name\r
232 # @param ArchList List of architecture of current build\r
233 # @param MetaFileDb Database containing meta-files\r
234 # @param BuildConfig Configuration of build\r
235 # @param ToolDefinition Tool chain definitions\r
236 # @param FlashDefinitionFile File of flash definition\r
237 # @param Fds FD list to be generated\r
238 # @param Fvs FV list to be generated\r
4234283c 239 # @param Caps Capsule list to be generated\r
52302d4d
LG
240 # @param SkuId SKU id from command line\r
241 #\r
242 def _Init(self, WorkspaceDir, ActivePlatform, Target, Toolchain, ArchList, MetaFileDb,\r
47fea6af 243 BuildConfig, ToolDefinition, FlashDefinitionFile='', Fds=None, Fvs=None, Caps=None, SkuId='', UniFlag=None,\r
9508d0fa 244 Progress=None, BuildModule=None):\r
4234283c
LG
245 if Fds is None:\r
246 Fds = []\r
247 if Fvs is None:\r
248 Fvs = []\r
249 if Caps is None:\r
250 Caps = []\r
0d2711a6
LG
251 self.BuildDatabase = MetaFileDb\r
252 self.MetaFile = ActivePlatform\r
52302d4d 253 self.WorkspaceDir = WorkspaceDir\r
0d2711a6 254 self.Platform = self.BuildDatabase[self.MetaFile, 'COMMON', Target, Toolchain]\r
d0acc87a 255 GlobalData.gActivePlatform = self.Platform\r
52302d4d
LG
256 self.BuildTarget = Target\r
257 self.ToolChain = Toolchain\r
258 self.ArchList = ArchList\r
259 self.SkuId = SkuId\r
f3decdc3 260 self.UniFlag = UniFlag\r
52302d4d 261\r
52302d4d
LG
262 self.TargetTxt = BuildConfig\r
263 self.ToolDef = ToolDefinition\r
264 self.FdfFile = FlashDefinitionFile\r
265 self.FdTargetList = Fds\r
266 self.FvTargetList = Fvs\r
4234283c 267 self.CapTargetList = Caps\r
52302d4d 268 self.AutoGenObjectList = []\r
36d083ef
YZ
269 self._BuildDir = None\r
270 self._FvDir = None\r
271 self._MakeFileDir = None\r
272 self._BuildCommand = None\r
52302d4d
LG
273\r
274 # there's many relative directory operations, so ...\r
275 os.chdir(self.WorkspaceDir)\r
276\r
0d2711a6
LG
277 #\r
278 # Merge Arch\r
279 #\r
280 if not self.ArchList:\r
281 ArchList = set(self.Platform.SupArchList)\r
282 else:\r
283 ArchList = set(self.ArchList) & set(self.Platform.SupArchList)\r
284 if not ArchList:\r
285 EdkLogger.error("build", PARAMETER_INVALID,\r
286 ExtraData = "Invalid ARCH specified. [Valid ARCH: %s]" % (" ".join(self.Platform.SupArchList)))\r
287 elif self.ArchList and len(ArchList) != len(self.ArchList):\r
288 SkippedArchList = set(self.ArchList).symmetric_difference(set(self.Platform.SupArchList))\r
289 EdkLogger.verbose("\nArch [%s] is ignored because the platform supports [%s] only!"\r
290 % (" ".join(SkippedArchList), " ".join(self.Platform.SupArchList)))\r
291 self.ArchList = tuple(ArchList)\r
292\r
293 # Validate build target\r
294 if self.BuildTarget not in self.Platform.BuildTargets:\r
47fea6af 295 EdkLogger.error("build", PARAMETER_INVALID,\r
0d2711a6
LG
296 ExtraData="Build target [%s] is not supported by the platform. [Valid target: %s]"\r
297 % (self.BuildTarget, " ".join(self.Platform.BuildTargets)))\r
298\r
12d37ace 299 \r
52302d4d 300 # parse FDF file to get PCDs in it, if any\r
0d2711a6
LG
301 if not self.FdfFile:\r
302 self.FdfFile = self.Platform.FlashDefinition\r
47fea6af 303\r
9508d0fa
LG
304 EdkLogger.info("")\r
305 if self.ArchList:\r
306 EdkLogger.info('%-16s = %s' % ("Architecture(s)", ' '.join(self.ArchList)))\r
307 EdkLogger.info('%-16s = %s' % ("Build target", self.BuildTarget))\r
47fea6af
YZ
308 EdkLogger.info('%-16s = %s' % ("Toolchain", self.ToolChain))\r
309\r
9508d0fa
LG
310 EdkLogger.info('\n%-24s = %s' % ("Active Platform", self.Platform))\r
311 if BuildModule:\r
312 EdkLogger.info('%-24s = %s' % ("Active Module", BuildModule))\r
47fea6af 313\r
9508d0fa
LG
314 if self.FdfFile:\r
315 EdkLogger.info('%-24s = %s' % ("Flash Image Definition", self.FdfFile))\r
0d2711a6 316\r
9508d0fa 317 EdkLogger.verbose("\nFLASH_DEFINITION = %s" % self.FdfFile)\r
47fea6af 318\r
9508d0fa
LG
319 if Progress:\r
320 Progress.Start("\nProcessing meta-data")\r
47fea6af 321\r
0d2711a6 322 if self.FdfFile:\r
df692f02
LG
323 #\r
324 # Mark now build in AutoGen Phase\r
325 #\r
47fea6af 326 GlobalData.gAutoGenPhase = True\r
52302d4d
LG
327 Fdf = FdfParser(self.FdfFile.Path)\r
328 Fdf.ParseFile()\r
a0a2cd1e 329 GlobalData.gFdfParser = Fdf\r
0d2711a6 330 GlobalData.gAutoGenPhase = False\r
52302d4d 331 PcdSet = Fdf.Profile.PcdDict\r
cb04330e
YZ
332 if Fdf.CurrentFdName and Fdf.CurrentFdName in Fdf.Profile.FdDict:\r
333 FdDict = Fdf.Profile.FdDict[Fdf.CurrentFdName]\r
334 for FdRegion in FdDict.RegionList:\r
335 if str(FdRegion.RegionType) is 'FILE' and self.Platform.VpdToolGuid in str(FdRegion.RegionDataList):\r
336 if int(FdRegion.Offset) % 8 != 0:\r
337 EdkLogger.error("build", FORMAT_INVALID, 'The VPD Base Address %s must be 8-byte aligned.' % (FdRegion.Offset))\r
52302d4d
LG
338 ModuleList = Fdf.Profile.InfList\r
339 self.FdfProfile = Fdf.Profile\r
0d2711a6
LG
340 for fvname in self.FvTargetList:\r
341 if fvname.upper() not in self.FdfProfile.FvDict:\r
342 EdkLogger.error("build", OPTION_VALUE_INVALID,\r
343 "No such an FV in FDF file: %s" % fvname)\r
2502b735 344\r
622b1758
YZ
345 # In DSC file may use FILE_GUID to override the module, then in the Platform.Modules use FILE_GUIDmodule.inf as key,\r
346 # but the path (self.MetaFile.Path) is the real path\r
2502b735
YZ
347 for key in self.FdfProfile.InfDict:\r
348 if key == 'ArchTBD':\r
349 Platform_cache = {}\r
622b1758 350 MetaFile_cache = {}\r
2502b735
YZ
351 for Arch in self.ArchList:\r
352 Platform_cache[Arch] = self.BuildDatabase[self.MetaFile, Arch, Target, Toolchain]\r
622b1758
YZ
353 MetaFile_cache[Arch] = []\r
354 for Pkey in Platform_cache[Arch].Modules.keys():\r
355 MetaFile_cache[Arch].append(Platform_cache[Arch].Modules[Pkey].MetaFile)\r
2502b735
YZ
356 for Inf in self.FdfProfile.InfDict[key]:\r
357 ModuleFile = PathClass(NormPath(Inf), GlobalData.gWorkspace, Arch)\r
358 for Arch in self.ArchList:\r
622b1758 359 if ModuleFile in MetaFile_cache[Arch]:\r
2502b735
YZ
360 break\r
361 else:\r
362 ModuleData = self.BuildDatabase[ModuleFile, Arch, Target, Toolchain]\r
363 if not ModuleData.IsBinaryModule:\r
364 EdkLogger.error('build', PARSER_ERROR, "Module %s NOT found in DSC file; Is it really a binary module?" % ModuleFile)\r
365\r
366 else:\r
367 for Arch in self.ArchList:\r
368 if Arch == key:\r
369 Platform = self.BuildDatabase[self.MetaFile, Arch, Target, Toolchain]\r
622b1758
YZ
370 MetaFileList = []\r
371 for Pkey in Platform.Modules.keys():\r
372 MetaFileList.append(Platform.Modules[Pkey].MetaFile)\r
2502b735
YZ
373 for Inf in self.FdfProfile.InfDict[key]:\r
374 ModuleFile = PathClass(NormPath(Inf), GlobalData.gWorkspace, Arch)\r
622b1758 375 if ModuleFile in MetaFileList:\r
2502b735
YZ
376 continue\r
377 ModuleData = self.BuildDatabase[ModuleFile, Arch, Target, Toolchain]\r
378 if not ModuleData.IsBinaryModule:\r
379 EdkLogger.error('build', PARSER_ERROR, "Module %s NOT found in DSC file; Is it really a binary module?" % ModuleFile)\r
380\r
52302d4d
LG
381 else:\r
382 PcdSet = {}\r
383 ModuleList = []\r
384 self.FdfProfile = None\r
0d2711a6
LG
385 if self.FdTargetList:\r
386 EdkLogger.info("No flash definition file found. FD [%s] will be ignored." % " ".join(self.FdTargetList))\r
387 self.FdTargetList = []\r
388 if self.FvTargetList:\r
389 EdkLogger.info("No flash definition file found. FV [%s] will be ignored." % " ".join(self.FvTargetList))\r
390 self.FvTargetList = []\r
391 if self.CapTargetList:\r
392 EdkLogger.info("No flash definition file found. Capsule [%s] will be ignored." % " ".join(self.CapTargetList))\r
393 self.CapTargetList = []\r
47fea6af 394\r
52302d4d
LG
395 # apply SKU and inject PCDs from Flash Definition file\r
396 for Arch in self.ArchList:\r
0d2711a6 397 Platform = self.BuildDatabase[self.MetaFile, Arch, Target, Toolchain]\r
64b2609f 398\r
25918452 399 DecPcds = {}\r
4afd3d04 400 DecPcdsKey = set()\r
64b2609f 401 PGen = PlatformAutoGen(self, self.MetaFile, Target, Toolchain, Arch)\r
763e8edf
YZ
402 if GlobalData.BuildOptionPcd:\r
403 for i, pcd in enumerate(GlobalData.BuildOptionPcd):\r
d7cd3356
YZ
404 if type(pcd) is tuple:\r
405 continue\r
763e8edf
YZ
406 (pcdname, pcdvalue) = pcd.split('=')\r
407 if not pcdvalue:\r
408 EdkLogger.error('build', AUTOGEN_ERROR, "No Value specified for the PCD %s." % (pcdname))\r
409 if '.' in pcdname:\r
410 (TokenSpaceGuidCName, TokenCName) = pcdname.split('.')\r
411 HasTokenSpace = True\r
412 else:\r
413 TokenCName = pcdname\r
414 TokenSpaceGuidCName = ''\r
415 HasTokenSpace = False\r
416 TokenSpaceGuidCNameList = []\r
417 FoundFlag = False\r
418 PcdDatumType = ''\r
419 NewValue = ''\r
420 for package in PGen.PackageList:\r
421 for key in package.Pcds:\r
422 PcdItem = package.Pcds[key]\r
423 if HasTokenSpace:\r
424 if (PcdItem.TokenCName, PcdItem.TokenSpaceGuidCName) == (TokenCName, TokenSpaceGuidCName):\r
425 PcdDatumType = PcdItem.DatumType\r
db55dac7 426 NewValue = BuildOptionPcdValueFormat(TokenSpaceGuidCName, TokenCName, PcdDatumType, pcdvalue)\r
763e8edf
YZ
427 FoundFlag = True\r
428 else:\r
429 if PcdItem.TokenCName == TokenCName:\r
430 if not PcdItem.TokenSpaceGuidCName in TokenSpaceGuidCNameList:\r
431 if len (TokenSpaceGuidCNameList) < 1:\r
432 TokenSpaceGuidCNameList.append(PcdItem.TokenSpaceGuidCName)\r
433 PcdDatumType = PcdItem.DatumType\r
434 TokenSpaceGuidCName = PcdItem.TokenSpaceGuidCName\r
db55dac7 435 NewValue = BuildOptionPcdValueFormat(TokenSpaceGuidCName, TokenCName, PcdDatumType, pcdvalue)\r
763e8edf
YZ
436 FoundFlag = True\r
437 else:\r
438 EdkLogger.error(\r
439 'build',\r
440 AUTOGEN_ERROR,\r
441 "The Pcd %s is found under multiple different TokenSpaceGuid: %s and %s." % (TokenCName, PcdItem.TokenSpaceGuidCName, TokenSpaceGuidCNameList[0])\r
442 )\r
443\r
444 GlobalData.BuildOptionPcd[i] = (TokenSpaceGuidCName, TokenCName, NewValue)\r
445\r
446 if not FoundFlag:\r
447 if HasTokenSpace:\r
448 EdkLogger.error('build', AUTOGEN_ERROR, "The Pcd %s.%s is not found in the DEC file." % (TokenSpaceGuidCName, TokenCName))\r
449 else:\r
450 EdkLogger.error('build', AUTOGEN_ERROR, "The Pcd %s is not found in the DEC file." % (TokenCName))\r
451\r
452 for BuildData in PGen.BuildDatabase._CACHE_.values():\r
453 if BuildData.Arch != Arch:\r
454 continue\r
455 if BuildData.MetaFile.Ext == '.dec':\r
456 continue\r
457 for key in BuildData.Pcds:\r
458 PcdItem = BuildData.Pcds[key]\r
459 if (TokenSpaceGuidCName, TokenCName) == (PcdItem.TokenSpaceGuidCName, PcdItem.TokenCName):\r
460 PcdItem.DefaultValue = NewValue\r
461\r
462 if (TokenCName, TokenSpaceGuidCName) in PcdSet:\r
463 PcdSet[(TokenCName, TokenSpaceGuidCName)] = NewValue\r
464\r
2a29017e
YZ
465 SourcePcdDict = {'DynamicEx':[], 'PatchableInModule':[],'Dynamic':[],'FixedAtBuild':[]}\r
466 BinaryPcdDict = {'DynamicEx':[], 'PatchableInModule':[]}\r
467 SourcePcdDict_Keys = SourcePcdDict.keys()\r
468 BinaryPcdDict_Keys = BinaryPcdDict.keys()\r
469\r
470 # generate the SourcePcdDict and BinaryPcdDict\r
471 for BuildData in PGen.BuildDatabase._CACHE_.values():\r
472 if BuildData.Arch != Arch:\r
473 continue\r
474 if BuildData.MetaFile.Ext == '.inf':\r
475 for key in BuildData.Pcds:\r
476 if BuildData.Pcds[key].Pending:\r
477 if key in Platform.Pcds:\r
478 PcdInPlatform = Platform.Pcds[key]\r
479 if PcdInPlatform.Type not in [None, '']:\r
480 BuildData.Pcds[key].Type = PcdInPlatform.Type\r
481\r
482 if BuildData.MetaFile in Platform.Modules:\r
483 PlatformModule = Platform.Modules[str(BuildData.MetaFile)]\r
484 if key in PlatformModule.Pcds:\r
485 PcdInPlatform = PlatformModule.Pcds[key]\r
486 if PcdInPlatform.Type not in [None, '']:\r
487 BuildData.Pcds[key].Type = PcdInPlatform.Type\r
488\r
489 if 'DynamicEx' in BuildData.Pcds[key].Type:\r
490 if BuildData.IsBinaryModule:\r
491 if (BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName) not in BinaryPcdDict['DynamicEx']:\r
492 BinaryPcdDict['DynamicEx'].append((BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName))\r
493 else:\r
494 if (BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName) not in SourcePcdDict['DynamicEx']:\r
495 SourcePcdDict['DynamicEx'].append((BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName))\r
496\r
497 elif 'PatchableInModule' in BuildData.Pcds[key].Type:\r
498 if BuildData.MetaFile.Ext == '.inf':\r
499 if BuildData.IsBinaryModule:\r
500 if (BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName) not in BinaryPcdDict['PatchableInModule']:\r
501 BinaryPcdDict['PatchableInModule'].append((BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName))\r
502 else:\r
503 if (BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName) not in SourcePcdDict['PatchableInModule']:\r
504 SourcePcdDict['PatchableInModule'].append((BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName))\r
505\r
506 elif 'Dynamic' in BuildData.Pcds[key].Type:\r
507 if (BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName) not in SourcePcdDict['Dynamic']:\r
508 SourcePcdDict['Dynamic'].append((BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName))\r
509 elif 'FixedAtBuild' in BuildData.Pcds[key].Type:\r
510 if (BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName) not in SourcePcdDict['FixedAtBuild']:\r
511 SourcePcdDict['FixedAtBuild'].append((BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName))\r
512 else:\r
513 pass\r
97cdb33b
YZ
514 #\r
515 # A PCD can only use one type for all source modules\r
516 #\r
517 for i in SourcePcdDict_Keys:\r
518 for j in SourcePcdDict_Keys:\r
519 if i != j:\r
520 IntersectionList = list(set(SourcePcdDict[i]).intersection(set(SourcePcdDict[j])))\r
521 if len(IntersectionList) > 0:\r
522 EdkLogger.error(\r
523 'build',\r
524 FORMAT_INVALID,\r
525 "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
526 ExtraData="%s" % '\n\t'.join([str(P[1]+'.'+P[0]) for P in IntersectionList])\r
527 )\r
528 else:\r
529 pass\r
2a29017e
YZ
530\r
531 #\r
532 # intersection the BinaryPCD for Mixed PCD\r
533 #\r
534 for i in BinaryPcdDict_Keys:\r
535 for j in BinaryPcdDict_Keys:\r
536 if i != j:\r
537 IntersectionList = list(set(BinaryPcdDict[i]).intersection(set(BinaryPcdDict[j])))\r
538 for item in IntersectionList:\r
539 NewPcd1 = (item[0] + '_' + i, item[1])\r
540 NewPcd2 = (item[0] + '_' + j, item[1])\r
541 if item not in GlobalData.MixedPcd:\r
542 GlobalData.MixedPcd[item] = [NewPcd1, NewPcd2]\r
543 else:\r
544 if NewPcd1 not in GlobalData.MixedPcd[item]:\r
545 GlobalData.MixedPcd[item].append(NewPcd1)\r
546 if NewPcd2 not in GlobalData.MixedPcd[item]:\r
547 GlobalData.MixedPcd[item].append(NewPcd2)\r
548 else:\r
549 pass\r
550\r
551 #\r
552 # intersection the SourcePCD and BinaryPCD for Mixed PCD\r
553 #\r
554 for i in SourcePcdDict_Keys:\r
555 for j in BinaryPcdDict_Keys:\r
556 if i != j:\r
557 IntersectionList = list(set(SourcePcdDict[i]).intersection(set(BinaryPcdDict[j])))\r
558 for item in IntersectionList:\r
559 NewPcd1 = (item[0] + '_' + i, item[1])\r
560 NewPcd2 = (item[0] + '_' + j, item[1])\r
561 if item not in GlobalData.MixedPcd:\r
562 GlobalData.MixedPcd[item] = [NewPcd1, NewPcd2]\r
563 else:\r
564 if NewPcd1 not in GlobalData.MixedPcd[item]:\r
565 GlobalData.MixedPcd[item].append(NewPcd1)\r
566 if NewPcd2 not in GlobalData.MixedPcd[item]:\r
567 GlobalData.MixedPcd[item].append(NewPcd2)\r
568 else:\r
569 pass\r
570\r
571 for BuildData in PGen.BuildDatabase._CACHE_.values():\r
572 if BuildData.Arch != Arch:\r
573 continue\r
574 for key in BuildData.Pcds:\r
575 for SinglePcd in GlobalData.MixedPcd:\r
576 if (BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName) == SinglePcd:\r
577 for item in GlobalData.MixedPcd[SinglePcd]:\r
578 Pcd_Type = item[0].split('_')[-1]\r
579 if (Pcd_Type == BuildData.Pcds[key].Type) or (Pcd_Type == TAB_PCDS_DYNAMIC_EX and BuildData.Pcds[key].Type in GenC.gDynamicExPcd) or \\r
580 (Pcd_Type == TAB_PCDS_DYNAMIC and BuildData.Pcds[key].Type in GenC.gDynamicPcd):\r
581 Value = BuildData.Pcds[key]\r
582 Value.TokenCName = BuildData.Pcds[key].TokenCName + '_' + Pcd_Type\r
583 if len(key) == 2:\r
584 newkey = (Value.TokenCName, key[1])\r
585 elif len(key) == 3:\r
586 newkey = (Value.TokenCName, key[1], key[2])\r
587 del BuildData.Pcds[key]\r
588 BuildData.Pcds[newkey] = Value\r
589 break\r
590 else:\r
591 pass\r
592 break\r
593 else:\r
594 pass\r
595\r
596 # handle the mixed pcd in FDF file\r
597 for key in PcdSet:\r
598 if key in GlobalData.MixedPcd:\r
599 Value = PcdSet[key]\r
600 del PcdSet[key]\r
601 for item in GlobalData.MixedPcd[key]:\r
602 PcdSet[item] = Value\r
603\r
97fa0ee9 604 #Collect package set information from INF of FDF\r
a0a2cd1e
FB
605 PkgSet = set()\r
606 for Inf in ModuleList:\r
607 ModuleFile = PathClass(NormPath(Inf), GlobalData.gWorkspace, Arch)\r
608 if ModuleFile in Platform.Modules:\r
609 continue\r
610 ModuleData = self.BuildDatabase[ModuleFile, Arch, Target, Toolchain]\r
611 PkgSet.update(ModuleData.Packages)\r
612 Pkgs = list(PkgSet) + list(PGen.PackageList)\r
64b2609f 613 for Pkg in Pkgs:\r
25918452
LG
614 for Pcd in Pkg.Pcds:\r
615 DecPcds[Pcd[0], Pcd[1]] = Pkg.Pcds[Pcd]\r
4afd3d04 616 DecPcdsKey.add((Pcd[0], Pcd[1], Pcd[2]))\r
64b2609f 617\r
52302d4d
LG
618 Platform.SkuName = self.SkuId\r
619 for Name, Guid in PcdSet:\r
64b2609f
LG
620 if (Name, Guid) not in DecPcds:\r
621 EdkLogger.error(\r
622 'build',\r
623 PARSER_ERROR,\r
624 "PCD (%s.%s) used in FDF is not declared in DEC files." % (Guid, Name),\r
625 File = self.FdfProfile.PcdFileLineDict[Name, Guid][0],\r
626 Line = self.FdfProfile.PcdFileLineDict[Name, Guid][1]\r
627 )\r
4afd3d04
LG
628 else:\r
629 # Check whether Dynamic or DynamicEx PCD used in FDF file. If used, build break and give a error message.\r
630 if (Name, Guid, TAB_PCDS_FIXED_AT_BUILD) in DecPcdsKey \\r
631 or (Name, Guid, TAB_PCDS_PATCHABLE_IN_MODULE) in DecPcdsKey \\r
632 or (Name, Guid, TAB_PCDS_FEATURE_FLAG) in DecPcdsKey:\r
633 Platform.AddPcd(Name, Guid, PcdSet[Name, Guid])\r
634 continue\r
635 elif (Name, Guid, TAB_PCDS_DYNAMIC) in DecPcdsKey or (Name, Guid, TAB_PCDS_DYNAMIC_EX) in DecPcdsKey:\r
636 EdkLogger.error(\r
637 'build',\r
638 PARSER_ERROR,\r
639 "Using Dynamic or DynamicEx type of PCD [%s.%s] in FDF file is not allowed." % (Guid, Name),\r
640 File = self.FdfProfile.PcdFileLineDict[Name, Guid][0],\r
641 Line = self.FdfProfile.PcdFileLineDict[Name, Guid][1]\r
642 )\r
52302d4d
LG
643\r
644 Pa = PlatformAutoGen(self, self.MetaFile, Target, Toolchain, Arch)\r
645 #\r
646 # Explicitly collect platform's dynamic PCDs\r
647 #\r
648 Pa.CollectPlatformDynamicPcds()\r
2bc3256c 649 Pa.CollectFixedAtBuildPcds()\r
52302d4d 650 self.AutoGenObjectList.append(Pa)\r
47fea6af 651\r
36d083ef
YZ
652 #\r
653 # Generate Package level hash value\r
654 #\r
655 GlobalData.gPackageHash[Arch] = {}\r
656 if GlobalData.gUseHashCache:\r
657 for Pkg in Pkgs:\r
658 self._GenPkgLevelHash(Pkg)\r
659\r
6780eef1
LG
660 #\r
661 # Check PCDs token value conflict in each DEC file.\r
662 #\r
663 self._CheckAllPcdsTokenValueConflict()\r
47fea6af 664\r
4234283c
LG
665 #\r
666 # Check PCD type and definition between DSC and DEC\r
667 #\r
668 self._CheckPcdDefineAndType()\r
97fa0ee9
YL
669\r
670# if self.FdfFile:\r
671# self._CheckDuplicateInFV(Fdf)\r
672\r
c17956e0 673 #\r
2d499388 674 # Create BuildOptions Macro & PCD metafile, also add the Active Platform and FDF file.\r
c17956e0
DL
675 #\r
676 content = 'gCommandLineDefines: '\r
677 content += str(GlobalData.gCommandLineDefines)\r
678 content += os.linesep\r
679 content += 'BuildOptionPcd: '\r
680 content += str(GlobalData.BuildOptionPcd)\r
2d499388
YZ
681 content += os.linesep\r
682 content += 'Active Platform: '\r
683 content += str(self.Platform)\r
684 content += os.linesep\r
685 if self.FdfFile:\r
686 content += 'Flash Image Definition: '\r
687 content += str(self.FdfFile)\r
36d083ef
YZ
688 content += os.linesep\r
689 if GlobalData.gBinCacheDest:\r
690 content += 'Cache of .efi location: '\r
691 content += str(GlobalData.gBinCacheDest)\r
c17956e0
DL
692 SaveFileOnChange(os.path.join(self.BuildDir, 'BuildOptions'), content, False)\r
693\r
99adfe9f
YZ
694 #\r
695 # Create PcdToken Number file for Dynamic/DynamicEx Pcd.\r
696 #\r
697 PcdTokenNumber = 'PcdTokenNumber: '\r
698 if Pa.PcdTokenNumber:\r
699 if Pa.DynamicPcdList:\r
700 for Pcd in Pa.DynamicPcdList:\r
701 PcdTokenNumber += os.linesep\r
702 PcdTokenNumber += str((Pcd.TokenCName, Pcd.TokenSpaceGuidCName))\r
703 PcdTokenNumber += ' : '\r
704 PcdTokenNumber += str(Pa.PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName])\r
705 SaveFileOnChange(os.path.join(self.BuildDir, 'PcdTokenNumber'), PcdTokenNumber, False)\r
706\r
c17956e0
DL
707 #\r
708 # Get set of workspace metafiles\r
709 #\r
710 AllWorkSpaceMetaFiles = self._GetMetaFiles(Target, Toolchain, Arch)\r
711\r
712 #\r
713 # Retrieve latest modified time of all metafiles\r
714 #\r
715 SrcTimeStamp = 0\r
716 for f in AllWorkSpaceMetaFiles:\r
717 if os.stat(f)[8] > SrcTimeStamp:\r
718 SrcTimeStamp = os.stat(f)[8]\r
719 self._SrcTimeStamp = SrcTimeStamp\r
720\r
36d083ef
YZ
721 if GlobalData.gUseHashCache:\r
722 m = hashlib.md5()\r
723 for files in AllWorkSpaceMetaFiles:\r
724 if files.endswith('.dec'):\r
725 continue\r
726 f = open(files, 'r')\r
727 Content = f.read()\r
728 f.close()\r
729 m.update(Content)\r
730 SaveFileOnChange(os.path.join(self.BuildDir, 'AutoGen.hash'), m.hexdigest(), True)\r
731 GlobalData.gPlatformHash = m.hexdigest()\r
732\r
c17956e0
DL
733 #\r
734 # Write metafile list to build directory\r
735 #\r
736 AutoGenFilePath = os.path.join(self.BuildDir, 'AutoGen')\r
737 if os.path.exists (AutoGenFilePath):\r
738 os.remove(AutoGenFilePath)\r
739 if not os.path.exists(self.BuildDir):\r
740 os.makedirs(self.BuildDir)\r
741 with open(os.path.join(self.BuildDir, 'AutoGen'), 'w+') as file:\r
742 for f in AllWorkSpaceMetaFiles:\r
743 print >> file, f\r
52302d4d
LG
744 return True\r
745\r
36d083ef
YZ
746 def _GenPkgLevelHash(self, Pkg):\r
747 PkgDir = os.path.join(self.BuildDir, Pkg.Arch, Pkg.PackageName)\r
748 CreateDirectory(PkgDir)\r
749 HashFile = os.path.join(PkgDir, Pkg.PackageName + '.hash')\r
750 m = hashlib.md5()\r
751 # Get .dec file's hash value\r
752 f = open(Pkg.MetaFile.Path, 'r')\r
753 Content = f.read()\r
754 f.close()\r
755 m.update(Content)\r
756 # Get include files hash value\r
757 if Pkg.Includes:\r
758 for inc in Pkg.Includes:\r
759 for Root, Dirs, Files in os.walk(str(inc)):\r
760 for File in Files:\r
761 File_Path = os.path.join(Root, File)\r
762 f = open(File_Path, 'r')\r
763 Content = f.read()\r
764 f.close()\r
765 m.update(Content)\r
766 SaveFileOnChange(HashFile, m.hexdigest(), True)\r
767 if Pkg.PackageName not in GlobalData.gPackageHash[Pkg.Arch]:\r
768 GlobalData.gPackageHash[Pkg.Arch][Pkg.PackageName] = m.hexdigest()\r
763e8edf 769\r
c17956e0
DL
770 def _GetMetaFiles(self, Target, Toolchain, Arch):\r
771 AllWorkSpaceMetaFiles = set()\r
772 #\r
773 # add fdf\r
774 #\r
775 if self.FdfFile:\r
776 AllWorkSpaceMetaFiles.add (self.FdfFile.Path)\r
777 if self.FdfFile:\r
778 FdfFiles = GlobalData.gFdfParser.GetAllIncludedFile()\r
779 for f in FdfFiles:\r
780 AllWorkSpaceMetaFiles.add (f.FileName)\r
781 #\r
782 # add dsc\r
783 #\r
784 AllWorkSpaceMetaFiles.add(self.MetaFile.Path)\r
785\r
786 #\r
86601b78
DL
787 # add build_rule.txt & tools_def.txt\r
788 #\r
51de5c30
YZ
789 AllWorkSpaceMetaFiles.add(os.path.join(GlobalData.gConfDirectory, gDefaultBuildRuleFile))\r
790 AllWorkSpaceMetaFiles.add(os.path.join(GlobalData.gConfDirectory, gDefaultToolsDefFile))\r
86601b78 791\r
c17956e0
DL
792 # add BuildOption metafile\r
793 #\r
794 AllWorkSpaceMetaFiles.add(os.path.join(self.BuildDir, 'BuildOptions'))\r
795\r
99adfe9f
YZ
796 # add PcdToken Number file for Dynamic/DynamicEx Pcd\r
797 #\r
798 AllWorkSpaceMetaFiles.add(os.path.join(self.BuildDir, 'PcdTokenNumber'))\r
799\r
c17956e0
DL
800 for Arch in self.ArchList:\r
801 Platform = self.BuildDatabase[self.MetaFile, Arch, Target, Toolchain]\r
802 PGen = PlatformAutoGen(self, self.MetaFile, Target, Toolchain, Arch)\r
803\r
804 #\r
805 # add dec\r
806 #\r
807 for Package in PGen.PackageList:\r
808 AllWorkSpaceMetaFiles.add(Package.MetaFile.Path)\r
809\r
810 #\r
811 # add included dsc\r
812 #\r
813 for filePath in Platform._RawData.IncludedFiles:\r
814 AllWorkSpaceMetaFiles.add(filePath.Path)\r
815\r
816 return AllWorkSpaceMetaFiles\r
817\r
79b74a03
LG
818 ## _CheckDuplicateInFV() method\r
819 #\r
820 # Check whether there is duplicate modules/files exist in FV section. \r
821 # The check base on the file GUID;\r
822 #\r
823 def _CheckDuplicateInFV(self, Fdf):\r
824 for Fv in Fdf.Profile.FvDict:\r
825 _GuidDict = {}\r
826 for FfsFile in Fdf.Profile.FvDict[Fv].FfsList:\r
827 if FfsFile.InfFileName and FfsFile.NameGuid == None:\r
828 #\r
829 # Get INF file GUID\r
830 #\r
47fea6af 831 InfFoundFlag = False\r
79b74a03 832 for Pa in self.AutoGenObjectList:\r
64b2609f
LG
833 if InfFoundFlag:\r
834 break\r
79b74a03
LG
835 for Module in Pa.ModuleAutoGenList:\r
836 if path.normpath(Module.MetaFile.File) == path.normpath(FfsFile.InfFileName):\r
837 InfFoundFlag = True\r
838 if not Module.Guid.upper() in _GuidDict.keys():\r
839 _GuidDict[Module.Guid.upper()] = FfsFile\r
64b2609f 840 break\r
79b74a03 841 else:\r
47fea6af 842 EdkLogger.error("build",\r
79b74a03 843 FORMAT_INVALID,\r
47fea6af 844 "Duplicate GUID found for these lines: Line %d: %s and Line %d: %s. GUID: %s" % (FfsFile.CurrentLineNum,\r
79b74a03
LG
845 FfsFile.CurrentLineContent,\r
846 _GuidDict[Module.Guid.upper()].CurrentLineNum,\r
847 _GuidDict[Module.Guid.upper()].CurrentLineContent,\r
848 Module.Guid.upper()),\r
849 ExtraData=self.FdfFile)\r
850 #\r
851 # Some INF files not have entity in DSC file. \r
852 #\r
853 if not InfFoundFlag:\r
854 if FfsFile.InfFileName.find('$') == -1:\r
855 InfPath = NormPath(FfsFile.InfFileName)\r
856 if not os.path.exists(InfPath):\r
857 EdkLogger.error('build', GENFDS_ERROR, "Non-existant Module %s !" % (FfsFile.InfFileName))\r
47fea6af 858\r
79b74a03
LG
859 PathClassObj = PathClass(FfsFile.InfFileName, self.WorkspaceDir)\r
860 #\r
861 # Here we just need to get FILE_GUID from INF file, use 'COMMON' as ARCH attribute. and use \r
862 # BuildObject from one of AutoGenObjectList is enough.\r
863 #\r
864 InfObj = self.AutoGenObjectList[0].BuildDatabase.WorkspaceDb.BuildObject[PathClassObj, 'COMMON', self.BuildTarget, self.ToolChain]\r
865 if not InfObj.Guid.upper() in _GuidDict.keys():\r
866 _GuidDict[InfObj.Guid.upper()] = FfsFile\r
867 else:\r
47fea6af 868 EdkLogger.error("build",\r
79b74a03 869 FORMAT_INVALID,\r
47fea6af 870 "Duplicate GUID found for these lines: Line %d: %s and Line %d: %s. GUID: %s" % (FfsFile.CurrentLineNum,\r
79b74a03
LG
871 FfsFile.CurrentLineContent,\r
872 _GuidDict[InfObj.Guid.upper()].CurrentLineNum,\r
873 _GuidDict[InfObj.Guid.upper()].CurrentLineContent,\r
874 InfObj.Guid.upper()),\r
875 ExtraData=self.FdfFile)\r
876 InfFoundFlag = False\r
47fea6af 877\r
79b74a03
LG
878 if FfsFile.NameGuid != None:\r
879 _CheckPCDAsGuidPattern = re.compile("^PCD\(.+\..+\)$")\r
47fea6af 880\r
79b74a03
LG
881 #\r
882 # If the NameGuid reference a PCD name. \r
883 # The style must match: PCD(xxxx.yyy)\r
884 #\r
885 if _CheckPCDAsGuidPattern.match(FfsFile.NameGuid):\r
886 #\r
887 # Replace the PCD value.\r
888 #\r
889 _PcdName = FfsFile.NameGuid.lstrip("PCD(").rstrip(")")\r
890 PcdFoundFlag = False\r
891 for Pa in self.AutoGenObjectList:\r
892 if not PcdFoundFlag:\r
893 for PcdItem in Pa.AllPcdList:\r
894 if (PcdItem.TokenSpaceGuidCName + "." + PcdItem.TokenCName) == _PcdName:\r
895 #\r
896 # First convert from CFormatGuid to GUID string\r
897 #\r
898 _PcdGuidString = GuidStructureStringToGuidString(PcdItem.DefaultValue)\r
47fea6af 899\r
79b74a03
LG
900 if not _PcdGuidString:\r
901 #\r
902 # Then try Byte array.\r
903 #\r
904 _PcdGuidString = GuidStructureByteArrayToGuidString(PcdItem.DefaultValue)\r
47fea6af 905\r
79b74a03
LG
906 if not _PcdGuidString:\r
907 #\r
908 # Not Byte array or CFormat GUID, raise error.\r
909 #\r
910 EdkLogger.error("build",\r
911 FORMAT_INVALID,\r
47fea6af 912 "The format of PCD value is incorrect. PCD: %s , Value: %s\n" % (_PcdName, PcdItem.DefaultValue),\r
79b74a03 913 ExtraData=self.FdfFile)\r
47fea6af
YZ
914\r
915 if not _PcdGuidString.upper() in _GuidDict.keys():\r
79b74a03
LG
916 _GuidDict[_PcdGuidString.upper()] = FfsFile\r
917 PcdFoundFlag = True\r
918 break\r
919 else:\r
47fea6af 920 EdkLogger.error("build",\r
79b74a03 921 FORMAT_INVALID,\r
47fea6af 922 "Duplicate GUID found for these lines: Line %d: %s and Line %d: %s. GUID: %s" % (FfsFile.CurrentLineNum,\r
79b74a03
LG
923 FfsFile.CurrentLineContent,\r
924 _GuidDict[_PcdGuidString.upper()].CurrentLineNum,\r
925 _GuidDict[_PcdGuidString.upper()].CurrentLineContent,\r
926 FfsFile.NameGuid.upper()),\r
47fea6af
YZ
927 ExtraData=self.FdfFile)\r
928\r
79b74a03
LG
929 if not FfsFile.NameGuid.upper() in _GuidDict.keys():\r
930 _GuidDict[FfsFile.NameGuid.upper()] = FfsFile\r
931 else:\r
932 #\r
933 # Two raw file GUID conflict.\r
934 #\r
47fea6af 935 EdkLogger.error("build",\r
79b74a03 936 FORMAT_INVALID,\r
47fea6af 937 "Duplicate GUID found for these lines: Line %d: %s and Line %d: %s. GUID: %s" % (FfsFile.CurrentLineNum,\r
79b74a03
LG
938 FfsFile.CurrentLineContent,\r
939 _GuidDict[FfsFile.NameGuid.upper()].CurrentLineNum,\r
940 _GuidDict[FfsFile.NameGuid.upper()].CurrentLineContent,\r
941 FfsFile.NameGuid.upper()),\r
942 ExtraData=self.FdfFile)\r
47fea6af 943\r
79b74a03 944\r
4234283c
LG
945 def _CheckPcdDefineAndType(self):\r
946 PcdTypeList = [\r
947 "FixedAtBuild", "PatchableInModule", "FeatureFlag",\r
948 "Dynamic", #"DynamicHii", "DynamicVpd",\r
949 "DynamicEx", # "DynamicExHii", "DynamicExVpd"\r
950 ]\r
951\r
952 # This dict store PCDs which are not used by any modules with specified arches\r
953 UnusedPcd = sdict()\r
954 for Pa in self.AutoGenObjectList:\r
955 # Key of DSC's Pcds dictionary is PcdCName, TokenSpaceGuid\r
956 for Pcd in Pa.Platform.Pcds:\r
957 PcdType = Pa.Platform.Pcds[Pcd].Type\r
47fea6af 958\r
4234283c
LG
959 # If no PCD type, this PCD comes from FDF \r
960 if not PcdType:\r
961 continue\r
47fea6af 962\r
4234283c
LG
963 # Try to remove Hii and Vpd suffix\r
964 if PcdType.startswith("DynamicEx"):\r
965 PcdType = "DynamicEx"\r
966 elif PcdType.startswith("Dynamic"):\r
967 PcdType = "Dynamic"\r
47fea6af 968\r
4234283c
LG
969 for Package in Pa.PackageList:\r
970 # Key of DEC's Pcds dictionary is PcdCName, TokenSpaceGuid, PcdType\r
971 if (Pcd[0], Pcd[1], PcdType) in Package.Pcds:\r
972 break\r
973 for Type in PcdTypeList:\r
974 if (Pcd[0], Pcd[1], Type) in Package.Pcds:\r
975 EdkLogger.error(\r
976 'build',\r
977 FORMAT_INVALID,\r
978 "Type [%s] of PCD [%s.%s] in DSC file doesn't match the type [%s] defined in DEC file." \\r
979 % (Pa.Platform.Pcds[Pcd].Type, Pcd[1], Pcd[0], Type),\r
980 ExtraData=None\r
981 )\r
982 return\r
983 else:\r
984 UnusedPcd.setdefault(Pcd, []).append(Pa.Arch)\r
985\r
986 for Pcd in UnusedPcd:\r
987 EdkLogger.warn(\r
988 'build',\r
989 "The PCD was not specified by any INF module in the platform for the given architecture.\n"\r
990 "\tPCD: [%s.%s]\n\tPlatform: [%s]\n\tArch: %s"\r
991 % (Pcd[1], Pcd[0], os.path.basename(str(self.MetaFile)), str(UnusedPcd[Pcd])),\r
992 ExtraData=None\r
993 )\r
994\r
52302d4d
LG
995 def __repr__(self):\r
996 return "%s [%s]" % (self.MetaFile, ", ".join(self.ArchList))\r
997\r
998 ## Return the directory to store FV files\r
999 def _GetFvDir(self):\r
1000 if self._FvDir == None:\r
1001 self._FvDir = path.join(self.BuildDir, 'FV')\r
1002 return self._FvDir\r
1003\r
1004 ## Return the directory to store all intermediate and final files built\r
1005 def _GetBuildDir(self):\r
36d083ef
YZ
1006 if self._BuildDir == None:\r
1007 return self.AutoGenObjectList[0].BuildDir\r
52302d4d
LG
1008\r
1009 ## Return the build output directory platform specifies\r
1010 def _GetOutputDir(self):\r
1011 return self.Platform.OutputDirectory\r
1012\r
1013 ## Return platform name\r
1014 def _GetName(self):\r
1015 return self.Platform.PlatformName\r
1016\r
1017 ## Return meta-file GUID\r
1018 def _GetGuid(self):\r
1019 return self.Platform.Guid\r
1020\r
1021 ## Return platform version\r
1022 def _GetVersion(self):\r
1023 return self.Platform.Version\r
1024\r
1025 ## Return paths of tools\r
1026 def _GetToolDefinition(self):\r
1027 return self.AutoGenObjectList[0].ToolDefinition\r
1028\r
1029 ## Return directory of platform makefile\r
1030 #\r
1031 # @retval string Makefile directory\r
1032 #\r
1033 def _GetMakeFileDir(self):\r
1034 if self._MakeFileDir == None:\r
1035 self._MakeFileDir = self.BuildDir\r
1036 return self._MakeFileDir\r
1037\r
1038 ## Return build command string\r
1039 #\r
1040 # @retval string Build command string\r
1041 #\r
1042 def _GetBuildCommand(self):\r
1043 if self._BuildCommand == None:\r
1044 # BuildCommand should be all the same. So just get one from platform AutoGen\r
1045 self._BuildCommand = self.AutoGenObjectList[0].BuildCommand\r
1046 return self._BuildCommand\r
47fea6af 1047\r
6780eef1
LG
1048 ## Check the PCDs token value conflict in each DEC file.\r
1049 #\r
1050 # Will cause build break and raise error message while two PCDs conflict.\r
1051 # \r
1052 # @return None\r
1053 #\r
1054 def _CheckAllPcdsTokenValueConflict(self):\r
b36d134f
LG
1055 for Pa in self.AutoGenObjectList:\r
1056 for Package in Pa.PackageList:\r
6780eef1 1057 PcdList = Package.Pcds.values()\r
f827cd07 1058 PcdList.sort(lambda x, y: cmp(int(x.TokenValue, 0), int(y.TokenValue, 0))) \r
6780eef1
LG
1059 Count = 0\r
1060 while (Count < len(PcdList) - 1) :\r
1061 Item = PcdList[Count]\r
1062 ItemNext = PcdList[Count + 1]\r
1063 #\r
1064 # Make sure in the same token space the TokenValue should be unique\r
1065 #\r
f827cd07 1066 if (int(Item.TokenValue, 0) == int(ItemNext.TokenValue, 0)):\r
6780eef1
LG
1067 SameTokenValuePcdList = []\r
1068 SameTokenValuePcdList.append(Item)\r
1069 SameTokenValuePcdList.append(ItemNext)\r
1070 RemainPcdListLength = len(PcdList) - Count - 2\r
1071 for ValueSameCount in range(RemainPcdListLength):\r
f827cd07 1072 if int(PcdList[len(PcdList) - RemainPcdListLength + ValueSameCount].TokenValue, 0) == int(Item.TokenValue, 0):\r
6780eef1
LG
1073 SameTokenValuePcdList.append(PcdList[len(PcdList) - RemainPcdListLength + ValueSameCount])\r
1074 else:\r
1075 break;\r
1076 #\r
1077 # Sort same token value PCD list with TokenGuid and TokenCName\r
1078 #\r
47fea6af
YZ
1079 SameTokenValuePcdList.sort(lambda x, y: cmp("%s.%s" % (x.TokenSpaceGuidCName, x.TokenCName), "%s.%s" % (y.TokenSpaceGuidCName, y.TokenCName)))\r
1080 SameTokenValuePcdListCount = 0\r
6780eef1 1081 while (SameTokenValuePcdListCount < len(SameTokenValuePcdList) - 1):\r
2a29017e 1082 Flag = False\r
47fea6af
YZ
1083 TemListItem = SameTokenValuePcdList[SameTokenValuePcdListCount]\r
1084 TemListItemNext = SameTokenValuePcdList[SameTokenValuePcdListCount + 1]\r
1085\r
6780eef1 1086 if (TemListItem.TokenSpaceGuidCName == TemListItemNext.TokenSpaceGuidCName) and (TemListItem.TokenCName != TemListItemNext.TokenCName):\r
2a29017e
YZ
1087 for PcdItem in GlobalData.MixedPcd:\r
1088 if (TemListItem.TokenCName, TemListItem.TokenSpaceGuidCName) in GlobalData.MixedPcd[PcdItem] or \\r
1089 (TemListItemNext.TokenCName, TemListItemNext.TokenSpaceGuidCName) in GlobalData.MixedPcd[PcdItem]:\r
1090 Flag = True\r
1091 if not Flag:\r
1092 EdkLogger.error(\r
1093 'build',\r
1094 FORMAT_INVALID,\r
1095 "The TokenValue [%s] of PCD [%s.%s] is conflict with: [%s.%s] in %s"\\r
1096 % (TemListItem.TokenValue, TemListItem.TokenSpaceGuidCName, TemListItem.TokenCName, TemListItemNext.TokenSpaceGuidCName, TemListItemNext.TokenCName, Package),\r
1097 ExtraData=None\r
1098 )\r
6780eef1
LG
1099 SameTokenValuePcdListCount += 1\r
1100 Count += SameTokenValuePcdListCount\r
1101 Count += 1\r
47fea6af 1102\r
6780eef1 1103 PcdList = Package.Pcds.values()\r
47fea6af 1104 PcdList.sort(lambda x, y: cmp("%s.%s" % (x.TokenSpaceGuidCName, x.TokenCName), "%s.%s" % (y.TokenSpaceGuidCName, y.TokenCName)))\r
6780eef1
LG
1105 Count = 0\r
1106 while (Count < len(PcdList) - 1) :\r
1107 Item = PcdList[Count]\r
47fea6af 1108 ItemNext = PcdList[Count + 1]\r
6780eef1
LG
1109 #\r
1110 # Check PCDs with same TokenSpaceGuidCName.TokenCName have same token value as well.\r
1111 #\r
f827cd07 1112 if (Item.TokenSpaceGuidCName == ItemNext.TokenSpaceGuidCName) and (Item.TokenCName == ItemNext.TokenCName) and (int(Item.TokenValue, 0) != int(ItemNext.TokenValue, 0)):\r
6780eef1
LG
1113 EdkLogger.error(\r
1114 'build',\r
1115 FORMAT_INVALID,\r
1116 "The TokenValue [%s] of PCD [%s.%s] in %s defined in two places should be same as well."\\r
1117 % (Item.TokenValue, Item.TokenSpaceGuidCName, Item.TokenCName, Package),\r
1118 ExtraData=None\r
1119 )\r
1120 Count += 1\r
97fa0ee9 1121 ## Generate fds command\r
03af2753
HC
1122 def _GenFdsCommand(self):\r
1123 return (GenMake.TopLevelMakefile(self)._TEMPLATE_.Replace(GenMake.TopLevelMakefile(self)._TemplateDict)).strip()\r
52302d4d 1124\r
e56468c0 1125 ## Create makefile for the platform and modules in it\r
52302d4d
LG
1126 #\r
1127 # @param CreateDepsMakeFile Flag indicating if the makefile for\r
1128 # modules will be created as well\r
1129 #\r
1130 def CreateMakeFile(self, CreateDepsMakeFile=False):\r
52302d4d
LG
1131 if CreateDepsMakeFile:\r
1132 for Pa in self.AutoGenObjectList:\r
1133 Pa.CreateMakeFile(CreateDepsMakeFile)\r
1134\r
1135 ## Create autogen code for platform and modules\r
1136 #\r
1137 # Since there's no autogen code for platform, this method will do nothing\r
1138 # if CreateModuleCodeFile is set to False.\r
1139 #\r
1140 # @param CreateDepsCodeFile Flag indicating if creating module's\r
1141 # autogen code file or not\r
1142 #\r
1143 def CreateCodeFile(self, CreateDepsCodeFile=False):\r
1144 if not CreateDepsCodeFile:\r
1145 return\r
1146 for Pa in self.AutoGenObjectList:\r
1147 Pa.CreateCodeFile(CreateDepsCodeFile)\r
1148\r
7c1fd323
LG
1149 ## Create AsBuilt INF file the platform\r
1150 #\r
1151 def CreateAsBuiltInf(self):\r
1152 return\r
1153\r
52302d4d
LG
1154 Name = property(_GetName)\r
1155 Guid = property(_GetGuid)\r
1156 Version = property(_GetVersion)\r
1157 OutputDir = property(_GetOutputDir)\r
1158\r
1159 ToolDefinition = property(_GetToolDefinition) # toolcode : tool path\r
1160\r
1161 BuildDir = property(_GetBuildDir)\r
1162 FvDir = property(_GetFvDir)\r
1163 MakeFileDir = property(_GetMakeFileDir)\r
1164 BuildCommand = property(_GetBuildCommand)\r
03af2753 1165 GenFdsCommand = property(_GenFdsCommand)\r
52302d4d
LG
1166\r
1167## AutoGen class for platform\r
1168#\r
1169# PlatformAutoGen class will process the original information in platform\r
1170# file in order to generate makefile for platform.\r
1171#\r
1172class PlatformAutoGen(AutoGen):\r
1173 #\r
1174 # Used to store all PCDs for both PEI and DXE phase, in order to generate \r
1175 # correct PCD database\r
1176 # \r
1177 _DynaPcdList_ = []\r
1178 _NonDynaPcdList_ = []\r
61ee1dff 1179 _PlatformPcds = {}\r
6780eef1
LG
1180 \r
1181 #\r
1182 # The priority list while override build option \r
1183 #\r
1184 PrioList = {"0x11111" : 16, # TARGET_TOOLCHAIN_ARCH_COMMANDTYPE_ATTRIBUTE (Highest)\r
1185 "0x01111" : 15, # ******_TOOLCHAIN_ARCH_COMMANDTYPE_ATTRIBUTE\r
1186 "0x10111" : 14, # TARGET_*********_ARCH_COMMANDTYPE_ATTRIBUTE\r
1187 "0x00111" : 13, # ******_*********_ARCH_COMMANDTYPE_ATTRIBUTE \r
1188 "0x11011" : 12, # TARGET_TOOLCHAIN_****_COMMANDTYPE_ATTRIBUTE\r
1189 "0x01011" : 11, # ******_TOOLCHAIN_****_COMMANDTYPE_ATTRIBUTE\r
1190 "0x10011" : 10, # TARGET_*********_****_COMMANDTYPE_ATTRIBUTE\r
1191 "0x00011" : 9, # ******_*********_****_COMMANDTYPE_ATTRIBUTE\r
1192 "0x11101" : 8, # TARGET_TOOLCHAIN_ARCH_***********_ATTRIBUTE\r
1193 "0x01101" : 7, # ******_TOOLCHAIN_ARCH_***********_ATTRIBUTE\r
1194 "0x10101" : 6, # TARGET_*********_ARCH_***********_ATTRIBUTE\r
1195 "0x00101" : 5, # ******_*********_ARCH_***********_ATTRIBUTE\r
1196 "0x11001" : 4, # TARGET_TOOLCHAIN_****_***********_ATTRIBUTE\r
1197 "0x01001" : 3, # ******_TOOLCHAIN_****_***********_ATTRIBUTE\r
1198 "0x10001" : 2, # TARGET_*********_****_***********_ATTRIBUTE\r
1199 "0x00001" : 1} # ******_*********_****_***********_ATTRIBUTE (Lowest)\r
47fea6af 1200\r
52302d4d
LG
1201 ## The real constructor of PlatformAutoGen\r
1202 #\r
1203 # This method is not supposed to be called by users of PlatformAutoGen. It's\r
1204 # only used by factory method __new__() to do real initialization work for an\r
1205 # object of PlatformAutoGen\r
1206 #\r
1207 # @param Workspace WorkspaceAutoGen object\r
1208 # @param PlatformFile Platform file (DSC file)\r
1209 # @param Target Build target (DEBUG, RELEASE)\r
1210 # @param Toolchain Name of tool chain\r
1211 # @param Arch arch of the platform supports\r
1212 #\r
1213 def _Init(self, Workspace, PlatformFile, Target, Toolchain, Arch):\r
1214 EdkLogger.debug(EdkLogger.DEBUG_9, "AutoGen platform [%s] [%s]" % (PlatformFile, Arch))\r
1215 GlobalData.gProcessingFile = "%s [%s, %s, %s]" % (PlatformFile, Arch, Toolchain, Target)\r
1216\r
1217 self.MetaFile = PlatformFile\r
1218 self.Workspace = Workspace\r
1219 self.WorkspaceDir = Workspace.WorkspaceDir\r
1220 self.ToolChain = Toolchain\r
1221 self.BuildTarget = Target\r
1222 self.Arch = Arch\r
1223 self.SourceDir = PlatformFile.SubDir\r
1224 self.SourceOverrideDir = None\r
1225 self.FdTargetList = self.Workspace.FdTargetList\r
1226 self.FvTargetList = self.Workspace.FvTargetList\r
1227 self.AllPcdList = []\r
a0a2cd1e
FB
1228 # get the original module/package/platform objects\r
1229 self.BuildDatabase = Workspace.BuildDatabase\r
52302d4d
LG
1230\r
1231 # flag indicating if the makefile/C-code file has been created or not\r
1232 self.IsMakeFileCreated = False\r
1233 self.IsCodeFileCreated = False\r
1234\r
1235 self._Platform = None\r
1236 self._Name = None\r
1237 self._Guid = None\r
1238 self._Version = None\r
1239\r
1240 self._BuildRule = None\r
1241 self._SourceDir = None\r
1242 self._BuildDir = None\r
1243 self._OutputDir = None\r
1244 self._FvDir = None\r
1245 self._MakeFileDir = None\r
1246 self._FdfFile = None\r
1247\r
1248 self._PcdTokenNumber = None # (TokenCName, TokenSpaceGuidCName) : GeneratedTokenNumber\r
1249 self._DynamicPcdList = None # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]\r
1250 self._NonDynamicPcdList = None # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]\r
2bc3256c 1251 self._NonDynamicPcdDict = {}\r
52302d4d
LG
1252\r
1253 self._ToolDefinitions = None\r
1254 self._ToolDefFile = None # toolcode : tool path\r
1255 self._ToolChainFamily = None\r
1256 self._BuildRuleFamily = None\r
1257 self._BuildOption = None # toolcode : option\r
1258 self._EdkBuildOption = None # edktoolcode : option\r
1259 self._EdkIIBuildOption = None # edkiitoolcode : option\r
1260 self._PackageList = None\r
1261 self._ModuleAutoGenList = None\r
1262 self._LibraryAutoGenList = None\r
1263 self._BuildCommand = None\r
a0a2cd1e
FB
1264 self._AsBuildInfList = []\r
1265 self._AsBuildModuleList = []\r
1266 if GlobalData.gFdfParser != None:\r
1267 self._AsBuildInfList = GlobalData.gFdfParser.Profile.InfList\r
1268 for Inf in self._AsBuildInfList:\r
1269 InfClass = PathClass(NormPath(Inf), GlobalData.gWorkspace, self.Arch)\r
1270 M = self.BuildDatabase[InfClass, self.Arch, self.BuildTarget, self.ToolChain]\r
1271 if not M.IsSupportedArch:\r
1272 continue\r
1273 self._AsBuildModuleList.append(InfClass)\r
03af2753
HC
1274 # get library/modules for build\r
1275 self.LibraryBuildDirectoryList = []\r
1276 self.ModuleBuildDirectoryList = []\r
52302d4d
LG
1277 return True\r
1278\r
1279 def __repr__(self):\r
1280 return "%s [%s]" % (self.MetaFile, self.Arch)\r
1281\r
1282 ## Create autogen code for platform and modules\r
1283 #\r
1284 # Since there's no autogen code for platform, this method will do nothing\r
1285 # if CreateModuleCodeFile is set to False.\r
1286 #\r
1287 # @param CreateModuleCodeFile Flag indicating if creating module's\r
1288 # autogen code file or not\r
1289 #\r
1290 def CreateCodeFile(self, CreateModuleCodeFile=False):\r
1291 # only module has code to be greated, so do nothing if CreateModuleCodeFile is False\r
1292 if self.IsCodeFileCreated or not CreateModuleCodeFile:\r
1293 return\r
1294\r
1295 for Ma in self.ModuleAutoGenList:\r
1296 Ma.CreateCodeFile(True)\r
1297\r
1298 # don't do this twice\r
1299 self.IsCodeFileCreated = True\r
1300\r
03af2753
HC
1301 ## Generate Fds Command\r
1302 def _GenFdsCommand(self):\r
1303 return self.Workspace.GenFdsCommand\r
481252bb 1304\r
52302d4d
LG
1305 ## Create makefile for the platform and mdoules in it\r
1306 #\r
1307 # @param CreateModuleMakeFile Flag indicating if the makefile for\r
1308 # modules will be created as well\r
1309 #\r
1310 def CreateMakeFile(self, CreateModuleMakeFile=False):\r
1311 if CreateModuleMakeFile:\r
1312 for ModuleFile in self.Platform.Modules:\r
1313 Ma = ModuleAutoGen(self.Workspace, ModuleFile, self.BuildTarget,\r
1314 self.ToolChain, self.Arch, self.MetaFile)\r
1315 Ma.CreateMakeFile(True)\r
97fa0ee9 1316 #Ma.CreateAsBuiltInf()\r
52302d4d
LG
1317\r
1318 # no need to create makefile for the platform more than once\r
1319 if self.IsMakeFileCreated:\r
1320 return\r
1321\r
03af2753 1322 # create library/module build dirs for platform\r
52302d4d 1323 Makefile = GenMake.PlatformMakefile(self)\r
03af2753
HC
1324 self.LibraryBuildDirectoryList = Makefile.GetLibraryBuildDirectoryList()\r
1325 self.ModuleBuildDirectoryList = Makefile.GetModuleBuildDirectoryList()\r
1326\r
52302d4d
LG
1327 self.IsMakeFileCreated = True\r
1328\r
2bc3256c
LG
1329 ## Deal with Shared FixedAtBuild Pcds\r
1330 #\r
1331 def CollectFixedAtBuildPcds(self):\r
1332 for LibAuto in self.LibraryAutoGenList:\r
1333 FixedAtBuildPcds = {} \r
1334 ShareFixedAtBuildPcdsSameValue = {} \r
1335 for Module in LibAuto._ReferenceModules: \r
1336 for Pcd in Module.FixedAtBuildPcds + LibAuto.FixedAtBuildPcds:\r
1337 key = ".".join((Pcd.TokenSpaceGuidCName,Pcd.TokenCName)) \r
1338 if key not in FixedAtBuildPcds:\r
1339 ShareFixedAtBuildPcdsSameValue[key] = True\r
1340 FixedAtBuildPcds[key] = Pcd.DefaultValue\r
1341 else:\r
1342 if FixedAtBuildPcds[key] != Pcd.DefaultValue:\r
1343 ShareFixedAtBuildPcdsSameValue[key] = False \r
1344 for Pcd in LibAuto.FixedAtBuildPcds:\r
1345 key = ".".join((Pcd.TokenSpaceGuidCName,Pcd.TokenCName))\r
1346 if (Pcd.TokenCName,Pcd.TokenSpaceGuidCName) not in self.NonDynamicPcdDict:\r
1347 continue\r
1348 else:\r
1349 DscPcd = self.NonDynamicPcdDict[(Pcd.TokenCName,Pcd.TokenSpaceGuidCName)]\r
1350 if DscPcd.Type != "FixedAtBuild":\r
1351 continue\r
1352 if key in ShareFixedAtBuildPcdsSameValue and ShareFixedAtBuildPcdsSameValue[key]: \r
1353 LibAuto.ConstPcd[key] = Pcd.DefaultValue\r
1354\r
52302d4d
LG
1355 ## Collect dynamic PCDs\r
1356 #\r
1357 # Gather dynamic PCDs list from each module and their settings from platform\r
1358 # This interface should be invoked explicitly when platform action is created.\r
1359 #\r
1360 def CollectPlatformDynamicPcds(self):\r
763e8edf
YZ
1361 # Override the platform Pcd's value by build option\r
1362 if GlobalData.BuildOptionPcd:\r
1363 for key in self.Platform.Pcds:\r
1364 PlatformPcd = self.Platform.Pcds[key]\r
1365 for PcdItem in GlobalData.BuildOptionPcd:\r
1366 if (PlatformPcd.TokenSpaceGuidCName, PlatformPcd.TokenCName) == (PcdItem[0], PcdItem[1]):\r
1367 PlatformPcd.DefaultValue = PcdItem[2]\r
1368 if PlatformPcd.SkuInfoList:\r
1369 Sku = PlatformPcd.SkuInfoList[PlatformPcd.SkuInfoList.keys()[0]]\r
1370 Sku.DefaultValue = PcdItem[2]\r
1371 break\r
1372\r
2a29017e
YZ
1373 for key in self.Platform.Pcds:\r
1374 for SinglePcd in GlobalData.MixedPcd:\r
1375 if (self.Platform.Pcds[key].TokenCName, self.Platform.Pcds[key].TokenSpaceGuidCName) == SinglePcd:\r
1376 for item in GlobalData.MixedPcd[SinglePcd]:\r
1377 Pcd_Type = item[0].split('_')[-1]\r
1378 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
1379 (Pcd_Type == TAB_PCDS_DYNAMIC and self.Platform.Pcds[key].Type in GenC.gDynamicPcd):\r
1380 Value = self.Platform.Pcds[key]\r
1381 Value.TokenCName = self.Platform.Pcds[key].TokenCName + '_' + Pcd_Type\r
1382 if len(key) == 2:\r
1383 newkey = (Value.TokenCName, key[1])\r
1384 elif len(key) == 3:\r
1385 newkey = (Value.TokenCName, key[1], key[2])\r
1386 del self.Platform.Pcds[key]\r
1387 self.Platform.Pcds[newkey] = Value\r
1388 break\r
1389 else:\r
1390 pass\r
1391 break\r
1392 else:\r
1393 pass\r
1394\r
52302d4d
LG
1395 # for gathering error information\r
1396 NoDatumTypePcdList = set()\r
a0a2cd1e 1397 PcdNotInDb = []\r
52302d4d 1398 self._GuidValue = {}\r
a0a2cd1e
FB
1399 FdfModuleList = []\r
1400 for InfName in self._AsBuildInfList:\r
05cc51ad 1401 InfName = mws.join(self.WorkspaceDir, InfName)\r
a0a2cd1e 1402 FdfModuleList.append(os.path.normpath(InfName))\r
52302d4d
LG
1403 for F in self.Platform.Modules.keys():\r
1404 M = ModuleAutoGen(self.Workspace, F, self.BuildTarget, self.ToolChain, self.Arch, self.MetaFile)\r
1405 #GuidValue.update(M.Guids)\r
1406 \r
1407 self.Platform.Modules[F].M = M\r
47fea6af
YZ
1408\r
1409 for PcdFromModule in M.ModulePcdList + M.LibraryPcdList:\r
52302d4d 1410 # make sure that the "VOID*" kind of datum has MaxDatumSize set\r
e8a47801 1411 if PcdFromModule.DatumType == "VOID*" and PcdFromModule.MaxDatumSize in [None, '']:\r
52302d4d
LG
1412 NoDatumTypePcdList.add("%s.%s [%s]" % (PcdFromModule.TokenSpaceGuidCName, PcdFromModule.TokenCName, F))\r
1413\r
97fa0ee9 1414 # Check the PCD from Binary INF or Source INF\r
a0a2cd1e
FB
1415 if M.IsBinaryModule == True:\r
1416 PcdFromModule.IsFromBinaryInf = True\r
97fa0ee9
YL
1417\r
1418 # Check the PCD from DSC or not \r
a0a2cd1e
FB
1419 if (PcdFromModule.TokenCName, PcdFromModule.TokenSpaceGuidCName) in self.Platform.Pcds.keys():\r
1420 PcdFromModule.IsFromDsc = True\r
1421 else:\r
1422 PcdFromModule.IsFromDsc = False\r
52302d4d 1423 if PcdFromModule.Type in GenC.gDynamicPcd or PcdFromModule.Type in GenC.gDynamicExPcd:\r
a0a2cd1e
FB
1424 if F.Path not in FdfModuleList:\r
1425 # If one of the Source built modules listed in the DSC is not listed \r
1426 # in FDF modules, and the INF lists a PCD can only use the PcdsDynamic \r
1427 # access method (it is only listed in the DEC file that declares the \r
1428 # PCD as PcdsDynamic), then build tool will report warning message\r
1429 # notify the PI that they are attempting to build a module that must \r
1430 # be included in a flash image in order to be functional. These Dynamic \r
1431 # PCD will not be added into the Database unless it is used by other \r
1432 # modules that are included in the FDF file.\r
1433 if PcdFromModule.Type in GenC.gDynamicPcd and \\r
1434 PcdFromModule.IsFromBinaryInf == False:\r
1435 # Print warning message to let the developer make a determine.\r
1436 if PcdFromModule not in PcdNotInDb:\r
a0a2cd1e
FB
1437 PcdNotInDb.append(PcdFromModule)\r
1438 continue\r
1439 # If one of the Source built modules listed in the DSC is not listed in \r
1440 # FDF modules, and the INF lists a PCD can only use the PcdsDynamicEx \r
1441 # access method (it is only listed in the DEC file that declares the \r
1442 # PCD as PcdsDynamicEx), then DO NOT break the build; DO NOT add the \r
1443 # PCD to the Platform's PCD Database.\r
1444 if PcdFromModule.Type in GenC.gDynamicExPcd:\r
1445 if PcdFromModule not in PcdNotInDb:\r
1446 PcdNotInDb.append(PcdFromModule)\r
1447 continue\r
52302d4d
LG
1448 #\r
1449 # If a dynamic PCD used by a PEM module/PEI module & DXE module,\r
1450 # it should be stored in Pcd PEI database, If a dynamic only\r
1451 # used by DXE module, it should be stored in DXE PCD database.\r
1452 # The default Phase is DXE\r
1453 #\r
1454 if M.ModuleType in ["PEIM", "PEI_CORE"]:\r
1455 PcdFromModule.Phase = "PEI"\r
1456 if PcdFromModule not in self._DynaPcdList_:\r
1457 self._DynaPcdList_.append(PcdFromModule)\r
1458 elif PcdFromModule.Phase == 'PEI':\r
1459 # overwrite any the same PCD existing, if Phase is PEI\r
1460 Index = self._DynaPcdList_.index(PcdFromModule)\r
1461 self._DynaPcdList_[Index] = PcdFromModule\r
1462 elif PcdFromModule not in self._NonDynaPcdList_:\r
1463 self._NonDynaPcdList_.append(PcdFromModule)\r
a0a2cd1e
FB
1464 elif PcdFromModule in self._NonDynaPcdList_ and PcdFromModule.IsFromBinaryInf == True:\r
1465 Index = self._NonDynaPcdList_.index(PcdFromModule)\r
1466 if self._NonDynaPcdList_[Index].IsFromBinaryInf == False:\r
1467 #The PCD from Binary INF will override the same one from source INF\r
1468 self._NonDynaPcdList_.remove (self._NonDynaPcdList_[Index])\r
1469 PcdFromModule.Pending = False\r
1470 self._NonDynaPcdList_.append (PcdFromModule)\r
1471 # Parse the DynamicEx PCD from the AsBuild INF module list of FDF.\r
1472 DscModuleList = []\r
1473 for ModuleInf in self.Platform.Modules.keys():\r
1474 DscModuleList.append (os.path.normpath(ModuleInf.Path))\r
1475 # add the PCD from modules that listed in FDF but not in DSC to Database \r
1476 for InfName in FdfModuleList:\r
1477 if InfName not in DscModuleList:\r
1478 InfClass = PathClass(InfName)\r
1479 M = self.BuildDatabase[InfClass, self.Arch, self.BuildTarget, self.ToolChain]\r
1480 # If a module INF in FDF but not in current arch's DSC module list, it must be module (either binary or source) \r
1481 # for different Arch. PCDs in source module for different Arch is already added before, so skip the source module here. \r
1482 # For binary module, if in current arch, we need to list the PCDs into database. \r
1483 if not M.IsSupportedArch:\r
1484 continue\r
1485 # Override the module PCD setting by platform setting\r
1486 ModulePcdList = self.ApplyPcdSetting(M, M.Pcds)\r
1487 for PcdFromModule in ModulePcdList:\r
1488 PcdFromModule.IsFromBinaryInf = True\r
1489 PcdFromModule.IsFromDsc = False\r
1490 # Only allow the DynamicEx and Patchable PCD in AsBuild INF\r
1491 if PcdFromModule.Type not in GenC.gDynamicExPcd and PcdFromModule.Type not in TAB_PCDS_PATCHABLE_IN_MODULE:\r
1492 EdkLogger.error("build", AUTOGEN_ERROR, "PCD setting error",\r
1493 File=self.MetaFile,\r
1494 ExtraData="\n\tExisted %s PCD %s in:\n\t\t%s\n"\r
1495 % (PcdFromModule.Type, PcdFromModule.TokenCName, InfName))\r
1496 # make sure that the "VOID*" kind of datum has MaxDatumSize set\r
1497 if PcdFromModule.DatumType == "VOID*" and PcdFromModule.MaxDatumSize in [None, '']:\r
1498 NoDatumTypePcdList.add("%s.%s [%s]" % (PcdFromModule.TokenSpaceGuidCName, PcdFromModule.TokenCName, InfName))\r
1499 if M.ModuleType in ["PEIM", "PEI_CORE"]:\r
1500 PcdFromModule.Phase = "PEI"\r
1501 if PcdFromModule not in self._DynaPcdList_ and PcdFromModule.Type in GenC.gDynamicExPcd:\r
1502 self._DynaPcdList_.append(PcdFromModule)\r
1503 elif PcdFromModule not in self._NonDynaPcdList_ and PcdFromModule.Type in TAB_PCDS_PATCHABLE_IN_MODULE:\r
1504 self._NonDynaPcdList_.append(PcdFromModule)\r
1505 if PcdFromModule in self._DynaPcdList_ and PcdFromModule.Phase == 'PEI' and PcdFromModule.Type in GenC.gDynamicExPcd:\r
97fa0ee9
YL
1506 # Overwrite the phase of any the same PCD existing, if Phase is PEI.\r
1507 # It is to solve the case that a dynamic PCD used by a PEM module/PEI \r
1508 # module & DXE module at a same time.\r
1509 # Overwrite the type of the PCDs in source INF by the type of AsBuild\r
1510 # INF file as DynamicEx. \r
a0a2cd1e
FB
1511 Index = self._DynaPcdList_.index(PcdFromModule)\r
1512 self._DynaPcdList_[Index].Phase = PcdFromModule.Phase\r
1513 self._DynaPcdList_[Index].Type = PcdFromModule.Type\r
1514 for PcdFromModule in self._NonDynaPcdList_:\r
1515 # If a PCD is not listed in the DSC file, but binary INF files used by \r
1516 # this platform all (that use this PCD) list the PCD in a [PatchPcds] \r
1517 # section, AND all source INF files used by this platform the build \r
1518 # that use the PCD list the PCD in either a [Pcds] or [PatchPcds] \r
1519 # section, then the tools must NOT add the PCD to the Platform's PCD\r
1520 # Database; the build must assign the access method for this PCD as \r
1521 # PcdsPatchableInModule.\r
1522 if PcdFromModule not in self._DynaPcdList_:\r
1523 continue\r
1524 Index = self._DynaPcdList_.index(PcdFromModule)\r
1525 if PcdFromModule.IsFromDsc == False and \\r
1526 PcdFromModule.Type in TAB_PCDS_PATCHABLE_IN_MODULE and \\r
1527 PcdFromModule.IsFromBinaryInf == True and \\r
1528 self._DynaPcdList_[Index].IsFromBinaryInf == False:\r
1529 Index = self._DynaPcdList_.index(PcdFromModule)\r
1530 self._DynaPcdList_.remove (self._DynaPcdList_[Index])\r
52302d4d
LG
1531\r
1532 # print out error information and break the build, if error found\r
1533 if len(NoDatumTypePcdList) > 0:\r
1534 NoDatumTypePcdListString = "\n\t\t".join(NoDatumTypePcdList)\r
1535 EdkLogger.error("build", AUTOGEN_ERROR, "PCD setting error",\r
1536 File=self.MetaFile,\r
1537 ExtraData="\n\tPCD(s) without MaxDatumSize:\n\t\t%s\n"\r
1538 % NoDatumTypePcdListString)\r
1539 self._NonDynamicPcdList = self._NonDynaPcdList_\r
1540 self._DynamicPcdList = self._DynaPcdList_\r
52302d4d
LG
1541 #\r
1542 # Sort dynamic PCD list to:\r
1543 # 1) If PCD's datum type is VOID* and value is unicode string which starts with L, the PCD item should \r
1544 # try to be put header of dynamicd List\r
1545 # 2) If PCD is HII type, the PCD item should be put after unicode type PCD\r
1546 #\r
1547 # The reason of sorting is make sure the unicode string is in double-byte alignment in string table.\r
1548 #\r
1549 UnicodePcdArray = []\r
1550 HiiPcdArray = []\r
1551 OtherPcdArray = []\r
6780eef1 1552 VpdPcdDict = {}\r
e56468c0 1553 VpdFile = VpdInfoFile.VpdInfoFile()\r
61ee1dff
YZ
1554 NeedProcessVpdMapFile = False\r
1555\r
1556 for pcd in self.Platform.Pcds.keys():\r
1557 if pcd not in self._PlatformPcds.keys():\r
1558 self._PlatformPcds[pcd] = self.Platform.Pcds[pcd]\r
1559\r
e56468c0 1560 if (self.Workspace.ArchList[-1] == self.Arch): \r
1561 for Pcd in self._DynamicPcdList:\r
e56468c0 1562 # just pick the a value to determine whether is unicode string type\r
47fea6af 1563 Sku = Pcd.SkuInfoList[Pcd.SkuInfoList.keys()[0]]\r
e56468c0 1564 Sku.VpdOffset = Sku.VpdOffset.strip()\r
47fea6af 1565\r
e56468c0 1566 PcdValue = Sku.DefaultValue\r
1567 if Pcd.DatumType == 'VOID*' and PcdValue.startswith("L"):\r
1568 # if found PCD which datum value is unicode string the insert to left size of UnicodeIndex\r
1569 UnicodePcdArray.append(Pcd)\r
1570 elif len(Sku.VariableName) > 0:\r
1571 # if found HII type PCD then insert to right of UnicodeIndex\r
1572 HiiPcdArray.append(Pcd)\r
1573 else:\r
1574 OtherPcdArray.append(Pcd)\r
e56468c0 1575 if Pcd.Type in [TAB_PCDS_DYNAMIC_VPD, TAB_PCDS_DYNAMIC_EX_VPD]:\r
47fea6af
YZ
1576 VpdPcdDict[(Pcd.TokenCName, Pcd.TokenSpaceGuidCName)] = Pcd\r
1577\r
61ee1dff 1578 PlatformPcds = self._PlatformPcds.keys()\r
47fea6af 1579 PlatformPcds.sort()\r
6780eef1
LG
1580 #\r
1581 # Add VPD type PCD into VpdFile and determine whether the VPD PCD need to be fixed up.\r
1582 #\r
1583 for PcdKey in PlatformPcds:\r
61ee1dff 1584 Pcd = self._PlatformPcds[PcdKey]\r
e8a47801
LG
1585 if Pcd.Type in [TAB_PCDS_DYNAMIC_VPD, TAB_PCDS_DYNAMIC_EX_VPD] and \\r
1586 PcdKey in VpdPcdDict:\r
1587 Pcd = VpdPcdDict[PcdKey]\r
1588 for (SkuName,Sku) in Pcd.SkuInfoList.items():\r
1589 Sku.VpdOffset = Sku.VpdOffset.strip()\r
5a13737a
YZ
1590 PcdValue = Sku.DefaultValue\r
1591 if PcdValue == "":\r
1592 PcdValue = Pcd.DefaultValue\r
1593 if Sku.VpdOffset != '*':\r
1594 if PcdValue.startswith("{"):\r
1595 Alignment = 8\r
1596 elif PcdValue.startswith("L"):\r
1597 Alignment = 2\r
1598 else:\r
1599 Alignment = 1\r
ca85291f
YZ
1600 try:\r
1601 VpdOffset = int(Sku.VpdOffset)\r
1602 except:\r
1603 try:\r
1604 VpdOffset = int(Sku.VpdOffset, 16)\r
1605 except:\r
1606 EdkLogger.error("build", FORMAT_INVALID, "Invalid offset value %s for PCD %s.%s." % (Sku.VpdOffset, Pcd.TokenSpaceGuidCName, Pcd.TokenCName))\r
1607 if VpdOffset % Alignment != 0:\r
815ada26
YZ
1608 if PcdValue.startswith("{"):\r
1609 EdkLogger.warn("build", "The offset value of PCD %s.%s is not 8-byte aligned!" %(Pcd.TokenSpaceGuidCName, Pcd.TokenCName), File=self.MetaFile)\r
1610 else:\r
1611 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
1612 VpdFile.Add(Pcd, Sku.VpdOffset)\r
1613 # if the offset of a VPD is *, then it need to be fixed up by third party tool.\r
1614 if not NeedProcessVpdMapFile and Sku.VpdOffset == "*":\r
1615 NeedProcessVpdMapFile = True\r
1616 if self.Platform.VpdToolGuid == None or self.Platform.VpdToolGuid == '':\r
1617 EdkLogger.error("Build", FILE_NOT_FOUND, \\r
1618 "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
1619\r
1620\r
e56468c0 1621 #\r
1622 # Fix the PCDs define in VPD PCD section that never referenced by module.\r
1623 # An example is PCD for signature usage.\r
6780eef1
LG
1624 # \r
1625 for DscPcd in PlatformPcds:\r
61ee1dff 1626 DscPcdEntry = self._PlatformPcds[DscPcd]\r
e56468c0 1627 if DscPcdEntry.Type in [TAB_PCDS_DYNAMIC_VPD, TAB_PCDS_DYNAMIC_EX_VPD]:\r
1628 if not (self.Platform.VpdToolGuid == None or self.Platform.VpdToolGuid == ''):\r
1629 FoundFlag = False\r
1630 for VpdPcd in VpdFile._VpdArray.keys():\r
1631 # This PCD has been referenced by module\r
1632 if (VpdPcd.TokenSpaceGuidCName == DscPcdEntry.TokenSpaceGuidCName) and \\r
1633 (VpdPcd.TokenCName == DscPcdEntry.TokenCName):\r
1634 FoundFlag = True\r
47fea6af 1635\r
e56468c0 1636 # Not found, it should be signature\r
1637 if not FoundFlag :\r
1638 # just pick the a value to determine whether is unicode string type\r
e8a47801
LG
1639 for (SkuName,Sku) in DscPcdEntry.SkuInfoList.items():\r
1640 Sku.VpdOffset = Sku.VpdOffset.strip() \r
1641 \r
1642 # Need to iterate DEC pcd information to get the value & datumtype\r
1643 for eachDec in self.PackageList:\r
1644 for DecPcd in eachDec.Pcds:\r
1645 DecPcdEntry = eachDec.Pcds[DecPcd]\r
1646 if (DecPcdEntry.TokenSpaceGuidCName == DscPcdEntry.TokenSpaceGuidCName) and \\r
1647 (DecPcdEntry.TokenCName == DscPcdEntry.TokenCName):\r
1648 # Print warning message to let the developer make a determine.\r
1649 EdkLogger.warn("build", "Unreferenced vpd pcd used!",\r
1650 File=self.MetaFile, \\r
1651 ExtraData = "PCD: %s.%s used in the DSC file %s is unreferenced." \\r
1652 %(DscPcdEntry.TokenSpaceGuidCName, DscPcdEntry.TokenCName, self.Platform.MetaFile.Path)) \r
1653 \r
1654 DscPcdEntry.DatumType = DecPcdEntry.DatumType\r
1655 DscPcdEntry.DefaultValue = DecPcdEntry.DefaultValue\r
1656 DscPcdEntry.TokenValue = DecPcdEntry.TokenValue\r
1657 DscPcdEntry.TokenSpaceGuidValue = eachDec.Guids[DecPcdEntry.TokenSpaceGuidCName]\r
1658 # Only fix the value while no value provided in DSC file.\r
1659 if (Sku.DefaultValue == "" or Sku.DefaultValue==None):\r
1660 DscPcdEntry.SkuInfoList[DscPcdEntry.SkuInfoList.keys()[0]].DefaultValue = DecPcdEntry.DefaultValue\r
1661 \r
1662 if DscPcdEntry not in self._DynamicPcdList:\r
1663 self._DynamicPcdList.append(DscPcdEntry)\r
1664# Sku = DscPcdEntry.SkuInfoList[DscPcdEntry.SkuInfoList.keys()[0]]\r
1665 Sku.VpdOffset = Sku.VpdOffset.strip()\r
1666 PcdValue = Sku.DefaultValue\r
5a13737a
YZ
1667 if PcdValue == "":\r
1668 PcdValue = DscPcdEntry.DefaultValue\r
1669 if Sku.VpdOffset != '*':\r
1670 if PcdValue.startswith("{"):\r
1671 Alignment = 8\r
1672 elif PcdValue.startswith("L"):\r
1673 Alignment = 2\r
1674 else:\r
1675 Alignment = 1\r
ca85291f
YZ
1676 try:\r
1677 VpdOffset = int(Sku.VpdOffset)\r
1678 except:\r
1679 try:\r
1680 VpdOffset = int(Sku.VpdOffset, 16)\r
1681 except:\r
1682 EdkLogger.error("build", FORMAT_INVALID, "Invalid offset value %s for PCD %s.%s." % (Sku.VpdOffset, DscPcdEntry.TokenSpaceGuidCName, DscPcdEntry.TokenCName))\r
1683 if VpdOffset % Alignment != 0:\r
815ada26
YZ
1684 if PcdValue.startswith("{"):\r
1685 EdkLogger.warn("build", "The offset value of PCD %s.%s is not 8-byte aligned!" %(DscPcdEntry.TokenSpaceGuidCName, DscPcdEntry.TokenCName), File=self.MetaFile)\r
1686 else:\r
1687 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
1688 VpdFile.Add(DscPcdEntry, Sku.VpdOffset)\r
1689 if not NeedProcessVpdMapFile and Sku.VpdOffset == "*":\r
1690 NeedProcessVpdMapFile = True \r
1691 if DscPcdEntry.DatumType == 'VOID*' and PcdValue.startswith("L"):\r
1692 UnicodePcdArray.append(DscPcdEntry)\r
1693 elif len(Sku.VariableName) > 0:\r
1694 HiiPcdArray.append(DscPcdEntry)\r
1695 else:\r
1696 OtherPcdArray.append(DscPcdEntry)\r
1697 \r
1698 # if the offset of a VPD is *, then it need to be fixed up by third party tool.\r
e56468c0 1699 \r
e56468c0 1700 \r
1701 \r
1702 if (self.Platform.FlashDefinition == None or self.Platform.FlashDefinition == '') and \\r
1703 VpdFile.GetCount() != 0:\r
1704 EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, \r
1705 "Fail to get FLASH_DEFINITION definition in DSC file %s which is required when DSC contains VPD PCD." % str(self.Platform.MetaFile))\r
47fea6af 1706\r
e56468c0 1707 if VpdFile.GetCount() != 0:\r
e56468c0 1708 FvPath = os.path.join(self.BuildDir, "FV")\r
1709 if not os.path.exists(FvPath):\r
1710 try:\r
1711 os.makedirs(FvPath)\r
1712 except:\r
1713 EdkLogger.error("build", FILE_WRITE_FAILURE, "Fail to create FV folder under %s" % self.BuildDir)\r
47fea6af 1714\r
08dd311f
LG
1715 VpdFilePath = os.path.join(FvPath, "%s.txt" % self.Platform.VpdToolGuid)\r
1716\r
e459de78 1717 if VpdFile.Write(VpdFilePath):\r
e56468c0 1718 # retrieve BPDG tool's path from tool_def.txt according to VPD_TOOL_GUID defined in DSC file.\r
1719 BPDGToolName = None\r
1720 for ToolDef in self.ToolDefinition.values():\r
1721 if ToolDef.has_key("GUID") and ToolDef["GUID"] == self.Platform.VpdToolGuid:\r
1722 if not ToolDef.has_key("PATH"):\r
1723 EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, "PATH attribute was not provided for BPDG guid tool %s in tools_def.txt" % self.Platform.VpdToolGuid)\r
1724 BPDGToolName = ToolDef["PATH"]\r
1725 break\r
1726 # Call third party GUID BPDG tool.\r
1727 if BPDGToolName != None:\r
08dd311f 1728 VpdInfoFile.CallExtenalBPDGTool(BPDGToolName, VpdFilePath)\r
e56468c0 1729 else:\r
1730 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 1731\r
e56468c0 1732 # Process VPD map file generated by third party BPDG tool\r
1733 if NeedProcessVpdMapFile:\r
08dd311f 1734 VpdMapFilePath = os.path.join(self.BuildDir, "FV", "%s.map" % self.Platform.VpdToolGuid)\r
e56468c0 1735 if os.path.exists(VpdMapFilePath):\r
1736 VpdFile.Read(VpdMapFilePath)\r
47fea6af 1737\r
e56468c0 1738 # Fixup "*" offset\r
1739 for Pcd in self._DynamicPcdList:\r
1740 # just pick the a value to determine whether is unicode string type\r
e8a47801
LG
1741 i = 0\r
1742 for (SkuName,Sku) in Pcd.SkuInfoList.items(): \r
1743 if Sku.VpdOffset == "*":\r
1744 Sku.VpdOffset = VpdFile.GetOffset(Pcd)[i].strip()\r
1745 i += 1\r
e56468c0 1746 else:\r
1747 EdkLogger.error("build", FILE_READ_FAILURE, "Can not find VPD map file %s to fix up VPD offset." % VpdMapFilePath)\r
47fea6af 1748\r
e56468c0 1749 # Delete the DynamicPcdList At the last time enter into this function \r
47fea6af 1750 del self._DynamicPcdList[:]\r
52302d4d
LG
1751 self._DynamicPcdList.extend(UnicodePcdArray)\r
1752 self._DynamicPcdList.extend(HiiPcdArray)\r
1753 self._DynamicPcdList.extend(OtherPcdArray)\r
a0a2cd1e 1754 self.AllPcdList = self._NonDynamicPcdList + self._DynamicPcdList\r
52302d4d
LG
1755 \r
1756 ## Return the platform build data object\r
1757 def _GetPlatform(self):\r
1758 if self._Platform == None:\r
0d2711a6 1759 self._Platform = self.BuildDatabase[self.MetaFile, self.Arch, self.BuildTarget, self.ToolChain]\r
52302d4d
LG
1760 return self._Platform\r
1761\r
1762 ## Return platform name\r
1763 def _GetName(self):\r
1764 return self.Platform.PlatformName\r
1765\r
1766 ## Return the meta file GUID\r
1767 def _GetGuid(self):\r
1768 return self.Platform.Guid\r
1769\r
1770 ## Return the platform version\r
1771 def _GetVersion(self):\r
1772 return self.Platform.Version\r
1773\r
1774 ## Return the FDF file name\r
1775 def _GetFdfFile(self):\r
1776 if self._FdfFile == None:\r
1777 if self.Workspace.FdfFile != "":\r
05cc51ad 1778 self._FdfFile= mws.join(self.WorkspaceDir, self.Workspace.FdfFile)\r
52302d4d
LG
1779 else:\r
1780 self._FdfFile = ''\r
1781 return self._FdfFile\r
1782\r
1783 ## Return the build output directory platform specifies\r
1784 def _GetOutputDir(self):\r
1785 return self.Platform.OutputDirectory\r
1786\r
1787 ## Return the directory to store all intermediate and final files built\r
1788 def _GetBuildDir(self):\r
1789 if self._BuildDir == None:\r
1790 if os.path.isabs(self.OutputDir):\r
1791 self._BuildDir = path.join(\r
1792 path.abspath(self.OutputDir),\r
1793 self.BuildTarget + "_" + self.ToolChain,\r
1794 )\r
1795 else:\r
1796 self._BuildDir = path.join(\r
1797 self.WorkspaceDir,\r
1798 self.OutputDir,\r
1799 self.BuildTarget + "_" + self.ToolChain,\r
1800 )\r
97058144 1801 GlobalData.gBuildDirectory = self._BuildDir\r
52302d4d
LG
1802 return self._BuildDir\r
1803\r
1804 ## Return directory of platform makefile\r
1805 #\r
1806 # @retval string Makefile directory\r
1807 #\r
1808 def _GetMakeFileDir(self):\r
1809 if self._MakeFileDir == None:\r
1810 self._MakeFileDir = path.join(self.BuildDir, self.Arch)\r
1811 return self._MakeFileDir\r
1812\r
1813 ## Return build command string\r
1814 #\r
1815 # @retval string Build command string\r
1816 #\r
1817 def _GetBuildCommand(self):\r
1818 if self._BuildCommand == None:\r
1819 self._BuildCommand = []\r
1820 if "MAKE" in self.ToolDefinition and "PATH" in self.ToolDefinition["MAKE"]:\r
1821 self._BuildCommand += SplitOption(self.ToolDefinition["MAKE"]["PATH"])\r
1822 if "FLAGS" in self.ToolDefinition["MAKE"]:\r
1823 NewOption = self.ToolDefinition["MAKE"]["FLAGS"].strip()\r
1824 if NewOption != '':\r
6780eef1 1825 self._BuildCommand += SplitOption(NewOption)\r
52302d4d
LG
1826 return self._BuildCommand\r
1827\r
1828 ## Get tool chain definition\r
1829 #\r
1830 # Get each tool defition for given tool chain from tools_def.txt and platform\r
1831 #\r
1832 def _GetToolDefinition(self):\r
1833 if self._ToolDefinitions == None:\r
1834 ToolDefinition = self.Workspace.ToolDef.ToolsDefTxtDictionary\r
1835 if TAB_TOD_DEFINES_COMMAND_TYPE not in self.Workspace.ToolDef.ToolsDefTxtDatabase:\r
1836 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, "No tools found in configuration",\r
1837 ExtraData="[%s]" % self.MetaFile)\r
1838 self._ToolDefinitions = {}\r
1839 DllPathList = set()\r
1840 for Def in ToolDefinition:\r
1841 Target, Tag, Arch, Tool, Attr = Def.split("_")\r
1842 if Target != self.BuildTarget or Tag != self.ToolChain or Arch != self.Arch:\r
1843 continue\r
1844\r
1845 Value = ToolDefinition[Def]\r
1846 # don't record the DLL\r
1847 if Attr == "DLL":\r
1848 DllPathList.add(Value)\r
1849 continue\r
1850\r
1851 if Tool not in self._ToolDefinitions:\r
1852 self._ToolDefinitions[Tool] = {}\r
1853 self._ToolDefinitions[Tool][Attr] = Value\r
1854\r
1855 ToolsDef = ''\r
1856 MakePath = ''\r
1857 if GlobalData.gOptions.SilentMode and "MAKE" in self._ToolDefinitions:\r
1858 if "FLAGS" not in self._ToolDefinitions["MAKE"]:\r
1859 self._ToolDefinitions["MAKE"]["FLAGS"] = ""\r
1860 self._ToolDefinitions["MAKE"]["FLAGS"] += " -s"\r
1861 MakeFlags = ''\r
1862 for Tool in self._ToolDefinitions:\r
1863 for Attr in self._ToolDefinitions[Tool]:\r
1864 Value = self._ToolDefinitions[Tool][Attr]\r
1865 if Tool in self.BuildOption and Attr in self.BuildOption[Tool]:\r
1866 # check if override is indicated\r
1867 if self.BuildOption[Tool][Attr].startswith('='):\r
1868 Value = self.BuildOption[Tool][Attr][1:]\r
1869 else:\r
95816356
YZ
1870 if Attr != 'PATH':\r
1871 Value += " " + self.BuildOption[Tool][Attr]\r
1872 else:\r
1873 Value = self.BuildOption[Tool][Attr]\r
52302d4d
LG
1874\r
1875 if Attr == "PATH":\r
1876 # Don't put MAKE definition in the file\r
1877 if Tool == "MAKE":\r
1878 MakePath = Value\r
1879 else:\r
1880 ToolsDef += "%s = %s\n" % (Tool, Value)\r
1881 elif Attr != "DLL":\r
1882 # Don't put MAKE definition in the file\r
1883 if Tool == "MAKE":\r
1884 if Attr == "FLAGS":\r
1885 MakeFlags = Value\r
1886 else:\r
1887 ToolsDef += "%s_%s = %s\n" % (Tool, Attr, Value)\r
1888 ToolsDef += "\n"\r
1889\r
1890 SaveFileOnChange(self.ToolDefinitionFile, ToolsDef)\r
1891 for DllPath in DllPathList:\r
1892 os.environ["PATH"] = DllPath + os.pathsep + os.environ["PATH"]\r
1893 os.environ["MAKE_FLAGS"] = MakeFlags\r
1894\r
1895 return self._ToolDefinitions\r
1896\r
1897 ## Return the paths of tools\r
1898 def _GetToolDefFile(self):\r
1899 if self._ToolDefFile == None:\r
1900 self._ToolDefFile = os.path.join(self.MakeFileDir, "TOOLS_DEF." + self.Arch)\r
1901 return self._ToolDefFile\r
1902\r
1903 ## Retrieve the toolchain family of given toolchain tag. Default to 'MSFT'.\r
1904 def _GetToolChainFamily(self):\r
1905 if self._ToolChainFamily == None:\r
1906 ToolDefinition = self.Workspace.ToolDef.ToolsDefTxtDatabase\r
1907 if TAB_TOD_DEFINES_FAMILY not in ToolDefinition \\r
1908 or self.ToolChain not in ToolDefinition[TAB_TOD_DEFINES_FAMILY] \\r
1909 or not ToolDefinition[TAB_TOD_DEFINES_FAMILY][self.ToolChain]:\r
1910 EdkLogger.verbose("No tool chain family found in configuration for %s. Default to MSFT." \\r
1911 % self.ToolChain)\r
1912 self._ToolChainFamily = "MSFT"\r
1913 else:\r
1914 self._ToolChainFamily = ToolDefinition[TAB_TOD_DEFINES_FAMILY][self.ToolChain]\r
1915 return self._ToolChainFamily\r
1916\r
1917 def _GetBuildRuleFamily(self):\r
1918 if self._BuildRuleFamily == None:\r
1919 ToolDefinition = self.Workspace.ToolDef.ToolsDefTxtDatabase\r
1920 if TAB_TOD_DEFINES_BUILDRULEFAMILY not in ToolDefinition \\r
1921 or self.ToolChain not in ToolDefinition[TAB_TOD_DEFINES_BUILDRULEFAMILY] \\r
1922 or not ToolDefinition[TAB_TOD_DEFINES_BUILDRULEFAMILY][self.ToolChain]:\r
1923 EdkLogger.verbose("No tool chain family found in configuration for %s. Default to MSFT." \\r
1924 % self.ToolChain)\r
1925 self._BuildRuleFamily = "MSFT"\r
1926 else:\r
1927 self._BuildRuleFamily = ToolDefinition[TAB_TOD_DEFINES_BUILDRULEFAMILY][self.ToolChain]\r
1928 return self._BuildRuleFamily\r
1929\r
1930 ## Return the build options specific for all modules in this platform\r
1931 def _GetBuildOptions(self):\r
1932 if self._BuildOption == None:\r
1933 self._BuildOption = self._ExpandBuildOption(self.Platform.BuildOptions)\r
1934 return self._BuildOption\r
1935\r
1936 ## Return the build options specific for EDK modules in this platform\r
1937 def _GetEdkBuildOptions(self):\r
1938 if self._EdkBuildOption == None:\r
1939 self._EdkBuildOption = self._ExpandBuildOption(self.Platform.BuildOptions, EDK_NAME)\r
1940 return self._EdkBuildOption\r
1941\r
1942 ## Return the build options specific for EDKII modules in this platform\r
1943 def _GetEdkIIBuildOptions(self):\r
1944 if self._EdkIIBuildOption == None:\r
1945 self._EdkIIBuildOption = self._ExpandBuildOption(self.Platform.BuildOptions, EDKII_NAME)\r
1946 return self._EdkIIBuildOption\r
1947\r
97fa0ee9 1948 ## Parse build_rule.txt in Conf Directory.\r
52302d4d
LG
1949 #\r
1950 # @retval BuildRule object\r
1951 #\r
1952 def _GetBuildRule(self):\r
1953 if self._BuildRule == None:\r
1954 BuildRuleFile = None\r
1955 if TAB_TAT_DEFINES_BUILD_RULE_CONF in self.Workspace.TargetTxt.TargetTxtDictionary:\r
1956 BuildRuleFile = self.Workspace.TargetTxt.TargetTxtDictionary[TAB_TAT_DEFINES_BUILD_RULE_CONF]\r
1957 if BuildRuleFile in [None, '']:\r
97fa0ee9 1958 BuildRuleFile = gDefaultBuildRuleFile\r
52302d4d 1959 self._BuildRule = BuildRule(BuildRuleFile)\r
64b2609f
LG
1960 if self._BuildRule._FileVersion == "":\r
1961 self._BuildRule._FileVersion = AutoGenReqBuildRuleVerNum\r
1962 else:\r
1963 if self._BuildRule._FileVersion < AutoGenReqBuildRuleVerNum :\r
1964 # If Build Rule's version is less than the version number required by the tools, halting the build.\r
47fea6af 1965 EdkLogger.error("build", AUTOGEN_ERROR,\r
64b2609f
LG
1966 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
1967 % (self._BuildRule._FileVersion, AutoGenReqBuildRuleVerNum))\r
47fea6af 1968\r
52302d4d
LG
1969 return self._BuildRule\r
1970\r
1971 ## Summarize the packages used by modules in this platform\r
1972 def _GetPackageList(self):\r
1973 if self._PackageList == None:\r
1974 self._PackageList = set()\r
1975 for La in self.LibraryAutoGenList:\r
1976 self._PackageList.update(La.DependentPackageList)\r
1977 for Ma in self.ModuleAutoGenList:\r
1978 self._PackageList.update(Ma.DependentPackageList)\r
a0a2cd1e
FB
1979 #Collect package set information from INF of FDF\r
1980 PkgSet = set()\r
1981 for ModuleFile in self._AsBuildModuleList:\r
1982 if ModuleFile in self.Platform.Modules:\r
1983 continue\r
1984 ModuleData = self.BuildDatabase[ModuleFile, self.Arch, self.BuildTarget, self.ToolChain]\r
1985 PkgSet.update(ModuleData.Packages)\r
1986 self._PackageList = list(self._PackageList) + list (PkgSet)\r
52302d4d
LG
1987 return self._PackageList\r
1988\r
2bc3256c
LG
1989 def _GetNonDynamicPcdDict(self):\r
1990 if self._NonDynamicPcdDict:\r
1991 return self._NonDynamicPcdDict\r
1992 for Pcd in self.NonDynamicPcdList:\r
1993 self._NonDynamicPcdDict[(Pcd.TokenCName,Pcd.TokenSpaceGuidCName)] = Pcd\r
1994 return self._NonDynamicPcdDict\r
1995\r
52302d4d
LG
1996 ## Get list of non-dynamic PCDs\r
1997 def _GetNonDynamicPcdList(self):\r
e56468c0 1998 if self._NonDynamicPcdList == None:\r
1999 self.CollectPlatformDynamicPcds()\r
52302d4d
LG
2000 return self._NonDynamicPcdList\r
2001\r
2002 ## Get list of dynamic PCDs\r
2003 def _GetDynamicPcdList(self):\r
e56468c0 2004 if self._DynamicPcdList == None:\r
2005 self.CollectPlatformDynamicPcds()\r
52302d4d
LG
2006 return self._DynamicPcdList\r
2007\r
2008 ## Generate Token Number for all PCD\r
2009 def _GetPcdTokenNumbers(self):\r
2010 if self._PcdTokenNumber == None:\r
2011 self._PcdTokenNumber = sdict()\r
2012 TokenNumber = 1\r
d0acc87a
LG
2013 #\r
2014 # Make the Dynamic and DynamicEx PCD use within different TokenNumber area. \r
2015 # Such as:\r
2016 # \r
2017 # Dynamic PCD:\r
2018 # TokenNumber 0 ~ 10\r
2019 # DynamicEx PCD:\r
2020 # TokeNumber 11 ~ 20\r
2021 #\r
52302d4d
LG
2022 for Pcd in self.DynamicPcdList:\r
2023 if Pcd.Phase == "PEI":\r
d0acc87a
LG
2024 if Pcd.Type in ["Dynamic", "DynamicDefault", "DynamicVpd", "DynamicHii"]:\r
2025 EdkLogger.debug(EdkLogger.DEBUG_5, "%s %s (%s) -> %d" % (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Pcd.Phase, TokenNumber))\r
2026 self._PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber\r
2027 TokenNumber += 1\r
47fea6af 2028\r
d0acc87a
LG
2029 for Pcd in self.DynamicPcdList:\r
2030 if Pcd.Phase == "PEI":\r
2031 if Pcd.Type in ["DynamicEx", "DynamicExDefault", "DynamicExVpd", "DynamicExHii"]:\r
2032 EdkLogger.debug(EdkLogger.DEBUG_5, "%s %s (%s) -> %d" % (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Pcd.Phase, TokenNumber))\r
2033 self._PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber\r
2034 TokenNumber += 1\r
47fea6af 2035\r
52302d4d
LG
2036 for Pcd in self.DynamicPcdList:\r
2037 if Pcd.Phase == "DXE":\r
d0acc87a
LG
2038 if Pcd.Type in ["Dynamic", "DynamicDefault", "DynamicVpd", "DynamicHii"]:\r
2039 EdkLogger.debug(EdkLogger.DEBUG_5, "%s %s (%s) -> %d" % (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Pcd.Phase, TokenNumber))\r
2040 self._PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber\r
2041 TokenNumber += 1\r
47fea6af 2042\r
d0acc87a
LG
2043 for Pcd in self.DynamicPcdList:\r
2044 if Pcd.Phase == "DXE":\r
2045 if Pcd.Type in ["DynamicEx", "DynamicExDefault", "DynamicExVpd", "DynamicExHii"]:\r
2046 EdkLogger.debug(EdkLogger.DEBUG_5, "%s %s (%s) -> %d" % (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Pcd.Phase, TokenNumber))\r
2047 self._PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber\r
2048 TokenNumber += 1\r
47fea6af 2049\r
52302d4d
LG
2050 for Pcd in self.NonDynamicPcdList:\r
2051 self._PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber\r
2052 TokenNumber += 1\r
2053 return self._PcdTokenNumber\r
2054\r
2055 ## Summarize ModuleAutoGen objects of all modules/libraries to be built for this platform\r
2056 def _GetAutoGenObjectList(self):\r
2057 self._ModuleAutoGenList = []\r
2058 self._LibraryAutoGenList = []\r
2059 for ModuleFile in self.Platform.Modules:\r
2060 Ma = ModuleAutoGen(\r
2061 self.Workspace,\r
2062 ModuleFile,\r
2063 self.BuildTarget,\r
2064 self.ToolChain,\r
2065 self.Arch,\r
2066 self.MetaFile\r
2067 )\r
2068 if Ma not in self._ModuleAutoGenList:\r
2069 self._ModuleAutoGenList.append(Ma)\r
2070 for La in Ma.LibraryAutoGenList:\r
2071 if La not in self._LibraryAutoGenList:\r
2072 self._LibraryAutoGenList.append(La)\r
2bc3256c
LG
2073 if Ma not in La._ReferenceModules:\r
2074 La._ReferenceModules.append(Ma)\r
52302d4d
LG
2075\r
2076 ## Summarize ModuleAutoGen objects of all modules to be built for this platform\r
2077 def _GetModuleAutoGenList(self):\r
2078 if self._ModuleAutoGenList == None:\r
2079 self._GetAutoGenObjectList()\r
2080 return self._ModuleAutoGenList\r
2081\r
2082 ## Summarize ModuleAutoGen objects of all libraries to be built for this platform\r
2083 def _GetLibraryAutoGenList(self):\r
2084 if self._LibraryAutoGenList == None:\r
2085 self._GetAutoGenObjectList()\r
2086 return self._LibraryAutoGenList\r
2087\r
2088 ## Test if a module is supported by the platform\r
2089 #\r
2090 # An error will be raised directly if the module or its arch is not supported\r
2091 # by the platform or current configuration\r
2092 #\r
2093 def ValidModule(self, Module):\r
a0a2cd1e
FB
2094 return Module in self.Platform.Modules or Module in self.Platform.LibraryInstances \\r
2095 or Module in self._AsBuildModuleList\r
52302d4d
LG
2096\r
2097 ## Resolve the library classes in a module to library instances\r
2098 #\r
2099 # This method will not only resolve library classes but also sort the library\r
2100 # instances according to the dependency-ship.\r
2101 #\r
2102 # @param Module The module from which the library classes will be resolved\r
2103 #\r
2104 # @retval library_list List of library instances sorted\r
2105 #\r
2106 def ApplyLibraryInstance(self, Module):\r
25193a33
YZ
2107 # Cover the case that the binary INF file is list in the FDF file but not DSC file, return empty list directly\r
2108 if str(Module) not in self.Platform.Modules:\r
2109 return []\r
2110\r
52302d4d
LG
2111 ModuleType = Module.ModuleType\r
2112\r
2113 # for overridding library instances with module specific setting\r
2114 PlatformModule = self.Platform.Modules[str(Module)]\r
2115\r
2116 # add forced library instances (specified under LibraryClasses sections)\r
da92f276
LG
2117 #\r
2118 # If a module has a MODULE_TYPE of USER_DEFINED,\r
2119 # do not link in NULL library class instances from the global [LibraryClasses.*] sections.\r
2120 #\r
2121 if Module.ModuleType != SUP_MODULE_USER_DEFINED:\r
2122 for LibraryClass in self.Platform.LibraryClasses.GetKeys():\r
2123 if LibraryClass.startswith("NULL") and self.Platform.LibraryClasses[LibraryClass, Module.ModuleType]:\r
2124 Module.LibraryClasses[LibraryClass] = self.Platform.LibraryClasses[LibraryClass, Module.ModuleType]\r
52302d4d
LG
2125\r
2126 # add forced library instances (specified in module overrides)\r
2127 for LibraryClass in PlatformModule.LibraryClasses:\r
2128 if LibraryClass.startswith("NULL"):\r
2129 Module.LibraryClasses[LibraryClass] = PlatformModule.LibraryClasses[LibraryClass]\r
2130\r
b36d134f 2131 # EdkII module\r
52302d4d
LG
2132 LibraryConsumerList = [Module]\r
2133 Constructor = []\r
2134 ConsumedByList = sdict()\r
2135 LibraryInstance = sdict()\r
2136\r
2137 EdkLogger.verbose("")\r
2138 EdkLogger.verbose("Library instances of module [%s] [%s]:" % (str(Module), self.Arch))\r
2139 while len(LibraryConsumerList) > 0:\r
2140 M = LibraryConsumerList.pop()\r
2141 for LibraryClassName in M.LibraryClasses:\r
2142 if LibraryClassName not in LibraryInstance:\r
2143 # override library instance for this module\r
2144 if LibraryClassName in PlatformModule.LibraryClasses:\r
2145 LibraryPath = PlatformModule.LibraryClasses[LibraryClassName]\r
2146 else:\r
2147 LibraryPath = self.Platform.LibraryClasses[LibraryClassName, ModuleType]\r
2148 if LibraryPath == None or LibraryPath == "":\r
2149 LibraryPath = M.LibraryClasses[LibraryClassName]\r
2150 if LibraryPath == None or LibraryPath == "":\r
2151 EdkLogger.error("build", RESOURCE_NOT_AVAILABLE,\r
2152 "Instance of library class [%s] is not found" % LibraryClassName,\r
2153 File=self.MetaFile,\r
2154 ExtraData="in [%s] [%s]\n\tconsumed by module [%s]" % (str(M), self.Arch, str(Module)))\r
2155\r
0d2711a6 2156 LibraryModule = self.BuildDatabase[LibraryPath, self.Arch, self.BuildTarget, self.ToolChain]\r
52302d4d
LG
2157 # for those forced library instance (NULL library), add a fake library class\r
2158 if LibraryClassName.startswith("NULL"):\r
2159 LibraryModule.LibraryClass.append(LibraryClassObject(LibraryClassName, [ModuleType]))\r
2160 elif LibraryModule.LibraryClass == None \\r
2161 or len(LibraryModule.LibraryClass) == 0 \\r
2162 or (ModuleType != 'USER_DEFINED'\r
2163 and ModuleType not in LibraryModule.LibraryClass[0].SupModList):\r
2164 # only USER_DEFINED can link against any library instance despite of its SupModList\r
2165 EdkLogger.error("build", OPTION_MISSING,\r
2166 "Module type [%s] is not supported by library instance [%s]" \\r
2167 % (ModuleType, LibraryPath), File=self.MetaFile,\r
2168 ExtraData="consumed by [%s]" % str(Module))\r
2169\r
2170 LibraryInstance[LibraryClassName] = LibraryModule\r
2171 LibraryConsumerList.append(LibraryModule)\r
2172 EdkLogger.verbose("\t" + str(LibraryClassName) + " : " + str(LibraryModule))\r
2173 else:\r
2174 LibraryModule = LibraryInstance[LibraryClassName]\r
2175\r
2176 if LibraryModule == None:\r
2177 continue\r
2178\r
2179 if LibraryModule.ConstructorList != [] and LibraryModule not in Constructor:\r
2180 Constructor.append(LibraryModule)\r
2181\r
2182 if LibraryModule not in ConsumedByList:\r
2183 ConsumedByList[LibraryModule] = []\r
2184 # don't add current module itself to consumer list\r
2185 if M != Module:\r
2186 if M in ConsumedByList[LibraryModule]:\r
2187 continue\r
2188 ConsumedByList[LibraryModule].append(M)\r
2189 #\r
2190 # Initialize the sorted output list to the empty set\r
2191 #\r
2192 SortedLibraryList = []\r
2193 #\r
2194 # Q <- Set of all nodes with no incoming edges\r
2195 #\r
2196 LibraryList = [] #LibraryInstance.values()\r
2197 Q = []\r
2198 for LibraryClassName in LibraryInstance:\r
2199 M = LibraryInstance[LibraryClassName]\r
2200 LibraryList.append(M)\r
2201 if ConsumedByList[M] == []:\r
2202 Q.append(M)\r
2203\r
2204 #\r
2205 # start the DAG algorithm\r
2206 #\r
2207 while True:\r
2208 EdgeRemoved = True\r
2209 while Q == [] and EdgeRemoved:\r
2210 EdgeRemoved = False\r
2211 # for each node Item with a Constructor\r
2212 for Item in LibraryList:\r
2213 if Item not in Constructor:\r
2214 continue\r
2215 # for each Node without a constructor with an edge e from Item to Node\r
2216 for Node in ConsumedByList[Item]:\r
2217 if Node in Constructor:\r
2218 continue\r
2219 # remove edge e from the graph if Node has no constructor\r
2220 ConsumedByList[Item].remove(Node)\r
2221 EdgeRemoved = True\r
2222 if ConsumedByList[Item] == []:\r
2223 # insert Item into Q\r
2224 Q.insert(0, Item)\r
2225 break\r
2226 if Q != []:\r
2227 break\r
2228 # DAG is done if there's no more incoming edge for all nodes\r
2229 if Q == []:\r
2230 break\r
2231\r
2232 # remove node from Q\r
2233 Node = Q.pop()\r
2234 # output Node\r
2235 SortedLibraryList.append(Node)\r
2236\r
2237 # for each node Item with an edge e from Node to Item do\r
2238 for Item in LibraryList:\r
2239 if Node not in ConsumedByList[Item]:\r
2240 continue\r
2241 # remove edge e from the graph\r
2242 ConsumedByList[Item].remove(Node)\r
2243\r
2244 if ConsumedByList[Item] != []:\r
2245 continue\r
2246 # insert Item into Q, if Item has no other incoming edges\r
2247 Q.insert(0, Item)\r
2248\r
2249 #\r
2250 # if any remaining node Item in the graph has a constructor and an incoming edge, then the graph has a cycle\r
2251 #\r
2252 for Item in LibraryList:\r
2253 if ConsumedByList[Item] != [] and Item in Constructor and len(Constructor) > 1:\r
2254 ErrorMessage = "\tconsumed by " + "\n\tconsumed by ".join([str(L) for L in ConsumedByList[Item]])\r
2255 EdkLogger.error("build", BUILD_ERROR, 'Library [%s] with constructors has a cycle' % str(Item),\r
2256 ExtraData=ErrorMessage, File=self.MetaFile)\r
2257 if Item not in SortedLibraryList:\r
2258 SortedLibraryList.append(Item)\r
2259\r
2260 #\r
2261 # Build the list of constructor and destructir names\r
2262 # The DAG Topo sort produces the destructor order, so the list of constructors must generated in the reverse order\r
2263 #\r
2264 SortedLibraryList.reverse()\r
2265 return SortedLibraryList\r
2266\r
2267\r
2268 ## Override PCD setting (type, value, ...)\r
2269 #\r
2270 # @param ToPcd The PCD to be overrided\r
2271 # @param FromPcd The PCD overrideing from\r
2272 #\r
2273 def _OverridePcd(self, ToPcd, FromPcd, Module=""):\r
2274 #\r
2275 # in case there's PCDs coming from FDF file, which have no type given.\r
2276 # at this point, ToPcd.Type has the type found from dependent\r
2277 # package\r
2278 #\r
2a29017e
YZ
2279 TokenCName = ToPcd.TokenCName\r
2280 for PcdItem in GlobalData.MixedPcd:\r
2281 if (ToPcd.TokenCName, ToPcd.TokenSpaceGuidCName) in GlobalData.MixedPcd[PcdItem]:\r
2282 TokenCName = PcdItem[0]\r
2283 break\r
52302d4d 2284 if FromPcd != None:\r
2a29017e
YZ
2285 if GlobalData.BuildOptionPcd:\r
2286 for pcd in GlobalData.BuildOptionPcd:\r
2287 if (FromPcd.TokenSpaceGuidCName, FromPcd.TokenCName) == (pcd[0], pcd[1]):\r
2288 FromPcd.DefaultValue = pcd[2]\r
2289 break\r
52302d4d
LG
2290 if ToPcd.Pending and FromPcd.Type not in [None, '']:\r
2291 ToPcd.Type = FromPcd.Type\r
e56468c0 2292 elif (ToPcd.Type not in [None, '']) and (FromPcd.Type not in [None, ''])\\r
2293 and (ToPcd.Type != FromPcd.Type) and (ToPcd.Type in FromPcd.Type):\r
2294 if ToPcd.Type.strip() == "DynamicEx":\r
47fea6af 2295 ToPcd.Type = FromPcd.Type\r
52302d4d
LG
2296 elif ToPcd.Type not in [None, ''] and FromPcd.Type not in [None, ''] \\r
2297 and ToPcd.Type != FromPcd.Type:\r
2298 EdkLogger.error("build", OPTION_CONFLICT, "Mismatched PCD type",\r
2299 ExtraData="%s.%s is defined as [%s] in module %s, but as [%s] in platform."\\r
2a29017e 2300 % (ToPcd.TokenSpaceGuidCName, TokenCName,\r
52302d4d
LG
2301 ToPcd.Type, Module, FromPcd.Type),\r
2302 File=self.MetaFile)\r
2303\r
2304 if FromPcd.MaxDatumSize not in [None, '']:\r
2305 ToPcd.MaxDatumSize = FromPcd.MaxDatumSize\r
2306 if FromPcd.DefaultValue not in [None, '']:\r
2307 ToPcd.DefaultValue = FromPcd.DefaultValue\r
2308 if FromPcd.TokenValue not in [None, '']:\r
2309 ToPcd.TokenValue = FromPcd.TokenValue\r
2310 if FromPcd.MaxDatumSize not in [None, '']:\r
2311 ToPcd.MaxDatumSize = FromPcd.MaxDatumSize\r
2312 if FromPcd.DatumType not in [None, '']:\r
2313 ToPcd.DatumType = FromPcd.DatumType\r
2314 if FromPcd.SkuInfoList not in [None, '', []]:\r
2315 ToPcd.SkuInfoList = FromPcd.SkuInfoList\r
2316\r
2317 # check the validation of datum\r
2318 IsValid, Cause = CheckPcdDatum(ToPcd.DatumType, ToPcd.DefaultValue)\r
2319 if not IsValid:\r
2320 EdkLogger.error('build', FORMAT_INVALID, Cause, File=self.MetaFile,\r
2a29017e 2321 ExtraData="%s.%s" % (ToPcd.TokenSpaceGuidCName, TokenCName))\r
82a6a960
BF
2322 ToPcd.validateranges = FromPcd.validateranges\r
2323 ToPcd.validlists = FromPcd.validlists\r
2324 ToPcd.expressions = FromPcd.expressions\r
52302d4d
LG
2325\r
2326 if ToPcd.DatumType == "VOID*" and ToPcd.MaxDatumSize in ['', None]:\r
2327 EdkLogger.debug(EdkLogger.DEBUG_9, "No MaxDatumSize specified for PCD %s.%s" \\r
2a29017e 2328 % (ToPcd.TokenSpaceGuidCName, TokenCName))\r
52302d4d
LG
2329 Value = ToPcd.DefaultValue\r
2330 if Value in [None, '']:\r
e8a47801 2331 ToPcd.MaxDatumSize = '1'\r
52302d4d 2332 elif Value[0] == 'L':\r
e8a47801 2333 ToPcd.MaxDatumSize = str((len(Value) - 2) * 2)\r
52302d4d
LG
2334 elif Value[0] == '{':\r
2335 ToPcd.MaxDatumSize = str(len(Value.split(',')))\r
2336 else:\r
e8a47801 2337 ToPcd.MaxDatumSize = str(len(Value) - 1)\r
52302d4d
LG
2338\r
2339 # apply default SKU for dynamic PCDS if specified one is not available\r
2340 if (ToPcd.Type in PCD_DYNAMIC_TYPE_LIST or ToPcd.Type in PCD_DYNAMIC_EX_TYPE_LIST) \\r
2341 and ToPcd.SkuInfoList in [None, {}, '']:\r
2342 if self.Platform.SkuName in self.Platform.SkuIds:\r
2343 SkuName = self.Platform.SkuName\r
2344 else:\r
2345 SkuName = 'DEFAULT'\r
2346 ToPcd.SkuInfoList = {\r
2347 SkuName : SkuInfoClass(SkuName, self.Platform.SkuIds[SkuName], '', '', '', '', '', ToPcd.DefaultValue)\r
2348 }\r
2349\r
2350 ## Apply PCD setting defined platform to a module\r
2351 #\r
2352 # @param Module The module from which the PCD setting will be overrided\r
2353 #\r
2354 # @retval PCD_list The list PCDs with settings from platform\r
2355 #\r
2356 def ApplyPcdSetting(self, Module, Pcds):\r
2357 # for each PCD in module\r
47fea6af
YZ
2358 for Name, Guid in Pcds:\r
2359 PcdInModule = Pcds[Name, Guid]\r
52302d4d 2360 # find out the PCD setting in platform\r
47fea6af
YZ
2361 if (Name, Guid) in self.Platform.Pcds:\r
2362 PcdInPlatform = self.Platform.Pcds[Name, Guid]\r
52302d4d
LG
2363 else:\r
2364 PcdInPlatform = None\r
2365 # then override the settings if any\r
2366 self._OverridePcd(PcdInModule, PcdInPlatform, Module)\r
2367 # resolve the VariableGuid value\r
2368 for SkuId in PcdInModule.SkuInfoList:\r
2369 Sku = PcdInModule.SkuInfoList[SkuId]\r
2370 if Sku.VariableGuid == '': continue\r
c28d2e10 2371 Sku.VariableGuidValue = GuidValue(Sku.VariableGuid, self.PackageList, self.MetaFile.Path)\r
52302d4d
LG
2372 if Sku.VariableGuidValue == None:\r
2373 PackageList = "\n\t".join([str(P) for P in self.PackageList])\r
2374 EdkLogger.error(\r
2375 'build',\r
2376 RESOURCE_NOT_AVAILABLE,\r
2377 "Value of GUID [%s] is not found in" % Sku.VariableGuid,\r
2378 ExtraData=PackageList + "\n\t(used with %s.%s from module %s)" \\r
2379 % (Guid, Name, str(Module)),\r
2380 File=self.MetaFile\r
2381 )\r
2382\r
2383 # override PCD settings with module specific setting\r
2384 if Module in self.Platform.Modules:\r
2385 PlatformModule = self.Platform.Modules[str(Module)]\r
2386 for Key in PlatformModule.Pcds:\r
aa9aa47e 2387 Flag = False\r
52302d4d 2388 if Key in Pcds:\r
aa9aa47e
YZ
2389 ToPcd = Pcds[Key]\r
2390 Flag = True\r
2391 elif Key in GlobalData.MixedPcd:\r
2392 for PcdItem in GlobalData.MixedPcd[Key]:\r
2393 if PcdItem in Pcds:\r
2394 ToPcd = Pcds[PcdItem]\r
2395 Flag = True\r
2396 break\r
2397 if Flag:\r
2398 self._OverridePcd(ToPcd, PlatformModule.Pcds[Key], Module)\r
52302d4d
LG
2399 return Pcds.values()\r
2400\r
2401 ## Resolve library names to library modules\r
2402 #\r
b36d134f 2403 # (for Edk.x modules)\r
52302d4d
LG
2404 #\r
2405 # @param Module The module from which the library names will be resolved\r
2406 #\r
2407 # @retval library_list The list of library modules\r
2408 #\r
2409 def ResolveLibraryReference(self, Module):\r
2410 EdkLogger.verbose("")\r
2411 EdkLogger.verbose("Library instances of module [%s] [%s]:" % (str(Module), self.Arch))\r
2412 LibraryConsumerList = [Module]\r
2413\r
b36d134f 2414 # "CompilerStub" is a must for Edk modules\r
52302d4d
LG
2415 if Module.Libraries:\r
2416 Module.Libraries.append("CompilerStub")\r
2417 LibraryList = []\r
2418 while len(LibraryConsumerList) > 0:\r
2419 M = LibraryConsumerList.pop()\r
2420 for LibraryName in M.Libraries:\r
2421 Library = self.Platform.LibraryClasses[LibraryName, ':dummy:']\r
2422 if Library == None:\r
2423 for Key in self.Platform.LibraryClasses.data.keys():\r
2424 if LibraryName.upper() == Key.upper():\r
2425 Library = self.Platform.LibraryClasses[Key, ':dummy:']\r
2426 break\r
2427 if Library == None:\r
2428 EdkLogger.warn("build", "Library [%s] is not found" % LibraryName, File=str(M),\r
2429 ExtraData="\t%s [%s]" % (str(Module), self.Arch))\r
2430 continue\r
2431\r
2432 if Library not in LibraryList:\r
2433 LibraryList.append(Library)\r
2434 LibraryConsumerList.append(Library)\r
2435 EdkLogger.verbose("\t" + LibraryName + " : " + str(Library) + ' ' + str(type(Library)))\r
2436 return LibraryList\r
2437\r
6780eef1
LG
2438 ## Calculate the priority value of the build option\r
2439 #\r
2440 # @param Key Build option definition contain: TARGET_TOOLCHAIN_ARCH_COMMANDTYPE_ATTRIBUTE\r
2441 #\r
2442 # @retval Value Priority value based on the priority list.\r
2443 #\r
2444 def CalculatePriorityValue(self, Key):\r
47fea6af
YZ
2445 Target, ToolChain, Arch, CommandType, Attr = Key.split('_')\r
2446 PriorityValue = 0x11111\r
6780eef1
LG
2447 if Target == "*":\r
2448 PriorityValue &= 0x01111\r
2449 if ToolChain == "*":\r
2450 PriorityValue &= 0x10111\r
2451 if Arch == "*":\r
2452 PriorityValue &= 0x11011\r
2453 if CommandType == "*":\r
2454 PriorityValue &= 0x11101\r
2455 if Attr == "*":\r
2456 PriorityValue &= 0x11110\r
47fea6af
YZ
2457\r
2458 return self.PrioList["0x%0.5x" % PriorityValue]\r
2459\r
6780eef1 2460\r
52302d4d
LG
2461 ## Expand * in build option key\r
2462 #\r
2463 # @param Options Options to be expanded\r
2464 #\r
2465 # @retval options Options expanded\r
6780eef1 2466 # \r
52302d4d
LG
2467 def _ExpandBuildOption(self, Options, ModuleStyle=None):\r
2468 BuildOptions = {}\r
2469 FamilyMatch = False\r
2470 FamilyIsNull = True\r
47fea6af 2471\r
6780eef1
LG
2472 OverrideList = {}\r
2473 #\r
2474 # Construct a list contain the build options which need override.\r
2475 #\r
2476 for Key in Options:\r
2477 #\r
2478 # Key[0] -- tool family\r
2479 # Key[1] -- TARGET_TOOLCHAIN_ARCH_COMMANDTYPE_ATTRIBUTE\r
2480 #\r
1ba5124e
YL
2481 if (Key[0] == self.BuildRuleFamily and\r
2482 (ModuleStyle == None or len(Key) < 3 or (len(Key) > 2 and Key[2] == ModuleStyle))):\r
6780eef1
LG
2483 Target, ToolChain, Arch, CommandType, Attr = Key[1].split('_')\r
2484 if Target == self.BuildTarget or Target == "*":\r
2485 if ToolChain == self.ToolChain or ToolChain == "*":\r
2486 if Arch == self.Arch or Arch == "*":\r
2487 if Options[Key].startswith("="):\r
47fea6af 2488 if OverrideList.get(Key[1]) != None:\r
6780eef1
LG
2489 OverrideList.pop(Key[1])\r
2490 OverrideList[Key[1]] = Options[Key]\r
2491 \r
2492 #\r
2493 # Use the highest priority value. \r
2494 #\r
2495 if (len(OverrideList) >= 2):\r
47fea6af 2496 KeyList = OverrideList.keys()\r
6780eef1 2497 for Index in range(len(KeyList)):\r
47fea6af 2498 NowKey = KeyList[Index]\r
6780eef1
LG
2499 Target1, ToolChain1, Arch1, CommandType1, Attr1 = NowKey.split("_")\r
2500 for Index1 in range(len(KeyList) - Index - 1):\r
2501 NextKey = KeyList[Index1 + Index + 1]\r
2502 #\r
2503 # Compare two Key, if one is included by another, choose the higher priority one\r
2504 # \r
2505 Target2, ToolChain2, Arch2, CommandType2, Attr2 = NextKey.split("_")\r
2506 if Target1 == Target2 or Target1 == "*" or Target2 == "*":\r
2507 if ToolChain1 == ToolChain2 or ToolChain1 == "*" or ToolChain2 == "*":\r
2508 if Arch1 == Arch2 or Arch1 == "*" or Arch2 == "*":\r
2509 if CommandType1 == CommandType2 or CommandType1 == "*" or CommandType2 == "*":\r
2510 if Attr1 == Attr2 or Attr1 == "*" or Attr2 == "*":\r
2511 if self.CalculatePriorityValue(NowKey) > self.CalculatePriorityValue(NextKey):\r
47fea6af 2512 if Options.get((self.BuildRuleFamily, NextKey)) != None:\r
6780eef1
LG
2513 Options.pop((self.BuildRuleFamily, NextKey))\r
2514 else:\r
47fea6af 2515 if Options.get((self.BuildRuleFamily, NowKey)) != None:\r
6780eef1
LG
2516 Options.pop((self.BuildRuleFamily, NowKey))\r
2517 \r
52302d4d
LG
2518 for Key in Options:\r
2519 if ModuleStyle != None and len (Key) > 2:\r
2520 # Check Module style is EDK or EDKII.\r
2521 # Only append build option for the matched style module.\r
2522 if ModuleStyle == EDK_NAME and Key[2] != EDK_NAME:\r
2523 continue\r
2524 elif ModuleStyle == EDKII_NAME and Key[2] != EDKII_NAME:\r
2525 continue\r
2526 Family = Key[0]\r
2527 Target, Tag, Arch, Tool, Attr = Key[1].split("_")\r
2528 # if tool chain family doesn't match, skip it\r
2529 if Tool in self.ToolDefinition and Family != "":\r
2530 FamilyIsNull = False\r
2531 if self.ToolDefinition[Tool].get(TAB_TOD_DEFINES_BUILDRULEFAMILY, "") != "":\r
2532 if Family != self.ToolDefinition[Tool][TAB_TOD_DEFINES_BUILDRULEFAMILY]:\r
2533 continue\r
2534 elif Family != self.ToolDefinition[Tool][TAB_TOD_DEFINES_FAMILY]:\r
2535 continue\r
2536 FamilyMatch = True\r
2537 # expand any wildcard\r
2538 if Target == "*" or Target == self.BuildTarget:\r
2539 if Tag == "*" or Tag == self.ToolChain:\r
2540 if Arch == "*" or Arch == self.Arch:\r
2541 if Tool not in BuildOptions:\r
2542 BuildOptions[Tool] = {}\r
5015bee2 2543 if Attr != "FLAGS" or Attr not in BuildOptions[Tool] or Options[Key].startswith('='):\r
52302d4d
LG
2544 BuildOptions[Tool][Attr] = Options[Key]\r
2545 else:\r
95816356
YZ
2546 # append options for the same tool except PATH\r
2547 if Attr != 'PATH':\r
2548 BuildOptions[Tool][Attr] += " " + Options[Key]\r
2549 else:\r
2550 BuildOptions[Tool][Attr] = Options[Key]\r
52302d4d
LG
2551 # Build Option Family has been checked, which need't to be checked again for family.\r
2552 if FamilyMatch or FamilyIsNull:\r
2553 return BuildOptions\r
1ba5124e 2554\r
52302d4d
LG
2555 for Key in Options:\r
2556 if ModuleStyle != None and len (Key) > 2:\r
2557 # Check Module style is EDK or EDKII.\r
2558 # Only append build option for the matched style module.\r
2559 if ModuleStyle == EDK_NAME and Key[2] != EDK_NAME:\r
2560 continue\r
2561 elif ModuleStyle == EDKII_NAME and Key[2] != EDKII_NAME:\r
2562 continue\r
2563 Family = Key[0]\r
2564 Target, Tag, Arch, Tool, Attr = Key[1].split("_")\r
2565 # if tool chain family doesn't match, skip it\r
47fea6af 2566 if Tool not in self.ToolDefinition or Family == "":\r
52302d4d
LG
2567 continue\r
2568 # option has been added before\r
2569 if Family != self.ToolDefinition[Tool][TAB_TOD_DEFINES_FAMILY]:\r
2570 continue\r
2571\r
2572 # expand any wildcard\r
2573 if Target == "*" or Target == self.BuildTarget:\r
2574 if Tag == "*" or Tag == self.ToolChain:\r
2575 if Arch == "*" or Arch == self.Arch:\r
2576 if Tool not in BuildOptions:\r
2577 BuildOptions[Tool] = {}\r
5015bee2 2578 if Attr != "FLAGS" or Attr not in BuildOptions[Tool] or Options[Key].startswith('='):\r
52302d4d
LG
2579 BuildOptions[Tool][Attr] = Options[Key]\r
2580 else:\r
95816356
YZ
2581 # append options for the same tool except PATH\r
2582 if Attr != 'PATH':\r
2583 BuildOptions[Tool][Attr] += " " + Options[Key]\r
2584 else:\r
2585 BuildOptions[Tool][Attr] = Options[Key]\r
52302d4d
LG
2586 return BuildOptions\r
2587\r
2588 ## Append build options in platform to a module\r
2589 #\r
2590 # @param Module The module to which the build options will be appened\r
2591 #\r
2592 # @retval options The options appended with build options in platform\r
2593 #\r
2594 def ApplyBuildOption(self, Module):\r
2595 # Get the different options for the different style module\r
2596 if Module.AutoGenVersion < 0x00010005:\r
2597 PlatformOptions = self.EdkBuildOption\r
35f69db9 2598 ModuleTypeOptions = self.Platform.GetBuildOptionsByModuleType(EDK_NAME, Module.ModuleType)\r
52302d4d
LG
2599 else:\r
2600 PlatformOptions = self.EdkIIBuildOption\r
35f69db9
YL
2601 ModuleTypeOptions = self.Platform.GetBuildOptionsByModuleType(EDKII_NAME, Module.ModuleType)\r
2602 ModuleTypeOptions = self._ExpandBuildOption(ModuleTypeOptions)\r
52302d4d
LG
2603 ModuleOptions = self._ExpandBuildOption(Module.BuildOptions)\r
2604 if Module in self.Platform.Modules:\r
2605 PlatformModule = self.Platform.Modules[str(Module)]\r
2606 PlatformModuleOptions = self._ExpandBuildOption(PlatformModule.BuildOptions)\r
2607 else:\r
2608 PlatformModuleOptions = {}\r
2609\r
fe4bf2f9 2610 BuildRuleOrder = None\r
35f69db9 2611 for Options in [self.ToolDefinition, ModuleOptions, PlatformOptions, ModuleTypeOptions, PlatformModuleOptions]:\r
fe4bf2f9
YL
2612 for Tool in Options:\r
2613 for Attr in Options[Tool]:\r
2614 if Attr == TAB_TOD_DEFINES_BUILDRULEORDER:\r
2615 BuildRuleOrder = Options[Tool][Attr]\r
2616\r
35f69db9
YL
2617 AllTools = set(ModuleOptions.keys() + PlatformOptions.keys() +\r
2618 PlatformModuleOptions.keys() + ModuleTypeOptions.keys() +\r
2619 self.ToolDefinition.keys())\r
52302d4d
LG
2620 BuildOptions = {}\r
2621 for Tool in AllTools:\r
2622 if Tool not in BuildOptions:\r
2623 BuildOptions[Tool] = {}\r
2624\r
35f69db9 2625 for Options in [self.ToolDefinition, ModuleOptions, PlatformOptions, ModuleTypeOptions, PlatformModuleOptions]:\r
52302d4d
LG
2626 if Tool not in Options:\r
2627 continue\r
2628 for Attr in Options[Tool]:\r
2629 Value = Options[Tool][Attr]\r
fe4bf2f9
YL
2630 #\r
2631 # Do not generate it in Makefile\r
2632 #\r
2633 if Attr == TAB_TOD_DEFINES_BUILDRULEORDER:\r
2634 continue\r
52302d4d
LG
2635 if Attr not in BuildOptions[Tool]:\r
2636 BuildOptions[Tool][Attr] = ""\r
2637 # check if override is indicated\r
2638 if Value.startswith('='):\r
05cc51ad
LY
2639 ToolPath = Value[1:]\r
2640 ToolPath = mws.handleWsMacro(ToolPath)\r
2641 BuildOptions[Tool][Attr] = ToolPath\r
5015bee2 2642 else:\r
05cc51ad 2643 Value = mws.handleWsMacro(Value)\r
95816356
YZ
2644 if Attr != 'PATH':\r
2645 BuildOptions[Tool][Attr] += " " + Value\r
2646 else:\r
2647 BuildOptions[Tool][Attr] = Value\r
f3decdc3
LG
2648 if Module.AutoGenVersion < 0x00010005 and self.Workspace.UniFlag != None:\r
2649 #\r
2650 # Override UNI flag only for EDK module.\r
2651 #\r
2652 if 'BUILD' not in BuildOptions:\r
2653 BuildOptions['BUILD'] = {}\r
2654 BuildOptions['BUILD']['FLAGS'] = self.Workspace.UniFlag\r
fe4bf2f9 2655 return BuildOptions, BuildRuleOrder\r
52302d4d
LG
2656\r
2657 Platform = property(_GetPlatform)\r
2658 Name = property(_GetName)\r
2659 Guid = property(_GetGuid)\r
2660 Version = property(_GetVersion)\r
2661\r
2662 OutputDir = property(_GetOutputDir)\r
2663 BuildDir = property(_GetBuildDir)\r
2664 MakeFileDir = property(_GetMakeFileDir)\r
2665 FdfFile = property(_GetFdfFile)\r
2666\r
2667 PcdTokenNumber = property(_GetPcdTokenNumbers) # (TokenCName, TokenSpaceGuidCName) : GeneratedTokenNumber\r
2668 DynamicPcdList = property(_GetDynamicPcdList) # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]\r
2669 NonDynamicPcdList = property(_GetNonDynamicPcdList) # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]\r
2bc3256c 2670 NonDynamicPcdDict = property(_GetNonDynamicPcdDict)\r
52302d4d
LG
2671 PackageList = property(_GetPackageList)\r
2672\r
2673 ToolDefinition = property(_GetToolDefinition) # toolcode : tool path\r
2674 ToolDefinitionFile = property(_GetToolDefFile) # toolcode : lib path\r
2675 ToolChainFamily = property(_GetToolChainFamily)\r
2676 BuildRuleFamily = property(_GetBuildRuleFamily)\r
2677 BuildOption = property(_GetBuildOptions) # toolcode : option\r
2678 EdkBuildOption = property(_GetEdkBuildOptions) # edktoolcode : option\r
2679 EdkIIBuildOption = property(_GetEdkIIBuildOptions) # edkiitoolcode : option\r
2680\r
2681 BuildCommand = property(_GetBuildCommand)\r
2682 BuildRule = property(_GetBuildRule)\r
2683 ModuleAutoGenList = property(_GetModuleAutoGenList)\r
2684 LibraryAutoGenList = property(_GetLibraryAutoGenList)\r
0923aa1c 2685 GenFdsCommand = property(_GenFdsCommand)\r
52302d4d
LG
2686\r
2687## ModuleAutoGen class\r
2688#\r
2689# This class encapsules the AutoGen behaviors for the build tools. In addition to\r
2690# the generation of AutoGen.h and AutoGen.c, it will generate *.depex file according\r
2691# to the [depex] section in module's inf file.\r
2692#\r
2693class ModuleAutoGen(AutoGen):\r
c17956e0
DL
2694 ## Cache the timestamps of metafiles of every module in a class variable\r
2695 #\r
2696 TimeDict = {}\r
2697\r
52302d4d
LG
2698 ## The real constructor of ModuleAutoGen\r
2699 #\r
2700 # This method is not supposed to be called by users of ModuleAutoGen. It's\r
2701 # only used by factory method __new__() to do real initialization work for an\r
2702 # object of ModuleAutoGen\r
2703 #\r
2704 # @param Workspace EdkIIWorkspaceBuild object\r
2705 # @param ModuleFile The path of module file\r
2706 # @param Target Build target (DEBUG, RELEASE)\r
2707 # @param Toolchain Name of tool chain\r
2708 # @param Arch The arch the module supports\r
2709 # @param PlatformFile Platform meta-file\r
2710 #\r
2711 def _Init(self, Workspace, ModuleFile, Target, Toolchain, Arch, PlatformFile):\r
2712 EdkLogger.debug(EdkLogger.DEBUG_9, "AutoGen module [%s] [%s]" % (ModuleFile, Arch))\r
2713 GlobalData.gProcessingFile = "%s [%s, %s, %s]" % (ModuleFile, Arch, Toolchain, Target)\r
2714\r
2715 self.Workspace = Workspace\r
2716 self.WorkspaceDir = Workspace.WorkspaceDir\r
2717\r
2718 self.MetaFile = ModuleFile\r
2719 self.PlatformInfo = PlatformAutoGen(Workspace, PlatformFile, Target, Toolchain, Arch)\r
2720 # check if this module is employed by active platform\r
2721 if not self.PlatformInfo.ValidModule(self.MetaFile):\r
2722 EdkLogger.verbose("Module [%s] for [%s] is not employed by active platform\n" \\r
2723 % (self.MetaFile, Arch))\r
2724 return False\r
2725\r
2726 self.SourceDir = self.MetaFile.SubDir\r
05cc51ad 2727 self.SourceDir = mws.relpath(self.SourceDir, self.WorkspaceDir)\r
97fa0ee9 2728\r
52302d4d
LG
2729 self.SourceOverrideDir = None\r
2730 # use overrided path defined in DSC file\r
2731 if self.MetaFile.Key in GlobalData.gOverrideDir:\r
2732 self.SourceOverrideDir = GlobalData.gOverrideDir[self.MetaFile.Key]\r
2733\r
2734 self.ToolChain = Toolchain\r
2735 self.BuildTarget = Target\r
2736 self.Arch = Arch\r
2737 self.ToolChainFamily = self.PlatformInfo.ToolChainFamily\r
2738 self.BuildRuleFamily = self.PlatformInfo.BuildRuleFamily\r
2739\r
2740 self.IsMakeFileCreated = False\r
2741 self.IsCodeFileCreated = False\r
da92f276
LG
2742 self.IsAsBuiltInfCreated = False\r
2743 self.DepexGenerated = False\r
52302d4d
LG
2744\r
2745 self.BuildDatabase = self.Workspace.BuildDatabase\r
fe4bf2f9 2746 self.BuildRuleOrder = None\r
1b8eca8b 2747 self.BuildTime = 0\r
52302d4d
LG
2748\r
2749 self._Module = None\r
2750 self._Name = None\r
2751 self._Guid = None\r
2752 self._Version = None\r
2753 self._ModuleType = None\r
2754 self._ComponentType = None\r
2755 self._PcdIsDriver = None\r
2756 self._AutoGenVersion = None\r
2757 self._LibraryFlag = None\r
2758 self._CustomMakefile = None\r
2759 self._Macro = None\r
2760\r
2761 self._BuildDir = None\r
2762 self._OutputDir = None\r
2763 self._DebugDir = None\r
2764 self._MakeFileDir = None\r
2765\r
2766 self._IncludePathList = None\r
725cdb8f 2767 self._IncludePathLength = 0\r
52302d4d
LG
2768 self._AutoGenFileList = None\r
2769 self._UnicodeFileList = None\r
5b97eb4c 2770 self._VfrFileList = None\r
333ba578 2771 self._IdfFileList = None\r
52302d4d
LG
2772 self._SourceFileList = None\r
2773 self._ObjectFileList = None\r
2774 self._BinaryFileList = None\r
2775\r
2776 self._DependentPackageList = None\r
2777 self._DependentLibraryList = None\r
2778 self._LibraryAutoGenList = None\r
2779 self._DerivedPackageList = None\r
2780 self._ModulePcdList = None\r
2781 self._LibraryPcdList = None\r
e8a47801 2782 self._PcdComments = sdict()\r
52302d4d 2783 self._GuidList = None\r
e8a47801
LG
2784 self._GuidsUsedByPcd = None\r
2785 self._GuidComments = sdict()\r
52302d4d 2786 self._ProtocolList = None\r
e8a47801 2787 self._ProtocolComments = sdict()\r
52302d4d 2788 self._PpiList = None\r
e8a47801 2789 self._PpiComments = sdict()\r
52302d4d
LG
2790 self._DepexList = None\r
2791 self._DepexExpressionList = None\r
2792 self._BuildOption = None\r
79b74a03 2793 self._BuildOptionIncPathList = None\r
52302d4d
LG
2794 self._BuildTargets = None\r
2795 self._IntroBuildTargetList = None\r
2796 self._FinalBuildTargetList = None\r
2797 self._FileTypes = None\r
2798 self._BuildRules = None\r
c17956e0
DL
2799\r
2800 self._TimeStampPath = None\r
2801\r
2802 self.AutoGenDepSet = set()\r
2803\r
2bc3256c
LG
2804 \r
2805 ## The Modules referenced to this Library\r
2806 # Only Library has this attribute\r
2807 self._ReferenceModules = [] \r
2808 \r
2809 ## Store the FixedAtBuild Pcds\r
2810 # \r
2811 self._FixedAtBuildPcds = []\r
2812 self.ConstPcd = {}\r
52302d4d
LG
2813 return True\r
2814\r
2815 def __repr__(self):\r
2816 return "%s [%s]" % (self.MetaFile, self.Arch)\r
2817\r
2bc3256c
LG
2818 # Get FixedAtBuild Pcds of this Module\r
2819 def _GetFixedAtBuildPcds(self):\r
2820 if self._FixedAtBuildPcds:\r
2821 return self._FixedAtBuildPcds\r
2822 for Pcd in self.ModulePcdList:\r
7256bd55 2823 if Pcd.Type != "FixedAtBuild":\r
2bc3256c
LG
2824 continue\r
2825 if Pcd not in self._FixedAtBuildPcds:\r
2826 self._FixedAtBuildPcds.append(Pcd)\r
2827 \r
2828 return self._FixedAtBuildPcds \r
2829\r
867d1cd4
YL
2830 def _GetUniqueBaseName(self):\r
2831 BaseName = self.Name\r
2832 for Module in self.PlatformInfo.ModuleAutoGenList:\r
2833 if Module.MetaFile == self.MetaFile:\r
2834 continue\r
2835 if Module.Name == self.Name:\r
867d1cd4
YL
2836 if uuid.UUID(Module.Guid) == uuid.UUID(self.Guid):\r
2837 EdkLogger.error("build", FILE_DUPLICATED, 'Modules have same BaseName and FILE_GUID:\n'\r
2838 ' %s\n %s' % (Module.MetaFile, self.MetaFile))\r
2839 BaseName = '%s_%s' % (self.Name, self.Guid)\r
2840 return BaseName\r
2841\r
52302d4d
LG
2842 # Macros could be used in build_rule.txt (also Makefile)\r
2843 def _GetMacros(self):\r
2844 if self._Macro == None:\r
2845 self._Macro = sdict()\r
2846 self._Macro["WORKSPACE" ] = self.WorkspaceDir\r
2847 self._Macro["MODULE_NAME" ] = self.Name\r
867d1cd4 2848 self._Macro["MODULE_NAME_GUID" ] = self._GetUniqueBaseName()\r
52302d4d
LG
2849 self._Macro["MODULE_GUID" ] = self.Guid\r
2850 self._Macro["MODULE_VERSION" ] = self.Version\r
2851 self._Macro["MODULE_TYPE" ] = self.ModuleType\r
2852 self._Macro["MODULE_FILE" ] = str(self.MetaFile)\r
2853 self._Macro["MODULE_FILE_BASE_NAME" ] = self.MetaFile.BaseName\r
2854 self._Macro["MODULE_RELATIVE_DIR" ] = self.SourceDir\r
2855 self._Macro["MODULE_DIR" ] = self.SourceDir\r
2856\r
2857 self._Macro["BASE_NAME" ] = self.Name\r
2858\r
2859 self._Macro["ARCH" ] = self.Arch\r
2860 self._Macro["TOOLCHAIN" ] = self.ToolChain\r
2861 self._Macro["TOOLCHAIN_TAG" ] = self.ToolChain\r
0d2711a6 2862 self._Macro["TOOL_CHAIN_TAG" ] = self.ToolChain\r
52302d4d
LG
2863 self._Macro["TARGET" ] = self.BuildTarget\r
2864\r
2865 self._Macro["BUILD_DIR" ] = self.PlatformInfo.BuildDir\r
2866 self._Macro["BIN_DIR" ] = os.path.join(self.PlatformInfo.BuildDir, self.Arch)\r
2867 self._Macro["LIB_DIR" ] = os.path.join(self.PlatformInfo.BuildDir, self.Arch)\r
2868 self._Macro["MODULE_BUILD_DIR" ] = self.BuildDir\r
2869 self._Macro["OUTPUT_DIR" ] = self.OutputDir\r
2870 self._Macro["DEBUG_DIR" ] = self.DebugDir\r
df1e1b63
YZ
2871 self._Macro["DEST_DIR_OUTPUT" ] = self.OutputDir\r
2872 self._Macro["DEST_DIR_DEBUG" ] = self.DebugDir\r
3570e332
YZ
2873 self._Macro["PLATFORM_NAME" ] = self.PlatformInfo.Name\r
2874 self._Macro["PLATFORM_GUID" ] = self.PlatformInfo.Guid\r
2875 self._Macro["PLATFORM_VERSION" ] = self.PlatformInfo.Version\r
2876 self._Macro["PLATFORM_RELATIVE_DIR" ] = self.PlatformInfo.SourceDir\r
2877 self._Macro["PLATFORM_DIR" ] = mws.join(self.WorkspaceDir, self.PlatformInfo.SourceDir)\r
2878 self._Macro["PLATFORM_OUTPUT_DIR" ] = self.PlatformInfo.OutputDir\r
52302d4d
LG
2879 return self._Macro\r
2880\r
2881 ## Return the module build data object\r
2882 def _GetModule(self):\r
2883 if self._Module == None:\r
0d2711a6 2884 self._Module = self.Workspace.BuildDatabase[self.MetaFile, self.Arch, self.BuildTarget, self.ToolChain]\r
52302d4d
LG
2885 return self._Module\r
2886\r
2887 ## Return the module name\r
2888 def _GetBaseName(self):\r
2889 return self.Module.BaseName\r
2890\r
b36d134f
LG
2891 ## Return the module DxsFile if exist\r
2892 def _GetDxsFile(self):\r
2893 return self.Module.DxsFile\r
2894\r
52302d4d
LG
2895 ## Return the module SourceOverridePath\r
2896 def _GetSourceOverridePath(self):\r
2897 return self.Module.SourceOverridePath\r
2898\r
2899 ## Return the module meta-file GUID\r
2900 def _GetGuid(self):\r
97fa0ee9
YL
2901 #\r
2902 # To build same module more than once, the module path with FILE_GUID overridden has\r
2903 # the file name FILE_GUIDmodule.inf, but the relative path (self.MetaFile.File) is the realy path\r
2904 # in DSC. The overridden GUID can be retrieved from file name\r
2905 #\r
2906 if os.path.basename(self.MetaFile.File) != os.path.basename(self.MetaFile.Path):\r
2907 #\r
2908 # Length of GUID is 36\r
2909 #\r
2910 return os.path.basename(self.MetaFile.Path)[:36]\r
52302d4d
LG
2911 return self.Module.Guid\r
2912\r
2913 ## Return the module version\r
2914 def _GetVersion(self):\r
2915 return self.Module.Version\r
2916\r
2917 ## Return the module type\r
2918 def _GetModuleType(self):\r
2919 return self.Module.ModuleType\r
2920\r
b36d134f 2921 ## Return the component type (for Edk.x style of module)\r
52302d4d
LG
2922 def _GetComponentType(self):\r
2923 return self.Module.ComponentType\r
2924\r
2925 ## Return the build type\r
2926 def _GetBuildType(self):\r
2927 return self.Module.BuildType\r
2928\r
2929 ## Return the PCD_IS_DRIVER setting\r
2930 def _GetPcdIsDriver(self):\r
2931 return self.Module.PcdIsDriver\r
2932\r
2933 ## Return the autogen version, i.e. module meta-file version\r
2934 def _GetAutoGenVersion(self):\r
2935 return self.Module.AutoGenVersion\r
2936\r
2937 ## Check if the module is library or not\r
2938 def _IsLibrary(self):\r
2939 if self._LibraryFlag == None:\r
2940 if self.Module.LibraryClass != None and self.Module.LibraryClass != []:\r
2941 self._LibraryFlag = True\r
2942 else:\r
2943 self._LibraryFlag = False\r
2944 return self._LibraryFlag\r
2945\r
e8a47801
LG
2946 ## Check if the module is binary module or not\r
2947 def _IsBinaryModule(self):\r
2948 return self.Module.IsBinaryModule\r
2949\r
52302d4d
LG
2950 ## Return the directory to store intermediate files of the module\r
2951 def _GetBuildDir(self):\r
2952 if self._BuildDir == None:\r
2953 self._BuildDir = path.join(\r
2954 self.PlatformInfo.BuildDir,\r
2955 self.Arch,\r
2956 self.SourceDir,\r
2957 self.MetaFile.BaseName\r
2958 )\r
2959 CreateDirectory(self._BuildDir)\r
2960 return self._BuildDir\r
2961\r
2962 ## Return the directory to store the intermediate object files of the mdoule\r
2963 def _GetOutputDir(self):\r
2964 if self._OutputDir == None:\r
2965 self._OutputDir = path.join(self.BuildDir, "OUTPUT")\r
2966 CreateDirectory(self._OutputDir)\r
2967 return self._OutputDir\r
2968\r
2969 ## Return the directory to store auto-gened source files of the mdoule\r
2970 def _GetDebugDir(self):\r
2971 if self._DebugDir == None:\r
2972 self._DebugDir = path.join(self.BuildDir, "DEBUG")\r
2973 CreateDirectory(self._DebugDir)\r
2974 return self._DebugDir\r
2975\r
2976 ## Return the path of custom file\r
2977 def _GetCustomMakefile(self):\r
2978 if self._CustomMakefile == None:\r
2979 self._CustomMakefile = {}\r
2980 for Type in self.Module.CustomMakefile:\r
2981 if Type in gMakeTypeMap:\r
2982 MakeType = gMakeTypeMap[Type]\r
2983 else:\r
2984 MakeType = 'nmake'\r
2985 if self.SourceOverrideDir != None:\r
2986 File = os.path.join(self.SourceOverrideDir, self.Module.CustomMakefile[Type])\r
2987 if not os.path.exists(File):\r
2988 File = os.path.join(self.SourceDir, self.Module.CustomMakefile[Type])\r
2989 else:\r
2990 File = os.path.join(self.SourceDir, self.Module.CustomMakefile[Type])\r
2991 self._CustomMakefile[MakeType] = File\r
2992 return self._CustomMakefile\r
2993\r
2994 ## Return the directory of the makefile\r
2995 #\r
2996 # @retval string The directory string of module's makefile\r
2997 #\r
2998 def _GetMakeFileDir(self):\r
2999 return self.BuildDir\r
3000\r
3001 ## Return build command string\r
3002 #\r
3003 # @retval string Build command string\r
3004 #\r
3005 def _GetBuildCommand(self):\r
3006 return self.PlatformInfo.BuildCommand\r
3007\r
3008 ## Get object list of all packages the module and its dependent libraries belong to\r
3009 #\r
3010 # @retval list The list of package object\r
3011 #\r
3012 def _GetDerivedPackageList(self):\r
3013 PackageList = []\r
3014 for M in [self.Module] + self.DependentLibraryList:\r
3015 for Package in M.Packages:\r
3016 if Package in PackageList:\r
3017 continue\r
3018 PackageList.append(Package)\r
3019 return PackageList\r
97fa0ee9
YL
3020 \r
3021 ## Get the depex string\r
3022 #\r
3023 # @return : a string contain all depex expresion.\r
3024 def _GetDepexExpresionString(self):\r
3025 DepexStr = ''\r
3026 DepexList = []\r
3027 ## DPX_SOURCE IN Define section.\r
3028 if self.Module.DxsFile:\r
3029 return DepexStr\r
3030 for M in [self.Module] + self.DependentLibraryList:\r
3031 Filename = M.MetaFile.Path\r
3032 InfObj = InfSectionParser.InfSectionParser(Filename)\r
3033 DepexExpresionList = InfObj.GetDepexExpresionList()\r
3034 for DepexExpresion in DepexExpresionList:\r
3035 for key in DepexExpresion.keys():\r
3036 Arch, ModuleType = key\r
518aebe2 3037 DepexExpr = [x for x in DepexExpresion[key] if not str(x).startswith('#')]\r
97fa0ee9
YL
3038 # the type of build module is USER_DEFINED.\r
3039 # All different DEPEX section tags would be copied into the As Built INF file\r
3040 # and there would be separate DEPEX section tags\r
3041 if self.ModuleType.upper() == SUP_MODULE_USER_DEFINED:\r
3042 if (Arch.upper() == self.Arch.upper()) and (ModuleType.upper() != TAB_ARCH_COMMON):\r
518aebe2 3043 DepexList.append({(Arch, ModuleType): DepexExpr})\r
97fa0ee9
YL
3044 else:\r
3045 if Arch.upper() == TAB_ARCH_COMMON or \\r
3046 (Arch.upper() == self.Arch.upper() and \\r
3047 ModuleType.upper() in [TAB_ARCH_COMMON, self.ModuleType.upper()]):\r
518aebe2 3048 DepexList.append({(Arch, ModuleType): DepexExpr})\r
97fa0ee9
YL
3049 \r
3050 #the type of build module is USER_DEFINED.\r
3051 if self.ModuleType.upper() == SUP_MODULE_USER_DEFINED:\r
3052 for Depex in DepexList:\r
3053 for key in Depex.keys():\r
3054 DepexStr += '[Depex.%s.%s]\n' % key\r
3055 DepexStr += '\n'.join(['# '+ val for val in Depex[key]])\r
3056 DepexStr += '\n\n'\r
3057 if not DepexStr:\r
3058 return '[Depex.%s]\n' % self.Arch\r
3059 return DepexStr\r
3060 \r
3061 #the type of build module not is USER_DEFINED.\r
3062 Count = 0\r
3063 for Depex in DepexList:\r
3064 Count += 1\r
3065 if DepexStr != '':\r
3066 DepexStr += ' AND '\r
3067 DepexStr += '('\r
3068 for D in Depex.values():\r
3069 DepexStr += ' '.join([val for val in D])\r
3070 Index = DepexStr.find('END')\r
3071 if Index > -1 and Index == len(DepexStr) - 3:\r
3072 DepexStr = DepexStr[:-3]\r
3073 DepexStr = DepexStr.strip()\r
3074 DepexStr += ')'\r
3075 if Count == 1:\r
3076 DepexStr = DepexStr.lstrip('(').rstrip(')').strip()\r
3077 if not DepexStr:\r
3078 return '[Depex.%s]\n' % self.Arch\r
3079 return '[Depex.%s]\n# ' % self.Arch + DepexStr\r
3080 \r
52302d4d
LG
3081 ## Merge dependency expression\r
3082 #\r
3083 # @retval list The token list of the dependency expression after parsed\r
3084 #\r
3085 def _GetDepexTokenList(self):\r
3086 if self._DepexList == None:\r
3087 self._DepexList = {}\r
b36d134f 3088 if self.DxsFile or self.IsLibrary or TAB_DEPENDENCY_EXPRESSION_FILE in self.FileTypes:\r
52302d4d
LG
3089 return self._DepexList\r
3090\r
3091 self._DepexList[self.ModuleType] = []\r
3092\r
3093 for ModuleType in self._DepexList:\r
3094 DepexList = self._DepexList[ModuleType]\r
3095 #\r
3096 # Append depex from dependent libraries, if not "BEFORE", "AFTER" expresion\r
3097 #\r
3098 for M in [self.Module] + self.DependentLibraryList:\r
3099 Inherited = False\r
3100 for D in M.Depex[self.Arch, ModuleType]:\r
3101 if DepexList != []:\r
3102 DepexList.append('AND')\r
3103 DepexList.append('(')\r
3104 DepexList.extend(D)\r
3105 if DepexList[-1] == 'END': # no need of a END at this time\r
3106 DepexList.pop()\r
3107 DepexList.append(')')\r
3108 Inherited = True\r
3109 if Inherited:\r
3110 EdkLogger.verbose("DEPEX[%s] (+%s) = %s" % (self.Name, M.BaseName, DepexList))\r
3111 if 'BEFORE' in DepexList or 'AFTER' in DepexList:\r
3112 break\r
3113 if len(DepexList) > 0:\r
3114 EdkLogger.verbose('')\r
3115 return self._DepexList\r
3116\r
3117 ## Merge dependency expression\r
3118 #\r
3119 # @retval list The token list of the dependency expression after parsed\r
3120 #\r
3121 def _GetDepexExpressionTokenList(self):\r
3122 if self._DepexExpressionList == None:\r
3123 self._DepexExpressionList = {}\r
b36d134f 3124 if self.DxsFile or self.IsLibrary or TAB_DEPENDENCY_EXPRESSION_FILE in self.FileTypes:\r
52302d4d
LG
3125 return self._DepexExpressionList\r
3126\r
3127 self._DepexExpressionList[self.ModuleType] = ''\r
3128\r
3129 for ModuleType in self._DepexExpressionList:\r
3130 DepexExpressionList = self._DepexExpressionList[ModuleType]\r
3131 #\r
3132 # Append depex from dependent libraries, if not "BEFORE", "AFTER" expresion\r
3133 #\r
3134 for M in [self.Module] + self.DependentLibraryList:\r
3135 Inherited = False\r
3136 for D in M.DepexExpression[self.Arch, ModuleType]:\r
3137 if DepexExpressionList != '':\r
3138 DepexExpressionList += ' AND '\r
3139 DepexExpressionList += '('\r
3140 DepexExpressionList += D\r
3141 DepexExpressionList = DepexExpressionList.rstrip('END').strip()\r
3142 DepexExpressionList += ')'\r
3143 Inherited = True\r
3144 if Inherited:\r
3145 EdkLogger.verbose("DEPEX[%s] (+%s) = %s" % (self.Name, M.BaseName, DepexExpressionList))\r
3146 if 'BEFORE' in DepexExpressionList or 'AFTER' in DepexExpressionList:\r
3147 break\r
3148 if len(DepexExpressionList) > 0:\r
3149 EdkLogger.verbose('')\r
3150 self._DepexExpressionList[ModuleType] = DepexExpressionList\r
3151 return self._DepexExpressionList\r
3152\r
dfa41b4a
YZ
3153 # Get the tiano core user extension, it is contain dependent library.\r
3154 # @retval: a list contain tiano core userextension.\r
3155 #\r
3156 def _GetTianoCoreUserExtensionList(self):\r
3157 TianoCoreUserExtentionList = []\r
3158 for M in [self.Module] + self.DependentLibraryList:\r
3159 Filename = M.MetaFile.Path\r
3160 InfObj = InfSectionParser.InfSectionParser(Filename)\r
3161 TianoCoreUserExtenList = InfObj.GetUserExtensionTianoCore()\r
3162 for TianoCoreUserExtent in TianoCoreUserExtenList:\r
3163 for Section in TianoCoreUserExtent.keys():\r
3164 ItemList = Section.split(TAB_SPLIT)\r
3165 Arch = self.Arch\r
3166 if len(ItemList) == 4:\r
3167 Arch = ItemList[3]\r
3168 if Arch.upper() == TAB_ARCH_COMMON or Arch.upper() == self.Arch.upper():\r
3169 TianoCoreList = []\r
3170 TianoCoreList.extend([TAB_SECTION_START + Section + TAB_SECTION_END])\r
3171 TianoCoreList.extend(TianoCoreUserExtent[Section][:])\r
3172 TianoCoreList.append('\n')\r
3173 TianoCoreUserExtentionList.append(TianoCoreList)\r
3174\r
3175 return TianoCoreUserExtentionList\r
3176\r
52302d4d
LG
3177 ## Return the list of specification version required for the module\r
3178 #\r
3179 # @retval list The list of specification defined in module file\r
3180 #\r
3181 def _GetSpecification(self):\r
3182 return self.Module.Specification\r
3183\r
3184 ## Tool option for the module build\r
3185 #\r
3186 # @param PlatformInfo The object of PlatformBuildInfo\r
3187 # @retval dict The dict containing valid options\r
3188 #\r
3189 def _GetModuleBuildOption(self):\r
3190 if self._BuildOption == None:\r
fe4bf2f9
YL
3191 self._BuildOption, self.BuildRuleOrder = self.PlatformInfo.ApplyBuildOption(self.Module)\r
3192 if self.BuildRuleOrder:\r
3193 self.BuildRuleOrder = ['.%s' % Ext for Ext in self.BuildRuleOrder.split()]\r
52302d4d
LG
3194 return self._BuildOption\r
3195\r
79b74a03
LG
3196 ## Get include path list from tool option for the module build\r
3197 #\r
3198 # @retval list The include path list\r
3199 #\r
3200 def _GetBuildOptionIncPathList(self):\r
3201 if self._BuildOptionIncPathList == None:\r
3202 #\r
d40b2ee6 3203 # Regular expression for finding Include Directories, the difference between MSFT and INTEL/GCC/RVCT\r
79b74a03
LG
3204 # is the former use /I , the Latter used -I to specify include directories\r
3205 #\r
3206 if self.PlatformInfo.ToolChainFamily in ('MSFT'):\r
47fea6af 3207 gBuildOptIncludePattern = re.compile(r"(?:.*?)/I[ \t]*([^ ]*)", re.MULTILINE | re.DOTALL)\r
d40b2ee6 3208 elif self.PlatformInfo.ToolChainFamily in ('INTEL', 'GCC', 'RVCT'):\r
47fea6af 3209 gBuildOptIncludePattern = re.compile(r"(?:.*?)-I[ \t]*([^ ]*)", re.MULTILINE | re.DOTALL)\r
d40b2ee6
LG
3210 else:\r
3211 #\r
3212 # New ToolChainFamily, don't known whether there is option to specify include directories\r
3213 #\r
3214 self._BuildOptionIncPathList = []\r
3215 return self._BuildOptionIncPathList\r
79b74a03
LG
3216 \r
3217 BuildOptionIncPathList = []\r
3218 for Tool in ('CC', 'PP', 'VFRPP', 'ASLPP', 'ASLCC', 'APP', 'ASM'):\r
3219 Attr = 'FLAGS'\r
3220 try:\r
3221 FlagOption = self.BuildOption[Tool][Attr]\r
3222 except KeyError:\r
3223 FlagOption = ''\r
3224 \r
d40b2ee6
LG
3225 if self.PlatformInfo.ToolChainFamily != 'RVCT':\r
3226 IncPathList = [NormPath(Path, self.Macros) for Path in gBuildOptIncludePattern.findall(FlagOption)]\r
3227 else:\r
3228 #\r
3229 # RVCT may specify a list of directory seperated by commas\r
3230 #\r
3231 IncPathList = []\r
3232 for Path in gBuildOptIncludePattern.findall(FlagOption):\r
3233 PathList = GetSplitList(Path, TAB_COMMA_SPLIT)\r
3234 IncPathList += [NormPath(PathEntry, self.Macros) for PathEntry in PathList]\r
3235\r
79b74a03
LG
3236 #\r
3237 # EDK II modules must not reference header files outside of the packages they depend on or \r
3238 # within the module's directory tree. Report error if violation.\r
3239 #\r
3240 if self.AutoGenVersion >= 0x00010005 and len(IncPathList) > 0:\r
3241 for Path in IncPathList:\r
3242 if (Path not in self.IncludePathList) and (CommonPath([Path, self.MetaFile.Dir]) != self.MetaFile.Dir):\r
47fea6af
YZ
3243 ErrMsg = "The include directory for the EDK II module in this line is invalid %s specified in %s FLAGS '%s'" % (Path, Tool, FlagOption)\r
3244 EdkLogger.error("build",\r
79b74a03 3245 PARAMETER_INVALID,\r
47fea6af
YZ
3246 ExtraData=ErrMsg,\r
3247 File=str(self.MetaFile))\r
79b74a03
LG
3248\r
3249 \r
3250 BuildOptionIncPathList += IncPathList\r
3251 \r
3252 self._BuildOptionIncPathList = BuildOptionIncPathList\r
3253 \r
3254 return self._BuildOptionIncPathList\r
3255 \r
52302d4d
LG
3256 ## Return a list of files which can be built from source\r
3257 #\r
3258 # What kind of files can be built is determined by build rules in\r
97fa0ee9 3259 # $(CONF_DIRECTORY)/build_rule.txt and toolchain family.\r
52302d4d
LG
3260 #\r
3261 def _GetSourceFileList(self):\r
3262 if self._SourceFileList == None:\r
3263 self._SourceFileList = []\r
3264 for F in self.Module.Sources:\r
3265 # match tool chain\r
08dd311f 3266 if F.TagName not in ("", "*", self.ToolChain):\r
52302d4d
LG
3267 EdkLogger.debug(EdkLogger.DEBUG_9, "The toolchain [%s] for processing file [%s] is found, "\r
3268 "but [%s] is needed" % (F.TagName, str(F), self.ToolChain))\r
3269 continue\r
e2597799
YZ
3270 # match tool chain family or build rule family\r
3271 if F.ToolChainFamily not in ("", "*", self.ToolChainFamily, self.BuildRuleFamily):\r
52302d4d
LG
3272 EdkLogger.debug(\r
3273 EdkLogger.DEBUG_0,\r
3274 "The file [%s] must be built by tools of [%s], " \\r
e2597799
YZ
3275 "but current toolchain family is [%s], buildrule family is [%s]" \\r
3276 % (str(F), F.ToolChainFamily, self.ToolChainFamily, self.BuildRuleFamily))\r
52302d4d
LG
3277 continue\r
3278\r
3279 # add the file path into search path list for file including\r
3280 if F.Dir not in self.IncludePathList and self.AutoGenVersion >= 0x00010005:\r
3281 self.IncludePathList.insert(0, F.Dir)\r
3282 self._SourceFileList.append(F)\r
4cb7bade
YZ
3283\r
3284 self._MatchBuildRuleOrder(self._SourceFileList)\r
3285\r
3286 for F in self._SourceFileList:\r
52302d4d
LG
3287 self._ApplyBuildRule(F, TAB_UNKNOWN_FILE)\r
3288 return self._SourceFileList\r
3289\r
4cb7bade
YZ
3290 def _MatchBuildRuleOrder(self, FileList):\r
3291 Order_Dict = {}\r
3292 self._GetModuleBuildOption()\r
3293 for SingleFile in FileList:\r
3294 if self.BuildRuleOrder and SingleFile.Ext in self.BuildRuleOrder and SingleFile.Ext in self.BuildRules:\r
3295 key = SingleFile.Path.split(SingleFile.Ext)[0]\r
3296 if key in Order_Dict:\r
3297 Order_Dict[key].append(SingleFile.Ext)\r
3298 else:\r
3299 Order_Dict[key] = [SingleFile.Ext]\r
3300\r
3301 RemoveList = []\r
3302 for F in Order_Dict:\r
3303 if len(Order_Dict[F]) > 1:\r
3304 Order_Dict[F].sort(key=lambda i: self.BuildRuleOrder.index(i))\r
3305 for Ext in Order_Dict[F][1:]:\r
3306 RemoveList.append(F + Ext)\r
3307 \r
3308 for item in RemoveList:\r
3309 FileList.remove(item)\r
3310\r
3311 return FileList\r
3312\r
52302d4d
LG
3313 ## Return the list of unicode files\r
3314 def _GetUnicodeFileList(self):\r
3315 if self._UnicodeFileList == None:\r
3316 if TAB_UNICODE_FILE in self.FileTypes:\r
3317 self._UnicodeFileList = self.FileTypes[TAB_UNICODE_FILE]\r
3318 else:\r
3319 self._UnicodeFileList = []\r
3320 return self._UnicodeFileList\r
3321\r
5b97eb4c
YZ
3322 ## Return the list of vfr files\r
3323 def _GetVfrFileList(self):\r
3324 if self._VfrFileList == None:\r
3325 if TAB_VFR_FILE in self.FileTypes:\r
3326 self._VfrFileList = self.FileTypes[TAB_VFR_FILE]\r
3327 else:\r
3328 self._VfrFileList = []\r
3329 return self._VfrFileList\r
3330\r
333ba578
YZ
3331 ## Return the list of Image Definition files\r
3332 def _GetIdfFileList(self):\r
3333 if self._IdfFileList == None:\r
3334 if TAB_IMAGE_FILE in self.FileTypes:\r
3335 self._IdfFileList = self.FileTypes[TAB_IMAGE_FILE]\r
3336 else:\r
3337 self._IdfFileList = []\r
3338 return self._IdfFileList\r
3339\r
52302d4d
LG
3340 ## Return a list of files which can be built from binary\r
3341 #\r
3342 # "Build" binary files are just to copy them to build directory.\r
3343 #\r
3344 # @retval list The list of files which can be built later\r
3345 #\r
3346 def _GetBinaryFiles(self):\r
3347 if self._BinaryFileList == None:\r
3348 self._BinaryFileList = []\r
3349 for F in self.Module.Binaries:\r
3350 if F.Target not in ['COMMON', '*'] and F.Target != self.BuildTarget:\r
3351 continue\r
3352 self._BinaryFileList.append(F)\r
3353 self._ApplyBuildRule(F, F.Type)\r
3354 return self._BinaryFileList\r
3355\r
3356 def _GetBuildRules(self):\r
3357 if self._BuildRules == None:\r
3358 BuildRules = {}\r
3359 BuildRuleDatabase = self.PlatformInfo.BuildRule\r
3360 for Type in BuildRuleDatabase.FileTypeList:\r
3361 #first try getting build rule by BuildRuleFamily\r
3362 RuleObject = BuildRuleDatabase[Type, self.BuildType, self.Arch, self.BuildRuleFamily]\r
3363 if not RuleObject:\r
3364 # build type is always module type, but ...\r
3365 if self.ModuleType != self.BuildType:\r
3366 RuleObject = BuildRuleDatabase[Type, self.ModuleType, self.Arch, self.BuildRuleFamily]\r
3367 #second try getting build rule by ToolChainFamily\r
3368 if not RuleObject:\r
3369 RuleObject = BuildRuleDatabase[Type, self.BuildType, self.Arch, self.ToolChainFamily]\r
3370 if not RuleObject:\r
3371 # build type is always module type, but ...\r
3372 if self.ModuleType != self.BuildType:\r
3373 RuleObject = BuildRuleDatabase[Type, self.ModuleType, self.Arch, self.ToolChainFamily]\r
3374 if not RuleObject:\r
3375 continue\r
3376 RuleObject = RuleObject.Instantiate(self.Macros)\r
3377 BuildRules[Type] = RuleObject\r
3378 for Ext in RuleObject.SourceFileExtList:\r
3379 BuildRules[Ext] = RuleObject\r
3380 self._BuildRules = BuildRules\r
3381 return self._BuildRules\r
3382\r
3383 def _ApplyBuildRule(self, File, FileType):\r
3384 if self._BuildTargets == None:\r
3385 self._IntroBuildTargetList = set()\r
3386 self._FinalBuildTargetList = set()\r
3387 self._BuildTargets = {}\r
3388 self._FileTypes = {}\r
3389\r
fcd4fbf3
YL
3390 SubDirectory = os.path.join(self.OutputDir, File.SubDir)\r
3391 if not os.path.exists(SubDirectory):\r
3392 CreateDirectory(SubDirectory)\r
52302d4d
LG
3393 LastTarget = None\r
3394 RuleChain = []\r
3395 SourceList = [File]\r
3396 Index = 0\r
fe4bf2f9
YL
3397 #\r
3398 # Make sure to get build rule order value\r
3399 #\r
3400 self._GetModuleBuildOption()\r
3401\r
52302d4d
LG
3402 while Index < len(SourceList):\r
3403 Source = SourceList[Index]\r
3404 Index = Index + 1\r
3405\r
3406 if Source != File:\r
3407 CreateDirectory(Source.Dir)\r
3408\r
3409 if File.IsBinary and File == Source and self._BinaryFileList != None and File in self._BinaryFileList:\r
da92f276
LG
3410 # Skip all files that are not binary libraries\r
3411 if not self.IsLibrary:\r
47fea6af 3412 continue\r
52302d4d
LG
3413 RuleObject = self.BuildRules[TAB_DEFAULT_BINARY_FILE]\r
3414 elif FileType in self.BuildRules:\r
3415 RuleObject = self.BuildRules[FileType]\r
3416 elif Source.Ext in self.BuildRules:\r
3417 RuleObject = self.BuildRules[Source.Ext]\r
3418 else:\r
3419 # stop at no more rules\r
3420 if LastTarget:\r
3421 self._FinalBuildTargetList.add(LastTarget)\r
3422 break\r
3423\r
3424 FileType = RuleObject.SourceFileType\r
3425 if FileType not in self._FileTypes:\r
3426 self._FileTypes[FileType] = set()\r
3427 self._FileTypes[FileType].add(Source)\r
3428\r
3429 # stop at STATIC_LIBRARY for library\r
3430 if self.IsLibrary and FileType == TAB_STATIC_LIBRARY:\r
3431 if LastTarget:\r
3432 self._FinalBuildTargetList.add(LastTarget)\r
3433 break\r
3434\r
fe4bf2f9 3435 Target = RuleObject.Apply(Source, self.BuildRuleOrder)\r
52302d4d
LG
3436 if not Target:\r
3437 if LastTarget:\r
3438 self._FinalBuildTargetList.add(LastTarget)\r
3439 break\r
3440 elif not Target.Outputs:\r
3441 # Only do build for target with outputs\r
3442 self._FinalBuildTargetList.add(Target)\r
3443\r
3444 if FileType not in self._BuildTargets:\r
3445 self._BuildTargets[FileType] = set()\r
3446 self._BuildTargets[FileType].add(Target)\r
3447\r
3448 if not Source.IsBinary and Source == File:\r
3449 self._IntroBuildTargetList.add(Target)\r
3450\r
3451 # to avoid cyclic rule\r
3452 if FileType in RuleChain:\r
3453 break\r
3454\r
3455 RuleChain.append(FileType)\r
3456 SourceList.extend(Target.Outputs)\r
3457 LastTarget = Target\r
3458 FileType = TAB_UNKNOWN_FILE\r
3459\r
3460 def _GetTargets(self):\r
3461 if self._BuildTargets == None:\r
3462 self._IntroBuildTargetList = set()\r
3463 self._FinalBuildTargetList = set()\r
3464 self._BuildTargets = {}\r
3465 self._FileTypes = {}\r
3466\r
b36d134f 3467 #TRICK: call _GetSourceFileList to apply build rule for source files\r
52302d4d
LG
3468 if self.SourceFileList:\r
3469 pass\r
3470\r
3471 #TRICK: call _GetBinaryFileList to apply build rule for binary files\r
3472 if self.BinaryFileList:\r
3473 pass\r
3474\r
3475 return self._BuildTargets\r
3476\r
3477 def _GetIntroTargetList(self):\r
3478 self._GetTargets()\r
3479 return self._IntroBuildTargetList\r
3480\r
3481 def _GetFinalTargetList(self):\r
3482 self._GetTargets()\r
3483 return self._FinalBuildTargetList\r
3484\r
3485 def _GetFileTypes(self):\r
3486 self._GetTargets()\r
3487 return self._FileTypes\r
3488\r
3489 ## Get the list of package object the module depends on\r
3490 #\r
3491 # @retval list The package object list\r
3492 #\r
3493 def _GetDependentPackageList(self):\r
3494 return self.Module.Packages\r
3495\r
3496 ## Return the list of auto-generated code file\r
3497 #\r
3498 # @retval list The list of auto-generated file\r
3499 #\r
3500 def _GetAutoGenFileList(self):\r
3501 UniStringAutoGenC = True\r
333ba578 3502 IdfStringAutoGenC = True\r
4234283c 3503 UniStringBinBuffer = StringIO()\r
333ba578 3504 IdfGenBinBuffer = StringIO()\r
52302d4d 3505 if self.BuildType == 'UEFI_HII':\r
52302d4d 3506 UniStringAutoGenC = False\r
333ba578 3507 IdfStringAutoGenC = False\r
52302d4d
LG
3508 if self._AutoGenFileList == None:\r
3509 self._AutoGenFileList = {}\r
3510 AutoGenC = TemplateString()\r
3511 AutoGenH = TemplateString()\r
3512 StringH = TemplateString()\r
333ba578
YZ
3513 StringIdf = TemplateString()\r
3514 GenC.CreateCode(self, AutoGenC, AutoGenH, StringH, UniStringAutoGenC, UniStringBinBuffer, StringIdf, IdfStringAutoGenC, IdfGenBinBuffer)\r
07b8564b
YL
3515 #\r
3516 # AutoGen.c is generated if there are library classes in inf, or there are object files\r
3517 #\r
3518 if str(AutoGenC) != "" and (len(self.Module.LibraryClasses) > 0\r
3519 or TAB_OBJECT_FILE in self.FileTypes):\r
52302d4d
LG
3520 AutoFile = PathClass(gAutoGenCodeFileName, self.DebugDir)\r
3521 self._AutoGenFileList[AutoFile] = str(AutoGenC)\r
3522 self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE)\r
3523 if str(AutoGenH) != "":\r
3524 AutoFile = PathClass(gAutoGenHeaderFileName, self.DebugDir)\r
3525 self._AutoGenFileList[AutoFile] = str(AutoGenH)\r
3526 self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE)\r
3527 if str(StringH) != "":\r
3528 AutoFile = PathClass(gAutoGenStringFileName % {"module_name":self.Name}, self.DebugDir)\r
3529 self._AutoGenFileList[AutoFile] = str(StringH)\r
3530 self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE)\r
3531 if UniStringBinBuffer != None and UniStringBinBuffer.getvalue() != "":\r
3532 AutoFile = PathClass(gAutoGenStringFormFileName % {"module_name":self.Name}, self.OutputDir)\r
3533 self._AutoGenFileList[AutoFile] = UniStringBinBuffer.getvalue()\r
3534 AutoFile.IsBinary = True\r
3535 self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE)\r
3536 if UniStringBinBuffer != None:\r
3537 UniStringBinBuffer.close()\r
333ba578
YZ
3538 if str(StringIdf) != "":\r
3539 AutoFile = PathClass(gAutoGenImageDefFileName % {"module_name":self.Name}, self.DebugDir)\r
3540 self._AutoGenFileList[AutoFile] = str(StringIdf)\r
3541 self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE)\r
3542 if IdfGenBinBuffer != None and IdfGenBinBuffer.getvalue() != "":\r
3543 AutoFile = PathClass(gAutoGenIdfFileName % {"module_name":self.Name}, self.OutputDir)\r
3544 self._AutoGenFileList[AutoFile] = IdfGenBinBuffer.getvalue()\r
3545 AutoFile.IsBinary = True\r
3546 self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE)\r
3547 if IdfGenBinBuffer != None:\r
3548 IdfGenBinBuffer.close()\r
52302d4d
LG
3549 return self._AutoGenFileList\r
3550\r
3551 ## Return the list of library modules explicitly or implicityly used by this module\r
3552 def _GetLibraryList(self):\r
3553 if self._DependentLibraryList == None:\r
3554 # only merge library classes and PCD for non-library module\r
3555 if self.IsLibrary:\r
3556 self._DependentLibraryList = []\r
3557 else:\r
3558 if self.AutoGenVersion < 0x00010005:\r
3559 self._DependentLibraryList = self.PlatformInfo.ResolveLibraryReference(self.Module)\r
3560 else:\r
3561 self._DependentLibraryList = self.PlatformInfo.ApplyLibraryInstance(self.Module)\r
3562 return self._DependentLibraryList\r
3563\r
e8a47801
LG
3564 @staticmethod\r
3565 def UpdateComments(Recver, Src):\r
3566 for Key in Src:\r
3567 if Key not in Recver:\r
3568 Recver[Key] = []\r
3569 Recver[Key].extend(Src[Key])\r
52302d4d
LG
3570 ## Get the list of PCDs from current module\r
3571 #\r
3572 # @retval list The list of PCD\r
3573 #\r
3574 def _GetModulePcdList(self):\r
3575 if self._ModulePcdList == None:\r
3576 # apply PCD settings from platform\r
3577 self._ModulePcdList = self.PlatformInfo.ApplyPcdSetting(self.Module, self.Module.Pcds)\r
e8a47801 3578 self.UpdateComments(self._PcdComments, self.Module.PcdComments)\r
52302d4d
LG
3579 return self._ModulePcdList\r
3580\r
3581 ## Get the list of PCDs from dependent libraries\r
3582 #\r
3583 # @retval list The list of PCD\r
3584 #\r
3585 def _GetLibraryPcdList(self):\r
3586 if self._LibraryPcdList == None:\r
79b74a03 3587 Pcds = sdict()\r
52302d4d
LG
3588 if not self.IsLibrary:\r
3589 # get PCDs from dependent libraries\r
3590 for Library in self.DependentLibraryList:\r
e8a47801 3591 self.UpdateComments(self._PcdComments, Library.PcdComments)\r
52302d4d
LG
3592 for Key in Library.Pcds:\r
3593 # skip duplicated PCDs\r
3594 if Key in self.Module.Pcds or Key in Pcds:\r
3595 continue\r
3596 Pcds[Key] = copy.copy(Library.Pcds[Key])\r
3597 # apply PCD settings from platform\r
3598 self._LibraryPcdList = self.PlatformInfo.ApplyPcdSetting(self.Module, Pcds)\r
3599 else:\r
3600 self._LibraryPcdList = []\r
3601 return self._LibraryPcdList\r
3602\r
3603 ## Get the GUID value mapping\r
3604 #\r
3605 # @retval dict The mapping between GUID cname and its value\r
3606 #\r
3607 def _GetGuidList(self):\r
3608 if self._GuidList == None:\r
8200fcfe
YL
3609 self._GuidList = sdict()\r
3610 self._GuidList.update(self.Module.Guids)\r
52302d4d
LG
3611 for Library in self.DependentLibraryList:\r
3612 self._GuidList.update(Library.Guids)\r
e8a47801
LG
3613 self.UpdateComments(self._GuidComments, Library.GuidComments)\r
3614 self.UpdateComments(self._GuidComments, self.Module.GuidComments)\r
52302d4d
LG
3615 return self._GuidList\r
3616\r
e8a47801
LG
3617 def GetGuidsUsedByPcd(self):\r
3618 if self._GuidsUsedByPcd == None:\r
3619 self._GuidsUsedByPcd = sdict()\r
3620 self._GuidsUsedByPcd.update(self.Module.GetGuidsUsedByPcd())\r
3621 for Library in self.DependentLibraryList:\r
3622 self._GuidsUsedByPcd.update(Library.GetGuidsUsedByPcd())\r
3623 return self._GuidsUsedByPcd\r
52302d4d
LG
3624 ## Get the protocol value mapping\r
3625 #\r
3626 # @retval dict The mapping between protocol cname and its value\r
3627 #\r
3628 def _GetProtocolList(self):\r
3629 if self._ProtocolList == None:\r
8200fcfe
YL
3630 self._ProtocolList = sdict()\r
3631 self._ProtocolList.update(self.Module.Protocols)\r
52302d4d
LG
3632 for Library in self.DependentLibraryList:\r
3633 self._ProtocolList.update(Library.Protocols)\r
e8a47801
LG
3634 self.UpdateComments(self._ProtocolComments, Library.ProtocolComments)\r
3635 self.UpdateComments(self._ProtocolComments, self.Module.ProtocolComments)\r
52302d4d
LG
3636 return self._ProtocolList\r
3637\r
3638 ## Get the PPI value mapping\r
3639 #\r
3640 # @retval dict The mapping between PPI cname and its value\r
3641 #\r
3642 def _GetPpiList(self):\r
3643 if self._PpiList == None:\r
8200fcfe
YL
3644 self._PpiList = sdict()\r
3645 self._PpiList.update(self.Module.Ppis)\r
52302d4d
LG
3646 for Library in self.DependentLibraryList:\r
3647 self._PpiList.update(Library.Ppis)\r
e8a47801
LG
3648 self.UpdateComments(self._PpiComments, Library.PpiComments)\r
3649 self.UpdateComments(self._PpiComments, self.Module.PpiComments)\r
52302d4d
LG
3650 return self._PpiList\r
3651\r
3652 ## Get the list of include search path\r
3653 #\r
3654 # @retval list The list path\r
3655 #\r
3656 def _GetIncludePathList(self):\r
3657 if self._IncludePathList == None:\r
3658 self._IncludePathList = []\r
3659 if self.AutoGenVersion < 0x00010005:\r
3660 for Inc in self.Module.Includes:\r
3661 if Inc not in self._IncludePathList:\r
3662 self._IncludePathList.append(Inc)\r
b36d134f 3663 # for Edk modules\r
52302d4d
LG
3664 Inc = path.join(Inc, self.Arch.capitalize())\r
3665 if os.path.exists(Inc) and Inc not in self._IncludePathList:\r
3666 self._IncludePathList.append(Inc)\r
b36d134f 3667 # Edk module needs to put DEBUG_DIR at the end of search path and not to use SOURCE_DIR all the time\r
52302d4d
LG
3668 self._IncludePathList.append(self.DebugDir)\r
3669 else:\r
3670 self._IncludePathList.append(self.MetaFile.Dir)\r
3671 self._IncludePathList.append(self.DebugDir)\r
3672\r
3673 for Package in self.Module.Packages:\r
05cc51ad 3674 PackageDir = mws.join(self.WorkspaceDir, Package.MetaFile.Dir)\r
52302d4d
LG
3675 if PackageDir not in self._IncludePathList:\r
3676 self._IncludePathList.append(PackageDir)\r
c28d2e10
YZ
3677 IncludesList = Package.Includes\r
3678 if Package._PrivateIncludes:\r
3679 if not self.MetaFile.Path.startswith(PackageDir):\r
3680 IncludesList = list(set(Package.Includes).difference(set(Package._PrivateIncludes)))\r
3681 for Inc in IncludesList:\r
52302d4d
LG
3682 if Inc not in self._IncludePathList:\r
3683 self._IncludePathList.append(str(Inc))\r
3684 return self._IncludePathList\r
3685\r
725cdb8f
YZ
3686 def _GetIncludePathLength(self):\r
3687 self._IncludePathLength = 0\r
3688 if self._IncludePathList:\r
3689 for inc in self._IncludePathList:\r
3690 self._IncludePathLength += len(' ' + inc)\r
3691 return self._IncludePathLength\r
3692\r
97fa0ee9
YL
3693 ## Get HII EX PCDs which maybe used by VFR\r
3694 #\r
3695 # efivarstore used by VFR may relate with HII EX PCDs\r
3696 # Get the variable name and GUID from efivarstore and HII EX PCD\r
3697 # List the HII EX PCDs in As Built INF if both name and GUID match.\r
3698 #\r
3699 # @retval list HII EX PCDs\r
3700 #\r
3701 def _GetPcdsMaybeUsedByVfr(self):\r
3702 if not self.SourceFileList:\r
3703 return []\r
3704\r
3705 NameGuids = []\r
3706 for SrcFile in self.SourceFileList:\r
3707 if SrcFile.Ext.lower() != '.vfr':\r
3708 continue\r
3709 Vfri = os.path.join(self.OutputDir, SrcFile.BaseName + '.i')\r
3710 if not os.path.exists(Vfri):\r
3711 continue\r
3712 VfriFile = open(Vfri, 'r')\r
3713 Content = VfriFile.read()\r
3714 VfriFile.close()\r
3715 Pos = Content.find('efivarstore')\r
3716 while Pos != -1:\r
3717 #\r
3718 # Make sure 'efivarstore' is the start of efivarstore statement\r
3719 # In case of the value of 'name' (name = efivarstore) is equal to 'efivarstore'\r
3720 #\r
3721 Index = Pos - 1\r
3722 while Index >= 0 and Content[Index] in ' \t\r\n':\r
3723 Index -= 1\r
3724 if Index >= 0 and Content[Index] != ';':\r
3725 Pos = Content.find('efivarstore', Pos + len('efivarstore'))\r
3726 continue\r
3727 #\r
3728 # 'efivarstore' must be followed by name and guid\r
3729 #\r
3730 Name = gEfiVarStoreNamePattern.search(Content, Pos)\r
3731 if not Name:\r
3732 break\r
3733 Guid = gEfiVarStoreGuidPattern.search(Content, Pos)\r
3734 if not Guid:\r
3735 break\r
3736 NameArray = ConvertStringToByteArray('L"' + Name.group(1) + '"')\r
3737 NameGuids.append((NameArray, GuidStructureStringToGuidString(Guid.group(1))))\r
3738 Pos = Content.find('efivarstore', Name.end())\r
3739 if not NameGuids:\r
3740 return []\r
3741 HiiExPcds = []\r
3742 for Pcd in self.PlatformInfo.Platform.Pcds.values():\r
3743 if Pcd.Type != TAB_PCDS_DYNAMIC_EX_HII:\r
3744 continue\r
3745 for SkuName in Pcd.SkuInfoList:\r
3746 SkuInfo = Pcd.SkuInfoList[SkuName]\r
3747 Name = ConvertStringToByteArray(SkuInfo.VariableName)\r
c28d2e10 3748 Value = GuidValue(SkuInfo.VariableGuid, self.PlatformInfo.PackageList, self.MetaFile.Path)\r
97fa0ee9
YL
3749 if not Value:\r
3750 continue\r
3751 Guid = GuidStructureStringToGuidString(Value)\r
3752 if (Name, Guid) in NameGuids and Pcd not in HiiExPcds:\r
3753 HiiExPcds.append(Pcd)\r
3754 break\r
3755\r
3756 return HiiExPcds\r
3757\r
aeaaf754
YL
3758 def _GenOffsetBin(self):\r
3759 VfrUniBaseName = {}\r
3760 for SourceFile in self.Module.Sources:\r
3761 if SourceFile.Type.upper() == ".VFR" :\r
3762 #\r
3763 # search the .map file to find the offset of vfr binary in the PE32+/TE file. \r
3764 #\r
3765 VfrUniBaseName[SourceFile.BaseName] = (SourceFile.BaseName + "Bin")\r
3766 if SourceFile.Type.upper() == ".UNI" :\r
3767 #\r
3768 # search the .map file to find the offset of Uni strings binary in the PE32+/TE file. \r
3769 #\r
3770 VfrUniBaseName["UniOffsetName"] = (self.Name + "Strings")\r
3771\r
3772 if len(VfrUniBaseName) == 0:\r
3773 return None\r
3774 MapFileName = os.path.join(self.OutputDir, self.Name + ".map")\r
3775 EfiFileName = os.path.join(self.OutputDir, self.Name + ".efi")\r
3776 VfrUniOffsetList = GetVariableOffset(MapFileName, EfiFileName, VfrUniBaseName.values())\r
3777 if not VfrUniOffsetList:\r
3778 return None\r
3779\r
3780 OutputName = '%sOffset.bin' % self.Name\r
3781 UniVfrOffsetFileName = os.path.join( self.OutputDir, OutputName)\r
3782\r
3783 try:\r
3784 fInputfile = open(UniVfrOffsetFileName, "wb+", 0)\r
3785 except:\r
3786 EdkLogger.error("build", FILE_OPEN_FAILURE, "File open failed for %s" % UniVfrOffsetFileName,None)\r
3787\r
3788 # Use a instance of StringIO to cache data\r
3789 fStringIO = StringIO('') \r
3790\r
3791 for Item in VfrUniOffsetList:\r
3792 if (Item[0].find("Strings") != -1):\r
3793 #\r
3794 # UNI offset in image.\r
3795 # GUID + Offset\r
3796 # { 0x8913c5e0, 0x33f6, 0x4d86, { 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66 } }\r
3797 #\r
3798 UniGuid = [0xe0, 0xc5, 0x13, 0x89, 0xf6, 0x33, 0x86, 0x4d, 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66]\r
3799 UniGuid = [chr(ItemGuid) for ItemGuid in UniGuid]\r
3800 fStringIO.write(''.join(UniGuid)) \r
3801 UniValue = pack ('Q', int (Item[1], 16))\r
3802 fStringIO.write (UniValue)\r
3803 else:\r
3804 #\r
3805 # VFR binary offset in image.\r
3806 # GUID + Offset\r
3807 # { 0xd0bc7cb4, 0x6a47, 0x495f, { 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2 } };\r
3808 #\r
3809 VfrGuid = [0xb4, 0x7c, 0xbc, 0xd0, 0x47, 0x6a, 0x5f, 0x49, 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2]\r
3810 VfrGuid = [chr(ItemGuid) for ItemGuid in VfrGuid]\r
3811 fStringIO.write(''.join(VfrGuid)) \r
3812 type (Item[1]) \r
3813 VfrValue = pack ('Q', int (Item[1], 16))\r
3814 fStringIO.write (VfrValue)\r
3815 #\r
3816 # write data into file.\r
3817 #\r
3818 try : \r
3819 fInputfile.write (fStringIO.getvalue())\r
3820 except:\r
3821 EdkLogger.error("build", FILE_WRITE_FAILURE, "Write data to file %s failed, please check whether the "\r
3822 "file been locked or using by other applications." %UniVfrOffsetFileName,None)\r
3823\r
3824 fStringIO.close ()\r
3825 fInputfile.close ()\r
3826 return OutputName\r
3827\r
da92f276
LG
3828 ## Create AsBuilt INF file the module\r
3829 #\r
3830 def CreateAsBuiltInf(self):\r
3831 if self.IsAsBuiltInfCreated:\r
3832 return\r
3833 \r
3834 # Skip the following code for EDK I inf\r
3835 if self.AutoGenVersion < 0x00010005:\r
3836 return\r
3837 \r
3838 # Skip the following code for libraries\r
3839 if self.IsLibrary:\r
3840 return\r
3841 \r
3842 # Skip the following code for modules with no source files\r
3843 if self.SourceFileList == None or self.SourceFileList == []:\r
3844 return\r
3845\r
3846 # Skip the following code for modules without any binary files\r
3847 if self.BinaryFileList <> None and self.BinaryFileList <> []:\r
3848 return\r
3849 \r
3850 ### TODO: How to handles mixed source and binary modules\r
3851\r
e8a47801 3852 # Find all DynamicEx and PatchableInModule PCDs used by this module and dependent libraries\r
da92f276
LG
3853 # Also find all packages that the DynamicEx PCDs depend on\r
3854 Pcds = []\r
e5cf9198 3855 PatchablePcds = []\r
47fea6af 3856 Packages = []\r
e8a47801
LG
3857 PcdCheckList = []\r
3858 PcdTokenSpaceList = []\r
da92f276 3859 for Pcd in self.ModulePcdList + self.LibraryPcdList:\r
e8a47801 3860 if Pcd.Type == TAB_PCDS_PATCHABLE_IN_MODULE:\r
e5cf9198 3861 PatchablePcds += [Pcd]\r
e8a47801
LG
3862 PcdCheckList.append((Pcd.TokenCName, Pcd.TokenSpaceGuidCName, 'PatchableInModule'))\r
3863 elif Pcd.Type in GenC.gDynamicExPcd:\r
3864 if Pcd not in Pcds:\r
3865 Pcds += [Pcd]\r
3866 PcdCheckList.append((Pcd.TokenCName, Pcd.TokenSpaceGuidCName, 'DynamicEx'))\r
3867 PcdCheckList.append((Pcd.TokenCName, Pcd.TokenSpaceGuidCName, 'Dynamic'))\r
3868 PcdTokenSpaceList.append(Pcd.TokenSpaceGuidCName)\r
3869 GuidList = sdict()\r
3870 GuidList.update(self.GuidList)\r
3871 for TokenSpace in self.GetGuidsUsedByPcd():\r
3872 # If token space is not referred by patch PCD or Ex PCD, remove the GUID from GUID list\r
3873 # The GUIDs in GUIDs section should really be the GUIDs in source INF or referred by Ex an patch PCDs\r
3874 if TokenSpace not in PcdTokenSpaceList and TokenSpace in GuidList:\r
3875 GuidList.pop(TokenSpace)\r
3876 CheckList = (GuidList, self.PpiList, self.ProtocolList, PcdCheckList)\r
3877 for Package in self.DerivedPackageList:\r
3878 if Package in Packages:\r
3879 continue\r
3880 BeChecked = (Package.Guids, Package.Ppis, Package.Protocols, Package.Pcds)\r
3881 Found = False\r
3882 for Index in range(len(BeChecked)):\r
3883 for Item in CheckList[Index]:\r
3884 if Item in BeChecked[Index]:\r
3885 Packages += [Package]\r
3886 Found = True\r
3887 break\r
3888 if Found: break\r
da92f276 3889\r
97fa0ee9
YL
3890 VfrPcds = self._GetPcdsMaybeUsedByVfr()\r
3891 for Pkg in self.PlatformInfo.PackageList:\r
3892 if Pkg in Packages:\r
3893 continue\r
3894 for VfrPcd in VfrPcds:\r
3895 if ((VfrPcd.TokenCName, VfrPcd.TokenSpaceGuidCName, 'DynamicEx') in Pkg.Pcds or\r
3896 (VfrPcd.TokenCName, VfrPcd.TokenSpaceGuidCName, 'Dynamic') in Pkg.Pcds):\r
3897 Packages += [Pkg]\r
3898 break\r
3899\r
da92f276
LG
3900 ModuleType = self.ModuleType\r
3901 if ModuleType == 'UEFI_DRIVER' and self.DepexGenerated:\r
e8a47801
LG
3902 ModuleType = 'DXE_DRIVER'\r
3903\r
3904 DriverType = ''\r
3905 if self.PcdIsDriver != '':\r
3906 DriverType = self.PcdIsDriver\r
da92f276 3907\r
97fa0ee9
YL
3908 Guid = self.Guid\r
3909 MDefs = self.Module.Defines\r
3910\r
da92f276
LG
3911 AsBuiltInfDict = {\r
3912 'module_name' : self.Name,\r
97fa0ee9 3913 'module_guid' : Guid,\r
da92f276 3914 'module_module_type' : ModuleType,\r
97fa0ee9 3915 'module_version_string' : [MDefs['VERSION_STRING']] if 'VERSION_STRING' in MDefs else [],\r
e8a47801 3916 'pcd_is_driver_string' : [],\r
da92f276
LG
3917 'module_uefi_specification_version' : [],\r
3918 'module_pi_specification_version' : [],\r
97fa0ee9
YL
3919 'module_entry_point' : self.Module.ModuleEntryPointList,\r
3920 'module_unload_image' : self.Module.ModuleUnloadImageList,\r
3921 'module_constructor' : self.Module.ConstructorList,\r
3922 'module_destructor' : self.Module.DestructorList,\r
3923 'module_shadow' : [MDefs['SHADOW']] if 'SHADOW' in MDefs else [],\r
3924 'module_pci_vendor_id' : [MDefs['PCI_VENDOR_ID']] if 'PCI_VENDOR_ID' in MDefs else [],\r
3925 'module_pci_device_id' : [MDefs['PCI_DEVICE_ID']] if 'PCI_DEVICE_ID' in MDefs else [],\r
3926 'module_pci_class_code' : [MDefs['PCI_CLASS_CODE']] if 'PCI_CLASS_CODE' in MDefs else [],\r
3927 'module_pci_revision' : [MDefs['PCI_REVISION']] if 'PCI_REVISION' in MDefs else [],\r
3928 'module_build_number' : [MDefs['BUILD_NUMBER']] if 'BUILD_NUMBER' in MDefs else [],\r
3929 'module_spec' : [MDefs['SPEC']] if 'SPEC' in MDefs else [],\r
3930 'module_uefi_hii_resource_section' : [MDefs['UEFI_HII_RESOURCE_SECTION']] if 'UEFI_HII_RESOURCE_SECTION' in MDefs else [],\r
3931 'module_uni_file' : [MDefs['MODULE_UNI_FILE']] if 'MODULE_UNI_FILE' in MDefs else [],\r
da92f276 3932 'module_arch' : self.Arch,\r
47fea6af 3933 'package_item' : ['%s' % (Package.MetaFile.File.replace('\\', '/')) for Package in Packages],\r
da92f276 3934 'binary_item' : [],\r
e8a47801 3935 'patchablepcd_item' : [],\r
da92f276 3936 'pcd_item' : [],\r
e8a47801
LG
3937 'protocol_item' : [],\r
3938 'ppi_item' : [],\r
3939 'guid_item' : [],\r
3940 'flags_item' : [],\r
3941 'libraryclasses_item' : []\r
da92f276 3942 }\r
97fa0ee9 3943\r
78bcd52a
YZ
3944 if 'MODULE_UNI_FILE' in MDefs:\r
3945 UNIFile = os.path.join(self.MetaFile.Dir, MDefs['MODULE_UNI_FILE'])\r
3946 if os.path.isfile(UNIFile):\r
3947 shutil.copy2(UNIFile, self.OutputDir)\r
3948\r
97fa0ee9
YL
3949 if self.AutoGenVersion > int(gInfSpecVersion, 0):\r
3950 AsBuiltInfDict['module_inf_version'] = '0x%08x' % self.AutoGenVersion\r
3951 else:\r
3952 AsBuiltInfDict['module_inf_version'] = gInfSpecVersion\r
3953\r
e8a47801
LG
3954 if DriverType:\r
3955 AsBuiltInfDict['pcd_is_driver_string'] += [DriverType]\r
da92f276
LG
3956\r
3957 if 'UEFI_SPECIFICATION_VERSION' in self.Specification:\r
481252bb 3958 AsBuiltInfDict['module_uefi_specification_version'] += [self.Specification['UEFI_SPECIFICATION_VERSION']]\r
da92f276 3959 if 'PI_SPECIFICATION_VERSION' in self.Specification:\r
481252bb 3960 AsBuiltInfDict['module_pi_specification_version'] += [self.Specification['PI_SPECIFICATION_VERSION']]\r
da92f276 3961\r
47fea6af 3962 OutputDir = self.OutputDir.replace('\\', '/').strip('/')\r
36d083ef 3963 self.OutputFile = []\r
481252bb 3964 for Item in self.CodaTargetList:\r
47fea6af 3965 File = Item.Target.Path.replace('\\', '/').strip('/').replace(OutputDir, '').strip('/')\r
36d083ef
YZ
3966 if File not in self.OutputFile:\r
3967 self.OutputFile.append(File)\r
47fea6af 3968 if Item.Target.Ext.lower() == '.aml':\r
481252bb 3969 AsBuiltInfDict['binary_item'] += ['ASL|' + File]\r
47fea6af 3970 elif Item.Target.Ext.lower() == '.acpi':\r
481252bb
YZ
3971 AsBuiltInfDict['binary_item'] += ['ACPI|' + File]\r
3972 elif Item.Target.Ext.lower() == '.efi':\r
3973 AsBuiltInfDict['binary_item'] += ['PE32|' + self.Name + '.efi']\r
da92f276 3974 else:\r
481252bb
YZ
3975 AsBuiltInfDict['binary_item'] += ['BIN|' + File]\r
3976 if self.DepexGenerated:\r
36d083ef
YZ
3977 if self.Name + '.depex' not in self.OutputFile:\r
3978 self.OutputFile.append(self.Name + '.depex')\r
da92f276 3979 if self.ModuleType in ['PEIM']:\r
481252bb 3980 AsBuiltInfDict['binary_item'] += ['PEI_DEPEX|' + self.Name + '.depex']\r
47fea6af 3981 if self.ModuleType in ['DXE_DRIVER', 'DXE_RUNTIME_DRIVER', 'DXE_SAL_DRIVER', 'UEFI_DRIVER']:\r
481252bb 3982 AsBuiltInfDict['binary_item'] += ['DXE_DEPEX|' + self.Name + '.depex']\r
da92f276 3983 if self.ModuleType in ['DXE_SMM_DRIVER']:\r
481252bb 3984 AsBuiltInfDict['binary_item'] += ['SMM_DEPEX|' + self.Name + '.depex']\r
da92f276 3985\r
aeaaf754
YL
3986 Bin = self._GenOffsetBin()\r
3987 if Bin:\r
3988 AsBuiltInfDict['binary_item'] += ['BIN|%s' % Bin]\r
36d083ef
YZ
3989 if Bin not in self.OutputFile:\r
3990 self.OutputFile.append(Bin)\r
aeaaf754 3991\r
e8a47801
LG
3992 for Root, Dirs, Files in os.walk(OutputDir):\r
3993 for File in Files:\r
3994 if File.lower().endswith('.pdb'):\r
3995 AsBuiltInfDict['binary_item'] += ['DISPOSABLE|' + File]\r
36d083ef
YZ
3996 if File not in self.OutputFile:\r
3997 self.OutputFile.append(File)\r
e8a47801
LG
3998 HeaderComments = self.Module.HeaderComments\r
3999 StartPos = 0\r
4000 for Index in range(len(HeaderComments)):\r
4001 if HeaderComments[Index].find('@BinaryHeader') != -1:\r
4002 HeaderComments[Index] = HeaderComments[Index].replace('@BinaryHeader', '@file')\r
4003 StartPos = Index\r
4004 break\r
4005 AsBuiltInfDict['header_comments'] = '\n'.join(HeaderComments[StartPos:]).replace(':#', '://')\r
97fa0ee9
YL
4006 AsBuiltInfDict['tail_comments'] = '\n'.join(self.Module.TailComments)\r
4007\r
e8a47801
LG
4008 GenList = [\r
4009 (self.ProtocolList, self._ProtocolComments, 'protocol_item'),\r
4010 (self.PpiList, self._PpiComments, 'ppi_item'),\r
4011 (GuidList, self._GuidComments, 'guid_item')\r
4012 ]\r
4013 for Item in GenList:\r
4014 for CName in Item[0]:\r
4015 Comments = ''\r
4016 if CName in Item[1]:\r
4017 Comments = '\n '.join(Item[1][CName])\r
4018 Entry = CName\r
4019 if Comments:\r
4020 Entry = Comments + '\n ' + CName\r
4021 AsBuiltInfDict[Item[2]].append(Entry)\r
4022 PatchList = parsePcdInfoFromMapFile(\r
4023 os.path.join(self.OutputDir, self.Name + '.map'),\r
4024 os.path.join(self.OutputDir, self.Name + '.efi')\r
4025 )\r
4026 if PatchList:\r
e5cf9198
YZ
4027 for Pcd in PatchablePcds:\r
4028 TokenCName = Pcd.TokenCName\r
4029 for PcdItem in GlobalData.MixedPcd:\r
4030 if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName) in GlobalData.MixedPcd[PcdItem]:\r
4031 TokenCName = PcdItem[0]\r
4032 break\r
4033 for PatchPcd in PatchList:\r
4034 if TokenCName == PatchPcd[0]:\r
4035 break\r
2a29017e 4036 else:\r
e8a47801 4037 continue\r
e8a47801 4038 PcdValue = ''\r
7ced8bb4
YZ
4039 if Pcd.DatumType == 'BOOLEAN':\r
4040 BoolValue = Pcd.DefaultValue.upper()\r
4041 if BoolValue == 'TRUE':\r
4042 Pcd.DefaultValue = '1'\r
4043 elif BoolValue == 'FALSE':\r
4044 Pcd.DefaultValue = '0'\r
4045\r
e8a47801
LG
4046 if Pcd.DatumType != 'VOID*':\r
4047 HexFormat = '0x%02x'\r
4048 if Pcd.DatumType == 'UINT16':\r
4049 HexFormat = '0x%04x'\r
4050 elif Pcd.DatumType == 'UINT32':\r
4051 HexFormat = '0x%08x'\r
4052 elif Pcd.DatumType == 'UINT64':\r
4053 HexFormat = '0x%016x'\r
4054 PcdValue = HexFormat % int(Pcd.DefaultValue, 0)\r
4055 else:\r
4056 if Pcd.MaxDatumSize == None or Pcd.MaxDatumSize == '':\r
4057 EdkLogger.error("build", AUTOGEN_ERROR,\r
2a29017e 4058 "Unknown [MaxDatumSize] of PCD [%s.%s]" % (Pcd.TokenSpaceGuidCName, TokenCName)\r
e8a47801
LG
4059 )\r
4060 ArraySize = int(Pcd.MaxDatumSize, 0)\r
4061 PcdValue = Pcd.DefaultValue\r
4062 if PcdValue[0] != '{':\r
4063 Unicode = False\r
4064 if PcdValue[0] == 'L':\r
4065 Unicode = True\r
4066 PcdValue = PcdValue.lstrip('L')\r
4067 PcdValue = eval(PcdValue)\r
4068 NewValue = '{'\r
4069 for Index in range(0, len(PcdValue)):\r
4070 if Unicode:\r
4071 CharVal = ord(PcdValue[Index])\r
4072 NewValue = NewValue + '0x%02x' % (CharVal & 0x00FF) + ', ' \\r
4073 + '0x%02x' % (CharVal >> 8) + ', '\r
4074 else:\r
4075 NewValue = NewValue + '0x%02x' % (ord(PcdValue[Index]) % 0x100) + ', '\r
4076 Padding = '0x00, '\r
4077 if Unicode:\r
4078 Padding = Padding * 2\r
4079 ArraySize = ArraySize / 2\r
4080 if ArraySize < (len(PcdValue) + 1):\r
4081 EdkLogger.error("build", AUTOGEN_ERROR,\r
2a29017e 4082 "The maximum size of VOID* type PCD '%s.%s' is less than its actual size occupied." % (Pcd.TokenSpaceGuidCName, TokenCName)\r
e8a47801
LG
4083 )\r
4084 if ArraySize > len(PcdValue) + 1:\r
4085 NewValue = NewValue + Padding * (ArraySize - len(PcdValue) - 1)\r
4086 PcdValue = NewValue + Padding.strip().rstrip(',') + '}'\r
4087 elif len(PcdValue.split(',')) <= ArraySize:\r
4088 PcdValue = PcdValue.rstrip('}') + ', 0x00' * (ArraySize - len(PcdValue.split(',')))\r
4089 PcdValue += '}'\r
4090 else:\r
4091 EdkLogger.error("build", AUTOGEN_ERROR,\r
2a29017e 4092 "The maximum size of VOID* type PCD '%s.%s' is less than its actual size occupied." % (Pcd.TokenSpaceGuidCName, TokenCName)\r
e8a47801
LG
4093 )\r
4094 PcdItem = '%s.%s|%s|0x%X' % \\r
2a29017e 4095 (Pcd.TokenSpaceGuidCName, TokenCName, PcdValue, PatchPcd[1])\r
e8a47801
LG
4096 PcdComments = ''\r
4097 if (Pcd.TokenSpaceGuidCName, Pcd.TokenCName) in self._PcdComments:\r
4098 PcdComments = '\n '.join(self._PcdComments[Pcd.TokenSpaceGuidCName, Pcd.TokenCName])\r
4099 if PcdComments:\r
4100 PcdItem = PcdComments + '\n ' + PcdItem\r
4101 AsBuiltInfDict['patchablepcd_item'].append(PcdItem)\r
97fa0ee9
YL
4102\r
4103 HiiPcds = []\r
4104 for Pcd in Pcds + VfrPcds:\r
e8a47801
LG
4105 PcdComments = ''\r
4106 PcdCommentList = []\r
4107 HiiInfo = ''\r
97fa0ee9 4108 SkuId = ''\r
2a29017e
YZ
4109 TokenCName = Pcd.TokenCName\r
4110 for PcdItem in GlobalData.MixedPcd:\r
4111 if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName) in GlobalData.MixedPcd[PcdItem]:\r
4112 TokenCName = PcdItem[0]\r
4113 break\r
e8a47801
LG
4114 if Pcd.Type == TAB_PCDS_DYNAMIC_EX_HII:\r
4115 for SkuName in Pcd.SkuInfoList:\r
4116 SkuInfo = Pcd.SkuInfoList[SkuName]\r
97fa0ee9 4117 SkuId = SkuInfo.SkuId\r
e8a47801
LG
4118 HiiInfo = '## %s|%s|%s' % (SkuInfo.VariableName, SkuInfo.VariableGuid, SkuInfo.VariableOffset)\r
4119 break\r
97fa0ee9
YL
4120 if SkuId:\r
4121 #\r
4122 # Don't generate duplicated HII PCD\r
4123 #\r
4124 if (SkuId, Pcd.TokenSpaceGuidCName, Pcd.TokenCName) in HiiPcds:\r
4125 continue\r
4126 else:\r
4127 HiiPcds.append((SkuId, Pcd.TokenSpaceGuidCName, Pcd.TokenCName))\r
e8a47801
LG
4128 if (Pcd.TokenSpaceGuidCName, Pcd.TokenCName) in self._PcdComments:\r
4129 PcdCommentList = self._PcdComments[Pcd.TokenSpaceGuidCName, Pcd.TokenCName][:]\r
4130 if HiiInfo:\r
4131 UsageIndex = -1\r
97fa0ee9 4132 UsageStr = ''\r
e8a47801
LG
4133 for Index, Comment in enumerate(PcdCommentList):\r
4134 for Usage in UsageList:\r
4135 if Comment.find(Usage) != -1:\r
97fa0ee9 4136 UsageStr = Usage\r
e8a47801
LG
4137 UsageIndex = Index\r
4138 break\r
4139 if UsageIndex != -1:\r
97fa0ee9 4140 PcdCommentList[UsageIndex] = '## %s %s %s' % (UsageStr, HiiInfo, PcdCommentList[UsageIndex].replace(UsageStr, '')) \r
e8a47801 4141 else:\r
97fa0ee9 4142 PcdCommentList.append('## UNDEFINED ' + HiiInfo)\r
e8a47801 4143 PcdComments = '\n '.join(PcdCommentList)\r
2a29017e 4144 PcdEntry = Pcd.TokenSpaceGuidCName + '.' + TokenCName\r
e8a47801
LG
4145 if PcdComments:\r
4146 PcdEntry = PcdComments + '\n ' + PcdEntry\r
4147 AsBuiltInfDict['pcd_item'] += [PcdEntry]\r
da92f276 4148 for Item in self.BuildOption:\r
481252bb
YZ
4149 if 'FLAGS' in self.BuildOption[Item]:\r
4150 AsBuiltInfDict['flags_item'] += ['%s:%s_%s_%s_%s_FLAGS = %s' % (self.ToolChainFamily, self.BuildTarget, self.ToolChain, self.Arch, Item, self.BuildOption[Item]['FLAGS'].strip())]\r
97fa0ee9
YL
4151\r
4152 # Generated LibraryClasses section in comments.\r
4153 for Library in self.LibraryAutoGenList:\r
4154 AsBuiltInfDict['libraryclasses_item'] += [Library.MetaFile.File.replace('\\', '/')]\r
4155 \r
dfa41b4a
YZ
4156 # Generated UserExtensions TianoCore section.\r
4157 # All tianocore user extensions are copied.\r
4158 UserExtStr = ''\r
4159 for TianoCore in self._GetTianoCoreUserExtensionList():\r
4160 UserExtStr += '\n'.join(TianoCore)\r
4161 ExtensionFile = os.path.join(self.MetaFile.Dir, TianoCore[1])\r
4162 if os.path.isfile(ExtensionFile):\r
4163 shutil.copy2(ExtensionFile, self.OutputDir)\r
4164 AsBuiltInfDict['userextension_tianocore_item'] = UserExtStr\r
4165\r
97fa0ee9
YL
4166 # Generated depex expression section in comments.\r
4167 AsBuiltInfDict['depexsection_item'] = ''\r
4168 DepexExpresion = self._GetDepexExpresionString()\r
4169 if DepexExpresion:\r
4170 AsBuiltInfDict['depexsection_item'] = DepexExpresion\r
da92f276
LG
4171 \r
4172 AsBuiltInf = TemplateString()\r
4173 AsBuiltInf.Append(gAsBuiltInfHeaderString.Replace(AsBuiltInfDict))\r
4174 \r
4175 SaveFileOnChange(os.path.join(self.OutputDir, self.Name + '.inf'), str(AsBuiltInf), False)\r
4176 \r
4177 self.IsAsBuiltInfCreated = True\r
36d083ef
YZ
4178 if GlobalData.gBinCacheDest:\r
4179 self.CopyModuleToCache()\r
4180\r
4181 def CopyModuleToCache(self):\r
4182 FileDir = path.join(GlobalData.gBinCacheDest, self.Arch, self.SourceDir, self.MetaFile.BaseName)\r
4183 CreateDirectory (FileDir)\r
4184 HashFile = path.join(self.BuildDir, self.Name + '.hash')\r
4185 ModuleFile = path.join(self.OutputDir, self.Name + '.inf')\r
4186 if os.path.exists(HashFile):\r
4187 shutil.copy2(HashFile, FileDir)\r
4188 if os.path.exists(ModuleFile):\r
4189 shutil.copy2(ModuleFile, FileDir)\r
4190 if self.OutputFile:\r
4191 for File in self.OutputFile:\r
4192 if not os.path.isabs(File):\r
4193 File = os.path.join(self.OutputDir, File)\r
4194 if os.path.exists(File):\r
4195 shutil.copy2(File, FileDir)\r
4196\r
4197 def AttemptModuleCacheCopy(self):\r
4198 if self.IsBinaryModule:\r
4199 return False\r
4200 FileDir = path.join(GlobalData.gBinCacheSource, self.Arch, self.SourceDir, self.MetaFile.BaseName)\r
4201 HashFile = path.join(FileDir, self.Name + '.hash')\r
4202 if os.path.exists(HashFile):\r
4203 f = open(HashFile, 'r')\r
4204 CacheHash = f.read()\r
4205 f.close()\r
4206 if GlobalData.gModuleHash[self.Arch][self.Name]:\r
4207 if CacheHash == GlobalData.gModuleHash[self.Arch][self.Name]:\r
4208 for root, dir, files in os.walk(FileDir):\r
4209 for f in files:\r
4210 if self.Name + '.hash' in f:\r
4211 shutil.copy2(HashFile, self.BuildDir)\r
4212 else:\r
4213 File = path.join(root, f)\r
4214 shutil.copy2(File, self.OutputDir)\r
4215 if self.Name == "PcdPeim" or self.Name == "PcdDxe":\r
4216 CreatePcdDatabaseCode(self, TemplateString(), TemplateString())\r
4217 return True\r
4218 return False\r
4219\r
52302d4d
LG
4220 ## Create makefile for the module and its dependent libraries\r
4221 #\r
4222 # @param CreateLibraryMakeFile Flag indicating if or not the makefiles of\r
4223 # dependent libraries will be created\r
4224 #\r
4225 def CreateMakeFile(self, CreateLibraryMakeFile=True):\r
fae62ff2 4226 # Ignore generating makefile when it is a binary module\r
a0a2cd1e
FB
4227 if self.IsBinaryModule:\r
4228 return\r
fae62ff2 4229\r
52302d4d
LG
4230 if self.IsMakeFileCreated:\r
4231 return\r
4232\r
4233 if not self.IsLibrary and CreateLibraryMakeFile:\r
4234 for LibraryAutoGen in self.LibraryAutoGenList:\r
4235 LibraryAutoGen.CreateMakeFile()\r
4236\r
36513f3a
YZ
4237 if self.CanSkip():\r
4238 return\r
4239\r
52302d4d
LG
4240 if len(self.CustomMakefile) == 0:\r
4241 Makefile = GenMake.ModuleMakefile(self)\r
4242 else:\r
4243 Makefile = GenMake.CustomMakefile(self)\r
4244 if Makefile.Generate():\r
4245 EdkLogger.debug(EdkLogger.DEBUG_9, "Generated makefile for module %s [%s]" %\r
4246 (self.Name, self.Arch))\r
4247 else:\r
4248 EdkLogger.debug(EdkLogger.DEBUG_9, "Skipped the generation of makefile for module %s [%s]" %\r
4249 (self.Name, self.Arch))\r
4250\r
c17956e0 4251 self.CreateTimeStamp(Makefile)\r
52302d4d
LG
4252 self.IsMakeFileCreated = True\r
4253\r
a0a2cd1e
FB
4254 def CopyBinaryFiles(self):\r
4255 for File in self.Module.Binaries:\r
4256 SrcPath = File.Path\r
4257 DstPath = os.path.join(self.OutputDir , os.path.basename(SrcPath))\r
4258 CopyLongFilePath(SrcPath, DstPath)\r
52302d4d
LG
4259 ## Create autogen code for the module and its dependent libraries\r
4260 #\r
4261 # @param CreateLibraryCodeFile Flag indicating if or not the code of\r
4262 # dependent libraries will be created\r
4263 #\r
4264 def CreateCodeFile(self, CreateLibraryCodeFile=True):\r
4265 if self.IsCodeFileCreated:\r
4266 return\r
4267\r
e8a47801
LG
4268 # Need to generate PcdDatabase even PcdDriver is binarymodule\r
4269 if self.IsBinaryModule and self.PcdIsDriver != '':\r
4270 CreatePcdDatabaseCode(self, TemplateString(), TemplateString())\r
4271 return\r
a0a2cd1e 4272 if self.IsBinaryModule:\r
49d9b71d
HC
4273 if self.IsLibrary:\r
4274 self.CopyBinaryFiles()\r
a0a2cd1e 4275 return\r
e8a47801 4276\r
52302d4d
LG
4277 if not self.IsLibrary and CreateLibraryCodeFile:\r
4278 for LibraryAutoGen in self.LibraryAutoGenList:\r
4279 LibraryAutoGen.CreateCodeFile()\r
4280\r
36513f3a
YZ
4281 if self.CanSkip():\r
4282 return\r
4283\r
52302d4d
LG
4284 AutoGenList = []\r
4285 IgoredAutoGenList = []\r
4286\r
4287 for File in self.AutoGenFileList:\r
4288 if GenC.Generate(File.Path, self.AutoGenFileList[File], File.IsBinary):\r
b36d134f 4289 #Ignore Edk AutoGen.c\r
52302d4d
LG
4290 if self.AutoGenVersion < 0x00010005 and File.Name == 'AutoGen.c':\r
4291 continue\r
4292\r
4293 AutoGenList.append(str(File))\r
4294 else:\r
4295 IgoredAutoGenList.append(str(File))\r
4296\r
4297 # Skip the following code for EDK I inf\r
4298 if self.AutoGenVersion < 0x00010005:\r
4299 return\r
4300\r
4301 for ModuleType in self.DepexList:\r
40d841f6
LG
4302 # Ignore empty [depex] section or [depex] section for "USER_DEFINED" module\r
4303 if len(self.DepexList[ModuleType]) == 0 or ModuleType == "USER_DEFINED":\r
52302d4d 4304 continue\r
40d841f6 4305\r
52302d4d
LG
4306 Dpx = GenDepex.DependencyExpression(self.DepexList[ModuleType], ModuleType, True)\r
4307 DpxFile = gAutoGenDepexFileName % {"module_name" : self.Name}\r
4308\r
da92f276 4309 if len(Dpx.PostfixNotation) <> 0:\r
0d2711a6 4310 self.DepexGenerated = True\r
da92f276 4311\r
52302d4d
LG
4312 if Dpx.Generate(path.join(self.OutputDir, DpxFile)):\r
4313 AutoGenList.append(str(DpxFile))\r
4314 else:\r
4315 IgoredAutoGenList.append(str(DpxFile))\r
4316\r
4317 if IgoredAutoGenList == []:\r
4318 EdkLogger.debug(EdkLogger.DEBUG_9, "Generated [%s] files for module %s [%s]" %\r
4319 (" ".join(AutoGenList), self.Name, self.Arch))\r
4320 elif AutoGenList == []:\r
4321 EdkLogger.debug(EdkLogger.DEBUG_9, "Skipped the generation of [%s] files for module %s [%s]" %\r
4322 (" ".join(IgoredAutoGenList), self.Name, self.Arch))\r
4323 else:\r
4324 EdkLogger.debug(EdkLogger.DEBUG_9, "Generated [%s] (skipped %s) files for module %s [%s]" %\r
4325 (" ".join(AutoGenList), " ".join(IgoredAutoGenList), self.Name, self.Arch))\r
4326\r
4327 self.IsCodeFileCreated = True\r
4328 return AutoGenList\r
4329\r
4330 ## Summarize the ModuleAutoGen objects of all libraries used by this module\r
4331 def _GetLibraryAutoGenList(self):\r
4332 if self._LibraryAutoGenList == None:\r
4333 self._LibraryAutoGenList = []\r
4334 for Library in self.DependentLibraryList:\r
4335 La = ModuleAutoGen(\r
4336 self.Workspace,\r
4337 Library.MetaFile,\r
4338 self.BuildTarget,\r
4339 self.ToolChain,\r
4340 self.Arch,\r
4341 self.PlatformInfo.MetaFile\r
4342 )\r
4343 if La not in self._LibraryAutoGenList:\r
4344 self._LibraryAutoGenList.append(La)\r
4345 for Lib in La.CodaTargetList:\r
4346 self._ApplyBuildRule(Lib.Target, TAB_UNKNOWN_FILE)\r
4347 return self._LibraryAutoGenList\r
4348\r
36d083ef
YZ
4349 def GenModuleHash(self):\r
4350 if self.Arch not in GlobalData.gModuleHash:\r
4351 GlobalData.gModuleHash[self.Arch] = {}\r
4352 m = hashlib.md5()\r
4353 # Add Platform level hash\r
4354 m.update(GlobalData.gPlatformHash)\r
4355 # Add Package level hash\r
4356 if self.DependentPackageList:\r
4357 for Pkg in self.DependentPackageList:\r
4358 if Pkg.PackageName in GlobalData.gPackageHash[self.Arch]:\r
4359 m.update(GlobalData.gPackageHash[self.Arch][Pkg.PackageName])\r
4360\r
4361 # Add Library hash\r
4362 if self.LibraryAutoGenList:\r
4363 for Lib in self.LibraryAutoGenList:\r
4364 if Lib.Name not in GlobalData.gModuleHash[self.Arch]:\r
4365 Lib.GenModuleHash()\r
4366 m.update(GlobalData.gModuleHash[self.Arch][Lib.Name])\r
4367\r
4368 # Add Module self\r
4369 f = open(str(self.MetaFile), 'r')\r
4370 Content = f.read()\r
4371 f.close()\r
4372 m.update(Content)\r
4373 # Add Module's source files\r
4374 if self.SourceFileList:\r
4375 for File in self.SourceFileList:\r
4376 f = open(str(File), 'r')\r
4377 Content = f.read()\r
4378 f.close()\r
4379 m.update(Content)\r
4380\r
4381 ModuleHashFile = path.join(self.BuildDir, self.Name + ".hash")\r
4382 if self.Name not in GlobalData.gModuleHash[self.Arch]:\r
4383 GlobalData.gModuleHash[self.Arch][self.Name] = m.hexdigest()\r
4384 if GlobalData.gBinCacheSource:\r
4385 CacheValid = self.AttemptModuleCacheCopy()\r
4386 if CacheValid:\r
4387 return False\r
4388 return SaveFileOnChange(ModuleHashFile, m.hexdigest(), True)\r
4389\r
4390 ## Decide whether we can skip the ModuleAutoGen process\r
4391 def CanSkipbyHash(self):\r
4392 if GlobalData.gUseHashCache:\r
4393 return not self.GenModuleHash()\r
4394\r
c17956e0 4395 ## Decide whether we can skip the ModuleAutoGen process\r
36d083ef 4396 # If any source file is newer than the module than we cannot skip\r
c17956e0
DL
4397 #\r
4398 def CanSkip(self):\r
4399 if not os.path.exists(self.GetTimeStampPath()):\r
4400 return False\r
4401 #last creation time of the module\r
4402 DstTimeStamp = os.stat(self.GetTimeStampPath())[8]\r
4403\r
4404 SrcTimeStamp = self.Workspace._SrcTimeStamp\r
4405 if SrcTimeStamp > DstTimeStamp:\r
4406 return False\r
4407\r
4408 with open(self.GetTimeStampPath(),'r') as f:\r
4409 for source in f:\r
4410 source = source.rstrip('\n')\r
4a1167df
YZ
4411 if not os.path.exists(source):\r
4412 return False\r
c17956e0
DL
4413 if source not in ModuleAutoGen.TimeDict :\r
4414 ModuleAutoGen.TimeDict[source] = os.stat(source)[8]\r
4415 if ModuleAutoGen.TimeDict[source] > DstTimeStamp:\r
4416 return False\r
4417 return True\r
4418\r
4419 def GetTimeStampPath(self):\r
4420 if self._TimeStampPath == None:\r
4421 self._TimeStampPath = os.path.join(self.MakeFileDir, 'AutoGenTimeStamp')\r
4422 return self._TimeStampPath\r
4423 def CreateTimeStamp(self, Makefile):\r
4424\r
4425 FileSet = set()\r
4426\r
4427 FileSet.add (self.MetaFile.Path)\r
4428\r
4429 for SourceFile in self.Module.Sources:\r
4430 FileSet.add (SourceFile.Path)\r
4431\r
4432 for Lib in self.DependentLibraryList:\r
4433 FileSet.add (Lib.MetaFile.Path)\r
4434\r
4435 for f in self.AutoGenDepSet:\r
4436 FileSet.add (f.Path)\r
4437\r
4438 if os.path.exists (self.GetTimeStampPath()):\r
4439 os.remove (self.GetTimeStampPath())\r
4440 with open(self.GetTimeStampPath(), 'w+') as file:\r
4441 for f in FileSet:\r
4442 print >> file, f\r
4443\r
52302d4d
LG
4444 Module = property(_GetModule)\r
4445 Name = property(_GetBaseName)\r
4446 Guid = property(_GetGuid)\r
4447 Version = property(_GetVersion)\r
4448 ModuleType = property(_GetModuleType)\r
4449 ComponentType = property(_GetComponentType)\r
4450 BuildType = property(_GetBuildType)\r
4451 PcdIsDriver = property(_GetPcdIsDriver)\r
4452 AutoGenVersion = property(_GetAutoGenVersion)\r
4453 Macros = property(_GetMacros)\r
4454 Specification = property(_GetSpecification)\r
4455\r
4456 IsLibrary = property(_IsLibrary)\r
e8a47801 4457 IsBinaryModule = property(_IsBinaryModule)\r
52302d4d
LG
4458 BuildDir = property(_GetBuildDir)\r
4459 OutputDir = property(_GetOutputDir)\r
4460 DebugDir = property(_GetDebugDir)\r
4461 MakeFileDir = property(_GetMakeFileDir)\r
4462 CustomMakefile = property(_GetCustomMakefile)\r
4463\r
4464 IncludePathList = property(_GetIncludePathList)\r
725cdb8f 4465 IncludePathLength = property(_GetIncludePathLength)\r
52302d4d
LG
4466 AutoGenFileList = property(_GetAutoGenFileList)\r
4467 UnicodeFileList = property(_GetUnicodeFileList)\r
5b97eb4c 4468 VfrFileList = property(_GetVfrFileList)\r
52302d4d
LG
4469 SourceFileList = property(_GetSourceFileList)\r
4470 BinaryFileList = property(_GetBinaryFiles) # FileType : [File List]\r
4471 Targets = property(_GetTargets)\r
4472 IntroTargetList = property(_GetIntroTargetList)\r
4473 CodaTargetList = property(_GetFinalTargetList)\r
4474 FileTypes = property(_GetFileTypes)\r
4475 BuildRules = property(_GetBuildRules)\r
333ba578 4476 IdfFileList = property(_GetIdfFileList)\r
52302d4d
LG
4477\r
4478 DependentPackageList = property(_GetDependentPackageList)\r
4479 DependentLibraryList = property(_GetLibraryList)\r
4480 LibraryAutoGenList = property(_GetLibraryAutoGenList)\r
4481 DerivedPackageList = property(_GetDerivedPackageList)\r
4482\r
4483 ModulePcdList = property(_GetModulePcdList)\r
4484 LibraryPcdList = property(_GetLibraryPcdList)\r
4485 GuidList = property(_GetGuidList)\r
4486 ProtocolList = property(_GetProtocolList)\r
4487 PpiList = property(_GetPpiList)\r
4488 DepexList = property(_GetDepexTokenList)\r
b36d134f 4489 DxsFile = property(_GetDxsFile)\r
52302d4d
LG
4490 DepexExpressionList = property(_GetDepexExpressionTokenList)\r
4491 BuildOption = property(_GetModuleBuildOption)\r
79b74a03 4492 BuildOptionIncPathList = property(_GetBuildOptionIncPathList)\r
52302d4d 4493 BuildCommand = property(_GetBuildCommand)\r
2bc3256c
LG
4494 \r
4495 FixedAtBuildPcds = property(_GetFixedAtBuildPcds)\r
52302d4d
LG
4496\r
4497# This acts like the main() function for the script, unless it is 'import'ed into another script.\r
4498if __name__ == '__main__':\r
4499 pass\r
4500\r