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