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