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