]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/AutoGen/AutoGen.py
BaseTools: Add PcdValueCommon logic into C source CommonLib
[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 688 content += os.linesep\r
c17956e0
DL
689 SaveFileOnChange(os.path.join(self.BuildDir, 'BuildOptions'), content, False)\r
690\r
99adfe9f
YZ
691 #\r
692 # Create PcdToken Number file for Dynamic/DynamicEx Pcd.\r
693 #\r
694 PcdTokenNumber = 'PcdTokenNumber: '\r
695 if Pa.PcdTokenNumber:\r
696 if Pa.DynamicPcdList:\r
697 for Pcd in Pa.DynamicPcdList:\r
698 PcdTokenNumber += os.linesep\r
699 PcdTokenNumber += str((Pcd.TokenCName, Pcd.TokenSpaceGuidCName))\r
700 PcdTokenNumber += ' : '\r
701 PcdTokenNumber += str(Pa.PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName])\r
702 SaveFileOnChange(os.path.join(self.BuildDir, 'PcdTokenNumber'), PcdTokenNumber, False)\r
703\r
c17956e0
DL
704 #\r
705 # Get set of workspace metafiles\r
706 #\r
707 AllWorkSpaceMetaFiles = self._GetMetaFiles(Target, Toolchain, Arch)\r
708\r
709 #\r
710 # Retrieve latest modified time of all metafiles\r
711 #\r
712 SrcTimeStamp = 0\r
713 for f in AllWorkSpaceMetaFiles:\r
714 if os.stat(f)[8] > SrcTimeStamp:\r
715 SrcTimeStamp = os.stat(f)[8]\r
716 self._SrcTimeStamp = SrcTimeStamp\r
717\r
36d083ef
YZ
718 if GlobalData.gUseHashCache:\r
719 m = hashlib.md5()\r
720 for files in AllWorkSpaceMetaFiles:\r
721 if files.endswith('.dec'):\r
722 continue\r
723 f = open(files, 'r')\r
724 Content = f.read()\r
725 f.close()\r
726 m.update(Content)\r
727 SaveFileOnChange(os.path.join(self.BuildDir, 'AutoGen.hash'), m.hexdigest(), True)\r
728 GlobalData.gPlatformHash = m.hexdigest()\r
729\r
c17956e0
DL
730 #\r
731 # Write metafile list to build directory\r
732 #\r
733 AutoGenFilePath = os.path.join(self.BuildDir, 'AutoGen')\r
734 if os.path.exists (AutoGenFilePath):\r
735 os.remove(AutoGenFilePath)\r
736 if not os.path.exists(self.BuildDir):\r
737 os.makedirs(self.BuildDir)\r
738 with open(os.path.join(self.BuildDir, 'AutoGen'), 'w+') as file:\r
739 for f in AllWorkSpaceMetaFiles:\r
740 print >> file, f\r
52302d4d
LG
741 return True\r
742\r
36d083ef
YZ
743 def _GenPkgLevelHash(self, Pkg):\r
744 PkgDir = os.path.join(self.BuildDir, Pkg.Arch, Pkg.PackageName)\r
745 CreateDirectory(PkgDir)\r
746 HashFile = os.path.join(PkgDir, Pkg.PackageName + '.hash')\r
747 m = hashlib.md5()\r
748 # Get .dec file's hash value\r
749 f = open(Pkg.MetaFile.Path, 'r')\r
750 Content = f.read()\r
751 f.close()\r
752 m.update(Content)\r
753 # Get include files hash value\r
754 if Pkg.Includes:\r
755 for inc in Pkg.Includes:\r
756 for Root, Dirs, Files in os.walk(str(inc)):\r
757 for File in Files:\r
758 File_Path = os.path.join(Root, File)\r
759 f = open(File_Path, 'r')\r
760 Content = f.read()\r
761 f.close()\r
762 m.update(Content)\r
763 SaveFileOnChange(HashFile, m.hexdigest(), True)\r
764 if Pkg.PackageName not in GlobalData.gPackageHash[Pkg.Arch]:\r
765 GlobalData.gPackageHash[Pkg.Arch][Pkg.PackageName] = m.hexdigest()\r
763e8edf 766\r
c17956e0
DL
767 def _GetMetaFiles(self, Target, Toolchain, Arch):\r
768 AllWorkSpaceMetaFiles = set()\r
769 #\r
770 # add fdf\r
771 #\r
772 if self.FdfFile:\r
773 AllWorkSpaceMetaFiles.add (self.FdfFile.Path)\r
774 if self.FdfFile:\r
775 FdfFiles = GlobalData.gFdfParser.GetAllIncludedFile()\r
776 for f in FdfFiles:\r
777 AllWorkSpaceMetaFiles.add (f.FileName)\r
778 #\r
779 # add dsc\r
780 #\r
781 AllWorkSpaceMetaFiles.add(self.MetaFile.Path)\r
782\r
783 #\r
86601b78
DL
784 # add build_rule.txt & tools_def.txt\r
785 #\r
51de5c30
YZ
786 AllWorkSpaceMetaFiles.add(os.path.join(GlobalData.gConfDirectory, gDefaultBuildRuleFile))\r
787 AllWorkSpaceMetaFiles.add(os.path.join(GlobalData.gConfDirectory, gDefaultToolsDefFile))\r
86601b78 788\r
c17956e0
DL
789 # add BuildOption metafile\r
790 #\r
791 AllWorkSpaceMetaFiles.add(os.path.join(self.BuildDir, 'BuildOptions'))\r
792\r
99adfe9f
YZ
793 # add PcdToken Number file for Dynamic/DynamicEx Pcd\r
794 #\r
795 AllWorkSpaceMetaFiles.add(os.path.join(self.BuildDir, 'PcdTokenNumber'))\r
796\r
c17956e0
DL
797 for Arch in self.ArchList:\r
798 Platform = self.BuildDatabase[self.MetaFile, Arch, Target, Toolchain]\r
799 PGen = PlatformAutoGen(self, self.MetaFile, Target, Toolchain, Arch)\r
800\r
801 #\r
802 # add dec\r
803 #\r
804 for Package in PGen.PackageList:\r
805 AllWorkSpaceMetaFiles.add(Package.MetaFile.Path)\r
806\r
807 #\r
808 # add included dsc\r
809 #\r
810 for filePath in Platform._RawData.IncludedFiles:\r
811 AllWorkSpaceMetaFiles.add(filePath.Path)\r
812\r
813 return AllWorkSpaceMetaFiles\r
814\r
79b74a03
LG
815 ## _CheckDuplicateInFV() method\r
816 #\r
817 # Check whether there is duplicate modules/files exist in FV section. \r
818 # The check base on the file GUID;\r
819 #\r
820 def _CheckDuplicateInFV(self, Fdf):\r
821 for Fv in Fdf.Profile.FvDict:\r
822 _GuidDict = {}\r
823 for FfsFile in Fdf.Profile.FvDict[Fv].FfsList:\r
824 if FfsFile.InfFileName and FfsFile.NameGuid == None:\r
825 #\r
826 # Get INF file GUID\r
827 #\r
47fea6af 828 InfFoundFlag = False\r
79b74a03 829 for Pa in self.AutoGenObjectList:\r
64b2609f
LG
830 if InfFoundFlag:\r
831 break\r
79b74a03
LG
832 for Module in Pa.ModuleAutoGenList:\r
833 if path.normpath(Module.MetaFile.File) == path.normpath(FfsFile.InfFileName):\r
834 InfFoundFlag = True\r
835 if not Module.Guid.upper() in _GuidDict.keys():\r
836 _GuidDict[Module.Guid.upper()] = FfsFile\r
64b2609f 837 break\r
79b74a03 838 else:\r
47fea6af 839 EdkLogger.error("build",\r
79b74a03 840 FORMAT_INVALID,\r
47fea6af 841 "Duplicate GUID found for these lines: Line %d: %s and Line %d: %s. GUID: %s" % (FfsFile.CurrentLineNum,\r
79b74a03
LG
842 FfsFile.CurrentLineContent,\r
843 _GuidDict[Module.Guid.upper()].CurrentLineNum,\r
844 _GuidDict[Module.Guid.upper()].CurrentLineContent,\r
845 Module.Guid.upper()),\r
846 ExtraData=self.FdfFile)\r
847 #\r
848 # Some INF files not have entity in DSC file. \r
849 #\r
850 if not InfFoundFlag:\r
851 if FfsFile.InfFileName.find('$') == -1:\r
852 InfPath = NormPath(FfsFile.InfFileName)\r
853 if not os.path.exists(InfPath):\r
854 EdkLogger.error('build', GENFDS_ERROR, "Non-existant Module %s !" % (FfsFile.InfFileName))\r
47fea6af 855\r
79b74a03
LG
856 PathClassObj = PathClass(FfsFile.InfFileName, self.WorkspaceDir)\r
857 #\r
858 # Here we just need to get FILE_GUID from INF file, use 'COMMON' as ARCH attribute. and use \r
859 # BuildObject from one of AutoGenObjectList is enough.\r
860 #\r
861 InfObj = self.AutoGenObjectList[0].BuildDatabase.WorkspaceDb.BuildObject[PathClassObj, 'COMMON', self.BuildTarget, self.ToolChain]\r
862 if not InfObj.Guid.upper() in _GuidDict.keys():\r
863 _GuidDict[InfObj.Guid.upper()] = FfsFile\r
864 else:\r
47fea6af 865 EdkLogger.error("build",\r
79b74a03 866 FORMAT_INVALID,\r
47fea6af 867 "Duplicate GUID found for these lines: Line %d: %s and Line %d: %s. GUID: %s" % (FfsFile.CurrentLineNum,\r
79b74a03
LG
868 FfsFile.CurrentLineContent,\r
869 _GuidDict[InfObj.Guid.upper()].CurrentLineNum,\r
870 _GuidDict[InfObj.Guid.upper()].CurrentLineContent,\r
871 InfObj.Guid.upper()),\r
872 ExtraData=self.FdfFile)\r
873 InfFoundFlag = False\r
47fea6af 874\r
79b74a03
LG
875 if FfsFile.NameGuid != None:\r
876 _CheckPCDAsGuidPattern = re.compile("^PCD\(.+\..+\)$")\r
47fea6af 877\r
79b74a03
LG
878 #\r
879 # If the NameGuid reference a PCD name. \r
880 # The style must match: PCD(xxxx.yyy)\r
881 #\r
882 if _CheckPCDAsGuidPattern.match(FfsFile.NameGuid):\r
883 #\r
884 # Replace the PCD value.\r
885 #\r
886 _PcdName = FfsFile.NameGuid.lstrip("PCD(").rstrip(")")\r
887 PcdFoundFlag = False\r
888 for Pa in self.AutoGenObjectList:\r
889 if not PcdFoundFlag:\r
890 for PcdItem in Pa.AllPcdList:\r
891 if (PcdItem.TokenSpaceGuidCName + "." + PcdItem.TokenCName) == _PcdName:\r
892 #\r
893 # First convert from CFormatGuid to GUID string\r
894 #\r
895 _PcdGuidString = GuidStructureStringToGuidString(PcdItem.DefaultValue)\r
47fea6af 896\r
79b74a03
LG
897 if not _PcdGuidString:\r
898 #\r
899 # Then try Byte array.\r
900 #\r
901 _PcdGuidString = GuidStructureByteArrayToGuidString(PcdItem.DefaultValue)\r
47fea6af 902\r
79b74a03
LG
903 if not _PcdGuidString:\r
904 #\r
905 # Not Byte array or CFormat GUID, raise error.\r
906 #\r
907 EdkLogger.error("build",\r
908 FORMAT_INVALID,\r
47fea6af 909 "The format of PCD value is incorrect. PCD: %s , Value: %s\n" % (_PcdName, PcdItem.DefaultValue),\r
79b74a03 910 ExtraData=self.FdfFile)\r
47fea6af
YZ
911\r
912 if not _PcdGuidString.upper() in _GuidDict.keys():\r
79b74a03
LG
913 _GuidDict[_PcdGuidString.upper()] = FfsFile\r
914 PcdFoundFlag = True\r
915 break\r
916 else:\r
47fea6af 917 EdkLogger.error("build",\r
79b74a03 918 FORMAT_INVALID,\r
47fea6af 919 "Duplicate GUID found for these lines: Line %d: %s and Line %d: %s. GUID: %s" % (FfsFile.CurrentLineNum,\r
79b74a03
LG
920 FfsFile.CurrentLineContent,\r
921 _GuidDict[_PcdGuidString.upper()].CurrentLineNum,\r
922 _GuidDict[_PcdGuidString.upper()].CurrentLineContent,\r
923 FfsFile.NameGuid.upper()),\r
47fea6af
YZ
924 ExtraData=self.FdfFile)\r
925\r
79b74a03
LG
926 if not FfsFile.NameGuid.upper() in _GuidDict.keys():\r
927 _GuidDict[FfsFile.NameGuid.upper()] = FfsFile\r
928 else:\r
929 #\r
930 # Two raw file GUID conflict.\r
931 #\r
47fea6af 932 EdkLogger.error("build",\r
79b74a03 933 FORMAT_INVALID,\r
47fea6af 934 "Duplicate GUID found for these lines: Line %d: %s and Line %d: %s. GUID: %s" % (FfsFile.CurrentLineNum,\r
79b74a03
LG
935 FfsFile.CurrentLineContent,\r
936 _GuidDict[FfsFile.NameGuid.upper()].CurrentLineNum,\r
937 _GuidDict[FfsFile.NameGuid.upper()].CurrentLineContent,\r
938 FfsFile.NameGuid.upper()),\r
939 ExtraData=self.FdfFile)\r
47fea6af 940\r
79b74a03 941\r
4234283c
LG
942 def _CheckPcdDefineAndType(self):\r
943 PcdTypeList = [\r
944 "FixedAtBuild", "PatchableInModule", "FeatureFlag",\r
945 "Dynamic", #"DynamicHii", "DynamicVpd",\r
946 "DynamicEx", # "DynamicExHii", "DynamicExVpd"\r
947 ]\r
948\r
949 # This dict store PCDs which are not used by any modules with specified arches\r
950 UnusedPcd = sdict()\r
951 for Pa in self.AutoGenObjectList:\r
952 # Key of DSC's Pcds dictionary is PcdCName, TokenSpaceGuid\r
953 for Pcd in Pa.Platform.Pcds:\r
954 PcdType = Pa.Platform.Pcds[Pcd].Type\r
47fea6af 955\r
4234283c
LG
956 # If no PCD type, this PCD comes from FDF \r
957 if not PcdType:\r
958 continue\r
47fea6af 959\r
4234283c
LG
960 # Try to remove Hii and Vpd suffix\r
961 if PcdType.startswith("DynamicEx"):\r
962 PcdType = "DynamicEx"\r
963 elif PcdType.startswith("Dynamic"):\r
964 PcdType = "Dynamic"\r
47fea6af 965\r
4234283c
LG
966 for Package in Pa.PackageList:\r
967 # Key of DEC's Pcds dictionary is PcdCName, TokenSpaceGuid, PcdType\r
968 if (Pcd[0], Pcd[1], PcdType) in Package.Pcds:\r
969 break\r
970 for Type in PcdTypeList:\r
971 if (Pcd[0], Pcd[1], Type) in Package.Pcds:\r
972 EdkLogger.error(\r
973 'build',\r
974 FORMAT_INVALID,\r
975 "Type [%s] of PCD [%s.%s] in DSC file doesn't match the type [%s] defined in DEC file." \\r
976 % (Pa.Platform.Pcds[Pcd].Type, Pcd[1], Pcd[0], Type),\r
977 ExtraData=None\r
978 )\r
979 return\r
980 else:\r
981 UnusedPcd.setdefault(Pcd, []).append(Pa.Arch)\r
982\r
983 for Pcd in UnusedPcd:\r
984 EdkLogger.warn(\r
985 'build',\r
986 "The PCD was not specified by any INF module in the platform for the given architecture.\n"\r
987 "\tPCD: [%s.%s]\n\tPlatform: [%s]\n\tArch: %s"\r
988 % (Pcd[1], Pcd[0], os.path.basename(str(self.MetaFile)), str(UnusedPcd[Pcd])),\r
989 ExtraData=None\r
990 )\r
991\r
52302d4d
LG
992 def __repr__(self):\r
993 return "%s [%s]" % (self.MetaFile, ", ".join(self.ArchList))\r
994\r
995 ## Return the directory to store FV files\r
996 def _GetFvDir(self):\r
997 if self._FvDir == None:\r
998 self._FvDir = path.join(self.BuildDir, 'FV')\r
999 return self._FvDir\r
1000\r
1001 ## Return the directory to store all intermediate and final files built\r
1002 def _GetBuildDir(self):\r
36d083ef
YZ
1003 if self._BuildDir == None:\r
1004 return self.AutoGenObjectList[0].BuildDir\r
52302d4d
LG
1005\r
1006 ## Return the build output directory platform specifies\r
1007 def _GetOutputDir(self):\r
1008 return self.Platform.OutputDirectory\r
1009\r
1010 ## Return platform name\r
1011 def _GetName(self):\r
1012 return self.Platform.PlatformName\r
1013\r
1014 ## Return meta-file GUID\r
1015 def _GetGuid(self):\r
1016 return self.Platform.Guid\r
1017\r
1018 ## Return platform version\r
1019 def _GetVersion(self):\r
1020 return self.Platform.Version\r
1021\r
1022 ## Return paths of tools\r
1023 def _GetToolDefinition(self):\r
1024 return self.AutoGenObjectList[0].ToolDefinition\r
1025\r
1026 ## Return directory of platform makefile\r
1027 #\r
1028 # @retval string Makefile directory\r
1029 #\r
1030 def _GetMakeFileDir(self):\r
1031 if self._MakeFileDir == None:\r
1032 self._MakeFileDir = self.BuildDir\r
1033 return self._MakeFileDir\r
1034\r
1035 ## Return build command string\r
1036 #\r
1037 # @retval string Build command string\r
1038 #\r
1039 def _GetBuildCommand(self):\r
1040 if self._BuildCommand == None:\r
1041 # BuildCommand should be all the same. So just get one from platform AutoGen\r
1042 self._BuildCommand = self.AutoGenObjectList[0].BuildCommand\r
1043 return self._BuildCommand\r
47fea6af 1044\r
6780eef1
LG
1045 ## Check the PCDs token value conflict in each DEC file.\r
1046 #\r
1047 # Will cause build break and raise error message while two PCDs conflict.\r
1048 # \r
1049 # @return None\r
1050 #\r
1051 def _CheckAllPcdsTokenValueConflict(self):\r
b36d134f
LG
1052 for Pa in self.AutoGenObjectList:\r
1053 for Package in Pa.PackageList:\r
6780eef1 1054 PcdList = Package.Pcds.values()\r
f827cd07 1055 PcdList.sort(lambda x, y: cmp(int(x.TokenValue, 0), int(y.TokenValue, 0))) \r
6780eef1
LG
1056 Count = 0\r
1057 while (Count < len(PcdList) - 1) :\r
1058 Item = PcdList[Count]\r
1059 ItemNext = PcdList[Count + 1]\r
1060 #\r
1061 # Make sure in the same token space the TokenValue should be unique\r
1062 #\r
f827cd07 1063 if (int(Item.TokenValue, 0) == int(ItemNext.TokenValue, 0)):\r
6780eef1
LG
1064 SameTokenValuePcdList = []\r
1065 SameTokenValuePcdList.append(Item)\r
1066 SameTokenValuePcdList.append(ItemNext)\r
1067 RemainPcdListLength = len(PcdList) - Count - 2\r
1068 for ValueSameCount in range(RemainPcdListLength):\r
f827cd07 1069 if int(PcdList[len(PcdList) - RemainPcdListLength + ValueSameCount].TokenValue, 0) == int(Item.TokenValue, 0):\r
6780eef1
LG
1070 SameTokenValuePcdList.append(PcdList[len(PcdList) - RemainPcdListLength + ValueSameCount])\r
1071 else:\r
1072 break;\r
1073 #\r
1074 # Sort same token value PCD list with TokenGuid and TokenCName\r
1075 #\r
47fea6af
YZ
1076 SameTokenValuePcdList.sort(lambda x, y: cmp("%s.%s" % (x.TokenSpaceGuidCName, x.TokenCName), "%s.%s" % (y.TokenSpaceGuidCName, y.TokenCName)))\r
1077 SameTokenValuePcdListCount = 0\r
6780eef1 1078 while (SameTokenValuePcdListCount < len(SameTokenValuePcdList) - 1):\r
2a29017e 1079 Flag = False\r
47fea6af
YZ
1080 TemListItem = SameTokenValuePcdList[SameTokenValuePcdListCount]\r
1081 TemListItemNext = SameTokenValuePcdList[SameTokenValuePcdListCount + 1]\r
1082\r
6780eef1 1083 if (TemListItem.TokenSpaceGuidCName == TemListItemNext.TokenSpaceGuidCName) and (TemListItem.TokenCName != TemListItemNext.TokenCName):\r
2a29017e
YZ
1084 for PcdItem in GlobalData.MixedPcd:\r
1085 if (TemListItem.TokenCName, TemListItem.TokenSpaceGuidCName) in GlobalData.MixedPcd[PcdItem] or \\r
1086 (TemListItemNext.TokenCName, TemListItemNext.TokenSpaceGuidCName) in GlobalData.MixedPcd[PcdItem]:\r
1087 Flag = True\r
1088 if not Flag:\r
1089 EdkLogger.error(\r
1090 'build',\r
1091 FORMAT_INVALID,\r
1092 "The TokenValue [%s] of PCD [%s.%s] is conflict with: [%s.%s] in %s"\\r
1093 % (TemListItem.TokenValue, TemListItem.TokenSpaceGuidCName, TemListItem.TokenCName, TemListItemNext.TokenSpaceGuidCName, TemListItemNext.TokenCName, Package),\r
1094 ExtraData=None\r
1095 )\r
6780eef1
LG
1096 SameTokenValuePcdListCount += 1\r
1097 Count += SameTokenValuePcdListCount\r
1098 Count += 1\r
47fea6af 1099\r
6780eef1 1100 PcdList = Package.Pcds.values()\r
47fea6af 1101 PcdList.sort(lambda x, y: cmp("%s.%s" % (x.TokenSpaceGuidCName, x.TokenCName), "%s.%s" % (y.TokenSpaceGuidCName, y.TokenCName)))\r
6780eef1
LG
1102 Count = 0\r
1103 while (Count < len(PcdList) - 1) :\r
1104 Item = PcdList[Count]\r
47fea6af 1105 ItemNext = PcdList[Count + 1]\r
6780eef1
LG
1106 #\r
1107 # Check PCDs with same TokenSpaceGuidCName.TokenCName have same token value as well.\r
1108 #\r
f827cd07 1109 if (Item.TokenSpaceGuidCName == ItemNext.TokenSpaceGuidCName) and (Item.TokenCName == ItemNext.TokenCName) and (int(Item.TokenValue, 0) != int(ItemNext.TokenValue, 0)):\r
6780eef1
LG
1110 EdkLogger.error(\r
1111 'build',\r
1112 FORMAT_INVALID,\r
1113 "The TokenValue [%s] of PCD [%s.%s] in %s defined in two places should be same as well."\\r
1114 % (Item.TokenValue, Item.TokenSpaceGuidCName, Item.TokenCName, Package),\r
1115 ExtraData=None\r
1116 )\r
1117 Count += 1\r
97fa0ee9 1118 ## Generate fds command\r
03af2753
HC
1119 def _GenFdsCommand(self):\r
1120 return (GenMake.TopLevelMakefile(self)._TEMPLATE_.Replace(GenMake.TopLevelMakefile(self)._TemplateDict)).strip()\r
52302d4d 1121\r
e56468c0 1122 ## Create makefile for the platform and modules in it\r
52302d4d
LG
1123 #\r
1124 # @param CreateDepsMakeFile Flag indicating if the makefile for\r
1125 # modules will be created as well\r
1126 #\r
1127 def CreateMakeFile(self, CreateDepsMakeFile=False):\r
52302d4d
LG
1128 if CreateDepsMakeFile:\r
1129 for Pa in self.AutoGenObjectList:\r
1130 Pa.CreateMakeFile(CreateDepsMakeFile)\r
1131\r
1132 ## Create autogen code for platform and modules\r
1133 #\r
1134 # Since there's no autogen code for platform, this method will do nothing\r
1135 # if CreateModuleCodeFile is set to False.\r
1136 #\r
1137 # @param CreateDepsCodeFile Flag indicating if creating module's\r
1138 # autogen code file or not\r
1139 #\r
1140 def CreateCodeFile(self, CreateDepsCodeFile=False):\r
1141 if not CreateDepsCodeFile:\r
1142 return\r
1143 for Pa in self.AutoGenObjectList:\r
1144 Pa.CreateCodeFile(CreateDepsCodeFile)\r
1145\r
7c1fd323
LG
1146 ## Create AsBuilt INF file the platform\r
1147 #\r
1148 def CreateAsBuiltInf(self):\r
1149 return\r
1150\r
52302d4d
LG
1151 Name = property(_GetName)\r
1152 Guid = property(_GetGuid)\r
1153 Version = property(_GetVersion)\r
1154 OutputDir = property(_GetOutputDir)\r
1155\r
1156 ToolDefinition = property(_GetToolDefinition) # toolcode : tool path\r
1157\r
1158 BuildDir = property(_GetBuildDir)\r
1159 FvDir = property(_GetFvDir)\r
1160 MakeFileDir = property(_GetMakeFileDir)\r
1161 BuildCommand = property(_GetBuildCommand)\r
03af2753 1162 GenFdsCommand = property(_GenFdsCommand)\r
52302d4d
LG
1163\r
1164## AutoGen class for platform\r
1165#\r
1166# PlatformAutoGen class will process the original information in platform\r
1167# file in order to generate makefile for platform.\r
1168#\r
1169class PlatformAutoGen(AutoGen):\r
1170 #\r
1171 # Used to store all PCDs for both PEI and DXE phase, in order to generate \r
1172 # correct PCD database\r
1173 # \r
1174 _DynaPcdList_ = []\r
1175 _NonDynaPcdList_ = []\r
61ee1dff 1176 _PlatformPcds = {}\r
6780eef1
LG
1177 \r
1178 #\r
1179 # The priority list while override build option \r
1180 #\r
1181 PrioList = {"0x11111" : 16, # TARGET_TOOLCHAIN_ARCH_COMMANDTYPE_ATTRIBUTE (Highest)\r
1182 "0x01111" : 15, # ******_TOOLCHAIN_ARCH_COMMANDTYPE_ATTRIBUTE\r
1183 "0x10111" : 14, # TARGET_*********_ARCH_COMMANDTYPE_ATTRIBUTE\r
1184 "0x00111" : 13, # ******_*********_ARCH_COMMANDTYPE_ATTRIBUTE \r
1185 "0x11011" : 12, # TARGET_TOOLCHAIN_****_COMMANDTYPE_ATTRIBUTE\r
1186 "0x01011" : 11, # ******_TOOLCHAIN_****_COMMANDTYPE_ATTRIBUTE\r
1187 "0x10011" : 10, # TARGET_*********_****_COMMANDTYPE_ATTRIBUTE\r
1188 "0x00011" : 9, # ******_*********_****_COMMANDTYPE_ATTRIBUTE\r
1189 "0x11101" : 8, # TARGET_TOOLCHAIN_ARCH_***********_ATTRIBUTE\r
1190 "0x01101" : 7, # ******_TOOLCHAIN_ARCH_***********_ATTRIBUTE\r
1191 "0x10101" : 6, # TARGET_*********_ARCH_***********_ATTRIBUTE\r
1192 "0x00101" : 5, # ******_*********_ARCH_***********_ATTRIBUTE\r
1193 "0x11001" : 4, # TARGET_TOOLCHAIN_****_***********_ATTRIBUTE\r
1194 "0x01001" : 3, # ******_TOOLCHAIN_****_***********_ATTRIBUTE\r
1195 "0x10001" : 2, # TARGET_*********_****_***********_ATTRIBUTE\r
1196 "0x00001" : 1} # ******_*********_****_***********_ATTRIBUTE (Lowest)\r
47fea6af 1197\r
52302d4d
LG
1198 ## The real constructor of PlatformAutoGen\r
1199 #\r
1200 # This method is not supposed to be called by users of PlatformAutoGen. It's\r
1201 # only used by factory method __new__() to do real initialization work for an\r
1202 # object of PlatformAutoGen\r
1203 #\r
1204 # @param Workspace WorkspaceAutoGen object\r
1205 # @param PlatformFile Platform file (DSC file)\r
1206 # @param Target Build target (DEBUG, RELEASE)\r
1207 # @param Toolchain Name of tool chain\r
1208 # @param Arch arch of the platform supports\r
1209 #\r
1210 def _Init(self, Workspace, PlatformFile, Target, Toolchain, Arch):\r
1211 EdkLogger.debug(EdkLogger.DEBUG_9, "AutoGen platform [%s] [%s]" % (PlatformFile, Arch))\r
1212 GlobalData.gProcessingFile = "%s [%s, %s, %s]" % (PlatformFile, Arch, Toolchain, Target)\r
1213\r
1214 self.MetaFile = PlatformFile\r
1215 self.Workspace = Workspace\r
1216 self.WorkspaceDir = Workspace.WorkspaceDir\r
1217 self.ToolChain = Toolchain\r
1218 self.BuildTarget = Target\r
1219 self.Arch = Arch\r
1220 self.SourceDir = PlatformFile.SubDir\r
1221 self.SourceOverrideDir = None\r
1222 self.FdTargetList = self.Workspace.FdTargetList\r
1223 self.FvTargetList = self.Workspace.FvTargetList\r
1224 self.AllPcdList = []\r
a0a2cd1e
FB
1225 # get the original module/package/platform objects\r
1226 self.BuildDatabase = Workspace.BuildDatabase\r
52302d4d
LG
1227\r
1228 # flag indicating if the makefile/C-code file has been created or not\r
1229 self.IsMakeFileCreated = False\r
1230 self.IsCodeFileCreated = False\r
1231\r
1232 self._Platform = None\r
1233 self._Name = None\r
1234 self._Guid = None\r
1235 self._Version = None\r
1236\r
1237 self._BuildRule = None\r
1238 self._SourceDir = None\r
1239 self._BuildDir = None\r
1240 self._OutputDir = None\r
1241 self._FvDir = None\r
1242 self._MakeFileDir = None\r
1243 self._FdfFile = None\r
1244\r
1245 self._PcdTokenNumber = None # (TokenCName, TokenSpaceGuidCName) : GeneratedTokenNumber\r
1246 self._DynamicPcdList = None # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]\r
1247 self._NonDynamicPcdList = None # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]\r
2bc3256c 1248 self._NonDynamicPcdDict = {}\r
52302d4d
LG
1249\r
1250 self._ToolDefinitions = None\r
1251 self._ToolDefFile = None # toolcode : tool path\r
1252 self._ToolChainFamily = None\r
1253 self._BuildRuleFamily = None\r
1254 self._BuildOption = None # toolcode : option\r
1255 self._EdkBuildOption = None # edktoolcode : option\r
1256 self._EdkIIBuildOption = None # edkiitoolcode : option\r
1257 self._PackageList = None\r
1258 self._ModuleAutoGenList = None\r
1259 self._LibraryAutoGenList = None\r
1260 self._BuildCommand = None\r
a0a2cd1e
FB
1261 self._AsBuildInfList = []\r
1262 self._AsBuildModuleList = []\r
1263 if GlobalData.gFdfParser != None:\r
1264 self._AsBuildInfList = GlobalData.gFdfParser.Profile.InfList\r
1265 for Inf in self._AsBuildInfList:\r
1266 InfClass = PathClass(NormPath(Inf), GlobalData.gWorkspace, self.Arch)\r
1267 M = self.BuildDatabase[InfClass, self.Arch, self.BuildTarget, self.ToolChain]\r
1268 if not M.IsSupportedArch:\r
1269 continue\r
1270 self._AsBuildModuleList.append(InfClass)\r
03af2753
HC
1271 # get library/modules for build\r
1272 self.LibraryBuildDirectoryList = []\r
1273 self.ModuleBuildDirectoryList = []\r
52302d4d
LG
1274 return True\r
1275\r
1276 def __repr__(self):\r
1277 return "%s [%s]" % (self.MetaFile, self.Arch)\r
1278\r
1279 ## Create autogen code for platform and modules\r
1280 #\r
1281 # Since there's no autogen code for platform, this method will do nothing\r
1282 # if CreateModuleCodeFile is set to False.\r
1283 #\r
1284 # @param CreateModuleCodeFile Flag indicating if creating module's\r
1285 # autogen code file or not\r
1286 #\r
1287 def CreateCodeFile(self, CreateModuleCodeFile=False):\r
1288 # only module has code to be greated, so do nothing if CreateModuleCodeFile is False\r
1289 if self.IsCodeFileCreated or not CreateModuleCodeFile:\r
1290 return\r
1291\r
1292 for Ma in self.ModuleAutoGenList:\r
1293 Ma.CreateCodeFile(True)\r
1294\r
1295 # don't do this twice\r
1296 self.IsCodeFileCreated = True\r
1297\r
03af2753
HC
1298 ## Generate Fds Command\r
1299 def _GenFdsCommand(self):\r
1300 return self.Workspace.GenFdsCommand\r
481252bb 1301\r
52302d4d
LG
1302 ## Create makefile for the platform and mdoules in it\r
1303 #\r
1304 # @param CreateModuleMakeFile Flag indicating if the makefile for\r
1305 # modules will be created as well\r
1306 #\r
37de70b7 1307 def CreateMakeFile(self, CreateModuleMakeFile=False, FfsCommand = {}):\r
52302d4d
LG
1308 if CreateModuleMakeFile:\r
1309 for ModuleFile in self.Platform.Modules:\r
1310 Ma = ModuleAutoGen(self.Workspace, ModuleFile, self.BuildTarget,\r
1311 self.ToolChain, self.Arch, self.MetaFile)\r
37de70b7
YZ
1312 if (ModuleFile.File, self.Arch) in FfsCommand:\r
1313 Ma.CreateMakeFile(True, FfsCommand[ModuleFile.File, self.Arch])\r
1314 else:\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
37de70b7 2763 self._FfsOutputDir = None\r
52302d4d
LG
2764 self._DebugDir = None\r
2765 self._MakeFileDir = None\r
2766\r
2767 self._IncludePathList = None\r
725cdb8f 2768 self._IncludePathLength = 0\r
52302d4d
LG
2769 self._AutoGenFileList = None\r
2770 self._UnicodeFileList = None\r
5b97eb4c 2771 self._VfrFileList = None\r
333ba578 2772 self._IdfFileList = None\r
52302d4d
LG
2773 self._SourceFileList = None\r
2774 self._ObjectFileList = None\r
2775 self._BinaryFileList = None\r
2776\r
2777 self._DependentPackageList = None\r
2778 self._DependentLibraryList = None\r
2779 self._LibraryAutoGenList = None\r
2780 self._DerivedPackageList = None\r
2781 self._ModulePcdList = None\r
2782 self._LibraryPcdList = None\r
e8a47801 2783 self._PcdComments = sdict()\r
52302d4d 2784 self._GuidList = None\r
e8a47801
LG
2785 self._GuidsUsedByPcd = None\r
2786 self._GuidComments = sdict()\r
52302d4d 2787 self._ProtocolList = None\r
e8a47801 2788 self._ProtocolComments = sdict()\r
52302d4d 2789 self._PpiList = None\r
e8a47801 2790 self._PpiComments = sdict()\r
52302d4d
LG
2791 self._DepexList = None\r
2792 self._DepexExpressionList = None\r
2793 self._BuildOption = None\r
79b74a03 2794 self._BuildOptionIncPathList = None\r
52302d4d
LG
2795 self._BuildTargets = None\r
2796 self._IntroBuildTargetList = None\r
2797 self._FinalBuildTargetList = None\r
2798 self._FileTypes = None\r
2799 self._BuildRules = None\r
c17956e0
DL
2800\r
2801 self._TimeStampPath = None\r
2802\r
2803 self.AutoGenDepSet = set()\r
2804\r
2bc3256c
LG
2805 \r
2806 ## The Modules referenced to this Library\r
2807 # Only Library has this attribute\r
2808 self._ReferenceModules = [] \r
2809 \r
2810 ## Store the FixedAtBuild Pcds\r
2811 # \r
2812 self._FixedAtBuildPcds = []\r
2813 self.ConstPcd = {}\r
52302d4d
LG
2814 return True\r
2815\r
2816 def __repr__(self):\r
2817 return "%s [%s]" % (self.MetaFile, self.Arch)\r
2818\r
2bc3256c
LG
2819 # Get FixedAtBuild Pcds of this Module\r
2820 def _GetFixedAtBuildPcds(self):\r
2821 if self._FixedAtBuildPcds:\r
2822 return self._FixedAtBuildPcds\r
2823 for Pcd in self.ModulePcdList:\r
7256bd55 2824 if Pcd.Type != "FixedAtBuild":\r
2bc3256c
LG
2825 continue\r
2826 if Pcd not in self._FixedAtBuildPcds:\r
2827 self._FixedAtBuildPcds.append(Pcd)\r
2828 \r
2829 return self._FixedAtBuildPcds \r
2830\r
867d1cd4
YL
2831 def _GetUniqueBaseName(self):\r
2832 BaseName = self.Name\r
2833 for Module in self.PlatformInfo.ModuleAutoGenList:\r
2834 if Module.MetaFile == self.MetaFile:\r
2835 continue\r
2836 if Module.Name == self.Name:\r
867d1cd4
YL
2837 if uuid.UUID(Module.Guid) == uuid.UUID(self.Guid):\r
2838 EdkLogger.error("build", FILE_DUPLICATED, 'Modules have same BaseName and FILE_GUID:\n'\r
2839 ' %s\n %s' % (Module.MetaFile, self.MetaFile))\r
2840 BaseName = '%s_%s' % (self.Name, self.Guid)\r
2841 return BaseName\r
2842\r
52302d4d
LG
2843 # Macros could be used in build_rule.txt (also Makefile)\r
2844 def _GetMacros(self):\r
2845 if self._Macro == None:\r
2846 self._Macro = sdict()\r
2847 self._Macro["WORKSPACE" ] = self.WorkspaceDir\r
2848 self._Macro["MODULE_NAME" ] = self.Name\r
867d1cd4 2849 self._Macro["MODULE_NAME_GUID" ] = self._GetUniqueBaseName()\r
52302d4d
LG
2850 self._Macro["MODULE_GUID" ] = self.Guid\r
2851 self._Macro["MODULE_VERSION" ] = self.Version\r
2852 self._Macro["MODULE_TYPE" ] = self.ModuleType\r
2853 self._Macro["MODULE_FILE" ] = str(self.MetaFile)\r
2854 self._Macro["MODULE_FILE_BASE_NAME" ] = self.MetaFile.BaseName\r
2855 self._Macro["MODULE_RELATIVE_DIR" ] = self.SourceDir\r
2856 self._Macro["MODULE_DIR" ] = self.SourceDir\r
2857\r
2858 self._Macro["BASE_NAME" ] = self.Name\r
2859\r
2860 self._Macro["ARCH" ] = self.Arch\r
2861 self._Macro["TOOLCHAIN" ] = self.ToolChain\r
2862 self._Macro["TOOLCHAIN_TAG" ] = self.ToolChain\r
0d2711a6 2863 self._Macro["TOOL_CHAIN_TAG" ] = self.ToolChain\r
52302d4d
LG
2864 self._Macro["TARGET" ] = self.BuildTarget\r
2865\r
2866 self._Macro["BUILD_DIR" ] = self.PlatformInfo.BuildDir\r
2867 self._Macro["BIN_DIR" ] = os.path.join(self.PlatformInfo.BuildDir, self.Arch)\r
2868 self._Macro["LIB_DIR" ] = os.path.join(self.PlatformInfo.BuildDir, self.Arch)\r
2869 self._Macro["MODULE_BUILD_DIR" ] = self.BuildDir\r
2870 self._Macro["OUTPUT_DIR" ] = self.OutputDir\r
2871 self._Macro["DEBUG_DIR" ] = self.DebugDir\r
df1e1b63
YZ
2872 self._Macro["DEST_DIR_OUTPUT" ] = self.OutputDir\r
2873 self._Macro["DEST_DIR_DEBUG" ] = self.DebugDir\r
3570e332
YZ
2874 self._Macro["PLATFORM_NAME" ] = self.PlatformInfo.Name\r
2875 self._Macro["PLATFORM_GUID" ] = self.PlatformInfo.Guid\r
2876 self._Macro["PLATFORM_VERSION" ] = self.PlatformInfo.Version\r
2877 self._Macro["PLATFORM_RELATIVE_DIR" ] = self.PlatformInfo.SourceDir\r
2878 self._Macro["PLATFORM_DIR" ] = mws.join(self.WorkspaceDir, self.PlatformInfo.SourceDir)\r
2879 self._Macro["PLATFORM_OUTPUT_DIR" ] = self.PlatformInfo.OutputDir\r
37de70b7 2880 self._Macro["FFS_OUTPUT_DIR" ] = self.FfsOutputDir\r
52302d4d
LG
2881 return self._Macro\r
2882\r
2883 ## Return the module build data object\r
2884 def _GetModule(self):\r
2885 if self._Module == None:\r
0d2711a6 2886 self._Module = self.Workspace.BuildDatabase[self.MetaFile, self.Arch, self.BuildTarget, self.ToolChain]\r
52302d4d
LG
2887 return self._Module\r
2888\r
2889 ## Return the module name\r
2890 def _GetBaseName(self):\r
2891 return self.Module.BaseName\r
2892\r
b36d134f
LG
2893 ## Return the module DxsFile if exist\r
2894 def _GetDxsFile(self):\r
2895 return self.Module.DxsFile\r
2896\r
52302d4d
LG
2897 ## Return the module SourceOverridePath\r
2898 def _GetSourceOverridePath(self):\r
2899 return self.Module.SourceOverridePath\r
2900\r
2901 ## Return the module meta-file GUID\r
2902 def _GetGuid(self):\r
97fa0ee9
YL
2903 #\r
2904 # To build same module more than once, the module path with FILE_GUID overridden has\r
2905 # the file name FILE_GUIDmodule.inf, but the relative path (self.MetaFile.File) is the realy path\r
2906 # in DSC. The overridden GUID can be retrieved from file name\r
2907 #\r
2908 if os.path.basename(self.MetaFile.File) != os.path.basename(self.MetaFile.Path):\r
2909 #\r
2910 # Length of GUID is 36\r
2911 #\r
2912 return os.path.basename(self.MetaFile.Path)[:36]\r
52302d4d
LG
2913 return self.Module.Guid\r
2914\r
2915 ## Return the module version\r
2916 def _GetVersion(self):\r
2917 return self.Module.Version\r
2918\r
2919 ## Return the module type\r
2920 def _GetModuleType(self):\r
2921 return self.Module.ModuleType\r
2922\r
b36d134f 2923 ## Return the component type (for Edk.x style of module)\r
52302d4d
LG
2924 def _GetComponentType(self):\r
2925 return self.Module.ComponentType\r
2926\r
2927 ## Return the build type\r
2928 def _GetBuildType(self):\r
2929 return self.Module.BuildType\r
2930\r
2931 ## Return the PCD_IS_DRIVER setting\r
2932 def _GetPcdIsDriver(self):\r
2933 return self.Module.PcdIsDriver\r
2934\r
2935 ## Return the autogen version, i.e. module meta-file version\r
2936 def _GetAutoGenVersion(self):\r
2937 return self.Module.AutoGenVersion\r
2938\r
2939 ## Check if the module is library or not\r
2940 def _IsLibrary(self):\r
2941 if self._LibraryFlag == None:\r
2942 if self.Module.LibraryClass != None and self.Module.LibraryClass != []:\r
2943 self._LibraryFlag = True\r
2944 else:\r
2945 self._LibraryFlag = False\r
2946 return self._LibraryFlag\r
2947\r
e8a47801
LG
2948 ## Check if the module is binary module or not\r
2949 def _IsBinaryModule(self):\r
2950 return self.Module.IsBinaryModule\r
2951\r
52302d4d
LG
2952 ## Return the directory to store intermediate files of the module\r
2953 def _GetBuildDir(self):\r
2954 if self._BuildDir == None:\r
2955 self._BuildDir = path.join(\r
2956 self.PlatformInfo.BuildDir,\r
2957 self.Arch,\r
2958 self.SourceDir,\r
2959 self.MetaFile.BaseName\r
2960 )\r
2961 CreateDirectory(self._BuildDir)\r
2962 return self._BuildDir\r
2963\r
2964 ## Return the directory to store the intermediate object files of the mdoule\r
2965 def _GetOutputDir(self):\r
2966 if self._OutputDir == None:\r
2967 self._OutputDir = path.join(self.BuildDir, "OUTPUT")\r
2968 CreateDirectory(self._OutputDir)\r
2969 return self._OutputDir\r
2970\r
37de70b7
YZ
2971 ## Return the directory to store ffs file\r
2972 def _GetFfsOutputDir(self):\r
2973 if self._FfsOutputDir == None:\r
2974 if GlobalData.gFdfParser != None:\r
2975 self._FfsOutputDir = path.join(self.PlatformInfo.BuildDir, "FV", "Ffs", self.Guid + self.Name)\r
2976 else:\r
2977 self._FfsOutputDir = ''\r
2978 return self._FfsOutputDir\r
2979\r
52302d4d
LG
2980 ## Return the directory to store auto-gened source files of the mdoule\r
2981 def _GetDebugDir(self):\r
2982 if self._DebugDir == None:\r
2983 self._DebugDir = path.join(self.BuildDir, "DEBUG")\r
2984 CreateDirectory(self._DebugDir)\r
2985 return self._DebugDir\r
2986\r
2987 ## Return the path of custom file\r
2988 def _GetCustomMakefile(self):\r
2989 if self._CustomMakefile == None:\r
2990 self._CustomMakefile = {}\r
2991 for Type in self.Module.CustomMakefile:\r
2992 if Type in gMakeTypeMap:\r
2993 MakeType = gMakeTypeMap[Type]\r
2994 else:\r
2995 MakeType = 'nmake'\r
2996 if self.SourceOverrideDir != None:\r
2997 File = os.path.join(self.SourceOverrideDir, self.Module.CustomMakefile[Type])\r
2998 if not os.path.exists(File):\r
2999 File = os.path.join(self.SourceDir, self.Module.CustomMakefile[Type])\r
3000 else:\r
3001 File = os.path.join(self.SourceDir, self.Module.CustomMakefile[Type])\r
3002 self._CustomMakefile[MakeType] = File\r
3003 return self._CustomMakefile\r
3004\r
3005 ## Return the directory of the makefile\r
3006 #\r
3007 # @retval string The directory string of module's makefile\r
3008 #\r
3009 def _GetMakeFileDir(self):\r
3010 return self.BuildDir\r
3011\r
3012 ## Return build command string\r
3013 #\r
3014 # @retval string Build command string\r
3015 #\r
3016 def _GetBuildCommand(self):\r
3017 return self.PlatformInfo.BuildCommand\r
3018\r
3019 ## Get object list of all packages the module and its dependent libraries belong to\r
3020 #\r
3021 # @retval list The list of package object\r
3022 #\r
3023 def _GetDerivedPackageList(self):\r
3024 PackageList = []\r
3025 for M in [self.Module] + self.DependentLibraryList:\r
3026 for Package in M.Packages:\r
3027 if Package in PackageList:\r
3028 continue\r
3029 PackageList.append(Package)\r
3030 return PackageList\r
97fa0ee9
YL
3031 \r
3032 ## Get the depex string\r
3033 #\r
3034 # @return : a string contain all depex expresion.\r
3035 def _GetDepexExpresionString(self):\r
3036 DepexStr = ''\r
3037 DepexList = []\r
3038 ## DPX_SOURCE IN Define section.\r
3039 if self.Module.DxsFile:\r
3040 return DepexStr\r
3041 for M in [self.Module] + self.DependentLibraryList:\r
3042 Filename = M.MetaFile.Path\r
3043 InfObj = InfSectionParser.InfSectionParser(Filename)\r
3044 DepexExpresionList = InfObj.GetDepexExpresionList()\r
3045 for DepexExpresion in DepexExpresionList:\r
3046 for key in DepexExpresion.keys():\r
3047 Arch, ModuleType = key\r
518aebe2 3048 DepexExpr = [x for x in DepexExpresion[key] if not str(x).startswith('#')]\r
97fa0ee9
YL
3049 # the type of build module is USER_DEFINED.\r
3050 # All different DEPEX section tags would be copied into the As Built INF file\r
3051 # and there would be separate DEPEX section tags\r
3052 if self.ModuleType.upper() == SUP_MODULE_USER_DEFINED:\r
3053 if (Arch.upper() == self.Arch.upper()) and (ModuleType.upper() != TAB_ARCH_COMMON):\r
518aebe2 3054 DepexList.append({(Arch, ModuleType): DepexExpr})\r
97fa0ee9
YL
3055 else:\r
3056 if Arch.upper() == TAB_ARCH_COMMON or \\r
3057 (Arch.upper() == self.Arch.upper() and \\r
3058 ModuleType.upper() in [TAB_ARCH_COMMON, self.ModuleType.upper()]):\r
518aebe2 3059 DepexList.append({(Arch, ModuleType): DepexExpr})\r
97fa0ee9
YL
3060 \r
3061 #the type of build module is USER_DEFINED.\r
3062 if self.ModuleType.upper() == SUP_MODULE_USER_DEFINED:\r
3063 for Depex in DepexList:\r
3064 for key in Depex.keys():\r
3065 DepexStr += '[Depex.%s.%s]\n' % key\r
3066 DepexStr += '\n'.join(['# '+ val for val in Depex[key]])\r
3067 DepexStr += '\n\n'\r
3068 if not DepexStr:\r
3069 return '[Depex.%s]\n' % self.Arch\r
3070 return DepexStr\r
3071 \r
3072 #the type of build module not is USER_DEFINED.\r
3073 Count = 0\r
3074 for Depex in DepexList:\r
3075 Count += 1\r
3076 if DepexStr != '':\r
3077 DepexStr += ' AND '\r
3078 DepexStr += '('\r
3079 for D in Depex.values():\r
3080 DepexStr += ' '.join([val for val in D])\r
3081 Index = DepexStr.find('END')\r
3082 if Index > -1 and Index == len(DepexStr) - 3:\r
3083 DepexStr = DepexStr[:-3]\r
3084 DepexStr = DepexStr.strip()\r
3085 DepexStr += ')'\r
3086 if Count == 1:\r
3087 DepexStr = DepexStr.lstrip('(').rstrip(')').strip()\r
3088 if not DepexStr:\r
3089 return '[Depex.%s]\n' % self.Arch\r
3090 return '[Depex.%s]\n# ' % self.Arch + DepexStr\r
3091 \r
52302d4d
LG
3092 ## Merge dependency expression\r
3093 #\r
3094 # @retval list The token list of the dependency expression after parsed\r
3095 #\r
3096 def _GetDepexTokenList(self):\r
3097 if self._DepexList == None:\r
3098 self._DepexList = {}\r
b36d134f 3099 if self.DxsFile or self.IsLibrary or TAB_DEPENDENCY_EXPRESSION_FILE in self.FileTypes:\r
52302d4d
LG
3100 return self._DepexList\r
3101\r
3102 self._DepexList[self.ModuleType] = []\r
3103\r
3104 for ModuleType in self._DepexList:\r
3105 DepexList = self._DepexList[ModuleType]\r
3106 #\r
3107 # Append depex from dependent libraries, if not "BEFORE", "AFTER" expresion\r
3108 #\r
3109 for M in [self.Module] + self.DependentLibraryList:\r
3110 Inherited = False\r
3111 for D in M.Depex[self.Arch, ModuleType]:\r
3112 if DepexList != []:\r
3113 DepexList.append('AND')\r
3114 DepexList.append('(')\r
3115 DepexList.extend(D)\r
3116 if DepexList[-1] == 'END': # no need of a END at this time\r
3117 DepexList.pop()\r
3118 DepexList.append(')')\r
3119 Inherited = True\r
3120 if Inherited:\r
3121 EdkLogger.verbose("DEPEX[%s] (+%s) = %s" % (self.Name, M.BaseName, DepexList))\r
3122 if 'BEFORE' in DepexList or 'AFTER' in DepexList:\r
3123 break\r
3124 if len(DepexList) > 0:\r
3125 EdkLogger.verbose('')\r
3126 return self._DepexList\r
3127\r
3128 ## Merge dependency expression\r
3129 #\r
3130 # @retval list The token list of the dependency expression after parsed\r
3131 #\r
3132 def _GetDepexExpressionTokenList(self):\r
3133 if self._DepexExpressionList == None:\r
3134 self._DepexExpressionList = {}\r
b36d134f 3135 if self.DxsFile or self.IsLibrary or TAB_DEPENDENCY_EXPRESSION_FILE in self.FileTypes:\r
52302d4d
LG
3136 return self._DepexExpressionList\r
3137\r
3138 self._DepexExpressionList[self.ModuleType] = ''\r
3139\r
3140 for ModuleType in self._DepexExpressionList:\r
3141 DepexExpressionList = self._DepexExpressionList[ModuleType]\r
3142 #\r
3143 # Append depex from dependent libraries, if not "BEFORE", "AFTER" expresion\r
3144 #\r
3145 for M in [self.Module] + self.DependentLibraryList:\r
3146 Inherited = False\r
3147 for D in M.DepexExpression[self.Arch, ModuleType]:\r
3148 if DepexExpressionList != '':\r
3149 DepexExpressionList += ' AND '\r
3150 DepexExpressionList += '('\r
3151 DepexExpressionList += D\r
3152 DepexExpressionList = DepexExpressionList.rstrip('END').strip()\r
3153 DepexExpressionList += ')'\r
3154 Inherited = True\r
3155 if Inherited:\r
3156 EdkLogger.verbose("DEPEX[%s] (+%s) = %s" % (self.Name, M.BaseName, DepexExpressionList))\r
3157 if 'BEFORE' in DepexExpressionList or 'AFTER' in DepexExpressionList:\r
3158 break\r
3159 if len(DepexExpressionList) > 0:\r
3160 EdkLogger.verbose('')\r
3161 self._DepexExpressionList[ModuleType] = DepexExpressionList\r
3162 return self._DepexExpressionList\r
3163\r
dfa41b4a
YZ
3164 # Get the tiano core user extension, it is contain dependent library.\r
3165 # @retval: a list contain tiano core userextension.\r
3166 #\r
3167 def _GetTianoCoreUserExtensionList(self):\r
3168 TianoCoreUserExtentionList = []\r
3169 for M in [self.Module] + self.DependentLibraryList:\r
3170 Filename = M.MetaFile.Path\r
3171 InfObj = InfSectionParser.InfSectionParser(Filename)\r
3172 TianoCoreUserExtenList = InfObj.GetUserExtensionTianoCore()\r
3173 for TianoCoreUserExtent in TianoCoreUserExtenList:\r
3174 for Section in TianoCoreUserExtent.keys():\r
3175 ItemList = Section.split(TAB_SPLIT)\r
3176 Arch = self.Arch\r
3177 if len(ItemList) == 4:\r
3178 Arch = ItemList[3]\r
3179 if Arch.upper() == TAB_ARCH_COMMON or Arch.upper() == self.Arch.upper():\r
3180 TianoCoreList = []\r
3181 TianoCoreList.extend([TAB_SECTION_START + Section + TAB_SECTION_END])\r
3182 TianoCoreList.extend(TianoCoreUserExtent[Section][:])\r
3183 TianoCoreList.append('\n')\r
3184 TianoCoreUserExtentionList.append(TianoCoreList)\r
3185\r
3186 return TianoCoreUserExtentionList\r
3187\r
52302d4d
LG
3188 ## Return the list of specification version required for the module\r
3189 #\r
3190 # @retval list The list of specification defined in module file\r
3191 #\r
3192 def _GetSpecification(self):\r
3193 return self.Module.Specification\r
3194\r
3195 ## Tool option for the module build\r
3196 #\r
3197 # @param PlatformInfo The object of PlatformBuildInfo\r
3198 # @retval dict The dict containing valid options\r
3199 #\r
3200 def _GetModuleBuildOption(self):\r
3201 if self._BuildOption == None:\r
fe4bf2f9
YL
3202 self._BuildOption, self.BuildRuleOrder = self.PlatformInfo.ApplyBuildOption(self.Module)\r
3203 if self.BuildRuleOrder:\r
3204 self.BuildRuleOrder = ['.%s' % Ext for Ext in self.BuildRuleOrder.split()]\r
52302d4d
LG
3205 return self._BuildOption\r
3206\r
79b74a03
LG
3207 ## Get include path list from tool option for the module build\r
3208 #\r
3209 # @retval list The include path list\r
3210 #\r
3211 def _GetBuildOptionIncPathList(self):\r
3212 if self._BuildOptionIncPathList == None:\r
3213 #\r
d40b2ee6 3214 # Regular expression for finding Include Directories, the difference between MSFT and INTEL/GCC/RVCT\r
79b74a03
LG
3215 # is the former use /I , the Latter used -I to specify include directories\r
3216 #\r
3217 if self.PlatformInfo.ToolChainFamily in ('MSFT'):\r
47fea6af 3218 gBuildOptIncludePattern = re.compile(r"(?:.*?)/I[ \t]*([^ ]*)", re.MULTILINE | re.DOTALL)\r
d40b2ee6 3219 elif self.PlatformInfo.ToolChainFamily in ('INTEL', 'GCC', 'RVCT'):\r
47fea6af 3220 gBuildOptIncludePattern = re.compile(r"(?:.*?)-I[ \t]*([^ ]*)", re.MULTILINE | re.DOTALL)\r
d40b2ee6
LG
3221 else:\r
3222 #\r
3223 # New ToolChainFamily, don't known whether there is option to specify include directories\r
3224 #\r
3225 self._BuildOptionIncPathList = []\r
3226 return self._BuildOptionIncPathList\r
79b74a03
LG
3227 \r
3228 BuildOptionIncPathList = []\r
3229 for Tool in ('CC', 'PP', 'VFRPP', 'ASLPP', 'ASLCC', 'APP', 'ASM'):\r
3230 Attr = 'FLAGS'\r
3231 try:\r
3232 FlagOption = self.BuildOption[Tool][Attr]\r
3233 except KeyError:\r
3234 FlagOption = ''\r
3235 \r
d40b2ee6
LG
3236 if self.PlatformInfo.ToolChainFamily != 'RVCT':\r
3237 IncPathList = [NormPath(Path, self.Macros) for Path in gBuildOptIncludePattern.findall(FlagOption)]\r
3238 else:\r
3239 #\r
3240 # RVCT may specify a list of directory seperated by commas\r
3241 #\r
3242 IncPathList = []\r
3243 for Path in gBuildOptIncludePattern.findall(FlagOption):\r
3244 PathList = GetSplitList(Path, TAB_COMMA_SPLIT)\r
3245 IncPathList += [NormPath(PathEntry, self.Macros) for PathEntry in PathList]\r
3246\r
79b74a03
LG
3247 #\r
3248 # EDK II modules must not reference header files outside of the packages they depend on or \r
3249 # within the module's directory tree. Report error if violation.\r
3250 #\r
3251 if self.AutoGenVersion >= 0x00010005 and len(IncPathList) > 0:\r
3252 for Path in IncPathList:\r
3253 if (Path not in self.IncludePathList) and (CommonPath([Path, self.MetaFile.Dir]) != self.MetaFile.Dir):\r
47fea6af
YZ
3254 ErrMsg = "The include directory for the EDK II module in this line is invalid %s specified in %s FLAGS '%s'" % (Path, Tool, FlagOption)\r
3255 EdkLogger.error("build",\r
79b74a03 3256 PARAMETER_INVALID,\r
47fea6af
YZ
3257 ExtraData=ErrMsg,\r
3258 File=str(self.MetaFile))\r
79b74a03
LG
3259\r
3260 \r
3261 BuildOptionIncPathList += IncPathList\r
3262 \r
3263 self._BuildOptionIncPathList = BuildOptionIncPathList\r
3264 \r
3265 return self._BuildOptionIncPathList\r
3266 \r
52302d4d
LG
3267 ## Return a list of files which can be built from source\r
3268 #\r
3269 # What kind of files can be built is determined by build rules in\r
97fa0ee9 3270 # $(CONF_DIRECTORY)/build_rule.txt and toolchain family.\r
52302d4d
LG
3271 #\r
3272 def _GetSourceFileList(self):\r
3273 if self._SourceFileList == None:\r
3274 self._SourceFileList = []\r
3275 for F in self.Module.Sources:\r
3276 # match tool chain\r
08dd311f 3277 if F.TagName not in ("", "*", self.ToolChain):\r
52302d4d
LG
3278 EdkLogger.debug(EdkLogger.DEBUG_9, "The toolchain [%s] for processing file [%s] is found, "\r
3279 "but [%s] is needed" % (F.TagName, str(F), self.ToolChain))\r
3280 continue\r
e2597799
YZ
3281 # match tool chain family or build rule family\r
3282 if F.ToolChainFamily not in ("", "*", self.ToolChainFamily, self.BuildRuleFamily):\r
52302d4d
LG
3283 EdkLogger.debug(\r
3284 EdkLogger.DEBUG_0,\r
3285 "The file [%s] must be built by tools of [%s], " \\r
e2597799
YZ
3286 "but current toolchain family is [%s], buildrule family is [%s]" \\r
3287 % (str(F), F.ToolChainFamily, self.ToolChainFamily, self.BuildRuleFamily))\r
52302d4d
LG
3288 continue\r
3289\r
3290 # add the file path into search path list for file including\r
3291 if F.Dir not in self.IncludePathList and self.AutoGenVersion >= 0x00010005:\r
3292 self.IncludePathList.insert(0, F.Dir)\r
3293 self._SourceFileList.append(F)\r
4cb7bade
YZ
3294\r
3295 self._MatchBuildRuleOrder(self._SourceFileList)\r
3296\r
3297 for F in self._SourceFileList:\r
52302d4d
LG
3298 self._ApplyBuildRule(F, TAB_UNKNOWN_FILE)\r
3299 return self._SourceFileList\r
3300\r
4cb7bade
YZ
3301 def _MatchBuildRuleOrder(self, FileList):\r
3302 Order_Dict = {}\r
3303 self._GetModuleBuildOption()\r
3304 for SingleFile in FileList:\r
3305 if self.BuildRuleOrder and SingleFile.Ext in self.BuildRuleOrder and SingleFile.Ext in self.BuildRules:\r
3306 key = SingleFile.Path.split(SingleFile.Ext)[0]\r
3307 if key in Order_Dict:\r
3308 Order_Dict[key].append(SingleFile.Ext)\r
3309 else:\r
3310 Order_Dict[key] = [SingleFile.Ext]\r
3311\r
3312 RemoveList = []\r
3313 for F in Order_Dict:\r
3314 if len(Order_Dict[F]) > 1:\r
3315 Order_Dict[F].sort(key=lambda i: self.BuildRuleOrder.index(i))\r
3316 for Ext in Order_Dict[F][1:]:\r
3317 RemoveList.append(F + Ext)\r
3318 \r
3319 for item in RemoveList:\r
3320 FileList.remove(item)\r
3321\r
3322 return FileList\r
3323\r
52302d4d
LG
3324 ## Return the list of unicode files\r
3325 def _GetUnicodeFileList(self):\r
3326 if self._UnicodeFileList == None:\r
3327 if TAB_UNICODE_FILE in self.FileTypes:\r
3328 self._UnicodeFileList = self.FileTypes[TAB_UNICODE_FILE]\r
3329 else:\r
3330 self._UnicodeFileList = []\r
3331 return self._UnicodeFileList\r
3332\r
5b97eb4c
YZ
3333 ## Return the list of vfr files\r
3334 def _GetVfrFileList(self):\r
3335 if self._VfrFileList == None:\r
3336 if TAB_VFR_FILE in self.FileTypes:\r
3337 self._VfrFileList = self.FileTypes[TAB_VFR_FILE]\r
3338 else:\r
3339 self._VfrFileList = []\r
3340 return self._VfrFileList\r
3341\r
333ba578
YZ
3342 ## Return the list of Image Definition files\r
3343 def _GetIdfFileList(self):\r
3344 if self._IdfFileList == None:\r
3345 if TAB_IMAGE_FILE in self.FileTypes:\r
3346 self._IdfFileList = self.FileTypes[TAB_IMAGE_FILE]\r
3347 else:\r
3348 self._IdfFileList = []\r
3349 return self._IdfFileList\r
3350\r
52302d4d
LG
3351 ## Return a list of files which can be built from binary\r
3352 #\r
3353 # "Build" binary files are just to copy them to build directory.\r
3354 #\r
3355 # @retval list The list of files which can be built later\r
3356 #\r
3357 def _GetBinaryFiles(self):\r
3358 if self._BinaryFileList == None:\r
3359 self._BinaryFileList = []\r
3360 for F in self.Module.Binaries:\r
3361 if F.Target not in ['COMMON', '*'] and F.Target != self.BuildTarget:\r
3362 continue\r
3363 self._BinaryFileList.append(F)\r
3364 self._ApplyBuildRule(F, F.Type)\r
3365 return self._BinaryFileList\r
3366\r
3367 def _GetBuildRules(self):\r
3368 if self._BuildRules == None:\r
3369 BuildRules = {}\r
3370 BuildRuleDatabase = self.PlatformInfo.BuildRule\r
3371 for Type in BuildRuleDatabase.FileTypeList:\r
3372 #first try getting build rule by BuildRuleFamily\r
3373 RuleObject = BuildRuleDatabase[Type, self.BuildType, self.Arch, self.BuildRuleFamily]\r
3374 if not RuleObject:\r
3375 # build type is always module type, but ...\r
3376 if self.ModuleType != self.BuildType:\r
3377 RuleObject = BuildRuleDatabase[Type, self.ModuleType, self.Arch, self.BuildRuleFamily]\r
3378 #second try getting build rule by ToolChainFamily\r
3379 if not RuleObject:\r
3380 RuleObject = BuildRuleDatabase[Type, self.BuildType, self.Arch, self.ToolChainFamily]\r
3381 if not RuleObject:\r
3382 # build type is always module type, but ...\r
3383 if self.ModuleType != self.BuildType:\r
3384 RuleObject = BuildRuleDatabase[Type, self.ModuleType, self.Arch, self.ToolChainFamily]\r
3385 if not RuleObject:\r
3386 continue\r
3387 RuleObject = RuleObject.Instantiate(self.Macros)\r
3388 BuildRules[Type] = RuleObject\r
3389 for Ext in RuleObject.SourceFileExtList:\r
3390 BuildRules[Ext] = RuleObject\r
3391 self._BuildRules = BuildRules\r
3392 return self._BuildRules\r
3393\r
3394 def _ApplyBuildRule(self, File, FileType):\r
3395 if self._BuildTargets == None:\r
3396 self._IntroBuildTargetList = set()\r
3397 self._FinalBuildTargetList = set()\r
3398 self._BuildTargets = {}\r
3399 self._FileTypes = {}\r
3400\r
fcd4fbf3
YL
3401 SubDirectory = os.path.join(self.OutputDir, File.SubDir)\r
3402 if not os.path.exists(SubDirectory):\r
3403 CreateDirectory(SubDirectory)\r
52302d4d
LG
3404 LastTarget = None\r
3405 RuleChain = []\r
3406 SourceList = [File]\r
3407 Index = 0\r
fe4bf2f9
YL
3408 #\r
3409 # Make sure to get build rule order value\r
3410 #\r
3411 self._GetModuleBuildOption()\r
3412\r
52302d4d
LG
3413 while Index < len(SourceList):\r
3414 Source = SourceList[Index]\r
3415 Index = Index + 1\r
3416\r
3417 if Source != File:\r
3418 CreateDirectory(Source.Dir)\r
3419\r
3420 if File.IsBinary and File == Source and self._BinaryFileList != None and File in self._BinaryFileList:\r
da92f276
LG
3421 # Skip all files that are not binary libraries\r
3422 if not self.IsLibrary:\r
47fea6af 3423 continue\r
52302d4d
LG
3424 RuleObject = self.BuildRules[TAB_DEFAULT_BINARY_FILE]\r
3425 elif FileType in self.BuildRules:\r
3426 RuleObject = self.BuildRules[FileType]\r
3427 elif Source.Ext in self.BuildRules:\r
3428 RuleObject = self.BuildRules[Source.Ext]\r
3429 else:\r
3430 # stop at no more rules\r
3431 if LastTarget:\r
3432 self._FinalBuildTargetList.add(LastTarget)\r
3433 break\r
3434\r
3435 FileType = RuleObject.SourceFileType\r
3436 if FileType not in self._FileTypes:\r
3437 self._FileTypes[FileType] = set()\r
3438 self._FileTypes[FileType].add(Source)\r
3439\r
3440 # stop at STATIC_LIBRARY for library\r
3441 if self.IsLibrary and FileType == TAB_STATIC_LIBRARY:\r
3442 if LastTarget:\r
3443 self._FinalBuildTargetList.add(LastTarget)\r
3444 break\r
3445\r
fe4bf2f9 3446 Target = RuleObject.Apply(Source, self.BuildRuleOrder)\r
52302d4d
LG
3447 if not Target:\r
3448 if LastTarget:\r
3449 self._FinalBuildTargetList.add(LastTarget)\r
3450 break\r
3451 elif not Target.Outputs:\r
3452 # Only do build for target with outputs\r
3453 self._FinalBuildTargetList.add(Target)\r
3454\r
3455 if FileType not in self._BuildTargets:\r
3456 self._BuildTargets[FileType] = set()\r
3457 self._BuildTargets[FileType].add(Target)\r
3458\r
3459 if not Source.IsBinary and Source == File:\r
3460 self._IntroBuildTargetList.add(Target)\r
3461\r
3462 # to avoid cyclic rule\r
3463 if FileType in RuleChain:\r
3464 break\r
3465\r
3466 RuleChain.append(FileType)\r
3467 SourceList.extend(Target.Outputs)\r
3468 LastTarget = Target\r
3469 FileType = TAB_UNKNOWN_FILE\r
3470\r
3471 def _GetTargets(self):\r
3472 if self._BuildTargets == None:\r
3473 self._IntroBuildTargetList = set()\r
3474 self._FinalBuildTargetList = set()\r
3475 self._BuildTargets = {}\r
3476 self._FileTypes = {}\r
3477\r
b36d134f 3478 #TRICK: call _GetSourceFileList to apply build rule for source files\r
52302d4d
LG
3479 if self.SourceFileList:\r
3480 pass\r
3481\r
3482 #TRICK: call _GetBinaryFileList to apply build rule for binary files\r
3483 if self.BinaryFileList:\r
3484 pass\r
3485\r
3486 return self._BuildTargets\r
3487\r
3488 def _GetIntroTargetList(self):\r
3489 self._GetTargets()\r
3490 return self._IntroBuildTargetList\r
3491\r
3492 def _GetFinalTargetList(self):\r
3493 self._GetTargets()\r
3494 return self._FinalBuildTargetList\r
3495\r
3496 def _GetFileTypes(self):\r
3497 self._GetTargets()\r
3498 return self._FileTypes\r
3499\r
3500 ## Get the list of package object the module depends on\r
3501 #\r
3502 # @retval list The package object list\r
3503 #\r
3504 def _GetDependentPackageList(self):\r
3505 return self.Module.Packages\r
3506\r
3507 ## Return the list of auto-generated code file\r
3508 #\r
3509 # @retval list The list of auto-generated file\r
3510 #\r
3511 def _GetAutoGenFileList(self):\r
3512 UniStringAutoGenC = True\r
333ba578 3513 IdfStringAutoGenC = True\r
4234283c 3514 UniStringBinBuffer = StringIO()\r
333ba578 3515 IdfGenBinBuffer = StringIO()\r
52302d4d 3516 if self.BuildType == 'UEFI_HII':\r
52302d4d 3517 UniStringAutoGenC = False\r
333ba578 3518 IdfStringAutoGenC = False\r
52302d4d
LG
3519 if self._AutoGenFileList == None:\r
3520 self._AutoGenFileList = {}\r
3521 AutoGenC = TemplateString()\r
3522 AutoGenH = TemplateString()\r
3523 StringH = TemplateString()\r
333ba578
YZ
3524 StringIdf = TemplateString()\r
3525 GenC.CreateCode(self, AutoGenC, AutoGenH, StringH, UniStringAutoGenC, UniStringBinBuffer, StringIdf, IdfStringAutoGenC, IdfGenBinBuffer)\r
07b8564b
YL
3526 #\r
3527 # AutoGen.c is generated if there are library classes in inf, or there are object files\r
3528 #\r
3529 if str(AutoGenC) != "" and (len(self.Module.LibraryClasses) > 0\r
3530 or TAB_OBJECT_FILE in self.FileTypes):\r
52302d4d
LG
3531 AutoFile = PathClass(gAutoGenCodeFileName, self.DebugDir)\r
3532 self._AutoGenFileList[AutoFile] = str(AutoGenC)\r
3533 self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE)\r
3534 if str(AutoGenH) != "":\r
3535 AutoFile = PathClass(gAutoGenHeaderFileName, self.DebugDir)\r
3536 self._AutoGenFileList[AutoFile] = str(AutoGenH)\r
3537 self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE)\r
3538 if str(StringH) != "":\r
3539 AutoFile = PathClass(gAutoGenStringFileName % {"module_name":self.Name}, self.DebugDir)\r
3540 self._AutoGenFileList[AutoFile] = str(StringH)\r
3541 self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE)\r
3542 if UniStringBinBuffer != None and UniStringBinBuffer.getvalue() != "":\r
3543 AutoFile = PathClass(gAutoGenStringFormFileName % {"module_name":self.Name}, self.OutputDir)\r
3544 self._AutoGenFileList[AutoFile] = UniStringBinBuffer.getvalue()\r
3545 AutoFile.IsBinary = True\r
3546 self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE)\r
3547 if UniStringBinBuffer != None:\r
3548 UniStringBinBuffer.close()\r
333ba578
YZ
3549 if str(StringIdf) != "":\r
3550 AutoFile = PathClass(gAutoGenImageDefFileName % {"module_name":self.Name}, self.DebugDir)\r
3551 self._AutoGenFileList[AutoFile] = str(StringIdf)\r
3552 self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE)\r
3553 if IdfGenBinBuffer != None and IdfGenBinBuffer.getvalue() != "":\r
3554 AutoFile = PathClass(gAutoGenIdfFileName % {"module_name":self.Name}, self.OutputDir)\r
3555 self._AutoGenFileList[AutoFile] = IdfGenBinBuffer.getvalue()\r
3556 AutoFile.IsBinary = True\r
3557 self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE)\r
3558 if IdfGenBinBuffer != None:\r
3559 IdfGenBinBuffer.close()\r
52302d4d
LG
3560 return self._AutoGenFileList\r
3561\r
3562 ## Return the list of library modules explicitly or implicityly used by this module\r
3563 def _GetLibraryList(self):\r
3564 if self._DependentLibraryList == None:\r
3565 # only merge library classes and PCD for non-library module\r
3566 if self.IsLibrary:\r
3567 self._DependentLibraryList = []\r
3568 else:\r
3569 if self.AutoGenVersion < 0x00010005:\r
3570 self._DependentLibraryList = self.PlatformInfo.ResolveLibraryReference(self.Module)\r
3571 else:\r
3572 self._DependentLibraryList = self.PlatformInfo.ApplyLibraryInstance(self.Module)\r
3573 return self._DependentLibraryList\r
3574\r
e8a47801
LG
3575 @staticmethod\r
3576 def UpdateComments(Recver, Src):\r
3577 for Key in Src:\r
3578 if Key not in Recver:\r
3579 Recver[Key] = []\r
3580 Recver[Key].extend(Src[Key])\r
52302d4d
LG
3581 ## Get the list of PCDs from current module\r
3582 #\r
3583 # @retval list The list of PCD\r
3584 #\r
3585 def _GetModulePcdList(self):\r
3586 if self._ModulePcdList == None:\r
3587 # apply PCD settings from platform\r
3588 self._ModulePcdList = self.PlatformInfo.ApplyPcdSetting(self.Module, self.Module.Pcds)\r
e8a47801 3589 self.UpdateComments(self._PcdComments, self.Module.PcdComments)\r
52302d4d
LG
3590 return self._ModulePcdList\r
3591\r
3592 ## Get the list of PCDs from dependent libraries\r
3593 #\r
3594 # @retval list The list of PCD\r
3595 #\r
3596 def _GetLibraryPcdList(self):\r
3597 if self._LibraryPcdList == None:\r
79b74a03 3598 Pcds = sdict()\r
52302d4d
LG
3599 if not self.IsLibrary:\r
3600 # get PCDs from dependent libraries\r
3601 for Library in self.DependentLibraryList:\r
e8a47801 3602 self.UpdateComments(self._PcdComments, Library.PcdComments)\r
52302d4d
LG
3603 for Key in Library.Pcds:\r
3604 # skip duplicated PCDs\r
3605 if Key in self.Module.Pcds or Key in Pcds:\r
3606 continue\r
3607 Pcds[Key] = copy.copy(Library.Pcds[Key])\r
3608 # apply PCD settings from platform\r
3609 self._LibraryPcdList = self.PlatformInfo.ApplyPcdSetting(self.Module, Pcds)\r
3610 else:\r
3611 self._LibraryPcdList = []\r
3612 return self._LibraryPcdList\r
3613\r
3614 ## Get the GUID value mapping\r
3615 #\r
3616 # @retval dict The mapping between GUID cname and its value\r
3617 #\r
3618 def _GetGuidList(self):\r
3619 if self._GuidList == None:\r
8200fcfe
YL
3620 self._GuidList = sdict()\r
3621 self._GuidList.update(self.Module.Guids)\r
52302d4d
LG
3622 for Library in self.DependentLibraryList:\r
3623 self._GuidList.update(Library.Guids)\r
e8a47801
LG
3624 self.UpdateComments(self._GuidComments, Library.GuidComments)\r
3625 self.UpdateComments(self._GuidComments, self.Module.GuidComments)\r
52302d4d
LG
3626 return self._GuidList\r
3627\r
e8a47801
LG
3628 def GetGuidsUsedByPcd(self):\r
3629 if self._GuidsUsedByPcd == None:\r
3630 self._GuidsUsedByPcd = sdict()\r
3631 self._GuidsUsedByPcd.update(self.Module.GetGuidsUsedByPcd())\r
3632 for Library in self.DependentLibraryList:\r
3633 self._GuidsUsedByPcd.update(Library.GetGuidsUsedByPcd())\r
3634 return self._GuidsUsedByPcd\r
52302d4d
LG
3635 ## Get the protocol value mapping\r
3636 #\r
3637 # @retval dict The mapping between protocol cname and its value\r
3638 #\r
3639 def _GetProtocolList(self):\r
3640 if self._ProtocolList == None:\r
8200fcfe
YL
3641 self._ProtocolList = sdict()\r
3642 self._ProtocolList.update(self.Module.Protocols)\r
52302d4d
LG
3643 for Library in self.DependentLibraryList:\r
3644 self._ProtocolList.update(Library.Protocols)\r
e8a47801
LG
3645 self.UpdateComments(self._ProtocolComments, Library.ProtocolComments)\r
3646 self.UpdateComments(self._ProtocolComments, self.Module.ProtocolComments)\r
52302d4d
LG
3647 return self._ProtocolList\r
3648\r
3649 ## Get the PPI value mapping\r
3650 #\r
3651 # @retval dict The mapping between PPI cname and its value\r
3652 #\r
3653 def _GetPpiList(self):\r
3654 if self._PpiList == None:\r
8200fcfe
YL
3655 self._PpiList = sdict()\r
3656 self._PpiList.update(self.Module.Ppis)\r
52302d4d
LG
3657 for Library in self.DependentLibraryList:\r
3658 self._PpiList.update(Library.Ppis)\r
e8a47801
LG
3659 self.UpdateComments(self._PpiComments, Library.PpiComments)\r
3660 self.UpdateComments(self._PpiComments, self.Module.PpiComments)\r
52302d4d
LG
3661 return self._PpiList\r
3662\r
3663 ## Get the list of include search path\r
3664 #\r
3665 # @retval list The list path\r
3666 #\r
3667 def _GetIncludePathList(self):\r
3668 if self._IncludePathList == None:\r
3669 self._IncludePathList = []\r
3670 if self.AutoGenVersion < 0x00010005:\r
3671 for Inc in self.Module.Includes:\r
3672 if Inc not in self._IncludePathList:\r
3673 self._IncludePathList.append(Inc)\r
b36d134f 3674 # for Edk modules\r
52302d4d
LG
3675 Inc = path.join(Inc, self.Arch.capitalize())\r
3676 if os.path.exists(Inc) and Inc not in self._IncludePathList:\r
3677 self._IncludePathList.append(Inc)\r
b36d134f 3678 # 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
3679 self._IncludePathList.append(self.DebugDir)\r
3680 else:\r
3681 self._IncludePathList.append(self.MetaFile.Dir)\r
3682 self._IncludePathList.append(self.DebugDir)\r
3683\r
3684 for Package in self.Module.Packages:\r
05cc51ad 3685 PackageDir = mws.join(self.WorkspaceDir, Package.MetaFile.Dir)\r
52302d4d
LG
3686 if PackageDir not in self._IncludePathList:\r
3687 self._IncludePathList.append(PackageDir)\r
c28d2e10
YZ
3688 IncludesList = Package.Includes\r
3689 if Package._PrivateIncludes:\r
3690 if not self.MetaFile.Path.startswith(PackageDir):\r
3691 IncludesList = list(set(Package.Includes).difference(set(Package._PrivateIncludes)))\r
3692 for Inc in IncludesList:\r
52302d4d
LG
3693 if Inc not in self._IncludePathList:\r
3694 self._IncludePathList.append(str(Inc))\r
3695 return self._IncludePathList\r
3696\r
725cdb8f
YZ
3697 def _GetIncludePathLength(self):\r
3698 self._IncludePathLength = 0\r
3699 if self._IncludePathList:\r
3700 for inc in self._IncludePathList:\r
3701 self._IncludePathLength += len(' ' + inc)\r
3702 return self._IncludePathLength\r
3703\r
97fa0ee9
YL
3704 ## Get HII EX PCDs which maybe used by VFR\r
3705 #\r
3706 # efivarstore used by VFR may relate with HII EX PCDs\r
3707 # Get the variable name and GUID from efivarstore and HII EX PCD\r
3708 # List the HII EX PCDs in As Built INF if both name and GUID match.\r
3709 #\r
3710 # @retval list HII EX PCDs\r
3711 #\r
3712 def _GetPcdsMaybeUsedByVfr(self):\r
3713 if not self.SourceFileList:\r
3714 return []\r
3715\r
3716 NameGuids = []\r
3717 for SrcFile in self.SourceFileList:\r
3718 if SrcFile.Ext.lower() != '.vfr':\r
3719 continue\r
3720 Vfri = os.path.join(self.OutputDir, SrcFile.BaseName + '.i')\r
3721 if not os.path.exists(Vfri):\r
3722 continue\r
3723 VfriFile = open(Vfri, 'r')\r
3724 Content = VfriFile.read()\r
3725 VfriFile.close()\r
3726 Pos = Content.find('efivarstore')\r
3727 while Pos != -1:\r
3728 #\r
3729 # Make sure 'efivarstore' is the start of efivarstore statement\r
3730 # In case of the value of 'name' (name = efivarstore) is equal to 'efivarstore'\r
3731 #\r
3732 Index = Pos - 1\r
3733 while Index >= 0 and Content[Index] in ' \t\r\n':\r
3734 Index -= 1\r
3735 if Index >= 0 and Content[Index] != ';':\r
3736 Pos = Content.find('efivarstore', Pos + len('efivarstore'))\r
3737 continue\r
3738 #\r
3739 # 'efivarstore' must be followed by name and guid\r
3740 #\r
3741 Name = gEfiVarStoreNamePattern.search(Content, Pos)\r
3742 if not Name:\r
3743 break\r
3744 Guid = gEfiVarStoreGuidPattern.search(Content, Pos)\r
3745 if not Guid:\r
3746 break\r
3747 NameArray = ConvertStringToByteArray('L"' + Name.group(1) + '"')\r
3748 NameGuids.append((NameArray, GuidStructureStringToGuidString(Guid.group(1))))\r
3749 Pos = Content.find('efivarstore', Name.end())\r
3750 if not NameGuids:\r
3751 return []\r
3752 HiiExPcds = []\r
3753 for Pcd in self.PlatformInfo.Platform.Pcds.values():\r
3754 if Pcd.Type != TAB_PCDS_DYNAMIC_EX_HII:\r
3755 continue\r
3756 for SkuName in Pcd.SkuInfoList:\r
3757 SkuInfo = Pcd.SkuInfoList[SkuName]\r
3758 Name = ConvertStringToByteArray(SkuInfo.VariableName)\r
c28d2e10 3759 Value = GuidValue(SkuInfo.VariableGuid, self.PlatformInfo.PackageList, self.MetaFile.Path)\r
97fa0ee9
YL
3760 if not Value:\r
3761 continue\r
3762 Guid = GuidStructureStringToGuidString(Value)\r
3763 if (Name, Guid) in NameGuids and Pcd not in HiiExPcds:\r
3764 HiiExPcds.append(Pcd)\r
3765 break\r
3766\r
3767 return HiiExPcds\r
3768\r
aeaaf754
YL
3769 def _GenOffsetBin(self):\r
3770 VfrUniBaseName = {}\r
3771 for SourceFile in self.Module.Sources:\r
3772 if SourceFile.Type.upper() == ".VFR" :\r
3773 #\r
3774 # search the .map file to find the offset of vfr binary in the PE32+/TE file. \r
3775 #\r
3776 VfrUniBaseName[SourceFile.BaseName] = (SourceFile.BaseName + "Bin")\r
3777 if SourceFile.Type.upper() == ".UNI" :\r
3778 #\r
3779 # search the .map file to find the offset of Uni strings binary in the PE32+/TE file. \r
3780 #\r
3781 VfrUniBaseName["UniOffsetName"] = (self.Name + "Strings")\r
3782\r
3783 if len(VfrUniBaseName) == 0:\r
3784 return None\r
3785 MapFileName = os.path.join(self.OutputDir, self.Name + ".map")\r
3786 EfiFileName = os.path.join(self.OutputDir, self.Name + ".efi")\r
3787 VfrUniOffsetList = GetVariableOffset(MapFileName, EfiFileName, VfrUniBaseName.values())\r
3788 if not VfrUniOffsetList:\r
3789 return None\r
3790\r
3791 OutputName = '%sOffset.bin' % self.Name\r
3792 UniVfrOffsetFileName = os.path.join( self.OutputDir, OutputName)\r
3793\r
3794 try:\r
3795 fInputfile = open(UniVfrOffsetFileName, "wb+", 0)\r
3796 except:\r
3797 EdkLogger.error("build", FILE_OPEN_FAILURE, "File open failed for %s" % UniVfrOffsetFileName,None)\r
3798\r
3799 # Use a instance of StringIO to cache data\r
3800 fStringIO = StringIO('') \r
3801\r
3802 for Item in VfrUniOffsetList:\r
3803 if (Item[0].find("Strings") != -1):\r
3804 #\r
3805 # UNI offset in image.\r
3806 # GUID + Offset\r
3807 # { 0x8913c5e0, 0x33f6, 0x4d86, { 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66 } }\r
3808 #\r
3809 UniGuid = [0xe0, 0xc5, 0x13, 0x89, 0xf6, 0x33, 0x86, 0x4d, 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66]\r
3810 UniGuid = [chr(ItemGuid) for ItemGuid in UniGuid]\r
3811 fStringIO.write(''.join(UniGuid)) \r
3812 UniValue = pack ('Q', int (Item[1], 16))\r
3813 fStringIO.write (UniValue)\r
3814 else:\r
3815 #\r
3816 # VFR binary offset in image.\r
3817 # GUID + Offset\r
3818 # { 0xd0bc7cb4, 0x6a47, 0x495f, { 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2 } };\r
3819 #\r
3820 VfrGuid = [0xb4, 0x7c, 0xbc, 0xd0, 0x47, 0x6a, 0x5f, 0x49, 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2]\r
3821 VfrGuid = [chr(ItemGuid) for ItemGuid in VfrGuid]\r
3822 fStringIO.write(''.join(VfrGuid)) \r
3823 type (Item[1]) \r
3824 VfrValue = pack ('Q', int (Item[1], 16))\r
3825 fStringIO.write (VfrValue)\r
3826 #\r
3827 # write data into file.\r
3828 #\r
3829 try : \r
3830 fInputfile.write (fStringIO.getvalue())\r
3831 except:\r
3832 EdkLogger.error("build", FILE_WRITE_FAILURE, "Write data to file %s failed, please check whether the "\r
3833 "file been locked or using by other applications." %UniVfrOffsetFileName,None)\r
3834\r
3835 fStringIO.close ()\r
3836 fInputfile.close ()\r
3837 return OutputName\r
3838\r
da92f276
LG
3839 ## Create AsBuilt INF file the module\r
3840 #\r
83397f95
YZ
3841 def CreateAsBuiltInf(self, IsOnlyCopy = False):\r
3842 self.OutputFile = []\r
3843 if IsOnlyCopy:\r
3844 if GlobalData.gBinCacheDest:\r
3845 self.CopyModuleToCache()\r
3846 return\r
3847\r
da92f276
LG
3848 if self.IsAsBuiltInfCreated:\r
3849 return\r
3850 \r
3851 # Skip the following code for EDK I inf\r
3852 if self.AutoGenVersion < 0x00010005:\r
3853 return\r
3854 \r
3855 # Skip the following code for libraries\r
3856 if self.IsLibrary:\r
3857 return\r
3858 \r
3859 # Skip the following code for modules with no source files\r
3860 if self.SourceFileList == None or self.SourceFileList == []:\r
3861 return\r
3862\r
3863 # Skip the following code for modules without any binary files\r
3864 if self.BinaryFileList <> None and self.BinaryFileList <> []:\r
3865 return\r
3866 \r
3867 ### TODO: How to handles mixed source and binary modules\r
3868\r
e8a47801 3869 # Find all DynamicEx and PatchableInModule PCDs used by this module and dependent libraries\r
da92f276
LG
3870 # Also find all packages that the DynamicEx PCDs depend on\r
3871 Pcds = []\r
e5cf9198 3872 PatchablePcds = []\r
47fea6af 3873 Packages = []\r
e8a47801
LG
3874 PcdCheckList = []\r
3875 PcdTokenSpaceList = []\r
da92f276 3876 for Pcd in self.ModulePcdList + self.LibraryPcdList:\r
e8a47801 3877 if Pcd.Type == TAB_PCDS_PATCHABLE_IN_MODULE:\r
e5cf9198 3878 PatchablePcds += [Pcd]\r
e8a47801
LG
3879 PcdCheckList.append((Pcd.TokenCName, Pcd.TokenSpaceGuidCName, 'PatchableInModule'))\r
3880 elif Pcd.Type in GenC.gDynamicExPcd:\r
3881 if Pcd not in Pcds:\r
3882 Pcds += [Pcd]\r
3883 PcdCheckList.append((Pcd.TokenCName, Pcd.TokenSpaceGuidCName, 'DynamicEx'))\r
3884 PcdCheckList.append((Pcd.TokenCName, Pcd.TokenSpaceGuidCName, 'Dynamic'))\r
3885 PcdTokenSpaceList.append(Pcd.TokenSpaceGuidCName)\r
3886 GuidList = sdict()\r
3887 GuidList.update(self.GuidList)\r
3888 for TokenSpace in self.GetGuidsUsedByPcd():\r
3889 # If token space is not referred by patch PCD or Ex PCD, remove the GUID from GUID list\r
3890 # The GUIDs in GUIDs section should really be the GUIDs in source INF or referred by Ex an patch PCDs\r
3891 if TokenSpace not in PcdTokenSpaceList and TokenSpace in GuidList:\r
3892 GuidList.pop(TokenSpace)\r
3893 CheckList = (GuidList, self.PpiList, self.ProtocolList, PcdCheckList)\r
3894 for Package in self.DerivedPackageList:\r
3895 if Package in Packages:\r
3896 continue\r
3897 BeChecked = (Package.Guids, Package.Ppis, Package.Protocols, Package.Pcds)\r
3898 Found = False\r
3899 for Index in range(len(BeChecked)):\r
3900 for Item in CheckList[Index]:\r
3901 if Item in BeChecked[Index]:\r
3902 Packages += [Package]\r
3903 Found = True\r
3904 break\r
3905 if Found: break\r
da92f276 3906\r
97fa0ee9
YL
3907 VfrPcds = self._GetPcdsMaybeUsedByVfr()\r
3908 for Pkg in self.PlatformInfo.PackageList:\r
3909 if Pkg in Packages:\r
3910 continue\r
3911 for VfrPcd in VfrPcds:\r
3912 if ((VfrPcd.TokenCName, VfrPcd.TokenSpaceGuidCName, 'DynamicEx') in Pkg.Pcds or\r
3913 (VfrPcd.TokenCName, VfrPcd.TokenSpaceGuidCName, 'Dynamic') in Pkg.Pcds):\r
3914 Packages += [Pkg]\r
3915 break\r
3916\r
da92f276
LG
3917 ModuleType = self.ModuleType\r
3918 if ModuleType == 'UEFI_DRIVER' and self.DepexGenerated:\r
e8a47801
LG
3919 ModuleType = 'DXE_DRIVER'\r
3920\r
3921 DriverType = ''\r
3922 if self.PcdIsDriver != '':\r
3923 DriverType = self.PcdIsDriver\r
da92f276 3924\r
97fa0ee9
YL
3925 Guid = self.Guid\r
3926 MDefs = self.Module.Defines\r
3927\r
da92f276
LG
3928 AsBuiltInfDict = {\r
3929 'module_name' : self.Name,\r
97fa0ee9 3930 'module_guid' : Guid,\r
da92f276 3931 'module_module_type' : ModuleType,\r
97fa0ee9 3932 'module_version_string' : [MDefs['VERSION_STRING']] if 'VERSION_STRING' in MDefs else [],\r
e8a47801 3933 'pcd_is_driver_string' : [],\r
da92f276
LG
3934 'module_uefi_specification_version' : [],\r
3935 'module_pi_specification_version' : [],\r
97fa0ee9
YL
3936 'module_entry_point' : self.Module.ModuleEntryPointList,\r
3937 'module_unload_image' : self.Module.ModuleUnloadImageList,\r
3938 'module_constructor' : self.Module.ConstructorList,\r
3939 'module_destructor' : self.Module.DestructorList,\r
3940 'module_shadow' : [MDefs['SHADOW']] if 'SHADOW' in MDefs else [],\r
3941 'module_pci_vendor_id' : [MDefs['PCI_VENDOR_ID']] if 'PCI_VENDOR_ID' in MDefs else [],\r
3942 'module_pci_device_id' : [MDefs['PCI_DEVICE_ID']] if 'PCI_DEVICE_ID' in MDefs else [],\r
3943 'module_pci_class_code' : [MDefs['PCI_CLASS_CODE']] if 'PCI_CLASS_CODE' in MDefs else [],\r
3944 'module_pci_revision' : [MDefs['PCI_REVISION']] if 'PCI_REVISION' in MDefs else [],\r
3945 'module_build_number' : [MDefs['BUILD_NUMBER']] if 'BUILD_NUMBER' in MDefs else [],\r
3946 'module_spec' : [MDefs['SPEC']] if 'SPEC' in MDefs else [],\r
3947 'module_uefi_hii_resource_section' : [MDefs['UEFI_HII_RESOURCE_SECTION']] if 'UEFI_HII_RESOURCE_SECTION' in MDefs else [],\r
3948 'module_uni_file' : [MDefs['MODULE_UNI_FILE']] if 'MODULE_UNI_FILE' in MDefs else [],\r
da92f276 3949 'module_arch' : self.Arch,\r
47fea6af 3950 'package_item' : ['%s' % (Package.MetaFile.File.replace('\\', '/')) for Package in Packages],\r
da92f276 3951 'binary_item' : [],\r
e8a47801 3952 'patchablepcd_item' : [],\r
da92f276 3953 'pcd_item' : [],\r
e8a47801
LG
3954 'protocol_item' : [],\r
3955 'ppi_item' : [],\r
3956 'guid_item' : [],\r
3957 'flags_item' : [],\r
3958 'libraryclasses_item' : []\r
da92f276 3959 }\r
97fa0ee9 3960\r
78bcd52a
YZ
3961 if 'MODULE_UNI_FILE' in MDefs:\r
3962 UNIFile = os.path.join(self.MetaFile.Dir, MDefs['MODULE_UNI_FILE'])\r
3963 if os.path.isfile(UNIFile):\r
3964 shutil.copy2(UNIFile, self.OutputDir)\r
3965\r
97fa0ee9
YL
3966 if self.AutoGenVersion > int(gInfSpecVersion, 0):\r
3967 AsBuiltInfDict['module_inf_version'] = '0x%08x' % self.AutoGenVersion\r
3968 else:\r
3969 AsBuiltInfDict['module_inf_version'] = gInfSpecVersion\r
3970\r
e8a47801
LG
3971 if DriverType:\r
3972 AsBuiltInfDict['pcd_is_driver_string'] += [DriverType]\r
da92f276
LG
3973\r
3974 if 'UEFI_SPECIFICATION_VERSION' in self.Specification:\r
481252bb 3975 AsBuiltInfDict['module_uefi_specification_version'] += [self.Specification['UEFI_SPECIFICATION_VERSION']]\r
da92f276 3976 if 'PI_SPECIFICATION_VERSION' in self.Specification:\r
481252bb 3977 AsBuiltInfDict['module_pi_specification_version'] += [self.Specification['PI_SPECIFICATION_VERSION']]\r
da92f276 3978\r
47fea6af 3979 OutputDir = self.OutputDir.replace('\\', '/').strip('/')\r
481252bb 3980 for Item in self.CodaTargetList:\r
47fea6af 3981 File = Item.Target.Path.replace('\\', '/').strip('/').replace(OutputDir, '').strip('/')\r
36d083ef
YZ
3982 if File not in self.OutputFile:\r
3983 self.OutputFile.append(File)\r
47fea6af 3984 if Item.Target.Ext.lower() == '.aml':\r
481252bb 3985 AsBuiltInfDict['binary_item'] += ['ASL|' + File]\r
47fea6af 3986 elif Item.Target.Ext.lower() == '.acpi':\r
481252bb
YZ
3987 AsBuiltInfDict['binary_item'] += ['ACPI|' + File]\r
3988 elif Item.Target.Ext.lower() == '.efi':\r
3989 AsBuiltInfDict['binary_item'] += ['PE32|' + self.Name + '.efi']\r
da92f276 3990 else:\r
481252bb
YZ
3991 AsBuiltInfDict['binary_item'] += ['BIN|' + File]\r
3992 if self.DepexGenerated:\r
36d083ef
YZ
3993 if self.Name + '.depex' not in self.OutputFile:\r
3994 self.OutputFile.append(self.Name + '.depex')\r
da92f276 3995 if self.ModuleType in ['PEIM']:\r
481252bb 3996 AsBuiltInfDict['binary_item'] += ['PEI_DEPEX|' + self.Name + '.depex']\r
47fea6af 3997 if self.ModuleType in ['DXE_DRIVER', 'DXE_RUNTIME_DRIVER', 'DXE_SAL_DRIVER', 'UEFI_DRIVER']:\r
481252bb 3998 AsBuiltInfDict['binary_item'] += ['DXE_DEPEX|' + self.Name + '.depex']\r
da92f276 3999 if self.ModuleType in ['DXE_SMM_DRIVER']:\r
481252bb 4000 AsBuiltInfDict['binary_item'] += ['SMM_DEPEX|' + self.Name + '.depex']\r
da92f276 4001\r
aeaaf754
YL
4002 Bin = self._GenOffsetBin()\r
4003 if Bin:\r
4004 AsBuiltInfDict['binary_item'] += ['BIN|%s' % Bin]\r
36d083ef
YZ
4005 if Bin not in self.OutputFile:\r
4006 self.OutputFile.append(Bin)\r
aeaaf754 4007\r
e8a47801
LG
4008 for Root, Dirs, Files in os.walk(OutputDir):\r
4009 for File in Files:\r
4010 if File.lower().endswith('.pdb'):\r
4011 AsBuiltInfDict['binary_item'] += ['DISPOSABLE|' + File]\r
36d083ef
YZ
4012 if File not in self.OutputFile:\r
4013 self.OutputFile.append(File)\r
e8a47801
LG
4014 HeaderComments = self.Module.HeaderComments\r
4015 StartPos = 0\r
4016 for Index in range(len(HeaderComments)):\r
4017 if HeaderComments[Index].find('@BinaryHeader') != -1:\r
4018 HeaderComments[Index] = HeaderComments[Index].replace('@BinaryHeader', '@file')\r
4019 StartPos = Index\r
4020 break\r
4021 AsBuiltInfDict['header_comments'] = '\n'.join(HeaderComments[StartPos:]).replace(':#', '://')\r
97fa0ee9
YL
4022 AsBuiltInfDict['tail_comments'] = '\n'.join(self.Module.TailComments)\r
4023\r
e8a47801
LG
4024 GenList = [\r
4025 (self.ProtocolList, self._ProtocolComments, 'protocol_item'),\r
4026 (self.PpiList, self._PpiComments, 'ppi_item'),\r
4027 (GuidList, self._GuidComments, 'guid_item')\r
4028 ]\r
4029 for Item in GenList:\r
4030 for CName in Item[0]:\r
4031 Comments = ''\r
4032 if CName in Item[1]:\r
4033 Comments = '\n '.join(Item[1][CName])\r
4034 Entry = CName\r
4035 if Comments:\r
4036 Entry = Comments + '\n ' + CName\r
4037 AsBuiltInfDict[Item[2]].append(Entry)\r
4038 PatchList = parsePcdInfoFromMapFile(\r
4039 os.path.join(self.OutputDir, self.Name + '.map'),\r
4040 os.path.join(self.OutputDir, self.Name + '.efi')\r
4041 )\r
4042 if PatchList:\r
e5cf9198
YZ
4043 for Pcd in PatchablePcds:\r
4044 TokenCName = Pcd.TokenCName\r
4045 for PcdItem in GlobalData.MixedPcd:\r
4046 if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName) in GlobalData.MixedPcd[PcdItem]:\r
4047 TokenCName = PcdItem[0]\r
4048 break\r
4049 for PatchPcd in PatchList:\r
4050 if TokenCName == PatchPcd[0]:\r
4051 break\r
2a29017e 4052 else:\r
e8a47801 4053 continue\r
e8a47801 4054 PcdValue = ''\r
7ced8bb4
YZ
4055 if Pcd.DatumType == 'BOOLEAN':\r
4056 BoolValue = Pcd.DefaultValue.upper()\r
4057 if BoolValue == 'TRUE':\r
4058 Pcd.DefaultValue = '1'\r
4059 elif BoolValue == 'FALSE':\r
4060 Pcd.DefaultValue = '0'\r
4061\r
e8a47801
LG
4062 if Pcd.DatumType != 'VOID*':\r
4063 HexFormat = '0x%02x'\r
4064 if Pcd.DatumType == 'UINT16':\r
4065 HexFormat = '0x%04x'\r
4066 elif Pcd.DatumType == 'UINT32':\r
4067 HexFormat = '0x%08x'\r
4068 elif Pcd.DatumType == 'UINT64':\r
4069 HexFormat = '0x%016x'\r
4070 PcdValue = HexFormat % int(Pcd.DefaultValue, 0)\r
4071 else:\r
4072 if Pcd.MaxDatumSize == None or Pcd.MaxDatumSize == '':\r
4073 EdkLogger.error("build", AUTOGEN_ERROR,\r
2a29017e 4074 "Unknown [MaxDatumSize] of PCD [%s.%s]" % (Pcd.TokenSpaceGuidCName, TokenCName)\r
e8a47801
LG
4075 )\r
4076 ArraySize = int(Pcd.MaxDatumSize, 0)\r
4077 PcdValue = Pcd.DefaultValue\r
4078 if PcdValue[0] != '{':\r
4079 Unicode = False\r
4080 if PcdValue[0] == 'L':\r
4081 Unicode = True\r
4082 PcdValue = PcdValue.lstrip('L')\r
4083 PcdValue = eval(PcdValue)\r
4084 NewValue = '{'\r
4085 for Index in range(0, len(PcdValue)):\r
4086 if Unicode:\r
4087 CharVal = ord(PcdValue[Index])\r
4088 NewValue = NewValue + '0x%02x' % (CharVal & 0x00FF) + ', ' \\r
4089 + '0x%02x' % (CharVal >> 8) + ', '\r
4090 else:\r
4091 NewValue = NewValue + '0x%02x' % (ord(PcdValue[Index]) % 0x100) + ', '\r
4092 Padding = '0x00, '\r
4093 if Unicode:\r
4094 Padding = Padding * 2\r
4095 ArraySize = ArraySize / 2\r
4096 if ArraySize < (len(PcdValue) + 1):\r
4097 EdkLogger.error("build", AUTOGEN_ERROR,\r
2a29017e 4098 "The maximum size of VOID* type PCD '%s.%s' is less than its actual size occupied." % (Pcd.TokenSpaceGuidCName, TokenCName)\r
e8a47801
LG
4099 )\r
4100 if ArraySize > len(PcdValue) + 1:\r
4101 NewValue = NewValue + Padding * (ArraySize - len(PcdValue) - 1)\r
4102 PcdValue = NewValue + Padding.strip().rstrip(',') + '}'\r
4103 elif len(PcdValue.split(',')) <= ArraySize:\r
4104 PcdValue = PcdValue.rstrip('}') + ', 0x00' * (ArraySize - len(PcdValue.split(',')))\r
4105 PcdValue += '}'\r
4106 else:\r
4107 EdkLogger.error("build", AUTOGEN_ERROR,\r
2a29017e 4108 "The maximum size of VOID* type PCD '%s.%s' is less than its actual size occupied." % (Pcd.TokenSpaceGuidCName, TokenCName)\r
e8a47801
LG
4109 )\r
4110 PcdItem = '%s.%s|%s|0x%X' % \\r
2a29017e 4111 (Pcd.TokenSpaceGuidCName, TokenCName, PcdValue, PatchPcd[1])\r
e8a47801
LG
4112 PcdComments = ''\r
4113 if (Pcd.TokenSpaceGuidCName, Pcd.TokenCName) in self._PcdComments:\r
4114 PcdComments = '\n '.join(self._PcdComments[Pcd.TokenSpaceGuidCName, Pcd.TokenCName])\r
4115 if PcdComments:\r
4116 PcdItem = PcdComments + '\n ' + PcdItem\r
4117 AsBuiltInfDict['patchablepcd_item'].append(PcdItem)\r
97fa0ee9
YL
4118\r
4119 HiiPcds = []\r
4120 for Pcd in Pcds + VfrPcds:\r
e8a47801
LG
4121 PcdComments = ''\r
4122 PcdCommentList = []\r
4123 HiiInfo = ''\r
97fa0ee9 4124 SkuId = ''\r
2a29017e
YZ
4125 TokenCName = Pcd.TokenCName\r
4126 for PcdItem in GlobalData.MixedPcd:\r
4127 if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName) in GlobalData.MixedPcd[PcdItem]:\r
4128 TokenCName = PcdItem[0]\r
4129 break\r
e8a47801
LG
4130 if Pcd.Type == TAB_PCDS_DYNAMIC_EX_HII:\r
4131 for SkuName in Pcd.SkuInfoList:\r
4132 SkuInfo = Pcd.SkuInfoList[SkuName]\r
97fa0ee9 4133 SkuId = SkuInfo.SkuId\r
e8a47801
LG
4134 HiiInfo = '## %s|%s|%s' % (SkuInfo.VariableName, SkuInfo.VariableGuid, SkuInfo.VariableOffset)\r
4135 break\r
97fa0ee9
YL
4136 if SkuId:\r
4137 #\r
4138 # Don't generate duplicated HII PCD\r
4139 #\r
4140 if (SkuId, Pcd.TokenSpaceGuidCName, Pcd.TokenCName) in HiiPcds:\r
4141 continue\r
4142 else:\r
4143 HiiPcds.append((SkuId, Pcd.TokenSpaceGuidCName, Pcd.TokenCName))\r
e8a47801
LG
4144 if (Pcd.TokenSpaceGuidCName, Pcd.TokenCName) in self._PcdComments:\r
4145 PcdCommentList = self._PcdComments[Pcd.TokenSpaceGuidCName, Pcd.TokenCName][:]\r
4146 if HiiInfo:\r
4147 UsageIndex = -1\r
97fa0ee9 4148 UsageStr = ''\r
e8a47801
LG
4149 for Index, Comment in enumerate(PcdCommentList):\r
4150 for Usage in UsageList:\r
4151 if Comment.find(Usage) != -1:\r
97fa0ee9 4152 UsageStr = Usage\r
e8a47801
LG
4153 UsageIndex = Index\r
4154 break\r
4155 if UsageIndex != -1:\r
97fa0ee9 4156 PcdCommentList[UsageIndex] = '## %s %s %s' % (UsageStr, HiiInfo, PcdCommentList[UsageIndex].replace(UsageStr, '')) \r
e8a47801 4157 else:\r
97fa0ee9 4158 PcdCommentList.append('## UNDEFINED ' + HiiInfo)\r
e8a47801 4159 PcdComments = '\n '.join(PcdCommentList)\r
2a29017e 4160 PcdEntry = Pcd.TokenSpaceGuidCName + '.' + TokenCName\r
e8a47801
LG
4161 if PcdComments:\r
4162 PcdEntry = PcdComments + '\n ' + PcdEntry\r
4163 AsBuiltInfDict['pcd_item'] += [PcdEntry]\r
da92f276 4164 for Item in self.BuildOption:\r
481252bb
YZ
4165 if 'FLAGS' in self.BuildOption[Item]:\r
4166 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
4167\r
4168 # Generated LibraryClasses section in comments.\r
4169 for Library in self.LibraryAutoGenList:\r
4170 AsBuiltInfDict['libraryclasses_item'] += [Library.MetaFile.File.replace('\\', '/')]\r
4171 \r
dfa41b4a
YZ
4172 # Generated UserExtensions TianoCore section.\r
4173 # All tianocore user extensions are copied.\r
4174 UserExtStr = ''\r
4175 for TianoCore in self._GetTianoCoreUserExtensionList():\r
4176 UserExtStr += '\n'.join(TianoCore)\r
4177 ExtensionFile = os.path.join(self.MetaFile.Dir, TianoCore[1])\r
4178 if os.path.isfile(ExtensionFile):\r
4179 shutil.copy2(ExtensionFile, self.OutputDir)\r
4180 AsBuiltInfDict['userextension_tianocore_item'] = UserExtStr\r
4181\r
97fa0ee9
YL
4182 # Generated depex expression section in comments.\r
4183 AsBuiltInfDict['depexsection_item'] = ''\r
4184 DepexExpresion = self._GetDepexExpresionString()\r
4185 if DepexExpresion:\r
4186 AsBuiltInfDict['depexsection_item'] = DepexExpresion\r
da92f276
LG
4187 \r
4188 AsBuiltInf = TemplateString()\r
4189 AsBuiltInf.Append(gAsBuiltInfHeaderString.Replace(AsBuiltInfDict))\r
4190 \r
4191 SaveFileOnChange(os.path.join(self.OutputDir, self.Name + '.inf'), str(AsBuiltInf), False)\r
4192 \r
4193 self.IsAsBuiltInfCreated = True\r
36d083ef
YZ
4194 if GlobalData.gBinCacheDest:\r
4195 self.CopyModuleToCache()\r
4196\r
4197 def CopyModuleToCache(self):\r
4198 FileDir = path.join(GlobalData.gBinCacheDest, self.Arch, self.SourceDir, self.MetaFile.BaseName)\r
4199 CreateDirectory (FileDir)\r
4200 HashFile = path.join(self.BuildDir, self.Name + '.hash')\r
4201 ModuleFile = path.join(self.OutputDir, self.Name + '.inf')\r
4202 if os.path.exists(HashFile):\r
4203 shutil.copy2(HashFile, FileDir)\r
4204 if os.path.exists(ModuleFile):\r
4205 shutil.copy2(ModuleFile, FileDir)\r
83397f95
YZ
4206 if not self.OutputFile:\r
4207 Ma = self.Workspace.BuildDatabase[PathClass(ModuleFile), self.Arch, self.BuildTarget, self.ToolChain]\r
4208 self.OutputFile = Ma.Binaries\r
36d083ef
YZ
4209 if self.OutputFile:\r
4210 for File in self.OutputFile:\r
83397f95 4211 File = str(File)\r
36d083ef
YZ
4212 if not os.path.isabs(File):\r
4213 File = os.path.join(self.OutputDir, File)\r
4214 if os.path.exists(File):\r
4215 shutil.copy2(File, FileDir)\r
4216\r
4217 def AttemptModuleCacheCopy(self):\r
4218 if self.IsBinaryModule:\r
4219 return False\r
4220 FileDir = path.join(GlobalData.gBinCacheSource, self.Arch, self.SourceDir, self.MetaFile.BaseName)\r
4221 HashFile = path.join(FileDir, self.Name + '.hash')\r
4222 if os.path.exists(HashFile):\r
4223 f = open(HashFile, 'r')\r
4224 CacheHash = f.read()\r
4225 f.close()\r
4226 if GlobalData.gModuleHash[self.Arch][self.Name]:\r
4227 if CacheHash == GlobalData.gModuleHash[self.Arch][self.Name]:\r
4228 for root, dir, files in os.walk(FileDir):\r
4229 for f in files:\r
4230 if self.Name + '.hash' in f:\r
4231 shutil.copy2(HashFile, self.BuildDir)\r
4232 else:\r
4233 File = path.join(root, f)\r
4234 shutil.copy2(File, self.OutputDir)\r
4235 if self.Name == "PcdPeim" or self.Name == "PcdDxe":\r
4236 CreatePcdDatabaseCode(self, TemplateString(), TemplateString())\r
4237 return True\r
4238 return False\r
4239\r
52302d4d
LG
4240 ## Create makefile for the module and its dependent libraries\r
4241 #\r
4242 # @param CreateLibraryMakeFile Flag indicating if or not the makefiles of\r
4243 # dependent libraries will be created\r
4244 #\r
37de70b7 4245 def CreateMakeFile(self, CreateLibraryMakeFile=True, GenFfsList = []):\r
fae62ff2 4246 # Ignore generating makefile when it is a binary module\r
a0a2cd1e
FB
4247 if self.IsBinaryModule:\r
4248 return\r
fae62ff2 4249\r
52302d4d
LG
4250 if self.IsMakeFileCreated:\r
4251 return\r
37de70b7 4252 self.GenFfsList = GenFfsList\r
52302d4d
LG
4253 if not self.IsLibrary and CreateLibraryMakeFile:\r
4254 for LibraryAutoGen in self.LibraryAutoGenList:\r
4255 LibraryAutoGen.CreateMakeFile()\r
4256\r
36513f3a
YZ
4257 if self.CanSkip():\r
4258 return\r
4259\r
52302d4d
LG
4260 if len(self.CustomMakefile) == 0:\r
4261 Makefile = GenMake.ModuleMakefile(self)\r
4262 else:\r
4263 Makefile = GenMake.CustomMakefile(self)\r
4264 if Makefile.Generate():\r
4265 EdkLogger.debug(EdkLogger.DEBUG_9, "Generated makefile for module %s [%s]" %\r
4266 (self.Name, self.Arch))\r
4267 else:\r
4268 EdkLogger.debug(EdkLogger.DEBUG_9, "Skipped the generation of makefile for module %s [%s]" %\r
4269 (self.Name, self.Arch))\r
4270\r
c17956e0 4271 self.CreateTimeStamp(Makefile)\r
52302d4d
LG
4272 self.IsMakeFileCreated = True\r
4273\r
a0a2cd1e
FB
4274 def CopyBinaryFiles(self):\r
4275 for File in self.Module.Binaries:\r
4276 SrcPath = File.Path\r
4277 DstPath = os.path.join(self.OutputDir , os.path.basename(SrcPath))\r
4278 CopyLongFilePath(SrcPath, DstPath)\r
52302d4d
LG
4279 ## Create autogen code for the module and its dependent libraries\r
4280 #\r
4281 # @param CreateLibraryCodeFile Flag indicating if or not the code of\r
4282 # dependent libraries will be created\r
4283 #\r
4284 def CreateCodeFile(self, CreateLibraryCodeFile=True):\r
4285 if self.IsCodeFileCreated:\r
4286 return\r
4287\r
e8a47801
LG
4288 # Need to generate PcdDatabase even PcdDriver is binarymodule\r
4289 if self.IsBinaryModule and self.PcdIsDriver != '':\r
4290 CreatePcdDatabaseCode(self, TemplateString(), TemplateString())\r
4291 return\r
a0a2cd1e 4292 if self.IsBinaryModule:\r
49d9b71d
HC
4293 if self.IsLibrary:\r
4294 self.CopyBinaryFiles()\r
a0a2cd1e 4295 return\r
e8a47801 4296\r
52302d4d
LG
4297 if not self.IsLibrary and CreateLibraryCodeFile:\r
4298 for LibraryAutoGen in self.LibraryAutoGenList:\r
4299 LibraryAutoGen.CreateCodeFile()\r
4300\r
36513f3a
YZ
4301 if self.CanSkip():\r
4302 return\r
4303\r
52302d4d
LG
4304 AutoGenList = []\r
4305 IgoredAutoGenList = []\r
4306\r
4307 for File in self.AutoGenFileList:\r
4308 if GenC.Generate(File.Path, self.AutoGenFileList[File], File.IsBinary):\r
b36d134f 4309 #Ignore Edk AutoGen.c\r
52302d4d
LG
4310 if self.AutoGenVersion < 0x00010005 and File.Name == 'AutoGen.c':\r
4311 continue\r
4312\r
4313 AutoGenList.append(str(File))\r
4314 else:\r
4315 IgoredAutoGenList.append(str(File))\r
4316\r
4317 # Skip the following code for EDK I inf\r
4318 if self.AutoGenVersion < 0x00010005:\r
4319 return\r
4320\r
4321 for ModuleType in self.DepexList:\r
40d841f6
LG
4322 # Ignore empty [depex] section or [depex] section for "USER_DEFINED" module\r
4323 if len(self.DepexList[ModuleType]) == 0 or ModuleType == "USER_DEFINED":\r
52302d4d 4324 continue\r
40d841f6 4325\r
52302d4d
LG
4326 Dpx = GenDepex.DependencyExpression(self.DepexList[ModuleType], ModuleType, True)\r
4327 DpxFile = gAutoGenDepexFileName % {"module_name" : self.Name}\r
4328\r
da92f276 4329 if len(Dpx.PostfixNotation) <> 0:\r
0d2711a6 4330 self.DepexGenerated = True\r
da92f276 4331\r
52302d4d
LG
4332 if Dpx.Generate(path.join(self.OutputDir, DpxFile)):\r
4333 AutoGenList.append(str(DpxFile))\r
4334 else:\r
4335 IgoredAutoGenList.append(str(DpxFile))\r
4336\r
4337 if IgoredAutoGenList == []:\r
4338 EdkLogger.debug(EdkLogger.DEBUG_9, "Generated [%s] files for module %s [%s]" %\r
4339 (" ".join(AutoGenList), self.Name, self.Arch))\r
4340 elif AutoGenList == []:\r
4341 EdkLogger.debug(EdkLogger.DEBUG_9, "Skipped the generation of [%s] files for module %s [%s]" %\r
4342 (" ".join(IgoredAutoGenList), self.Name, self.Arch))\r
4343 else:\r
4344 EdkLogger.debug(EdkLogger.DEBUG_9, "Generated [%s] (skipped %s) files for module %s [%s]" %\r
4345 (" ".join(AutoGenList), " ".join(IgoredAutoGenList), self.Name, self.Arch))\r
4346\r
4347 self.IsCodeFileCreated = True\r
4348 return AutoGenList\r
4349\r
4350 ## Summarize the ModuleAutoGen objects of all libraries used by this module\r
4351 def _GetLibraryAutoGenList(self):\r
4352 if self._LibraryAutoGenList == None:\r
4353 self._LibraryAutoGenList = []\r
4354 for Library in self.DependentLibraryList:\r
4355 La = ModuleAutoGen(\r
4356 self.Workspace,\r
4357 Library.MetaFile,\r
4358 self.BuildTarget,\r
4359 self.ToolChain,\r
4360 self.Arch,\r
4361 self.PlatformInfo.MetaFile\r
4362 )\r
4363 if La not in self._LibraryAutoGenList:\r
4364 self._LibraryAutoGenList.append(La)\r
4365 for Lib in La.CodaTargetList:\r
4366 self._ApplyBuildRule(Lib.Target, TAB_UNKNOWN_FILE)\r
4367 return self._LibraryAutoGenList\r
4368\r
36d083ef
YZ
4369 def GenModuleHash(self):\r
4370 if self.Arch not in GlobalData.gModuleHash:\r
4371 GlobalData.gModuleHash[self.Arch] = {}\r
4372 m = hashlib.md5()\r
4373 # Add Platform level hash\r
4374 m.update(GlobalData.gPlatformHash)\r
4375 # Add Package level hash\r
4376 if self.DependentPackageList:\r
4377 for Pkg in self.DependentPackageList:\r
4378 if Pkg.PackageName in GlobalData.gPackageHash[self.Arch]:\r
4379 m.update(GlobalData.gPackageHash[self.Arch][Pkg.PackageName])\r
4380\r
4381 # Add Library hash\r
4382 if self.LibraryAutoGenList:\r
4383 for Lib in self.LibraryAutoGenList:\r
4384 if Lib.Name not in GlobalData.gModuleHash[self.Arch]:\r
4385 Lib.GenModuleHash()\r
4386 m.update(GlobalData.gModuleHash[self.Arch][Lib.Name])\r
4387\r
4388 # Add Module self\r
4389 f = open(str(self.MetaFile), 'r')\r
4390 Content = f.read()\r
4391 f.close()\r
4392 m.update(Content)\r
4393 # Add Module's source files\r
4394 if self.SourceFileList:\r
4395 for File in self.SourceFileList:\r
4396 f = open(str(File), 'r')\r
4397 Content = f.read()\r
4398 f.close()\r
4399 m.update(Content)\r
4400\r
4401 ModuleHashFile = path.join(self.BuildDir, self.Name + ".hash")\r
4402 if self.Name not in GlobalData.gModuleHash[self.Arch]:\r
4403 GlobalData.gModuleHash[self.Arch][self.Name] = m.hexdigest()\r
4404 if GlobalData.gBinCacheSource:\r
4405 CacheValid = self.AttemptModuleCacheCopy()\r
4406 if CacheValid:\r
4407 return False\r
4408 return SaveFileOnChange(ModuleHashFile, m.hexdigest(), True)\r
4409\r
4410 ## Decide whether we can skip the ModuleAutoGen process\r
4411 def CanSkipbyHash(self):\r
4412 if GlobalData.gUseHashCache:\r
4413 return not self.GenModuleHash()\r
4414\r
c17956e0 4415 ## Decide whether we can skip the ModuleAutoGen process\r
36d083ef 4416 # If any source file is newer than the module than we cannot skip\r
c17956e0
DL
4417 #\r
4418 def CanSkip(self):\r
4419 if not os.path.exists(self.GetTimeStampPath()):\r
4420 return False\r
4421 #last creation time of the module\r
4422 DstTimeStamp = os.stat(self.GetTimeStampPath())[8]\r
4423\r
4424 SrcTimeStamp = self.Workspace._SrcTimeStamp\r
4425 if SrcTimeStamp > DstTimeStamp:\r
4426 return False\r
4427\r
4428 with open(self.GetTimeStampPath(),'r') as f:\r
4429 for source in f:\r
4430 source = source.rstrip('\n')\r
4a1167df
YZ
4431 if not os.path.exists(source):\r
4432 return False\r
c17956e0
DL
4433 if source not in ModuleAutoGen.TimeDict :\r
4434 ModuleAutoGen.TimeDict[source] = os.stat(source)[8]\r
4435 if ModuleAutoGen.TimeDict[source] > DstTimeStamp:\r
4436 return False\r
4437 return True\r
4438\r
4439 def GetTimeStampPath(self):\r
4440 if self._TimeStampPath == None:\r
4441 self._TimeStampPath = os.path.join(self.MakeFileDir, 'AutoGenTimeStamp')\r
4442 return self._TimeStampPath\r
4443 def CreateTimeStamp(self, Makefile):\r
4444\r
4445 FileSet = set()\r
4446\r
4447 FileSet.add (self.MetaFile.Path)\r
4448\r
4449 for SourceFile in self.Module.Sources:\r
4450 FileSet.add (SourceFile.Path)\r
4451\r
4452 for Lib in self.DependentLibraryList:\r
4453 FileSet.add (Lib.MetaFile.Path)\r
4454\r
4455 for f in self.AutoGenDepSet:\r
4456 FileSet.add (f.Path)\r
4457\r
4458 if os.path.exists (self.GetTimeStampPath()):\r
4459 os.remove (self.GetTimeStampPath())\r
4460 with open(self.GetTimeStampPath(), 'w+') as file:\r
4461 for f in FileSet:\r
4462 print >> file, f\r
4463\r
52302d4d
LG
4464 Module = property(_GetModule)\r
4465 Name = property(_GetBaseName)\r
4466 Guid = property(_GetGuid)\r
4467 Version = property(_GetVersion)\r
4468 ModuleType = property(_GetModuleType)\r
4469 ComponentType = property(_GetComponentType)\r
4470 BuildType = property(_GetBuildType)\r
4471 PcdIsDriver = property(_GetPcdIsDriver)\r
4472 AutoGenVersion = property(_GetAutoGenVersion)\r
4473 Macros = property(_GetMacros)\r
4474 Specification = property(_GetSpecification)\r
4475\r
4476 IsLibrary = property(_IsLibrary)\r
e8a47801 4477 IsBinaryModule = property(_IsBinaryModule)\r
52302d4d
LG
4478 BuildDir = property(_GetBuildDir)\r
4479 OutputDir = property(_GetOutputDir)\r
37de70b7 4480 FfsOutputDir = property(_GetFfsOutputDir)\r
52302d4d
LG
4481 DebugDir = property(_GetDebugDir)\r
4482 MakeFileDir = property(_GetMakeFileDir)\r
4483 CustomMakefile = property(_GetCustomMakefile)\r
4484\r
4485 IncludePathList = property(_GetIncludePathList)\r
725cdb8f 4486 IncludePathLength = property(_GetIncludePathLength)\r
52302d4d
LG
4487 AutoGenFileList = property(_GetAutoGenFileList)\r
4488 UnicodeFileList = property(_GetUnicodeFileList)\r
5b97eb4c 4489 VfrFileList = property(_GetVfrFileList)\r
52302d4d
LG
4490 SourceFileList = property(_GetSourceFileList)\r
4491 BinaryFileList = property(_GetBinaryFiles) # FileType : [File List]\r
4492 Targets = property(_GetTargets)\r
4493 IntroTargetList = property(_GetIntroTargetList)\r
4494 CodaTargetList = property(_GetFinalTargetList)\r
4495 FileTypes = property(_GetFileTypes)\r
4496 BuildRules = property(_GetBuildRules)\r
333ba578 4497 IdfFileList = property(_GetIdfFileList)\r
52302d4d
LG
4498\r
4499 DependentPackageList = property(_GetDependentPackageList)\r
4500 DependentLibraryList = property(_GetLibraryList)\r
4501 LibraryAutoGenList = property(_GetLibraryAutoGenList)\r
4502 DerivedPackageList = property(_GetDerivedPackageList)\r
4503\r
4504 ModulePcdList = property(_GetModulePcdList)\r
4505 LibraryPcdList = property(_GetLibraryPcdList)\r
4506 GuidList = property(_GetGuidList)\r
4507 ProtocolList = property(_GetProtocolList)\r
4508 PpiList = property(_GetPpiList)\r
4509 DepexList = property(_GetDepexTokenList)\r
b36d134f 4510 DxsFile = property(_GetDxsFile)\r
52302d4d
LG
4511 DepexExpressionList = property(_GetDepexExpressionTokenList)\r
4512 BuildOption = property(_GetModuleBuildOption)\r
79b74a03 4513 BuildOptionIncPathList = property(_GetBuildOptionIncPathList)\r
52302d4d 4514 BuildCommand = property(_GetBuildCommand)\r
2bc3256c
LG
4515 \r
4516 FixedAtBuildPcds = property(_GetFixedAtBuildPcds)\r
52302d4d
LG
4517\r
4518# This acts like the main() function for the script, unless it is 'import'ed into another script.\r
4519if __name__ == '__main__':\r
4520 pass\r
4521\r