]>
Commit | Line | Data |
---|---|---|
f51461c8 LG |
1 | ## @file\r |
2 | # Global variables for GenFds\r | |
3 | #\r | |
ab957f03 | 4 | # Copyright (c) 2007 - 2021, Intel Corporation. All rights reserved.<BR>\r |
f51461c8 | 5 | #\r |
2e351cbe | 6 | # SPDX-License-Identifier: BSD-2-Clause-Patent\r |
f51461c8 LG |
7 | #\r |
8 | \r | |
9 | ##\r | |
10 | # Import Modules\r | |
11 | #\r | |
1ccc4d89 | 12 | from __future__ import print_function\r |
9e47e6f9 CJ |
13 | from __future__ import absolute_import\r |
14 | \r | |
1be2ed90 | 15 | import Common.LongFilePathOs as os\r |
a1f94045 | 16 | import sys\r |
9e47e6f9 CJ |
17 | from sys import stdout\r |
18 | from subprocess import PIPE,Popen\r | |
19 | from struct import Struct\r | |
20 | from array import array\r | |
f51461c8 | 21 | \r |
9e47e6f9 | 22 | from Common.BuildToolError import COMMAND_FAILURE,GENFDS_ERROR\r |
f51461c8 LG |
23 | from Common import EdkLogger\r |
24 | from Common.Misc import SaveFileOnChange\r | |
25 | \r | |
4465cd12 FZ |
26 | from Common.TargetTxtClassObject import TargetTxtDict\r |
27 | from Common.ToolDefClassObject import ToolDefDict\r | |
28 | from AutoGen.BuildEngine import ToolBuildRule\r | |
f51461c8 | 29 | import Common.DataType as DataType\r |
20b292d0 | 30 | from Common.Misc import PathClass,CreateDirectory\r |
1be2ed90 | 31 | from Common.LongFilePathSupport import OpenLongFilePath as open\r |
05cc51ad | 32 | from Common.MultipleWorkspace import MultipleWorkspace as mws\r |
b1e27d17 | 33 | import Common.GlobalData as GlobalData\r |
20b292d0 | 34 | from Common.BuildToolError import *\r |
ef3840c1 | 35 | from AutoGen.AutoGen import CalculatePriorityValue\r |
f51461c8 LG |
36 | \r |
37 | ## Global variables\r | |
38 | #\r | |
39 | #\r | |
40 | class GenFdsGlobalVariable:\r | |
41 | FvDir = ''\r | |
42 | OutputDirDict = {}\r | |
43 | BinDir = ''\r | |
44 | # will be FvDir + os.sep + 'Ffs'\r | |
45 | FfsDir = ''\r | |
46 | FdfParser = None\r | |
47 | LibDir = ''\r | |
48 | WorkSpace = None\r | |
49 | WorkSpaceDir = ''\r | |
97fa0ee9 | 50 | ConfDir = ''\r |
f51461c8 LG |
51 | OutputDirFromDscDict = {}\r |
52 | TargetName = ''\r | |
53 | ToolChainTag = ''\r | |
54 | RuleDict = {}\r | |
55 | ArchList = None\r | |
f51461c8 LG |
56 | ActivePlatform = None\r |
57 | FvAddressFileName = ''\r | |
58 | VerboseMode = False\r | |
59 | DebugLevel = -1\r | |
60 | SharpCounter = 0\r | |
61 | SharpNumberPerLine = 40\r | |
62 | FdfFile = ''\r | |
63 | FdfFileTimeStamp = 0\r | |
64 | FixedLoadAddress = False\r | |
65 | PlatformName = ''\r | |
f7496d71 | 66 | \r |
94c04559 CJ |
67 | BuildRuleFamily = DataType.TAB_COMPILER_MSFT\r |
68 | ToolChainFamily = DataType.TAB_COMPILER_MSFT\r | |
f51461c8 | 69 | __BuildRuleDatabase = None\r |
213ae077 | 70 | GuidToolDefinition = {}\r |
37de70b7 YZ |
71 | FfsCmdDict = {}\r |
72 | SecCmdList = []\r | |
73 | CopyList = []\r | |
74 | ModuleFile = ''\r | |
7809492c | 75 | EnableGenfdsMultiThread = True\r |
f7496d71 | 76 | \r |
f51461c8 LG |
77 | #\r |
78 | # The list whose element are flags to indicate if large FFS or SECTION files exist in FV.\r | |
79 | # At the beginning of each generation of FV, false flag is appended to the list,\r | |
80 | # after the call to GenerateSection returns, check the size of the output file,\r | |
81 | # if it is greater than 0xFFFFFF, the tail flag in list is set to true,\r | |
82 | # and EFI_FIRMWARE_FILE_SYSTEM3_GUID is passed to C GenFv.\r | |
83 | # At the end of generation of FV, pop the flag.\r | |
84 | # List is used as a stack to handle nested FV generation.\r | |
85 | #\r | |
86 | LargeFileInFvFlags = []\r | |
87 | EFI_FIRMWARE_FILE_SYSTEM3_GUID = '5473C07A-3DCB-4dca-BD6F-1E9689E7349A'\r | |
88 | LARGE_FILE_SIZE = 0x1000000\r | |
89 | \r | |
9e47e6f9 | 90 | SectionHeader = Struct("3B 1B")\r |
f7496d71 | 91 | \r |
7de00838 GL |
92 | # FvName, FdName, CapName in FDF, Image file name\r |
93 | ImageBinDict = {}\r | |
94 | \r | |
f51461c8 LG |
95 | ## LoadBuildRule\r |
96 | #\r | |
97 | @staticmethod\r | |
9e47e6f9 | 98 | def _LoadBuildRule():\r |
f51461c8 LG |
99 | if GenFdsGlobalVariable.__BuildRuleDatabase:\r |
100 | return GenFdsGlobalVariable.__BuildRuleDatabase\r | |
4465cd12 FZ |
101 | BuildRule = ToolBuildRule()\r |
102 | GenFdsGlobalVariable.__BuildRuleDatabase = BuildRule.ToolBuildRule\r | |
103 | TargetObj = TargetTxtDict()\r | |
104 | ToolDefinitionFile = TargetObj.Target.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF]\r | |
db01c8e3 FB |
105 | if ToolDefinitionFile == '':\r |
106 | ToolDefinitionFile = "Conf/tools_def.txt"\r | |
107 | if os.path.isfile(ToolDefinitionFile):\r | |
4465cd12 FZ |
108 | ToolDefObj = ToolDefDict((os.path.join(os.getenv("WORKSPACE"), "Conf")))\r |
109 | ToolDefinition = ToolDefObj.ToolDef.ToolsDefTxtDatabase\r | |
db01c8e3 FB |
110 | if DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY in ToolDefinition \\r |
111 | and GenFdsGlobalVariable.ToolChainTag in ToolDefinition[DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY] \\r | |
112 | and ToolDefinition[DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY][GenFdsGlobalVariable.ToolChainTag]:\r | |
113 | GenFdsGlobalVariable.BuildRuleFamily = ToolDefinition[DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY][GenFdsGlobalVariable.ToolChainTag]\r | |
114 | \r | |
115 | if DataType.TAB_TOD_DEFINES_FAMILY in ToolDefinition \\r | |
116 | and GenFdsGlobalVariable.ToolChainTag in ToolDefinition[DataType.TAB_TOD_DEFINES_FAMILY] \\r | |
117 | and ToolDefinition[DataType.TAB_TOD_DEFINES_FAMILY][GenFdsGlobalVariable.ToolChainTag]:\r | |
118 | GenFdsGlobalVariable.ToolChainFamily = ToolDefinition[DataType.TAB_TOD_DEFINES_FAMILY][GenFdsGlobalVariable.ToolChainTag]\r | |
f51461c8 LG |
119 | return GenFdsGlobalVariable.__BuildRuleDatabase\r |
120 | \r | |
121 | ## GetBuildRules\r | |
122 | # @param Inf: object of InfBuildData\r | |
123 | # @param Arch: current arch\r | |
124 | #\r | |
125 | @staticmethod\r | |
126 | def GetBuildRules(Inf, Arch):\r | |
127 | if not Arch:\r | |
55c84777 | 128 | Arch = DataType.TAB_COMMON\r |
f51461c8 LG |
129 | \r |
130 | if not Arch in GenFdsGlobalVariable.OutputDirDict:\r | |
131 | return {}\r | |
132 | \r | |
9e47e6f9 | 133 | BuildRuleDatabase = GenFdsGlobalVariable._LoadBuildRule()\r |
f51461c8 LG |
134 | if not BuildRuleDatabase:\r |
135 | return {}\r | |
136 | \r | |
137 | PathClassObj = PathClass(Inf.MetaFile.File,\r | |
138 | GenFdsGlobalVariable.WorkSpaceDir)\r | |
f51461c8 LG |
139 | BuildDir = os.path.join(\r |
140 | GenFdsGlobalVariable.OutputDirDict[Arch],\r | |
141 | Arch,\r | |
142 | PathClassObj.SubDir,\r | |
143 | PathClassObj.BaseName\r | |
144 | )\r | |
9e47e6f9 CJ |
145 | BinDir = os.path.join(GenFdsGlobalVariable.OutputDirDict[Arch], Arch)\r |
146 | Macro = {\r | |
147 | "WORKSPACE":GenFdsGlobalVariable.WorkSpaceDir,\r | |
148 | "MODULE_NAME":Inf.BaseName,\r | |
149 | "MODULE_GUID":Inf.Guid,\r | |
150 | "MODULE_VERSION":Inf.Version,\r | |
151 | "MODULE_TYPE":Inf.ModuleType,\r | |
152 | "MODULE_FILE":str(PathClassObj),\r | |
153 | "MODULE_FILE_BASE_NAME":PathClassObj.BaseName,\r | |
154 | "MODULE_RELATIVE_DIR":PathClassObj.SubDir,\r | |
155 | "MODULE_DIR":PathClassObj.SubDir,\r | |
156 | "BASE_NAME":Inf.BaseName,\r | |
157 | "ARCH":Arch,\r | |
158 | "TOOLCHAIN":GenFdsGlobalVariable.ToolChainTag,\r | |
159 | "TOOLCHAIN_TAG":GenFdsGlobalVariable.ToolChainTag,\r | |
160 | "TOOL_CHAIN_TAG":GenFdsGlobalVariable.ToolChainTag,\r | |
161 | "TARGET":GenFdsGlobalVariable.TargetName,\r | |
162 | "BUILD_DIR":GenFdsGlobalVariable.OutputDirDict[Arch],\r | |
163 | "BIN_DIR":BinDir,\r | |
164 | "LIB_DIR":BinDir,\r | |
165 | "MODULE_BUILD_DIR":BuildDir,\r | |
166 | "OUTPUT_DIR":os.path.join(BuildDir, "OUTPUT"),\r | |
167 | "DEBUG_DIR":os.path.join(BuildDir, "DEBUG")\r | |
168 | }\r | |
0deca401 | 169 | \r |
f51461c8 LG |
170 | BuildRules = {}\r |
171 | for Type in BuildRuleDatabase.FileTypeList:\r | |
172 | #first try getting build rule by BuildRuleFamily\r | |
173 | RuleObject = BuildRuleDatabase[Type, Inf.BuildType, Arch, GenFdsGlobalVariable.BuildRuleFamily]\r | |
174 | if not RuleObject:\r | |
175 | # build type is always module type, but ...\r | |
176 | if Inf.ModuleType != Inf.BuildType:\r | |
177 | RuleObject = BuildRuleDatabase[Type, Inf.ModuleType, Arch, GenFdsGlobalVariable.BuildRuleFamily]\r | |
178 | #second try getting build rule by ToolChainFamily\r | |
179 | if not RuleObject:\r | |
180 | RuleObject = BuildRuleDatabase[Type, Inf.BuildType, Arch, GenFdsGlobalVariable.ToolChainFamily]\r | |
181 | if not RuleObject:\r | |
182 | # build type is always module type, but ...\r | |
183 | if Inf.ModuleType != Inf.BuildType:\r | |
184 | RuleObject = BuildRuleDatabase[Type, Inf.ModuleType, Arch, GenFdsGlobalVariable.ToolChainFamily]\r | |
185 | if not RuleObject:\r | |
186 | continue\r | |
187 | RuleObject = RuleObject.Instantiate(Macro)\r | |
188 | BuildRules[Type] = RuleObject\r | |
189 | for Ext in RuleObject.SourceFileExtList:\r | |
190 | BuildRules[Ext] = RuleObject\r | |
191 | return BuildRules\r | |
192 | \r | |
193 | ## GetModuleCodaTargetList\r | |
194 | #\r | |
195 | # @param Inf: object of InfBuildData\r | |
196 | # @param Arch: current arch\r | |
197 | #\r | |
198 | @staticmethod\r | |
199 | def GetModuleCodaTargetList(Inf, Arch):\r | |
200 | BuildRules = GenFdsGlobalVariable.GetBuildRules(Inf, Arch)\r | |
201 | if not BuildRules:\r | |
202 | return []\r | |
203 | \r | |
204 | TargetList = set()\r | |
205 | FileList = []\r | |
97fa0ee9 YL |
206 | \r |
207 | if not Inf.IsBinaryModule:\r | |
208 | for File in Inf.Sources:\r | |
bc39c5cb JC |
209 | if File.TagName in {"", DataType.TAB_STAR, GenFdsGlobalVariable.ToolChainTag} and \\r |
210 | File.ToolChainFamily in {"", DataType.TAB_STAR, GenFdsGlobalVariable.ToolChainFamily}:\r | |
97fa0ee9 YL |
211 | FileList.append((File, DataType.TAB_UNKNOWN_FILE))\r |
212 | \r | |
f51461c8 | 213 | for File in Inf.Binaries:\r |
bc39c5cb | 214 | if File.Target in {DataType.TAB_COMMON, DataType.TAB_STAR, GenFdsGlobalVariable.TargetName}:\r |
f51461c8 LG |
215 | FileList.append((File, File.Type))\r |
216 | \r | |
217 | for File, FileType in FileList:\r | |
218 | LastTarget = None\r | |
219 | RuleChain = []\r | |
220 | SourceList = [File]\r | |
221 | Index = 0\r | |
222 | while Index < len(SourceList):\r | |
223 | Source = SourceList[Index]\r | |
224 | Index = Index + 1\r | |
f7496d71 | 225 | \r |
9e47e6f9 | 226 | if File.IsBinary and File == Source and Inf.Binaries and File in Inf.Binaries:\r |
f51461c8 LG |
227 | # Skip all files that are not binary libraries\r |
228 | if not Inf.LibraryClass:\r | |
f7496d71 | 229 | continue\r |
f51461c8 LG |
230 | RuleObject = BuildRules[DataType.TAB_DEFAULT_BINARY_FILE]\r |
231 | elif FileType in BuildRules:\r | |
232 | RuleObject = BuildRules[FileType]\r | |
233 | elif Source.Ext in BuildRules:\r | |
234 | RuleObject = BuildRules[Source.Ext]\r | |
235 | else:\r | |
236 | # stop at no more rules\r | |
237 | if LastTarget:\r | |
238 | TargetList.add(str(LastTarget))\r | |
239 | break\r | |
f7496d71 | 240 | \r |
f51461c8 | 241 | FileType = RuleObject.SourceFileType\r |
f7496d71 | 242 | \r |
f51461c8 LG |
243 | # stop at STATIC_LIBRARY for library\r |
244 | if Inf.LibraryClass and FileType == DataType.TAB_STATIC_LIBRARY:\r | |
245 | if LastTarget:\r | |
246 | TargetList.add(str(LastTarget))\r | |
247 | break\r | |
f7496d71 | 248 | \r |
f51461c8 LG |
249 | Target = RuleObject.Apply(Source)\r |
250 | if not Target:\r | |
251 | if LastTarget:\r | |
252 | TargetList.add(str(LastTarget))\r | |
253 | break\r | |
254 | elif not Target.Outputs:\r | |
255 | # Only do build for target with outputs\r | |
256 | TargetList.add(str(Target))\r | |
f7496d71 | 257 | \r |
f51461c8 LG |
258 | # to avoid cyclic rule\r |
259 | if FileType in RuleChain:\r | |
260 | break\r | |
f7496d71 | 261 | \r |
f51461c8 LG |
262 | RuleChain.append(FileType)\r |
263 | SourceList.extend(Target.Outputs)\r | |
264 | LastTarget = Target\r | |
265 | FileType = DataType.TAB_UNKNOWN_FILE\r | |
37de70b7 YZ |
266 | for Cmd in Target.Commands:\r |
267 | if "$(CP)" == Cmd.split()[0]:\r | |
268 | CpTarget = Cmd.split()[2]\r | |
269 | TargetList.add(CpTarget)\r | |
f51461c8 LG |
270 | \r |
271 | return list(TargetList)\r | |
272 | \r | |
273 | ## SetDir()\r | |
274 | #\r | |
275 | # @param OutputDir Output directory\r | |
276 | # @param FdfParser FDF contents parser\r | |
277 | # @param Workspace The directory of workspace\r | |
278 | # @param ArchList The Arch list of platform\r | |
279 | #\r | |
9e47e6f9 | 280 | @staticmethod\r |
f51461c8 | 281 | def SetDir (OutputDir, FdfParser, WorkSpace, ArchList):\r |
9e47e6f9 | 282 | GenFdsGlobalVariable.VerboseLogger("GenFdsGlobalVariable.OutputDir:%s" % OutputDir)\r |
f51461c8 LG |
283 | GenFdsGlobalVariable.FdfParser = FdfParser\r |
284 | GenFdsGlobalVariable.WorkSpace = WorkSpace\r | |
91fa33ee | 285 | GenFdsGlobalVariable.FvDir = os.path.join(GenFdsGlobalVariable.OutputDirDict[ArchList[0]], DataType.TAB_FV_DIRECTORY)\r |
9e47e6f9 | 286 | if not os.path.exists(GenFdsGlobalVariable.FvDir):\r |
f51461c8 LG |
287 | os.makedirs(GenFdsGlobalVariable.FvDir)\r |
288 | GenFdsGlobalVariable.FfsDir = os.path.join(GenFdsGlobalVariable.FvDir, 'Ffs')\r | |
9e47e6f9 | 289 | if not os.path.exists(GenFdsGlobalVariable.FfsDir):\r |
f51461c8 | 290 | os.makedirs(GenFdsGlobalVariable.FfsDir)\r |
f51461c8 | 291 | \r |
f51461c8 LG |
292 | #\r |
293 | # Create FV Address inf file\r | |
294 | #\r | |
295 | GenFdsGlobalVariable.FvAddressFileName = os.path.join(GenFdsGlobalVariable.FfsDir, 'FvAddress.inf')\r | |
47fea6af | 296 | FvAddressFile = open(GenFdsGlobalVariable.FvAddressFileName, 'w')\r |
f51461c8 LG |
297 | #\r |
298 | # Add [Options]\r | |
299 | #\r | |
9e47e6f9 | 300 | FvAddressFile.writelines("[options]" + DataType.TAB_LINE_BREAK)\r |
f51461c8 LG |
301 | BsAddress = '0'\r |
302 | for Arch in ArchList:\r | |
303 | if GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].BsBaseAddress:\r | |
304 | BsAddress = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].BsBaseAddress\r | |
305 | break\r | |
306 | \r | |
307 | FvAddressFile.writelines("EFI_BOOT_DRIVER_BASE_ADDRESS = " + \\r | |
47fea6af | 308 | BsAddress + \\r |
9e47e6f9 | 309 | DataType.TAB_LINE_BREAK)\r |
f51461c8 LG |
310 | \r |
311 | RtAddress = '0'\r | |
9e47e6f9 CJ |
312 | for Arch in reversed(ArchList):\r |
313 | temp = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].RtBaseAddress\r | |
314 | if temp:\r | |
315 | RtAddress = temp\r | |
316 | break\r | |
f51461c8 LG |
317 | \r |
318 | FvAddressFile.writelines("EFI_RUNTIME_DRIVER_BASE_ADDRESS = " + \\r | |
47fea6af | 319 | RtAddress + \\r |
9e47e6f9 | 320 | DataType.TAB_LINE_BREAK)\r |
f51461c8 LG |
321 | \r |
322 | FvAddressFile.close()\r | |
323 | \r | |
9e47e6f9 | 324 | @staticmethod\r |
37de70b7 YZ |
325 | def SetEnv(FdfParser, WorkSpace, ArchList, GlobalData):\r |
326 | GenFdsGlobalVariable.ModuleFile = WorkSpace.ModuleFile\r | |
327 | GenFdsGlobalVariable.FdfParser = FdfParser\r | |
328 | GenFdsGlobalVariable.WorkSpace = WorkSpace.Db\r | |
329 | GenFdsGlobalVariable.ArchList = ArchList\r | |
330 | GenFdsGlobalVariable.ToolChainTag = GlobalData.gGlobalDefines["TOOL_CHAIN_TAG"]\r | |
331 | GenFdsGlobalVariable.TargetName = GlobalData.gGlobalDefines["TARGET"]\r | |
332 | GenFdsGlobalVariable.ActivePlatform = GlobalData.gActivePlatform\r | |
37de70b7 YZ |
333 | GenFdsGlobalVariable.ConfDir = GlobalData.gConfDirectory\r |
334 | GenFdsGlobalVariable.EnableGenfdsMultiThread = GlobalData.gEnableGenfdsMultiThread\r | |
335 | for Arch in ArchList:\r | |
336 | GenFdsGlobalVariable.OutputDirDict[Arch] = os.path.normpath(\r | |
337 | os.path.join(GlobalData.gWorkspace,\r | |
ccaa7754 | 338 | WorkSpace.Db.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GlobalData.gGlobalDefines['TARGET'],\r |
37de70b7 YZ |
339 | GlobalData.gGlobalDefines['TOOLCHAIN']].OutputDirectory,\r |
340 | GlobalData.gGlobalDefines['TARGET'] +'_' + GlobalData.gGlobalDefines['TOOLCHAIN']))\r | |
341 | GenFdsGlobalVariable.OutputDirFromDscDict[Arch] = os.path.normpath(\r | |
342 | WorkSpace.Db.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch,\r | |
343 | GlobalData.gGlobalDefines['TARGET'], GlobalData.gGlobalDefines['TOOLCHAIN']].OutputDirectory)\r | |
344 | GenFdsGlobalVariable.PlatformName = WorkSpace.Db.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch,\r | |
345 | GlobalData.gGlobalDefines['TARGET'],\r | |
346 | GlobalData.gGlobalDefines['TOOLCHAIN']].PlatformName\r | |
91fa33ee | 347 | GenFdsGlobalVariable.FvDir = os.path.join(GenFdsGlobalVariable.OutputDirDict[ArchList[0]], DataType.TAB_FV_DIRECTORY)\r |
37de70b7 YZ |
348 | if not os.path.exists(GenFdsGlobalVariable.FvDir):\r |
349 | os.makedirs(GenFdsGlobalVariable.FvDir)\r | |
350 | GenFdsGlobalVariable.FfsDir = os.path.join(GenFdsGlobalVariable.FvDir, 'Ffs')\r | |
351 | if not os.path.exists(GenFdsGlobalVariable.FfsDir):\r | |
352 | os.makedirs(GenFdsGlobalVariable.FfsDir)\r | |
353 | \r | |
37de70b7 YZ |
354 | #\r |
355 | # Create FV Address inf file\r | |
356 | #\r | |
357 | GenFdsGlobalVariable.FvAddressFileName = os.path.join(GenFdsGlobalVariable.FfsDir, 'FvAddress.inf')\r | |
358 | FvAddressFile = open(GenFdsGlobalVariable.FvAddressFileName, 'w')\r | |
359 | #\r | |
360 | # Add [Options]\r | |
361 | #\r | |
9e47e6f9 | 362 | FvAddressFile.writelines("[options]" + DataType.TAB_LINE_BREAK)\r |
37de70b7 YZ |
363 | BsAddress = '0'\r |
364 | for Arch in ArchList:\r | |
365 | BsAddress = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch,\r | |
366 | GlobalData.gGlobalDefines['TARGET'],\r | |
367 | GlobalData.gGlobalDefines["TOOL_CHAIN_TAG"]].BsBaseAddress\r | |
368 | if BsAddress:\r | |
369 | break\r | |
370 | \r | |
371 | FvAddressFile.writelines("EFI_BOOT_DRIVER_BASE_ADDRESS = " + \\r | |
372 | BsAddress + \\r | |
9e47e6f9 | 373 | DataType.TAB_LINE_BREAK)\r |
37de70b7 YZ |
374 | \r |
375 | RtAddress = '0'\r | |
9e47e6f9 CJ |
376 | for Arch in reversed(ArchList):\r |
377 | temp = GenFdsGlobalVariable.WorkSpace.BuildObject[\r | |
37de70b7 | 378 | GenFdsGlobalVariable.ActivePlatform, Arch, GlobalData.gGlobalDefines['TARGET'],\r |
9e47e6f9 CJ |
379 | GlobalData.gGlobalDefines["TOOL_CHAIN_TAG"]].RtBaseAddress\r |
380 | if temp:\r | |
381 | RtAddress = temp\r | |
382 | break\r | |
37de70b7 YZ |
383 | \r |
384 | FvAddressFile.writelines("EFI_RUNTIME_DRIVER_BASE_ADDRESS = " + \\r | |
385 | RtAddress + \\r | |
9e47e6f9 | 386 | DataType.TAB_LINE_BREAK)\r |
37de70b7 YZ |
387 | \r |
388 | FvAddressFile.close()\r | |
389 | \r | |
f51461c8 LG |
390 | ## ReplaceWorkspaceMacro()\r |
391 | #\r | |
392 | # @param String String that may contain macro\r | |
393 | #\r | |
9e47e6f9 | 394 | @staticmethod\r |
f51461c8 | 395 | def ReplaceWorkspaceMacro(String):\r |
05cc51ad | 396 | String = mws.handleWsMacro(String)\r |
f51461c8 LG |
397 | Str = String.replace('$(WORKSPACE)', GenFdsGlobalVariable.WorkSpaceDir)\r |
398 | if os.path.exists(Str):\r | |
399 | if not os.path.isabs(Str):\r | |
400 | Str = os.path.abspath(Str)\r | |
401 | else:\r | |
05cc51ad | 402 | Str = mws.join(GenFdsGlobalVariable.WorkSpaceDir, String)\r |
f51461c8 LG |
403 | return os.path.normpath(Str)\r |
404 | \r | |
405 | ## Check if the input files are newer than output files\r | |
406 | #\r | |
407 | # @param Output Path of output file\r | |
408 | # @param Input Path list of input files\r | |
409 | #\r | |
410 | # @retval True if Output doesn't exist, or any Input is newer\r | |
411 | # @retval False if all Input is older than Output\r | |
412 | #\r | |
413 | @staticmethod\r | |
414 | def NeedsUpdate(Output, Input):\r | |
415 | if not os.path.exists(Output):\r | |
416 | return True\r | |
417 | # always update "Output" if no "Input" given\r | |
9e47e6f9 | 418 | if not Input:\r |
f51461c8 LG |
419 | return True\r |
420 | \r | |
421 | # if fdf file is changed after the 'Output" is generated, update the 'Output'\r | |
422 | OutputTime = os.path.getmtime(Output)\r | |
423 | if GenFdsGlobalVariable.FdfFileTimeStamp > OutputTime:\r | |
424 | return True\r | |
425 | \r | |
426 | for F in Input:\r | |
427 | # always update "Output" if any "Input" doesn't exist\r | |
428 | if not os.path.exists(F):\r | |
429 | return True\r | |
430 | # always update "Output" if any "Input" is newer than "Output"\r | |
431 | if os.path.getmtime(F) > OutputTime:\r | |
432 | return True\r | |
433 | return False\r | |
434 | \r | |
435 | @staticmethod\r | |
436 | def GenerateSection(Output, Input, Type=None, CompressionType=None, Guid=None,\r | |
caf74495 | 437 | GuidHdrLen=None, GuidAttr=[], Ui=None, Ver=None, InputAlign=[], BuildNumber=None, DummyFile=None, IsMakefile=False):\r |
f51461c8 | 438 | Cmd = ["GenSec"]\r |
c93356ad | 439 | if Type:\r |
caf74495 | 440 | Cmd += ("-s", Type)\r |
c93356ad | 441 | if CompressionType:\r |
caf74495 | 442 | Cmd += ("-c", CompressionType)\r |
9e47e6f9 | 443 | if Guid:\r |
caf74495 | 444 | Cmd += ("-g", Guid)\r |
9e47e6f9 | 445 | if DummyFile:\r |
caf74495 | 446 | Cmd += ("--dummy", DummyFile)\r |
c93356ad | 447 | if GuidHdrLen:\r |
caf74495 JC |
448 | Cmd += ("-l", GuidHdrLen)\r |
449 | #Add each guided attribute\r | |
450 | for Attr in GuidAttr:\r | |
451 | Cmd += ("-r", Attr)\r | |
452 | #Section Align is only for dummy section without section type\r | |
453 | for SecAlign in InputAlign:\r | |
454 | Cmd += ("--sectionalign", SecAlign)\r | |
f51461c8 LG |
455 | \r |
456 | CommandFile = Output + '.txt'\r | |
c93356ad | 457 | if Ui:\r |
37de70b7 | 458 | if IsMakefile:\r |
a146c532 | 459 | if Ui == "$(MODULE_NAME)":\r |
caf74495 | 460 | Cmd += ('-n', Ui)\r |
a146c532 | 461 | else:\r |
caf74495 JC |
462 | Cmd += ("-n", '"' + Ui + '"')\r |
463 | Cmd += ("-o", Output)\r | |
37de70b7 YZ |
464 | if ' '.join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList:\r |
465 | GenFdsGlobalVariable.SecCmdList.append(' '.join(Cmd).strip())\r | |
466 | else:\r | |
9e47e6f9 | 467 | SectionData = array('B', [0, 0, 0, 0])\r |
20b292d0 | 468 | SectionData.fromlist(array('B',Ui.encode('utf-16-le')).tolist())\r |
37de70b7 YZ |
469 | SectionData.append(0)\r |
470 | SectionData.append(0)\r | |
471 | Len = len(SectionData)\r | |
472 | GenFdsGlobalVariable.SectionHeader.pack_into(SectionData, 0, Len & 0xff, (Len >> 8) & 0xff, (Len >> 16) & 0xff, 0x15)\r | |
20b292d0 BF |
473 | \r |
474 | \r | |
475 | DirName = os.path.dirname(Output)\r | |
476 | if not CreateDirectory(DirName):\r | |
477 | EdkLogger.error(None, FILE_CREATE_FAILURE, "Could not create directory %s" % DirName)\r | |
478 | else:\r | |
479 | if DirName == '':\r | |
480 | DirName = os.getcwd()\r | |
481 | if not os.access(DirName, os.W_OK):\r | |
482 | EdkLogger.error(None, PERMISSION_FAILURE, "Do not have write permission on directory %s" % DirName)\r | |
483 | \r | |
484 | try:\r | |
485 | with open(Output, "wb") as Fd:\r | |
486 | SectionData.tofile(Fd)\r | |
487 | Fd.flush()\r | |
488 | except IOError as X:\r | |
489 | EdkLogger.error(None, FILE_CREATE_FAILURE, ExtraData='IOError %s' % X)\r | |
37de70b7 | 490 | \r |
c93356ad | 491 | elif Ver:\r |
caf74495 | 492 | Cmd += ("-n", Ver)\r |
f51461c8 | 493 | if BuildNumber:\r |
caf74495 JC |
494 | Cmd += ("-j", BuildNumber)\r |
495 | Cmd += ("-o", Output)\r | |
f51461c8 LG |
496 | \r |
497 | SaveFileOnChange(CommandFile, ' '.join(Cmd), False)\r | |
37de70b7 YZ |
498 | if IsMakefile:\r |
499 | if ' '.join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList:\r | |
500 | GenFdsGlobalVariable.SecCmdList.append(' '.join(Cmd).strip())\r | |
501 | else:\r | |
502 | if not GenFdsGlobalVariable.NeedsUpdate(Output, list(Input) + [CommandFile]):\r | |
503 | return\r | |
504 | GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate section")\r | |
f51461c8 | 505 | else:\r |
caf74495 | 506 | Cmd += ("-o", Output)\r |
f51461c8 LG |
507 | Cmd += Input\r |
508 | \r | |
509 | SaveFileOnChange(CommandFile, ' '.join(Cmd), False)\r | |
37de70b7 | 510 | if IsMakefile:\r |
a1f94045 | 511 | if sys.platform == "win32":\r |
b1e27d17 FB |
512 | Cmd = ['if', 'exist', Input[0]] + Cmd\r |
513 | else:\r | |
f23da864 | 514 | Cmd = ['-test', '-e', Input[0], "&&"] + Cmd\r |
37de70b7 YZ |
515 | if ' '.join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList:\r |
516 | GenFdsGlobalVariable.SecCmdList.append(' '.join(Cmd).strip())\r | |
6735645d | 517 | elif GenFdsGlobalVariable.NeedsUpdate(Output, list(Input) + [CommandFile]):\r |
f51461c8 LG |
518 | GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))\r |
519 | GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate section")\r | |
37de70b7 YZ |
520 | if (os.path.getsize(Output) >= GenFdsGlobalVariable.LARGE_FILE_SIZE and\r |
521 | GenFdsGlobalVariable.LargeFileInFvFlags):\r | |
522 | GenFdsGlobalVariable.LargeFileInFvFlags[-1] = True\r | |
f51461c8 LG |
523 | \r |
524 | @staticmethod\r | |
525 | def GetAlignment (AlignString):\r | |
7bf1eb6e | 526 | if not AlignString:\r |
f51461c8 | 527 | return 0\r |
7bf1eb6e | 528 | if AlignString.endswith('K'):\r |
52302d4d | 529 | return int (AlignString.rstrip('K')) * 1024\r |
7bf1eb6e | 530 | if AlignString.endswith('M'):\r |
e921f58d | 531 | return int (AlignString.rstrip('M')) * 1024 * 1024\r |
7bf1eb6e CJ |
532 | if AlignString.endswith('G'):\r |
533 | return int (AlignString.rstrip('G')) * 1024 * 1024 * 1024\r | |
534 | return int (AlignString)\r | |
f51461c8 LG |
535 | \r |
536 | @staticmethod\r | |
537 | def GenerateFfs(Output, Input, Type, Guid, Fixed=False, CheckSum=False, Align=None,\r | |
37de70b7 | 538 | SectionAlign=None, MakefilePath=None):\r |
f51461c8 | 539 | Cmd = ["GenFfs", "-t", Type, "-g", Guid]\r |
e921f58d | 540 | mFfsValidAlign = ["0", "8", "16", "128", "512", "1K", "4K", "32K", "64K", "128K", "256K", "512K", "1M", "2M", "4M", "8M", "16M"]\r |
f51461c8 | 541 | if Fixed == True:\r |
caf74495 | 542 | Cmd.append("-x")\r |
f51461c8 | 543 | if CheckSum:\r |
caf74495 | 544 | Cmd.append("-s")\r |
c93356ad | 545 | if Align:\r |
d2192f12 YZ |
546 | if Align not in mFfsValidAlign:\r |
547 | Align = GenFdsGlobalVariable.GetAlignment (Align)\r | |
548 | for index in range(0, len(mFfsValidAlign) - 1):\r | |
549 | if ((Align > GenFdsGlobalVariable.GetAlignment(mFfsValidAlign[index])) and (Align <= GenFdsGlobalVariable.GetAlignment(mFfsValidAlign[index + 1]))):\r | |
550 | break\r | |
551 | Align = mFfsValidAlign[index + 1]\r | |
caf74495 | 552 | Cmd += ("-a", Align)\r |
f51461c8 | 553 | \r |
caf74495 | 554 | Cmd += ("-o", Output)\r |
f51461c8 | 555 | for I in range(0, len(Input)):\r |
b1e27d17 FB |
556 | if MakefilePath:\r |
557 | Cmd += ("-oi", Input[I])\r | |
558 | else:\r | |
559 | Cmd += ("-i", Input[I])\r | |
c93356ad | 560 | if SectionAlign and SectionAlign[I]:\r |
f51461c8 LG |
561 | Cmd += ("-n", SectionAlign[I])\r |
562 | \r | |
563 | CommandFile = Output + '.txt'\r | |
564 | SaveFileOnChange(CommandFile, ' '.join(Cmd), False)\r | |
f51461c8 | 565 | \r |
37de70b7 YZ |
566 | GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))\r |
567 | if MakefilePath:\r | |
ccaa7754 | 568 | if (tuple(Cmd), tuple(GenFdsGlobalVariable.SecCmdList), tuple(GenFdsGlobalVariable.CopyList)) not in GenFdsGlobalVariable.FfsCmdDict:\r |
37de70b7 YZ |
569 | GenFdsGlobalVariable.FfsCmdDict[tuple(Cmd), tuple(GenFdsGlobalVariable.SecCmdList), tuple(GenFdsGlobalVariable.CopyList)] = MakefilePath\r |
570 | GenFdsGlobalVariable.SecCmdList = []\r | |
571 | GenFdsGlobalVariable.CopyList = []\r | |
572 | else:\r | |
6735645d | 573 | if not GenFdsGlobalVariable.NeedsUpdate(Output, list(Input) + [CommandFile]):\r |
37de70b7 YZ |
574 | return\r |
575 | GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate FFS")\r | |
f51461c8 LG |
576 | \r |
577 | @staticmethod\r | |
578 | def GenerateFirmwareVolume(Output, Input, BaseAddress=None, ForceRebase=None, Capsule=False, Dump=False,\r | |
579 | AddressFile=None, MapFile=None, FfsList=[], FileSystemGuid=None):\r | |
580 | if not GenFdsGlobalVariable.NeedsUpdate(Output, Input+FfsList):\r | |
581 | return\r | |
582 | GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))\r | |
583 | \r | |
584 | Cmd = ["GenFv"]\r | |
c93356ad | 585 | if BaseAddress:\r |
caf74495 | 586 | Cmd += ("-r", BaseAddress)\r |
47fea6af | 587 | \r |
599bb2be | 588 | if ForceRebase == False:\r |
caf74495 | 589 | Cmd += ("-F", "FALSE")\r |
599bb2be | 590 | elif ForceRebase == True:\r |
caf74495 | 591 | Cmd += ("-F", "TRUE")\r |
47fea6af | 592 | \r |
f51461c8 | 593 | if Capsule:\r |
caf74495 | 594 | Cmd.append("-c")\r |
f51461c8 | 595 | if Dump:\r |
caf74495 | 596 | Cmd.append("-p")\r |
c93356ad | 597 | if AddressFile:\r |
caf74495 | 598 | Cmd += ("-a", AddressFile)\r |
c93356ad | 599 | if MapFile:\r |
caf74495 | 600 | Cmd += ("-m", MapFile)\r |
f51461c8 | 601 | if FileSystemGuid:\r |
caf74495 JC |
602 | Cmd += ("-g", FileSystemGuid)\r |
603 | Cmd += ("-o", Output)\r | |
f51461c8 | 604 | for I in Input:\r |
caf74495 | 605 | Cmd += ("-i", I)\r |
f51461c8 LG |
606 | \r |
607 | GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate FV")\r | |
608 | \r | |
f51461c8 LG |
609 | @staticmethod\r |
610 | def GenerateFirmwareImage(Output, Input, Type="efi", SubType=None, Zero=False,\r | |
611 | Strip=False, Replace=False, TimeStamp=None, Join=False,\r | |
37de70b7 YZ |
612 | Align=None, Padding=None, Convert=False, IsMakefile=False):\r |
613 | if not GenFdsGlobalVariable.NeedsUpdate(Output, Input) and not IsMakefile:\r | |
f51461c8 LG |
614 | return\r |
615 | GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))\r | |
616 | \r | |
617 | Cmd = ["GenFw"]\r | |
618 | if Type.lower() == "te":\r | |
caf74495 | 619 | Cmd.append("-t")\r |
c93356ad | 620 | if SubType:\r |
caf74495 | 621 | Cmd += ("-e", SubType)\r |
c93356ad | 622 | if TimeStamp:\r |
caf74495 | 623 | Cmd += ("-s", TimeStamp)\r |
c93356ad | 624 | if Align:\r |
caf74495 | 625 | Cmd += ("-a", Align)\r |
c93356ad | 626 | if Padding:\r |
caf74495 | 627 | Cmd += ("-p", Padding)\r |
f51461c8 | 628 | if Zero:\r |
caf74495 | 629 | Cmd.append("-z")\r |
f51461c8 | 630 | if Strip:\r |
caf74495 | 631 | Cmd.append("-l")\r |
f51461c8 | 632 | if Replace:\r |
caf74495 | 633 | Cmd.append("-r")\r |
f51461c8 | 634 | if Join:\r |
caf74495 | 635 | Cmd.append("-j")\r |
f51461c8 | 636 | if Convert:\r |
caf74495 JC |
637 | Cmd.append("-m")\r |
638 | Cmd += ("-o", Output)\r | |
f51461c8 | 639 | Cmd += Input\r |
37de70b7 YZ |
640 | if IsMakefile:\r |
641 | if " ".join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList:\r | |
642 | GenFdsGlobalVariable.SecCmdList.append(" ".join(Cmd).strip())\r | |
643 | else:\r | |
644 | GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate firmware image")\r | |
f51461c8 LG |
645 | \r |
646 | @staticmethod\r | |
647 | def GenerateOptionRom(Output, EfiInput, BinaryInput, Compress=False, ClassCode=None,\r | |
37de70b7 | 648 | Revision=None, DeviceId=None, VendorId=None, IsMakefile=False):\r |
f7496d71 | 649 | InputList = []\r |
f51461c8 | 650 | Cmd = ["EfiRom"]\r |
9e47e6f9 | 651 | if EfiInput:\r |
f7496d71 | 652 | \r |
f51461c8 | 653 | if Compress:\r |
caf74495 | 654 | Cmd.append("-ec")\r |
f51461c8 | 655 | else:\r |
caf74495 | 656 | Cmd.append("-e")\r |
f7496d71 | 657 | \r |
f51461c8 | 658 | for EfiFile in EfiInput:\r |
caf74495 | 659 | Cmd.append(EfiFile)\r |
f51461c8 | 660 | InputList.append (EfiFile)\r |
f7496d71 | 661 | \r |
9e47e6f9 | 662 | if BinaryInput:\r |
caf74495 | 663 | Cmd.append("-b")\r |
f51461c8 | 664 | for BinFile in BinaryInput:\r |
caf74495 | 665 | Cmd.append(BinFile)\r |
f51461c8 LG |
666 | InputList.append (BinFile)\r |
667 | \r | |
668 | # Check List\r | |
37de70b7 | 669 | if not GenFdsGlobalVariable.NeedsUpdate(Output, InputList) and not IsMakefile:\r |
f51461c8 LG |
670 | return\r |
671 | GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, InputList))\r | |
f7496d71 | 672 | \r |
9e47e6f9 | 673 | if ClassCode:\r |
caf74495 | 674 | Cmd += ("-l", ClassCode)\r |
9e47e6f9 | 675 | if Revision:\r |
caf74495 | 676 | Cmd += ("-r", Revision)\r |
9e47e6f9 | 677 | if DeviceId:\r |
caf74495 | 678 | Cmd += ("-i", DeviceId)\r |
9e47e6f9 | 679 | if VendorId:\r |
caf74495 | 680 | Cmd += ("-f", VendorId)\r |
f51461c8 | 681 | \r |
caf74495 | 682 | Cmd += ("-o", Output)\r |
37de70b7 YZ |
683 | if IsMakefile:\r |
684 | if " ".join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList:\r | |
685 | GenFdsGlobalVariable.SecCmdList.append(" ".join(Cmd).strip())\r | |
686 | else:\r | |
687 | GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate option rom")\r | |
f51461c8 LG |
688 | \r |
689 | @staticmethod\r | |
37de70b7 YZ |
690 | def GuidTool(Output, Input, ToolPath, Options='', returnValue=[], IsMakefile=False):\r |
691 | if not GenFdsGlobalVariable.NeedsUpdate(Output, Input) and not IsMakefile:\r | |
f51461c8 LG |
692 | return\r |
693 | GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))\r | |
694 | \r | |
695 | Cmd = [ToolPath, ]\r | |
696 | Cmd += Options.split(' ')\r | |
caf74495 | 697 | Cmd += ("-o", Output)\r |
f51461c8 | 698 | Cmd += Input\r |
37de70b7 YZ |
699 | if IsMakefile:\r |
700 | if " ".join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList:\r | |
701 | GenFdsGlobalVariable.SecCmdList.append(" ".join(Cmd).strip())\r | |
702 | else:\r | |
703 | GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to call " + ToolPath, returnValue)\r | |
f51461c8 | 704 | \r |
9e47e6f9 | 705 | @staticmethod\r |
f51461c8 LG |
706 | def CallExternalTool (cmd, errorMess, returnValue=[]):\r |
707 | \r | |
708 | if type(cmd) not in (tuple, list):\r | |
709 | GenFdsGlobalVariable.ErrorLogger("ToolError! Invalid parameter type in call to CallExternalTool")\r | |
710 | \r | |
711 | if GenFdsGlobalVariable.DebugLevel != -1:\r | |
712 | cmd += ('--debug', str(GenFdsGlobalVariable.DebugLevel))\r | |
713 | GenFdsGlobalVariable.InfLogger (cmd)\r | |
714 | \r | |
715 | if GenFdsGlobalVariable.VerboseMode:\r | |
716 | cmd += ('-v',)\r | |
717 | GenFdsGlobalVariable.InfLogger (cmd)\r | |
718 | else:\r | |
9e47e6f9 CJ |
719 | stdout.write ('#')\r |
720 | stdout.flush()\r | |
f51461c8 LG |
721 | GenFdsGlobalVariable.SharpCounter = GenFdsGlobalVariable.SharpCounter + 1\r |
722 | if GenFdsGlobalVariable.SharpCounter % GenFdsGlobalVariable.SharpNumberPerLine == 0:\r | |
9e47e6f9 | 723 | stdout.write('\n')\r |
f51461c8 LG |
724 | \r |
725 | try:\r | |
9e47e6f9 | 726 | PopenObject = Popen(' '.join(cmd), stdout=PIPE, stderr=PIPE, shell=True)\r |
5b0671c1 | 727 | except Exception as X:\r |
f51461c8 LG |
728 | EdkLogger.error("GenFds", COMMAND_FAILURE, ExtraData="%s: %s" % (str(X), cmd[0]))\r |
729 | (out, error) = PopenObject.communicate()\r | |
730 | \r | |
9e47e6f9 | 731 | while PopenObject.returncode is None:\r |
f51461c8 LG |
732 | PopenObject.wait()\r |
733 | if returnValue != [] and returnValue[0] != 0:\r | |
734 | #get command return value\r | |
735 | returnValue[0] = PopenObject.returncode\r | |
736 | return\r | |
737 | if PopenObject.returncode != 0 or GenFdsGlobalVariable.VerboseMode or GenFdsGlobalVariable.DebugLevel != -1:\r | |
47fea6af | 738 | GenFdsGlobalVariable.InfLogger ("Return Value = %d" % PopenObject.returncode)\r |
d943b0c3 FB |
739 | GenFdsGlobalVariable.InfLogger(out.decode(encoding='utf-8', errors='ignore'))\r |
740 | GenFdsGlobalVariable.InfLogger(error.decode(encoding='utf-8', errors='ignore'))\r | |
f51461c8 | 741 | if PopenObject.returncode != 0:\r |
72443dd2 | 742 | print("###", cmd)\r |
f51461c8 LG |
743 | EdkLogger.error("GenFds", COMMAND_FAILURE, errorMess)\r |
744 | \r | |
9e47e6f9 | 745 | @staticmethod\r |
f51461c8 LG |
746 | def VerboseLogger (msg):\r |
747 | EdkLogger.verbose(msg)\r | |
748 | \r | |
9e47e6f9 | 749 | @staticmethod\r |
f51461c8 LG |
750 | def InfLogger (msg):\r |
751 | EdkLogger.info(msg)\r | |
752 | \r | |
9e47e6f9 | 753 | @staticmethod\r |
47fea6af | 754 | def ErrorLogger (msg, File=None, Line=None, ExtraData=None):\r |
f51461c8 LG |
755 | EdkLogger.error('GenFds', GENFDS_ERROR, msg, File, Line, ExtraData)\r |
756 | \r | |
9e47e6f9 | 757 | @staticmethod\r |
f51461c8 LG |
758 | def DebugLogger (Level, msg):\r |
759 | EdkLogger.debug(Level, msg)\r | |
760 | \r | |
9e47e6f9 | 761 | ## MacroExtend()\r |
f51461c8 LG |
762 | #\r |
763 | # @param Str String that may contain macro\r | |
764 | # @param MacroDict Dictionary that contains macro value pair\r | |
765 | #\r | |
9e47e6f9 | 766 | @staticmethod\r |
e32f7bc9 | 767 | def MacroExtend (Str, MacroDict=None, Arch=DataType.TAB_COMMON):\r |
9e47e6f9 | 768 | if Str is None:\r |
f51461c8 LG |
769 | return None\r |
770 | \r | |
9e47e6f9 | 771 | Dict = {'$(WORKSPACE)': GenFdsGlobalVariable.WorkSpaceDir,\r |
f51461c8 | 772 | # '$(OUTPUT_DIRECTORY)': GenFdsGlobalVariable.OutputDirFromDsc,\r |
9e47e6f9 CJ |
773 | '$(TARGET)': GenFdsGlobalVariable.TargetName,\r |
774 | '$(TOOL_CHAIN_TAG)': GenFdsGlobalVariable.ToolChainTag,\r | |
775 | '$(SPACE)': ' '\r | |
f51461c8 | 776 | }\r |
9e47e6f9 | 777 | \r |
55c84777 | 778 | if Arch != DataType.TAB_COMMON and Arch in GenFdsGlobalVariable.ArchList:\r |
f51461c8 | 779 | OutputDir = GenFdsGlobalVariable.OutputDirFromDscDict[Arch]\r |
9e47e6f9 CJ |
780 | else:\r |
781 | OutputDir = GenFdsGlobalVariable.OutputDirFromDscDict[GenFdsGlobalVariable.ArchList[0]]\r | |
f51461c8 LG |
782 | \r |
783 | Dict['$(OUTPUT_DIRECTORY)'] = OutputDir\r | |
784 | \r | |
9e47e6f9 | 785 | if MacroDict:\r |
f51461c8 LG |
786 | Dict.update(MacroDict)\r |
787 | \r | |
9eb87141 | 788 | for key in Dict:\r |
9e47e6f9 | 789 | if Str.find(key) >= 0:\r |
f51461c8 LG |
790 | Str = Str.replace (key, Dict[key])\r |
791 | \r | |
792 | if Str.find('$(ARCH)') >= 0:\r | |
793 | if len(GenFdsGlobalVariable.ArchList) == 1:\r | |
794 | Str = Str.replace('$(ARCH)', GenFdsGlobalVariable.ArchList[0])\r | |
795 | else:\r | |
796 | EdkLogger.error("GenFds", GENFDS_ERROR, "No way to determine $(ARCH) for %s" % Str)\r | |
797 | \r | |
798 | return Str\r | |
799 | \r | |
800 | ## GetPcdValue()\r | |
801 | #\r | |
802 | # @param PcdPattern pattern that labels a PCD.\r | |
803 | #\r | |
9e47e6f9 | 804 | @staticmethod\r |
f51461c8 | 805 | def GetPcdValue (PcdPattern):\r |
9e47e6f9 | 806 | if PcdPattern is None:\r |
f51461c8 | 807 | return None\r |
bb824f68 FB |
808 | if PcdPattern.startswith('PCD('):\r |
809 | PcdPair = PcdPattern[4:].rstrip(')').strip().split('.')\r | |
810 | else:\r | |
811 | PcdPair = PcdPattern.strip().split('.')\r | |
f51461c8 LG |
812 | TokenSpace = PcdPair[0]\r |
813 | TokenCName = PcdPair[1]\r | |
814 | \r | |
f51461c8 LG |
815 | for Arch in GenFdsGlobalVariable.ArchList:\r |
816 | Platform = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r | |
817 | PcdDict = Platform.Pcds\r | |
818 | for Key in PcdDict:\r | |
819 | PcdObj = PcdDict[Key]\r | |
820 | if (PcdObj.TokenCName == TokenCName) and (PcdObj.TokenSpaceGuidCName == TokenSpace):\r | |
be409b67 | 821 | if PcdObj.Type != DataType.TAB_PCDS_FIXED_AT_BUILD:\r |
f51461c8 | 822 | EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not FixedAtBuild type." % PcdPattern)\r |
656d2539 | 823 | if PcdObj.DatumType != DataType.TAB_VOID:\r |
f51461c8 | 824 | EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not VOID* datum type." % PcdPattern)\r |
f7496d71 | 825 | \r |
9e47e6f9 | 826 | return PcdObj.DefaultValue\r |
47fea6af YZ |
827 | \r |
828 | for Package in GenFdsGlobalVariable.WorkSpace.GetPackageList(GenFdsGlobalVariable.ActivePlatform,\r | |
829 | Arch,\r | |
830 | GenFdsGlobalVariable.TargetName,\r | |
f51461c8 LG |
831 | GenFdsGlobalVariable.ToolChainTag):\r |
832 | PcdDict = Package.Pcds\r | |
833 | for Key in PcdDict:\r | |
834 | PcdObj = PcdDict[Key]\r | |
835 | if (PcdObj.TokenCName == TokenCName) and (PcdObj.TokenSpaceGuidCName == TokenSpace):\r | |
be409b67 | 836 | if PcdObj.Type != DataType.TAB_PCDS_FIXED_AT_BUILD:\r |
f51461c8 | 837 | EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not FixedAtBuild type." % PcdPattern)\r |
656d2539 | 838 | if PcdObj.DatumType != DataType.TAB_VOID:\r |
f51461c8 | 839 | EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not VOID* datum type." % PcdPattern)\r |
f7496d71 | 840 | \r |
9e47e6f9 | 841 | return PcdObj.DefaultValue\r |
f51461c8 | 842 | \r |
9e47e6f9 | 843 | return ''\r |
89a69d4b GL |
844 | \r |
845 | ## FindExtendTool()\r | |
846 | #\r | |
847 | # Find location of tools to process data\r | |
848 | #\r | |
849 | # @param KeyStringList Filter for inputs of section generation\r | |
850 | # @param CurrentArchList Arch list\r | |
851 | # @param NameGuid The Guid name\r | |
852 | #\r | |
853 | def FindExtendTool(KeyStringList, CurrentArchList, NameGuid):\r | |
ef3840c1 MK |
854 | if GenFdsGlobalVariable.GuidToolDefinition:\r |
855 | if NameGuid in GenFdsGlobalVariable.GuidToolDefinition:\r | |
856 | return GenFdsGlobalVariable.GuidToolDefinition[NameGuid]\r | |
857 | \r | |
4465cd12 FZ |
858 | ToolDefObj = ToolDefDict((os.path.join(os.getenv("WORKSPACE"), "Conf")))\r |
859 | ToolDef = ToolDefObj.ToolDef\r | |
db01c8e3 | 860 | ToolDb = ToolDef.ToolsDefTxtDatabase\r |
89a69d4b GL |
861 | # if user not specify filter, try to deduce it from global data.\r |
862 | if KeyStringList is None or KeyStringList == []:\r | |
863 | Target = GenFdsGlobalVariable.TargetName\r | |
864 | ToolChain = GenFdsGlobalVariable.ToolChainTag\r | |
865 | if ToolChain not in ToolDb['TOOL_CHAIN_TAG']:\r | |
866 | EdkLogger.error("GenFds", GENFDS_ERROR, "Can not find external tool because tool tag %s is not defined in tools_def.txt!" % ToolChain)\r | |
867 | KeyStringList = [Target + '_' + ToolChain + '_' + CurrentArchList[0]]\r | |
868 | for Arch in CurrentArchList:\r | |
869 | if Target + '_' + ToolChain + '_' + Arch not in KeyStringList:\r | |
870 | KeyStringList.append(Target + '_' + ToolChain + '_' + Arch)\r | |
871 | \r | |
89a69d4b GL |
872 | ToolPathTmp = None\r |
873 | ToolOption = None\r | |
ef3840c1 MK |
874 | for Arch in CurrentArchList:\r |
875 | MatchItem = None\r | |
876 | MatchPathItem = None\r | |
877 | MatchOptionsItem = None\r | |
ab957f03 MK |
878 | for KeyString in KeyStringList:\r |
879 | KeyStringBuildTarget, KeyStringToolChain, KeyStringArch = KeyString.split('_')\r | |
ef3840c1 MK |
880 | if KeyStringArch != Arch:\r |
881 | continue\r | |
882 | for Item in ToolDef.ToolsDefTxtDictionary:\r | |
883 | if len(Item.split('_')) < 5:\r | |
884 | continue\r | |
885 | ItemTarget, ItemToolChain, ItemArch, ItemTool, ItemAttr = Item.split('_')\r | |
886 | if ItemTarget == DataType.TAB_STAR:\r | |
887 | ItemTarget = KeyStringBuildTarget\r | |
888 | if ItemToolChain == DataType.TAB_STAR:\r | |
889 | ItemToolChain = KeyStringToolChain\r | |
890 | if ItemArch == DataType.TAB_STAR:\r | |
891 | ItemArch = KeyStringArch\r | |
892 | if ItemTarget != KeyStringBuildTarget:\r | |
893 | continue\r | |
894 | if ItemToolChain != KeyStringToolChain:\r | |
895 | continue\r | |
896 | if ItemArch != KeyStringArch:\r | |
897 | continue\r | |
898 | if ItemAttr != DataType.TAB_GUID:\r | |
899 | # Not GUID attribute\r | |
900 | continue\r | |
901 | if ToolDef.ToolsDefTxtDictionary[Item].lower() != NameGuid.lower():\r | |
902 | # No GUID value match\r | |
903 | continue\r | |
904 | if MatchItem:\r | |
905 | if MatchItem.split('_')[3] == ItemTool:\r | |
906 | # Tool name is the same\r | |
907 | continue\r | |
908 | if CalculatePriorityValue(MatchItem) > CalculatePriorityValue(Item):\r | |
909 | # Current MatchItem is higher priority than new match item\r | |
910 | continue\r | |
911 | MatchItem = Item\r | |
912 | if not MatchItem:\r | |
913 | continue\r | |
914 | ToolName = MatchItem.split('_')[3]\r | |
915 | for Item in ToolDef.ToolsDefTxtDictionary:\r | |
916 | if len(Item.split('_')) < 5:\r | |
917 | continue\r | |
918 | ItemTarget, ItemToolChain, ItemArch, ItemTool, ItemAttr = Item.split('_')\r | |
919 | if ItemTarget == DataType.TAB_STAR:\r | |
920 | ItemTarget = KeyStringBuildTarget\r | |
921 | if ItemToolChain == DataType.TAB_STAR:\r | |
922 | ItemToolChain = KeyStringToolChain\r | |
923 | if ItemArch == DataType.TAB_STAR:\r | |
924 | ItemArch = KeyStringArch\r | |
925 | if ItemTarget != KeyStringBuildTarget:\r | |
926 | continue\r | |
927 | if ItemToolChain != KeyStringToolChain:\r | |
928 | continue\r | |
929 | if ItemArch != KeyStringArch:\r | |
930 | continue\r | |
931 | if ItemTool != ToolName:\r | |
932 | continue\r | |
933 | if ItemAttr == 'PATH':\r | |
934 | if MatchPathItem:\r | |
935 | if CalculatePriorityValue(MatchPathItem) <= CalculatePriorityValue(Item):\r | |
936 | MatchPathItem = Item\r | |
937 | else:\r | |
938 | MatchPathItem = Item\r | |
939 | if ItemAttr == 'FLAGS':\r | |
940 | if MatchOptionsItem:\r | |
941 | if CalculatePriorityValue(MatchOptionsItem) <= CalculatePriorityValue(Item):\r | |
942 | MatchOptionsItem = Item\r | |
943 | else:\r | |
944 | MatchOptionsItem = Item\r | |
945 | if MatchPathItem:\r | |
946 | ToolPathTmp = ToolDef.ToolsDefTxtDictionary[MatchPathItem]\r | |
947 | if MatchOptionsItem:\r | |
948 | ToolOption = ToolDef.ToolsDefTxtDictionary[MatchOptionsItem]\r | |
89a69d4b | 949 | \r |
89a69d4b | 950 | for Arch in CurrentArchList:\r |
ef3840c1 MK |
951 | MatchItem = None\r |
952 | MatchPathItem = None\r | |
953 | MatchOptionsItem = None\r | |
954 | for KeyString in KeyStringList:\r | |
955 | KeyStringBuildTarget, KeyStringToolChain, KeyStringArch = KeyString.split('_')\r | |
956 | if KeyStringArch != Arch:\r | |
957 | continue\r | |
958 | Platform = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, KeyStringBuildTarget, KeyStringToolChain]\r | |
959 | for Item in Platform.BuildOptions:\r | |
960 | if len(Item[1].split('_')) < 5:\r | |
961 | continue\r | |
962 | ItemTarget, ItemToolChain, ItemArch, ItemTool, ItemAttr = Item[1].split('_')\r | |
963 | if ItemTarget == DataType.TAB_STAR:\r | |
964 | ItemTarget = KeyStringBuildTarget\r | |
965 | if ItemToolChain == DataType.TAB_STAR:\r | |
966 | ItemToolChain = KeyStringToolChain\r | |
967 | if ItemArch == DataType.TAB_STAR:\r | |
968 | ItemArch = KeyStringArch\r | |
969 | if ItemTarget != KeyStringBuildTarget:\r | |
970 | continue\r | |
971 | if ItemToolChain != KeyStringToolChain:\r | |
972 | continue\r | |
973 | if ItemArch != KeyStringArch:\r | |
974 | continue\r | |
975 | if ItemAttr != DataType.TAB_GUID:\r | |
976 | # Not GUID attribute match\r | |
977 | continue\r | |
978 | if Platform.BuildOptions[Item].lower() != NameGuid.lower():\r | |
979 | # No GUID value match\r | |
980 | continue\r | |
981 | if MatchItem:\r | |
982 | if MatchItem[1].split('_')[3] == ItemTool:\r | |
983 | # Tool name is the same\r | |
984 | continue\r | |
985 | if CalculatePriorityValue(MatchItem[1]) > CalculatePriorityValue(Item[1]):\r | |
986 | # Current MatchItem is higher priority than new match item\r | |
987 | continue\r | |
988 | MatchItem = Item\r | |
989 | if not MatchItem:\r | |
990 | continue\r | |
991 | ToolName = MatchItem[1].split('_')[3]\r | |
992 | for Item in Platform.BuildOptions:\r | |
993 | if len(Item[1].split('_')) < 5:\r | |
994 | continue\r | |
995 | ItemTarget, ItemToolChain, ItemArch, ItemTool, ItemAttr = Item[1].split('_')\r | |
996 | if ItemTarget == DataType.TAB_STAR:\r | |
997 | ItemTarget = KeyStringBuildTarget\r | |
998 | if ItemToolChain == DataType.TAB_STAR:\r | |
999 | ItemToolChain = KeyStringToolChain\r | |
1000 | if ItemArch == DataType.TAB_STAR:\r | |
1001 | ItemArch = KeyStringArch\r | |
1002 | if ItemTarget != KeyStringBuildTarget:\r | |
1003 | continue\r | |
1004 | if ItemToolChain != KeyStringToolChain:\r | |
1005 | continue\r | |
1006 | if ItemArch != KeyStringArch:\r | |
1007 | continue\r | |
1008 | if ItemTool != ToolName:\r | |
1009 | continue\r | |
1010 | if ItemAttr == 'PATH':\r | |
1011 | if MatchPathItem:\r | |
1012 | if CalculatePriorityValue(MatchPathItem[1]) <= CalculatePriorityValue(Item[1]):\r | |
1013 | MatchPathItem = Item\r | |
1014 | else:\r | |
1015 | MatchPathItem = Item\r | |
1016 | if ItemAttr == 'FLAGS':\r | |
1017 | if MatchOptionsItem:\r | |
1018 | if CalculatePriorityValue(MatchOptionsItem[1]) <= CalculatePriorityValue(Item[1]):\r | |
1019 | MatchOptionsItem = Item\r | |
1020 | else:\r | |
1021 | MatchOptionsItem = Item\r | |
1022 | if MatchPathItem:\r | |
1023 | ToolPathTmp = Platform.BuildOptions[MatchPathItem]\r | |
1024 | if MatchOptionsItem:\r | |
1025 | ToolOption = Platform.BuildOptions[MatchOptionsItem]\r | |
89a69d4b GL |
1026 | GenFdsGlobalVariable.GuidToolDefinition[NameGuid] = (ToolPathTmp, ToolOption)\r |
1027 | return ToolPathTmp, ToolOption\r |