]>
Commit | Line | Data |
---|---|---|
e8449e1d FB |
1 | ## @file\r |
2 | # Create makefile for MS nmake and GNU make\r | |
3 | #\r | |
4 | # Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>\r | |
5 | # SPDX-License-Identifier: BSD-2-Clause-Patent\r | |
6 | #\r | |
7 | \r | |
8 | ## Import Modules\r | |
9 | #\r | |
10 | from __future__ import print_function\r | |
11 | from __future__ import absolute_import\r | |
12 | import os.path as path\r | |
13 | import hashlib\r | |
14 | from collections import defaultdict\r | |
15 | from GenFds.FdfParser import FdfParser\r | |
16 | from Workspace.WorkspaceCommon import GetModuleLibInstances\r | |
17 | from AutoGen import GenMake\r | |
18 | from AutoGen.AutoGen import AutoGen\r | |
19 | from AutoGen.PlatformAutoGen import PlatformAutoGen\r | |
20 | from AutoGen.BuildEngine import gDefaultBuildRuleFile\r | |
21 | from Common.ToolDefClassObject import gDefaultToolsDefFile\r | |
22 | from Common.StringUtils import NormPath\r | |
23 | from Common.BuildToolError import *\r | |
24 | from Common.DataType import *\r | |
25 | from Common.Misc import *\r | |
26 | \r | |
27 | ## Regular expression for splitting Dependency Expression string into tokens\r | |
28 | gDepexTokenPattern = re.compile("(\(|\)|\w+| \S+\.inf)")\r | |
29 | \r | |
30 | ## Regular expression for match: PCD(xxxx.yyy)\r | |
31 | gPCDAsGuidPattern = re.compile(r"^PCD\(.+\..+\)$")\r | |
32 | \r | |
33 | ## Workspace AutoGen class\r | |
34 | #\r | |
35 | # This class is used mainly to control the whole platform build for different\r | |
36 | # architecture. This class will generate top level makefile.\r | |
37 | #\r | |
38 | class WorkspaceAutoGen(AutoGen):\r | |
39 | # call super().__init__ then call the worker function with different parameter count\r | |
40 | def __init__(self, Workspace, MetaFile, Target, Toolchain, Arch, *args, **kwargs):\r | |
41 | if not hasattr(self, "_Init"):\r | |
42 | self._InitWorker(Workspace, MetaFile, Target, Toolchain, Arch, *args, **kwargs)\r | |
43 | self._Init = True\r | |
44 | \r | |
45 | ## Initialize WorkspaceAutoGen\r | |
46 | #\r | |
47 | # @param WorkspaceDir Root directory of workspace\r | |
48 | # @param ActivePlatform Meta-file of active platform\r | |
49 | # @param Target Build target\r | |
50 | # @param Toolchain Tool chain name\r | |
51 | # @param ArchList List of architecture of current build\r | |
52 | # @param MetaFileDb Database containing meta-files\r | |
53 | # @param BuildConfig Configuration of build\r | |
54 | # @param ToolDefinition Tool chain definitions\r | |
55 | # @param FlashDefinitionFile File of flash definition\r | |
56 | # @param Fds FD list to be generated\r | |
57 | # @param Fvs FV list to be generated\r | |
58 | # @param Caps Capsule list to be generated\r | |
59 | # @param SkuId SKU id from command line\r | |
60 | #\r | |
61 | def _InitWorker(self, WorkspaceDir, ActivePlatform, Target, Toolchain, ArchList, MetaFileDb,\r | |
62 | BuildConfig, ToolDefinition, FlashDefinitionFile='', Fds=None, Fvs=None, Caps=None, SkuId='', UniFlag=None,\r | |
63 | Progress=None, BuildModule=None):\r | |
64 | self.BuildDatabase = MetaFileDb\r | |
65 | self.MetaFile = ActivePlatform\r | |
66 | self.WorkspaceDir = WorkspaceDir\r | |
67 | self.Platform = self.BuildDatabase[self.MetaFile, TAB_ARCH_COMMON, Target, Toolchain]\r | |
68 | GlobalData.gActivePlatform = self.Platform\r | |
69 | self.BuildTarget = Target\r | |
70 | self.ToolChain = Toolchain\r | |
71 | self.ArchList = ArchList\r | |
72 | self.SkuId = SkuId\r | |
73 | self.UniFlag = UniFlag\r | |
74 | \r | |
75 | self.TargetTxt = BuildConfig\r | |
76 | self.ToolDef = ToolDefinition\r | |
77 | self.FdfFile = FlashDefinitionFile\r | |
78 | self.FdTargetList = Fds if Fds else []\r | |
79 | self.FvTargetList = Fvs if Fvs else []\r | |
80 | self.CapTargetList = Caps if Caps else []\r | |
81 | self.AutoGenObjectList = []\r | |
82 | self._GuidDict = {}\r | |
83 | \r | |
84 | # there's many relative directory operations, so ...\r | |
85 | os.chdir(self.WorkspaceDir)\r | |
86 | \r | |
87 | self.MergeArch()\r | |
88 | self.ValidateBuildTarget()\r | |
89 | \r | |
90 | EdkLogger.info("")\r | |
91 | if self.ArchList:\r | |
92 | EdkLogger.info('%-16s = %s' % ("Architecture(s)", ' '.join(self.ArchList)))\r | |
93 | EdkLogger.info('%-16s = %s' % ("Build target", self.BuildTarget))\r | |
94 | EdkLogger.info('%-16s = %s' % ("Toolchain", self.ToolChain))\r | |
95 | \r | |
96 | EdkLogger.info('\n%-24s = %s' % ("Active Platform", self.Platform))\r | |
97 | if BuildModule:\r | |
98 | EdkLogger.info('%-24s = %s' % ("Active Module", BuildModule))\r | |
99 | \r | |
100 | if self.FdfFile:\r | |
101 | EdkLogger.info('%-24s = %s' % ("Flash Image Definition", self.FdfFile))\r | |
102 | \r | |
103 | EdkLogger.verbose("\nFLASH_DEFINITION = %s" % self.FdfFile)\r | |
104 | \r | |
105 | if Progress:\r | |
106 | Progress.Start("\nProcessing meta-data")\r | |
107 | #\r | |
108 | # Mark now build in AutoGen Phase\r | |
109 | #\r | |
110 | GlobalData.gAutoGenPhase = True\r | |
111 | self.ProcessModuleFromPdf()\r | |
112 | self.ProcessPcdType()\r | |
113 | self.ProcessMixedPcd()\r | |
114 | self.VerifyPcdsFromFDF()\r | |
115 | self.CollectAllPcds()\r | |
673d09a2 FB |
116 | for Pa in self.AutoGenObjectList:\r |
117 | Pa.FillData_LibConstPcd()\r | |
e8449e1d FB |
118 | self.GeneratePkgLevelHash()\r |
119 | #\r | |
120 | # Check PCDs token value conflict in each DEC file.\r | |
121 | #\r | |
122 | self._CheckAllPcdsTokenValueConflict()\r | |
123 | #\r | |
124 | # Check PCD type and definition between DSC and DEC\r | |
125 | #\r | |
126 | self._CheckPcdDefineAndType()\r | |
127 | \r | |
128 | self.CreateBuildOptionsFile()\r | |
129 | self.CreatePcdTokenNumberFile()\r | |
130 | self.CreateModuleHashInfo()\r | |
e8449e1d FB |
131 | \r |
132 | #\r | |
133 | # Merge Arch\r | |
134 | #\r | |
135 | def MergeArch(self):\r | |
136 | if not self.ArchList:\r | |
137 | ArchList = set(self.Platform.SupArchList)\r | |
138 | else:\r | |
139 | ArchList = set(self.ArchList) & set(self.Platform.SupArchList)\r | |
140 | if not ArchList:\r | |
141 | EdkLogger.error("build", PARAMETER_INVALID,\r | |
142 | ExtraData = "Invalid ARCH specified. [Valid ARCH: %s]" % (" ".join(self.Platform.SupArchList)))\r | |
143 | elif self.ArchList and len(ArchList) != len(self.ArchList):\r | |
144 | SkippedArchList = set(self.ArchList).symmetric_difference(set(self.Platform.SupArchList))\r | |
145 | EdkLogger.verbose("\nArch [%s] is ignored because the platform supports [%s] only!"\r | |
146 | % (" ".join(SkippedArchList), " ".join(self.Platform.SupArchList)))\r | |
147 | self.ArchList = tuple(ArchList)\r | |
148 | \r | |
149 | # Validate build target\r | |
150 | def ValidateBuildTarget(self):\r | |
151 | if self.BuildTarget not in self.Platform.BuildTargets:\r | |
152 | EdkLogger.error("build", PARAMETER_INVALID,\r | |
153 | ExtraData="Build target [%s] is not supported by the platform. [Valid target: %s]"\r | |
154 | % (self.BuildTarget, " ".join(self.Platform.BuildTargets)))\r | |
155 | @cached_property\r | |
156 | def FdfProfile(self):\r | |
157 | if not self.FdfFile:\r | |
158 | self.FdfFile = self.Platform.FlashDefinition\r | |
159 | \r | |
160 | FdfProfile = None\r | |
161 | if self.FdfFile:\r | |
162 | Fdf = FdfParser(self.FdfFile.Path)\r | |
163 | Fdf.ParseFile()\r | |
164 | GlobalData.gFdfParser = Fdf\r | |
165 | if Fdf.CurrentFdName and Fdf.CurrentFdName in Fdf.Profile.FdDict:\r | |
166 | FdDict = Fdf.Profile.FdDict[Fdf.CurrentFdName]\r | |
167 | for FdRegion in FdDict.RegionList:\r | |
168 | if str(FdRegion.RegionType) is 'FILE' and self.Platform.VpdToolGuid in str(FdRegion.RegionDataList):\r | |
169 | if int(FdRegion.Offset) % 8 != 0:\r | |
170 | EdkLogger.error("build", FORMAT_INVALID, 'The VPD Base Address %s must be 8-byte aligned.' % (FdRegion.Offset))\r | |
171 | FdfProfile = Fdf.Profile\r | |
172 | else:\r | |
173 | if self.FdTargetList:\r | |
174 | EdkLogger.info("No flash definition file found. FD [%s] will be ignored." % " ".join(self.FdTargetList))\r | |
175 | self.FdTargetList = []\r | |
176 | if self.FvTargetList:\r | |
177 | EdkLogger.info("No flash definition file found. FV [%s] will be ignored." % " ".join(self.FvTargetList))\r | |
178 | self.FvTargetList = []\r | |
179 | if self.CapTargetList:\r | |
180 | EdkLogger.info("No flash definition file found. Capsule [%s] will be ignored." % " ".join(self.CapTargetList))\r | |
181 | self.CapTargetList = []\r | |
182 | \r | |
183 | return FdfProfile\r | |
184 | \r | |
185 | def ProcessModuleFromPdf(self):\r | |
186 | \r | |
187 | if self.FdfProfile:\r | |
188 | for fvname in self.FvTargetList:\r | |
189 | if fvname.upper() not in self.FdfProfile.FvDict:\r | |
190 | EdkLogger.error("build", OPTION_VALUE_INVALID,\r | |
191 | "No such an FV in FDF file: %s" % fvname)\r | |
192 | \r | |
193 | # In DSC file may use FILE_GUID to override the module, then in the Platform.Modules use FILE_GUIDmodule.inf as key,\r | |
194 | # but the path (self.MetaFile.Path) is the real path\r | |
195 | for key in self.FdfProfile.InfDict:\r | |
196 | if key == 'ArchTBD':\r | |
197 | MetaFile_cache = defaultdict(set)\r | |
198 | for Arch in self.ArchList:\r | |
199 | Current_Platform_cache = self.BuildDatabase[self.MetaFile, Arch, self.BuildTarget, self.ToolChain]\r | |
200 | for Pkey in Current_Platform_cache.Modules:\r | |
201 | MetaFile_cache[Arch].add(Current_Platform_cache.Modules[Pkey].MetaFile)\r | |
202 | for Inf in self.FdfProfile.InfDict[key]:\r | |
203 | ModuleFile = PathClass(NormPath(Inf), GlobalData.gWorkspace, Arch)\r | |
204 | for Arch in self.ArchList:\r | |
205 | if ModuleFile in MetaFile_cache[Arch]:\r | |
206 | break\r | |
207 | else:\r | |
208 | ModuleData = self.BuildDatabase[ModuleFile, Arch, self.BuildTarget, self.ToolChain]\r | |
209 | if not ModuleData.IsBinaryModule:\r | |
210 | EdkLogger.error('build', PARSER_ERROR, "Module %s NOT found in DSC file; Is it really a binary module?" % ModuleFile)\r | |
211 | \r | |
212 | else:\r | |
213 | for Arch in self.ArchList:\r | |
214 | if Arch == key:\r | |
215 | Platform = self.BuildDatabase[self.MetaFile, Arch, self.BuildTarget, self.ToolChain]\r | |
216 | MetaFileList = set()\r | |
217 | for Pkey in Platform.Modules:\r | |
218 | MetaFileList.add(Platform.Modules[Pkey].MetaFile)\r | |
219 | for Inf in self.FdfProfile.InfDict[key]:\r | |
220 | ModuleFile = PathClass(NormPath(Inf), GlobalData.gWorkspace, Arch)\r | |
221 | if ModuleFile in MetaFileList:\r | |
222 | continue\r | |
223 | ModuleData = self.BuildDatabase[ModuleFile, Arch, self.BuildTarget, self.ToolChain]\r | |
224 | if not ModuleData.IsBinaryModule:\r | |
225 | EdkLogger.error('build', PARSER_ERROR, "Module %s NOT found in DSC file; Is it really a binary module?" % ModuleFile)\r | |
226 | \r | |
227 | \r | |
228 | \r | |
229 | # parse FDF file to get PCDs in it, if any\r | |
230 | def VerifyPcdsFromFDF(self):\r | |
231 | \r | |
232 | if self.FdfProfile:\r | |
233 | PcdSet = self.FdfProfile.PcdDict\r | |
234 | self.VerifyPcdDeclearation(PcdSet)\r | |
235 | \r | |
236 | def ProcessPcdType(self):\r | |
237 | for Arch in self.ArchList:\r | |
238 | Platform = self.BuildDatabase[self.MetaFile, Arch, self.BuildTarget, self.ToolChain]\r | |
239 | Platform.Pcds\r | |
240 | # generate the SourcePcdDict and BinaryPcdDict\r | |
241 | Libs = []\r | |
242 | for BuildData in list(self.BuildDatabase._CACHE_.values()):\r | |
243 | if BuildData.Arch != Arch:\r | |
244 | continue\r | |
245 | if BuildData.MetaFile.Ext == '.inf' and str(BuildData) in Platform.Modules :\r | |
246 | Libs.extend(GetModuleLibInstances(BuildData, Platform,\r | |
247 | self.BuildDatabase,\r | |
248 | Arch,\r | |
249 | self.BuildTarget,\r | |
abc0155b FB |
250 | self.ToolChain,\r |
251 | self.Platform.MetaFile,\r | |
252 | EdkLogger\r | |
e8449e1d FB |
253 | ))\r |
254 | for BuildData in list(self.BuildDatabase._CACHE_.values()):\r | |
255 | if BuildData.Arch != Arch:\r | |
256 | continue\r | |
257 | if BuildData.MetaFile.Ext == '.inf':\r | |
258 | for key in BuildData.Pcds:\r | |
259 | if BuildData.Pcds[key].Pending:\r | |
260 | if key in Platform.Pcds:\r | |
261 | PcdInPlatform = Platform.Pcds[key]\r | |
262 | if PcdInPlatform.Type:\r | |
263 | BuildData.Pcds[key].Type = PcdInPlatform.Type\r | |
264 | BuildData.Pcds[key].Pending = False\r | |
265 | \r | |
266 | if BuildData.MetaFile in Platform.Modules:\r | |
267 | PlatformModule = Platform.Modules[str(BuildData.MetaFile)]\r | |
268 | if key in PlatformModule.Pcds:\r | |
269 | PcdInPlatform = PlatformModule.Pcds[key]\r | |
270 | if PcdInPlatform.Type:\r | |
271 | BuildData.Pcds[key].Type = PcdInPlatform.Type\r | |
272 | BuildData.Pcds[key].Pending = False\r | |
273 | else:\r | |
274 | #Pcd used in Library, Pcd Type from reference module if Pcd Type is Pending\r | |
275 | if BuildData.Pcds[key].Pending:\r | |
276 | if bool(BuildData.LibraryClass):\r | |
277 | if BuildData in set(Libs):\r | |
278 | ReferenceModules = BuildData.ReferenceModules\r | |
279 | for ReferenceModule in ReferenceModules:\r | |
280 | if ReferenceModule.MetaFile in Platform.Modules:\r | |
281 | RefPlatformModule = Platform.Modules[str(ReferenceModule.MetaFile)]\r | |
282 | if key in RefPlatformModule.Pcds:\r | |
283 | PcdInReferenceModule = RefPlatformModule.Pcds[key]\r | |
284 | if PcdInReferenceModule.Type:\r | |
285 | BuildData.Pcds[key].Type = PcdInReferenceModule.Type\r | |
286 | BuildData.Pcds[key].Pending = False\r | |
287 | break\r | |
288 | \r | |
289 | def ProcessMixedPcd(self):\r | |
290 | for Arch in self.ArchList:\r | |
291 | SourcePcdDict = {TAB_PCDS_DYNAMIC_EX:set(), TAB_PCDS_PATCHABLE_IN_MODULE:set(),TAB_PCDS_DYNAMIC:set(),TAB_PCDS_FIXED_AT_BUILD:set()}\r | |
292 | BinaryPcdDict = {TAB_PCDS_DYNAMIC_EX:set(), TAB_PCDS_PATCHABLE_IN_MODULE:set()}\r | |
293 | SourcePcdDict_Keys = SourcePcdDict.keys()\r | |
294 | BinaryPcdDict_Keys = BinaryPcdDict.keys()\r | |
295 | \r | |
296 | # generate the SourcePcdDict and BinaryPcdDict\r | |
297 | \r | |
298 | for BuildData in list(self.BuildDatabase._CACHE_.values()):\r | |
299 | if BuildData.Arch != Arch:\r | |
300 | continue\r | |
301 | if BuildData.MetaFile.Ext == '.inf':\r | |
302 | for key in BuildData.Pcds:\r | |
303 | if TAB_PCDS_DYNAMIC_EX in BuildData.Pcds[key].Type:\r | |
304 | if BuildData.IsBinaryModule:\r | |
305 | BinaryPcdDict[TAB_PCDS_DYNAMIC_EX].add((BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName))\r | |
306 | else:\r | |
307 | SourcePcdDict[TAB_PCDS_DYNAMIC_EX].add((BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName))\r | |
308 | \r | |
309 | elif TAB_PCDS_PATCHABLE_IN_MODULE in BuildData.Pcds[key].Type:\r | |
310 | if BuildData.MetaFile.Ext == '.inf':\r | |
311 | if BuildData.IsBinaryModule:\r | |
312 | BinaryPcdDict[TAB_PCDS_PATCHABLE_IN_MODULE].add((BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName))\r | |
313 | else:\r | |
314 | SourcePcdDict[TAB_PCDS_PATCHABLE_IN_MODULE].add((BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName))\r | |
315 | \r | |
316 | elif TAB_PCDS_DYNAMIC in BuildData.Pcds[key].Type:\r | |
317 | SourcePcdDict[TAB_PCDS_DYNAMIC].add((BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName))\r | |
318 | elif TAB_PCDS_FIXED_AT_BUILD in BuildData.Pcds[key].Type:\r | |
319 | SourcePcdDict[TAB_PCDS_FIXED_AT_BUILD].add((BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName))\r | |
320 | \r | |
321 | #\r | |
322 | # A PCD can only use one type for all source modules\r | |
323 | #\r | |
324 | for i in SourcePcdDict_Keys:\r | |
325 | for j in SourcePcdDict_Keys:\r | |
326 | if i != j:\r | |
327 | Intersections = SourcePcdDict[i].intersection(SourcePcdDict[j])\r | |
328 | if len(Intersections) > 0:\r | |
329 | EdkLogger.error(\r | |
330 | 'build',\r | |
331 | FORMAT_INVALID,\r | |
332 | "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 | |
333 | ExtraData='\n\t'.join(str(P[1]+'.'+P[0]) for P in Intersections)\r | |
334 | )\r | |
335 | \r | |
336 | #\r | |
337 | # intersection the BinaryPCD for Mixed PCD\r | |
338 | #\r | |
339 | for i in BinaryPcdDict_Keys:\r | |
340 | for j in BinaryPcdDict_Keys:\r | |
341 | if i != j:\r | |
342 | Intersections = BinaryPcdDict[i].intersection(BinaryPcdDict[j])\r | |
343 | for item in Intersections:\r | |
344 | NewPcd1 = (item[0] + '_' + i, item[1])\r | |
345 | NewPcd2 = (item[0] + '_' + j, item[1])\r | |
346 | if item not in GlobalData.MixedPcd:\r | |
347 | GlobalData.MixedPcd[item] = [NewPcd1, NewPcd2]\r | |
348 | else:\r | |
349 | if NewPcd1 not in GlobalData.MixedPcd[item]:\r | |
350 | GlobalData.MixedPcd[item].append(NewPcd1)\r | |
351 | if NewPcd2 not in GlobalData.MixedPcd[item]:\r | |
352 | GlobalData.MixedPcd[item].append(NewPcd2)\r | |
353 | \r | |
354 | #\r | |
355 | # intersection the SourcePCD and BinaryPCD for Mixed PCD\r | |
356 | #\r | |
357 | for i in SourcePcdDict_Keys:\r | |
358 | for j in BinaryPcdDict_Keys:\r | |
359 | if i != j:\r | |
360 | Intersections = SourcePcdDict[i].intersection(BinaryPcdDict[j])\r | |
361 | for item in Intersections:\r | |
362 | NewPcd1 = (item[0] + '_' + i, item[1])\r | |
363 | NewPcd2 = (item[0] + '_' + j, item[1])\r | |
364 | if item not in GlobalData.MixedPcd:\r | |
365 | GlobalData.MixedPcd[item] = [NewPcd1, NewPcd2]\r | |
366 | else:\r | |
367 | if NewPcd1 not in GlobalData.MixedPcd[item]:\r | |
368 | GlobalData.MixedPcd[item].append(NewPcd1)\r | |
369 | if NewPcd2 not in GlobalData.MixedPcd[item]:\r | |
370 | GlobalData.MixedPcd[item].append(NewPcd2)\r | |
371 | \r | |
372 | BuildData = self.BuildDatabase[self.MetaFile, Arch, self.BuildTarget, self.ToolChain]\r | |
373 | for key in BuildData.Pcds:\r | |
374 | for SinglePcd in GlobalData.MixedPcd:\r | |
375 | if (BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName) == SinglePcd:\r | |
376 | for item in GlobalData.MixedPcd[SinglePcd]:\r | |
377 | Pcd_Type = item[0].split('_')[-1]\r | |
378 | 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 | |
379 | (Pcd_Type == TAB_PCDS_DYNAMIC and BuildData.Pcds[key].Type in PCD_DYNAMIC_TYPE_SET):\r | |
380 | Value = BuildData.Pcds[key]\r | |
381 | Value.TokenCName = BuildData.Pcds[key].TokenCName + '_' + Pcd_Type\r | |
382 | if len(key) == 2:\r | |
383 | newkey = (Value.TokenCName, key[1])\r | |
384 | elif len(key) == 3:\r | |
385 | newkey = (Value.TokenCName, key[1], key[2])\r | |
386 | del BuildData.Pcds[key]\r | |
387 | BuildData.Pcds[newkey] = Value\r | |
388 | break\r | |
389 | break\r | |
390 | \r | |
391 | if self.FdfProfile:\r | |
392 | PcdSet = self.FdfProfile.PcdDict\r | |
393 | # handle the mixed pcd in FDF file\r | |
394 | for key in PcdSet:\r | |
395 | if key in GlobalData.MixedPcd:\r | |
396 | Value = PcdSet[key]\r | |
397 | del PcdSet[key]\r | |
398 | for item in GlobalData.MixedPcd[key]:\r | |
399 | PcdSet[item] = Value\r | |
400 | \r | |
401 | #Collect package set information from INF of FDF\r | |
402 | @cached_property\r | |
403 | def PkgSet(self):\r | |
404 | if not self.FdfFile:\r | |
405 | self.FdfFile = self.Platform.FlashDefinition\r | |
406 | \r | |
407 | if self.FdfFile:\r | |
408 | ModuleList = self.FdfProfile.InfList\r | |
409 | else:\r | |
410 | ModuleList = []\r | |
411 | Pkgs = {}\r | |
412 | for Arch in self.ArchList:\r | |
413 | Platform = self.BuildDatabase[self.MetaFile, Arch, self.BuildTarget, self.ToolChain]\r | |
414 | PkgSet = set()\r | |
415 | for mb in [self.BuildDatabase[m, Arch, self.BuildTarget, self.ToolChain] for m in Platform.Modules]:\r | |
416 | PkgSet.update(mb.Packages)\r | |
417 | for Inf in ModuleList:\r | |
418 | ModuleFile = PathClass(NormPath(Inf), GlobalData.gWorkspace, Arch)\r | |
419 | if ModuleFile in Platform.Modules:\r | |
420 | continue\r | |
421 | ModuleData = self.BuildDatabase[ModuleFile, Arch, self.BuildTarget, self.ToolChain]\r | |
422 | PkgSet.update(ModuleData.Packages)\r | |
423 | Pkgs[Arch] = list(PkgSet)\r | |
424 | return Pkgs\r | |
425 | \r | |
426 | def VerifyPcdDeclearation(self,PcdSet):\r | |
427 | for Arch in self.ArchList:\r | |
428 | Platform = self.BuildDatabase[self.MetaFile, Arch, self.BuildTarget, self.ToolChain]\r | |
429 | Pkgs = self.PkgSet[Arch]\r | |
430 | DecPcds = set()\r | |
431 | DecPcdsKey = set()\r | |
432 | for Pkg in Pkgs:\r | |
433 | for Pcd in Pkg.Pcds:\r | |
434 | DecPcds.add((Pcd[0], Pcd[1]))\r | |
435 | DecPcdsKey.add((Pcd[0], Pcd[1], Pcd[2]))\r | |
436 | \r | |
437 | Platform.SkuName = self.SkuId\r | |
438 | for Name, Guid,Fileds in PcdSet:\r | |
439 | if (Name, Guid) not in DecPcds:\r | |
440 | EdkLogger.error(\r | |
441 | 'build',\r | |
442 | PARSER_ERROR,\r | |
443 | "PCD (%s.%s) used in FDF is not declared in DEC files." % (Guid, Name),\r | |
444 | File = self.FdfProfile.PcdFileLineDict[Name, Guid, Fileds][0],\r | |
445 | Line = self.FdfProfile.PcdFileLineDict[Name, Guid, Fileds][1]\r | |
446 | )\r | |
447 | else:\r | |
448 | # Check whether Dynamic or DynamicEx PCD used in FDF file. If used, build break and give a error message.\r | |
449 | if (Name, Guid, TAB_PCDS_FIXED_AT_BUILD) in DecPcdsKey \\r | |
450 | or (Name, Guid, TAB_PCDS_PATCHABLE_IN_MODULE) in DecPcdsKey \\r | |
451 | or (Name, Guid, TAB_PCDS_FEATURE_FLAG) in DecPcdsKey:\r | |
452 | continue\r | |
453 | elif (Name, Guid, TAB_PCDS_DYNAMIC) in DecPcdsKey or (Name, Guid, TAB_PCDS_DYNAMIC_EX) in DecPcdsKey:\r | |
454 | EdkLogger.error(\r | |
455 | 'build',\r | |
456 | PARSER_ERROR,\r | |
457 | "Using Dynamic or DynamicEx type of PCD [%s.%s] in FDF file is not allowed." % (Guid, Name),\r | |
458 | File = self.FdfProfile.PcdFileLineDict[Name, Guid, Fileds][0],\r | |
459 | Line = self.FdfProfile.PcdFileLineDict[Name, Guid, Fileds][1]\r | |
460 | )\r | |
461 | def CollectAllPcds(self):\r | |
462 | \r | |
463 | for Arch in self.ArchList:\r | |
464 | Pa = PlatformAutoGen(self, self.MetaFile, self.BuildTarget, self.ToolChain, Arch)\r | |
465 | #\r | |
466 | # Explicitly collect platform's dynamic PCDs\r | |
467 | #\r | |
468 | Pa.CollectPlatformDynamicPcds()\r | |
469 | Pa.CollectFixedAtBuildPcds()\r | |
470 | self.AutoGenObjectList.append(Pa)\r | |
471 | # We need to calculate the PcdTokenNumber after all Arch Pcds are collected.\r | |
472 | for Arch in self.ArchList:\r | |
473 | #Pcd TokenNumber\r | |
474 | Pa = PlatformAutoGen(self, self.MetaFile, self.BuildTarget, self.ToolChain, Arch)\r | |
475 | self.UpdateModuleDataPipe(Arch, {"PCD_TNUM":Pa.PcdTokenNumber})\r | |
476 | \r | |
477 | def UpdateModuleDataPipe(self,arch, attr_dict):\r | |
478 | for (Target, Toolchain, Arch, MetaFile) in AutoGen.Cache():\r | |
479 | if Arch != arch:\r | |
480 | continue\r | |
481 | try:\r | |
482 | AutoGen.Cache()[(Target, Toolchain, Arch, MetaFile)].DataPipe.DataContainer = attr_dict\r | |
483 | except Exception:\r | |
484 | pass\r | |
485 | #\r | |
486 | # Generate Package level hash value\r | |
487 | #\r | |
488 | def GeneratePkgLevelHash(self):\r | |
489 | for Arch in self.ArchList:\r | |
490 | GlobalData.gPackageHash = {}\r | |
491 | if GlobalData.gUseHashCache:\r | |
492 | for Pkg in self.PkgSet[Arch]:\r | |
493 | self._GenPkgLevelHash(Pkg)\r | |
494 | \r | |
495 | \r | |
496 | def CreateBuildOptionsFile(self):\r | |
497 | #\r | |
498 | # Create BuildOptions Macro & PCD metafile, also add the Active Platform and FDF file.\r | |
499 | #\r | |
500 | content = 'gCommandLineDefines: '\r | |
501 | content += str(GlobalData.gCommandLineDefines)\r | |
502 | content += TAB_LINE_BREAK\r | |
503 | content += 'BuildOptionPcd: '\r | |
504 | content += str(GlobalData.BuildOptionPcd)\r | |
505 | content += TAB_LINE_BREAK\r | |
506 | content += 'Active Platform: '\r | |
507 | content += str(self.Platform)\r | |
508 | content += TAB_LINE_BREAK\r | |
509 | if self.FdfFile:\r | |
510 | content += 'Flash Image Definition: '\r | |
511 | content += str(self.FdfFile)\r | |
512 | content += TAB_LINE_BREAK\r | |
513 | SaveFileOnChange(os.path.join(self.BuildDir, 'BuildOptions'), content, False)\r | |
514 | \r | |
515 | def CreatePcdTokenNumberFile(self):\r | |
516 | #\r | |
517 | # Create PcdToken Number file for Dynamic/DynamicEx Pcd.\r | |
518 | #\r | |
519 | PcdTokenNumber = 'PcdTokenNumber: '\r | |
520 | Pa = self.AutoGenObjectList[0]\r | |
521 | if Pa.PcdTokenNumber:\r | |
522 | if Pa.DynamicPcdList:\r | |
523 | for Pcd in Pa.DynamicPcdList:\r | |
524 | PcdTokenNumber += TAB_LINE_BREAK\r | |
525 | PcdTokenNumber += str((Pcd.TokenCName, Pcd.TokenSpaceGuidCName))\r | |
526 | PcdTokenNumber += ' : '\r | |
527 | PcdTokenNumber += str(Pa.PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName])\r | |
528 | SaveFileOnChange(os.path.join(self.BuildDir, 'PcdTokenNumber'), PcdTokenNumber, False)\r | |
529 | \r | |
530 | def CreateModuleHashInfo(self):\r | |
531 | #\r | |
532 | # Get set of workspace metafiles\r | |
533 | #\r | |
534 | AllWorkSpaceMetaFiles = self._GetMetaFiles(self.BuildTarget, self.ToolChain)\r | |
535 | \r | |
536 | #\r | |
537 | # Retrieve latest modified time of all metafiles\r | |
538 | #\r | |
539 | SrcTimeStamp = 0\r | |
540 | for f in AllWorkSpaceMetaFiles:\r | |
541 | if os.stat(f)[8] > SrcTimeStamp:\r | |
542 | SrcTimeStamp = os.stat(f)[8]\r | |
543 | self._SrcTimeStamp = SrcTimeStamp\r | |
544 | \r | |
545 | if GlobalData.gUseHashCache:\r | |
546 | m = hashlib.md5()\r | |
547 | for files in AllWorkSpaceMetaFiles:\r | |
548 | if files.endswith('.dec'):\r | |
549 | continue\r | |
550 | f = open(files, 'rb')\r | |
551 | Content = f.read()\r | |
552 | f.close()\r | |
553 | m.update(Content)\r | |
554 | SaveFileOnChange(os.path.join(self.BuildDir, 'AutoGen.hash'), m.hexdigest(), False)\r | |
555 | GlobalData.gPlatformHash = m.hexdigest()\r | |
556 | \r | |
557 | #\r | |
558 | # Write metafile list to build directory\r | |
559 | #\r | |
560 | AutoGenFilePath = os.path.join(self.BuildDir, 'AutoGen')\r | |
561 | if os.path.exists (AutoGenFilePath):\r | |
562 | os.remove(AutoGenFilePath)\r | |
563 | if not os.path.exists(self.BuildDir):\r | |
564 | os.makedirs(self.BuildDir)\r | |
565 | with open(os.path.join(self.BuildDir, 'AutoGen'), 'w+') as file:\r | |
566 | for f in AllWorkSpaceMetaFiles:\r | |
567 | print(f, file=file)\r | |
568 | return True\r | |
569 | \r | |
570 | def _GenPkgLevelHash(self, Pkg):\r | |
571 | if Pkg.PackageName in GlobalData.gPackageHash:\r | |
572 | return\r | |
573 | \r | |
574 | PkgDir = os.path.join(self.BuildDir, Pkg.Arch, Pkg.PackageName)\r | |
575 | CreateDirectory(PkgDir)\r | |
576 | HashFile = os.path.join(PkgDir, Pkg.PackageName + '.hash')\r | |
577 | m = hashlib.md5()\r | |
578 | # Get .dec file's hash value\r | |
579 | f = open(Pkg.MetaFile.Path, 'rb')\r | |
580 | Content = f.read()\r | |
581 | f.close()\r | |
582 | m.update(Content)\r | |
583 | # Get include files hash value\r | |
584 | if Pkg.Includes:\r | |
585 | for inc in sorted(Pkg.Includes, key=lambda x: str(x)):\r | |
586 | for Root, Dirs, Files in os.walk(str(inc)):\r | |
587 | for File in sorted(Files):\r | |
588 | File_Path = os.path.join(Root, File)\r | |
589 | f = open(File_Path, 'rb')\r | |
590 | Content = f.read()\r | |
591 | f.close()\r | |
592 | m.update(Content)\r | |
593 | SaveFileOnChange(HashFile, m.hexdigest(), False)\r | |
594 | GlobalData.gPackageHash[Pkg.PackageName] = m.hexdigest()\r | |
595 | \r | |
596 | def _GetMetaFiles(self, Target, Toolchain):\r | |
597 | AllWorkSpaceMetaFiles = set()\r | |
598 | #\r | |
599 | # add fdf\r | |
600 | #\r | |
601 | if self.FdfFile:\r | |
602 | AllWorkSpaceMetaFiles.add (self.FdfFile.Path)\r | |
603 | for f in GlobalData.gFdfParser.GetAllIncludedFile():\r | |
604 | AllWorkSpaceMetaFiles.add (f.FileName)\r | |
605 | #\r | |
606 | # add dsc\r | |
607 | #\r | |
608 | AllWorkSpaceMetaFiles.add(self.MetaFile.Path)\r | |
609 | \r | |
610 | #\r | |
611 | # add build_rule.txt & tools_def.txt\r | |
612 | #\r | |
613 | AllWorkSpaceMetaFiles.add(os.path.join(GlobalData.gConfDirectory, gDefaultBuildRuleFile))\r | |
614 | AllWorkSpaceMetaFiles.add(os.path.join(GlobalData.gConfDirectory, gDefaultToolsDefFile))\r | |
615 | \r | |
616 | # add BuildOption metafile\r | |
617 | #\r | |
618 | AllWorkSpaceMetaFiles.add(os.path.join(self.BuildDir, 'BuildOptions'))\r | |
619 | \r | |
620 | # add PcdToken Number file for Dynamic/DynamicEx Pcd\r | |
621 | #\r | |
622 | AllWorkSpaceMetaFiles.add(os.path.join(self.BuildDir, 'PcdTokenNumber'))\r | |
623 | \r | |
624 | for Pa in self.AutoGenObjectList:\r | |
625 | AllWorkSpaceMetaFiles.add(Pa.ToolDefinitionFile)\r | |
626 | \r | |
627 | for Arch in self.ArchList:\r | |
628 | #\r | |
629 | # add dec\r | |
630 | #\r | |
631 | for Package in PlatformAutoGen(self, self.MetaFile, Target, Toolchain, Arch).PackageList:\r | |
632 | AllWorkSpaceMetaFiles.add(Package.MetaFile.Path)\r | |
633 | \r | |
634 | #\r | |
635 | # add included dsc\r | |
636 | #\r | |
637 | for filePath in self.BuildDatabase[self.MetaFile, Arch, Target, Toolchain]._RawData.IncludedFiles:\r | |
638 | AllWorkSpaceMetaFiles.add(filePath.Path)\r | |
639 | \r | |
640 | return AllWorkSpaceMetaFiles\r | |
641 | \r | |
642 | def _CheckPcdDefineAndType(self):\r | |
643 | PcdTypeSet = {TAB_PCDS_FIXED_AT_BUILD,\r | |
644 | TAB_PCDS_PATCHABLE_IN_MODULE,\r | |
645 | TAB_PCDS_FEATURE_FLAG,\r | |
646 | TAB_PCDS_DYNAMIC,\r | |
647 | TAB_PCDS_DYNAMIC_EX}\r | |
648 | \r | |
649 | # This dict store PCDs which are not used by any modules with specified arches\r | |
650 | UnusedPcd = OrderedDict()\r | |
651 | for Pa in self.AutoGenObjectList:\r | |
652 | # Key of DSC's Pcds dictionary is PcdCName, TokenSpaceGuid\r | |
653 | for Pcd in Pa.Platform.Pcds:\r | |
654 | PcdType = Pa.Platform.Pcds[Pcd].Type\r | |
655 | \r | |
656 | # If no PCD type, this PCD comes from FDF\r | |
657 | if not PcdType:\r | |
658 | continue\r | |
659 | \r | |
660 | # Try to remove Hii and Vpd suffix\r | |
661 | if PcdType.startswith(TAB_PCDS_DYNAMIC_EX):\r | |
662 | PcdType = TAB_PCDS_DYNAMIC_EX\r | |
663 | elif PcdType.startswith(TAB_PCDS_DYNAMIC):\r | |
664 | PcdType = TAB_PCDS_DYNAMIC\r | |
665 | \r | |
666 | for Package in Pa.PackageList:\r | |
667 | # Key of DEC's Pcds dictionary is PcdCName, TokenSpaceGuid, PcdType\r | |
668 | if (Pcd[0], Pcd[1], PcdType) in Package.Pcds:\r | |
669 | break\r | |
670 | for Type in PcdTypeSet:\r | |
671 | if (Pcd[0], Pcd[1], Type) in Package.Pcds:\r | |
672 | EdkLogger.error(\r | |
673 | 'build',\r | |
674 | FORMAT_INVALID,\r | |
675 | "Type [%s] of PCD [%s.%s] in DSC file doesn't match the type [%s] defined in DEC file." \\r | |
676 | % (Pa.Platform.Pcds[Pcd].Type, Pcd[1], Pcd[0], Type),\r | |
677 | ExtraData=None\r | |
678 | )\r | |
679 | return\r | |
680 | else:\r | |
681 | UnusedPcd.setdefault(Pcd, []).append(Pa.Arch)\r | |
682 | \r | |
683 | for Pcd in UnusedPcd:\r | |
684 | EdkLogger.warn(\r | |
685 | 'build',\r | |
686 | "The PCD was not specified by any INF module in the platform for the given architecture.\n"\r | |
687 | "\tPCD: [%s.%s]\n\tPlatform: [%s]\n\tArch: %s"\r | |
688 | % (Pcd[1], Pcd[0], os.path.basename(str(self.MetaFile)), str(UnusedPcd[Pcd])),\r | |
689 | ExtraData=None\r | |
690 | )\r | |
691 | \r | |
692 | def __repr__(self):\r | |
693 | return "%s [%s]" % (self.MetaFile, ", ".join(self.ArchList))\r | |
694 | \r | |
695 | ## Return the directory to store FV files\r | |
696 | @cached_property\r | |
697 | def FvDir(self):\r | |
698 | return path.join(self.BuildDir, TAB_FV_DIRECTORY)\r | |
699 | \r | |
700 | ## Return the directory to store all intermediate and final files built\r | |
701 | @cached_property\r | |
702 | def BuildDir(self):\r | |
703 | return self.AutoGenObjectList[0].BuildDir\r | |
704 | \r | |
705 | ## Return the build output directory platform specifies\r | |
706 | @cached_property\r | |
707 | def OutputDir(self):\r | |
708 | return self.Platform.OutputDirectory\r | |
709 | \r | |
710 | ## Return platform name\r | |
711 | @cached_property\r | |
712 | def Name(self):\r | |
713 | return self.Platform.PlatformName\r | |
714 | \r | |
715 | ## Return meta-file GUID\r | |
716 | @cached_property\r | |
717 | def Guid(self):\r | |
718 | return self.Platform.Guid\r | |
719 | \r | |
720 | ## Return platform version\r | |
721 | @cached_property\r | |
722 | def Version(self):\r | |
723 | return self.Platform.Version\r | |
724 | \r | |
725 | ## Return paths of tools\r | |
726 | @cached_property\r | |
727 | def ToolDefinition(self):\r | |
728 | return self.AutoGenObjectList[0].ToolDefinition\r | |
729 | \r | |
730 | ## Return directory of platform makefile\r | |
731 | #\r | |
732 | # @retval string Makefile directory\r | |
733 | #\r | |
734 | @cached_property\r | |
735 | def MakeFileDir(self):\r | |
736 | return self.BuildDir\r | |
737 | \r | |
738 | ## Return build command string\r | |
739 | #\r | |
740 | # @retval string Build command string\r | |
741 | #\r | |
742 | @cached_property\r | |
743 | def BuildCommand(self):\r | |
744 | # BuildCommand should be all the same. So just get one from platform AutoGen\r | |
745 | return self.AutoGenObjectList[0].BuildCommand\r | |
746 | \r | |
747 | ## Check the PCDs token value conflict in each DEC file.\r | |
748 | #\r | |
749 | # Will cause build break and raise error message while two PCDs conflict.\r | |
750 | #\r | |
751 | # @return None\r | |
752 | #\r | |
753 | def _CheckAllPcdsTokenValueConflict(self):\r | |
754 | for Pa in self.AutoGenObjectList:\r | |
755 | for Package in Pa.PackageList:\r | |
756 | PcdList = list(Package.Pcds.values())\r | |
757 | PcdList.sort(key=lambda x: int(x.TokenValue, 0))\r | |
758 | Count = 0\r | |
759 | while (Count < len(PcdList) - 1) :\r | |
760 | Item = PcdList[Count]\r | |
761 | ItemNext = PcdList[Count + 1]\r | |
762 | #\r | |
763 | # Make sure in the same token space the TokenValue should be unique\r | |
764 | #\r | |
765 | if (int(Item.TokenValue, 0) == int(ItemNext.TokenValue, 0)):\r | |
766 | SameTokenValuePcdList = []\r | |
767 | SameTokenValuePcdList.append(Item)\r | |
768 | SameTokenValuePcdList.append(ItemNext)\r | |
769 | RemainPcdListLength = len(PcdList) - Count - 2\r | |
770 | for ValueSameCount in range(RemainPcdListLength):\r | |
771 | if int(PcdList[len(PcdList) - RemainPcdListLength + ValueSameCount].TokenValue, 0) == int(Item.TokenValue, 0):\r | |
772 | SameTokenValuePcdList.append(PcdList[len(PcdList) - RemainPcdListLength + ValueSameCount])\r | |
773 | else:\r | |
774 | break;\r | |
775 | #\r | |
776 | # Sort same token value PCD list with TokenGuid and TokenCName\r | |
777 | #\r | |
778 | SameTokenValuePcdList.sort(key=lambda x: "%s.%s" % (x.TokenSpaceGuidCName, x.TokenCName))\r | |
779 | SameTokenValuePcdListCount = 0\r | |
780 | while (SameTokenValuePcdListCount < len(SameTokenValuePcdList) - 1):\r | |
781 | Flag = False\r | |
782 | TemListItem = SameTokenValuePcdList[SameTokenValuePcdListCount]\r | |
783 | TemListItemNext = SameTokenValuePcdList[SameTokenValuePcdListCount + 1]\r | |
784 | \r | |
785 | if (TemListItem.TokenSpaceGuidCName == TemListItemNext.TokenSpaceGuidCName) and (TemListItem.TokenCName != TemListItemNext.TokenCName):\r | |
786 | for PcdItem in GlobalData.MixedPcd:\r | |
787 | if (TemListItem.TokenCName, TemListItem.TokenSpaceGuidCName) in GlobalData.MixedPcd[PcdItem] or \\r | |
788 | (TemListItemNext.TokenCName, TemListItemNext.TokenSpaceGuidCName) in GlobalData.MixedPcd[PcdItem]:\r | |
789 | Flag = True\r | |
790 | if not Flag:\r | |
791 | EdkLogger.error(\r | |
792 | 'build',\r | |
793 | FORMAT_INVALID,\r | |
794 | "The TokenValue [%s] of PCD [%s.%s] is conflict with: [%s.%s] in %s"\\r | |
795 | % (TemListItem.TokenValue, TemListItem.TokenSpaceGuidCName, TemListItem.TokenCName, TemListItemNext.TokenSpaceGuidCName, TemListItemNext.TokenCName, Package),\r | |
796 | ExtraData=None\r | |
797 | )\r | |
798 | SameTokenValuePcdListCount += 1\r | |
799 | Count += SameTokenValuePcdListCount\r | |
800 | Count += 1\r | |
801 | \r | |
802 | PcdList = list(Package.Pcds.values())\r | |
803 | PcdList.sort(key=lambda x: "%s.%s" % (x.TokenSpaceGuidCName, x.TokenCName))\r | |
804 | Count = 0\r | |
805 | while (Count < len(PcdList) - 1) :\r | |
806 | Item = PcdList[Count]\r | |
807 | ItemNext = PcdList[Count + 1]\r | |
808 | #\r | |
809 | # Check PCDs with same TokenSpaceGuidCName.TokenCName have same token value as well.\r | |
810 | #\r | |
811 | if (Item.TokenSpaceGuidCName == ItemNext.TokenSpaceGuidCName) and (Item.TokenCName == ItemNext.TokenCName) and (int(Item.TokenValue, 0) != int(ItemNext.TokenValue, 0)):\r | |
812 | EdkLogger.error(\r | |
813 | 'build',\r | |
814 | FORMAT_INVALID,\r | |
815 | "The TokenValue [%s] of PCD [%s.%s] in %s defined in two places should be same as well."\\r | |
816 | % (Item.TokenValue, Item.TokenSpaceGuidCName, Item.TokenCName, Package),\r | |
817 | ExtraData=None\r | |
818 | )\r | |
819 | Count += 1\r | |
820 | ## Generate fds command\r | |
821 | @property\r | |
822 | def GenFdsCommand(self):\r | |
823 | return (GenMake.TopLevelMakefile(self)._TEMPLATE_.Replace(GenMake.TopLevelMakefile(self)._TemplateDict)).strip()\r | |
824 | \r | |
825 | @property\r | |
826 | def GenFdsCommandDict(self):\r | |
827 | FdsCommandDict = {}\r | |
828 | LogLevel = EdkLogger.GetLevel()\r | |
829 | if LogLevel == EdkLogger.VERBOSE:\r | |
830 | FdsCommandDict["verbose"] = True\r | |
831 | elif LogLevel <= EdkLogger.DEBUG_9:\r | |
832 | FdsCommandDict["debug"] = LogLevel - 1\r | |
833 | elif LogLevel == EdkLogger.QUIET:\r | |
834 | FdsCommandDict["quiet"] = True\r | |
835 | \r | |
7809492c | 836 | FdsCommandDict["GenfdsMultiThread"] = GlobalData.gEnableGenfdsMultiThread\r |
e8449e1d FB |
837 | if GlobalData.gIgnoreSource:\r |
838 | FdsCommandDict["IgnoreSources"] = True\r | |
839 | \r | |
840 | FdsCommandDict["OptionPcd"] = []\r | |
841 | for pcd in GlobalData.BuildOptionPcd:\r | |
842 | if pcd[2]:\r | |
843 | pcdname = '.'.join(pcd[0:3])\r | |
844 | else:\r | |
845 | pcdname = '.'.join(pcd[0:2])\r | |
846 | if pcd[3].startswith('{'):\r | |
847 | FdsCommandDict["OptionPcd"].append(pcdname + '=' + 'H' + '"' + pcd[3] + '"')\r | |
848 | else:\r | |
849 | FdsCommandDict["OptionPcd"].append(pcdname + '=' + pcd[3])\r | |
850 | \r | |
851 | MacroList = []\r | |
852 | # macros passed to GenFds\r | |
853 | MacroDict = {}\r | |
854 | MacroDict.update(GlobalData.gGlobalDefines)\r | |
855 | MacroDict.update(GlobalData.gCommandLineDefines)\r | |
856 | for MacroName in MacroDict:\r | |
857 | if MacroDict[MacroName] != "":\r | |
858 | MacroList.append('"%s=%s"' % (MacroName, MacroDict[MacroName].replace('\\', '\\\\')))\r | |
859 | else:\r | |
860 | MacroList.append('"%s"' % MacroName)\r | |
861 | FdsCommandDict["macro"] = MacroList\r | |
862 | \r | |
863 | FdsCommandDict["fdf_file"] = [self.FdfFile]\r | |
864 | FdsCommandDict["build_target"] = self.BuildTarget\r | |
865 | FdsCommandDict["toolchain_tag"] = self.ToolChain\r | |
866 | FdsCommandDict["active_platform"] = str(self)\r | |
867 | \r | |
868 | FdsCommandDict["conf_directory"] = GlobalData.gConfDirectory\r | |
869 | FdsCommandDict["build_architecture_list"] = ','.join(self.ArchList)\r | |
870 | FdsCommandDict["platform_build_directory"] = self.BuildDir\r | |
871 | \r | |
872 | FdsCommandDict["fd"] = self.FdTargetList\r | |
873 | FdsCommandDict["fv"] = self.FvTargetList\r | |
874 | FdsCommandDict["cap"] = self.CapTargetList\r | |
875 | return FdsCommandDict\r | |
876 | \r | |
877 | ## Create makefile for the platform and modules in it\r | |
878 | #\r | |
879 | # @param CreateDepsMakeFile Flag indicating if the makefile for\r | |
880 | # modules will be created as well\r | |
881 | #\r | |
882 | def CreateMakeFile(self, CreateDepsMakeFile=False):\r | |
883 | if not CreateDepsMakeFile:\r | |
884 | return\r | |
885 | for Pa in self.AutoGenObjectList:\r | |
673d09a2 | 886 | Pa.CreateMakeFile(CreateDepsMakeFile)\r |
e8449e1d FB |
887 | \r |
888 | ## Create autogen code for platform and modules\r | |
889 | #\r | |
890 | # Since there's no autogen code for platform, this method will do nothing\r | |
891 | # if CreateModuleCodeFile is set to False.\r | |
892 | #\r | |
893 | # @param CreateDepsCodeFile Flag indicating if creating module's\r | |
894 | # autogen code file or not\r | |
895 | #\r | |
896 | def CreateCodeFile(self, CreateDepsCodeFile=False):\r | |
897 | if not CreateDepsCodeFile:\r | |
898 | return\r | |
899 | for Pa in self.AutoGenObjectList:\r | |
673d09a2 | 900 | Pa.CreateCodeFile(CreateDepsCodeFile)\r |
e8449e1d FB |
901 | \r |
902 | ## Create AsBuilt INF file the platform\r | |
903 | #\r | |
904 | def CreateAsBuiltInf(self):\r | |
905 | return\r | |
906 | \r |