]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - BaseTools/Source/Python/AutoGen/GenMake.py
BaseTools: Enable structure pcd in FDF file
[mirror_edk2.git] / BaseTools / Source / Python / AutoGen / GenMake.py
... / ...
CommitLineData
1## @file\r
2# Create makefile for MS nmake and GNU make\r
3#\r
4# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>\r
5# This program and the accompanying materials\r
6# are licensed and made available under the terms and conditions of the BSD License\r
7# which accompanies this distribution. The full text of the license may be found at\r
8# http://opensource.org/licenses/bsd-license.php\r
9#\r
10# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12#\r
13\r
14## Import Modules\r
15#\r
16import Common.LongFilePathOs as os\r
17import sys\r
18import string\r
19import re\r
20import os.path as path\r
21from Common.LongFilePathSupport import OpenLongFilePath as open\r
22from Common.MultipleWorkspace import MultipleWorkspace as mws\r
23from Common.BuildToolError import *\r
24from Common.Misc import *\r
25from Common.StringUtils import *\r
26from BuildEngine import *\r
27import Common.GlobalData as GlobalData\r
28from collections import OrderedDict\r
29\r
30## Regular expression for finding header file inclusions\r
31gIncludePattern = re.compile(r"^[ \t]*#?[ \t]*include(?:[ \t]*(?:\\(?:\r\n|\r|\n))*[ \t]*)*(?:\(?[\"<]?[ \t]*)([-\w.\\/() \t]+)(?:[ \t]*[\">]?\)?)", re.MULTILINE | re.UNICODE | re.IGNORECASE)\r
32\r
33## Regular expression for matching macro used in header file inclusion\r
34gMacroPattern = re.compile("([_A-Z][_A-Z0-9]*)[ \t]*\((.+)\)", re.UNICODE)\r
35\r
36gIsFileMap = {}\r
37\r
38## pattern for include style in Edk.x code\r
39gProtocolDefinition = "Protocol/%(HeaderKey)s/%(HeaderKey)s.h"\r
40gGuidDefinition = "Guid/%(HeaderKey)s/%(HeaderKey)s.h"\r
41gArchProtocolDefinition = "ArchProtocol/%(HeaderKey)s/%(HeaderKey)s.h"\r
42gPpiDefinition = "Ppi/%(HeaderKey)s/%(HeaderKey)s.h"\r
43gIncludeMacroConversion = {\r
44 "EFI_PROTOCOL_DEFINITION" : gProtocolDefinition,\r
45 "EFI_GUID_DEFINITION" : gGuidDefinition,\r
46 "EFI_ARCH_PROTOCOL_DEFINITION" : gArchProtocolDefinition,\r
47 "EFI_PROTOCOL_PRODUCER" : gProtocolDefinition,\r
48 "EFI_PROTOCOL_CONSUMER" : gProtocolDefinition,\r
49 "EFI_PROTOCOL_DEPENDENCY" : gProtocolDefinition,\r
50 "EFI_ARCH_PROTOCOL_PRODUCER" : gArchProtocolDefinition,\r
51 "EFI_ARCH_PROTOCOL_CONSUMER" : gArchProtocolDefinition,\r
52 "EFI_ARCH_PROTOCOL_DEPENDENCY" : gArchProtocolDefinition,\r
53 "EFI_PPI_DEFINITION" : gPpiDefinition,\r
54 "EFI_PPI_PRODUCER" : gPpiDefinition,\r
55 "EFI_PPI_CONSUMER" : gPpiDefinition,\r
56 "EFI_PPI_DEPENDENCY" : gPpiDefinition,\r
57}\r
58\r
59## default makefile type\r
60gMakeType = ""\r
61if sys.platform == "win32":\r
62 gMakeType = "nmake"\r
63else:\r
64 gMakeType = "gmake"\r
65\r
66\r
67## BuildFile class\r
68#\r
69# This base class encapsules build file and its generation. It uses template to generate\r
70# the content of build file. The content of build file will be got from AutoGen objects.\r
71#\r
72class BuildFile(object):\r
73 ## template used to generate the build file (i.e. makefile if using make)\r
74 _TEMPLATE_ = TemplateString('')\r
75\r
76 _DEFAULT_FILE_NAME_ = "Makefile"\r
77\r
78 ## default file name for each type of build file\r
79 _FILE_NAME_ = {\r
80 "nmake" : "Makefile",\r
81 "gmake" : "GNUmakefile"\r
82 }\r
83\r
84 ## Fixed header string for makefile\r
85 _MAKEFILE_HEADER = '''#\r
86# DO NOT EDIT\r
87# This file is auto-generated by build utility\r
88#\r
89# Module Name:\r
90#\r
91# %s\r
92#\r
93# Abstract:\r
94#\r
95# Auto-generated makefile for building modules, libraries or platform\r
96#\r
97 '''\r
98\r
99 ## Header string for each type of build file\r
100 _FILE_HEADER_ = {\r
101 "nmake" : _MAKEFILE_HEADER % _FILE_NAME_["nmake"],\r
102 "gmake" : _MAKEFILE_HEADER % _FILE_NAME_["gmake"]\r
103 }\r
104\r
105 ## shell commands which can be used in build file in the form of macro\r
106 # $(CP) copy file command\r
107 # $(MV) move file command\r
108 # $(RM) remove file command\r
109 # $(MD) create dir command\r
110 # $(RD) remove dir command\r
111 #\r
112 _SHELL_CMD_ = {\r
113 "nmake" : {\r
114 "CP" : "copy /y",\r
115 "MV" : "move /y",\r
116 "RM" : "del /f /q",\r
117 "MD" : "mkdir",\r
118 "RD" : "rmdir /s /q",\r
119 },\r
120\r
121 "gmake" : {\r
122 "CP" : "cp -f",\r
123 "MV" : "mv -f",\r
124 "RM" : "rm -f",\r
125 "MD" : "mkdir -p",\r
126 "RD" : "rm -r -f",\r
127 }\r
128 }\r
129\r
130 ## directory separator\r
131 _SEP_ = {\r
132 "nmake" : "\\",\r
133 "gmake" : "/"\r
134 }\r
135\r
136 ## directory creation template\r
137 _MD_TEMPLATE_ = {\r
138 "nmake" : 'if not exist %(dir)s $(MD) %(dir)s',\r
139 "gmake" : "$(MD) %(dir)s"\r
140 }\r
141\r
142 ## directory removal template\r
143 _RD_TEMPLATE_ = {\r
144 "nmake" : 'if exist %(dir)s $(RD) %(dir)s',\r
145 "gmake" : "$(RD) %(dir)s"\r
146 }\r
147 ## cp if exist\r
148 _CP_TEMPLATE_ = {\r
149 "nmake" : 'if exist %(Src)s $(CP) %(Src)s %(Dst)s',\r
150 "gmake" : "test -f %(Src)s && $(CP) %(Src)s %(Dst)s"\r
151 }\r
152\r
153 _CD_TEMPLATE_ = {\r
154 "nmake" : 'if exist %(dir)s cd %(dir)s',\r
155 "gmake" : "test -e %(dir)s && cd %(dir)s"\r
156 }\r
157\r
158 _MAKE_TEMPLATE_ = {\r
159 "nmake" : 'if exist %(file)s "$(MAKE)" $(MAKE_FLAGS) -f %(file)s',\r
160 "gmake" : 'test -e %(file)s && "$(MAKE)" $(MAKE_FLAGS) -f %(file)s'\r
161 }\r
162\r
163 _INCLUDE_CMD_ = {\r
164 "nmake" : '!INCLUDE',\r
165 "gmake" : "include"\r
166 }\r
167\r
168 _INC_FLAG_ = {"MSFT" : "/I", "GCC" : "-I", "INTEL" : "-I", "RVCT" : "-I"}\r
169\r
170 ## Constructor of BuildFile\r
171 #\r
172 # @param AutoGenObject Object of AutoGen class\r
173 #\r
174 def __init__(self, AutoGenObject):\r
175 self._AutoGenObject = AutoGenObject\r
176 self._FileType = gMakeType\r
177\r
178 ## Create build file\r
179 #\r
180 # @param FileType Type of build file. Only nmake and gmake are supported now.\r
181 #\r
182 # @retval TRUE The build file is created or re-created successfully\r
183 # @retval FALSE The build file exists and is the same as the one to be generated\r
184 #\r
185 def Generate(self, FileType=gMakeType):\r
186 if FileType not in self._FILE_NAME_:\r
187 EdkLogger.error("build", PARAMETER_INVALID, "Invalid build type [%s]" % FileType,\r
188 ExtraData="[%s]" % str(self._AutoGenObject))\r
189 self._FileType = FileType\r
190 FileContent = self._TEMPLATE_.Replace(self._TemplateDict)\r
191 FileName = self._FILE_NAME_[FileType]\r
192 return SaveFileOnChange(os.path.join(self._AutoGenObject.MakeFileDir, FileName), FileContent, False)\r
193\r
194 ## Return a list of directory creation command string\r
195 #\r
196 # @param DirList The list of directory to be created\r
197 #\r
198 # @retval list The directory creation command list\r
199 #\r
200 def GetCreateDirectoryCommand(self, DirList):\r
201 return [self._MD_TEMPLATE_[self._FileType] % {'dir':Dir} for Dir in DirList]\r
202\r
203 ## Return a list of directory removal command string\r
204 #\r
205 # @param DirList The list of directory to be removed\r
206 #\r
207 # @retval list The directory removal command list\r
208 #\r
209 def GetRemoveDirectoryCommand(self, DirList):\r
210 return [self._RD_TEMPLATE_[self._FileType] % {'dir':Dir} for Dir in DirList]\r
211\r
212 def PlaceMacro(self, Path, MacroDefinitions={}):\r
213 if Path.startswith("$("):\r
214 return Path\r
215 else:\r
216 PathLength = len(Path)\r
217 for MacroName in MacroDefinitions:\r
218 MacroValue = MacroDefinitions[MacroName]\r
219 MacroValueLength = len(MacroValue)\r
220 if MacroValueLength == 0:\r
221 continue\r
222 if MacroValueLength <= PathLength and Path.startswith(MacroValue):\r
223 Path = "$(%s)%s" % (MacroName, Path[MacroValueLength:])\r
224 break\r
225 return Path\r
226\r
227## ModuleMakefile class\r
228#\r
229# This class encapsules makefie and its generation for module. It uses template to generate\r
230# the content of makefile. The content of makefile will be got from ModuleAutoGen object.\r
231#\r
232class ModuleMakefile(BuildFile):\r
233 ## template used to generate the makefile for module\r
234 _TEMPLATE_ = TemplateString('''\\r
235${makefile_header}\r
236\r
237#\r
238# Platform Macro Definition\r
239#\r
240PLATFORM_NAME = ${platform_name}\r
241PLATFORM_GUID = ${platform_guid}\r
242PLATFORM_VERSION = ${platform_version}\r
243PLATFORM_RELATIVE_DIR = ${platform_relative_directory}\r
244PLATFORM_DIR = ${platform_dir}\r
245PLATFORM_OUTPUT_DIR = ${platform_output_directory}\r
246\r
247#\r
248# Module Macro Definition\r
249#\r
250MODULE_NAME = ${module_name}\r
251MODULE_GUID = ${module_guid}\r
252MODULE_NAME_GUID = ${module_name_guid}\r
253MODULE_VERSION = ${module_version}\r
254MODULE_TYPE = ${module_type}\r
255MODULE_FILE = ${module_file}\r
256MODULE_FILE_BASE_NAME = ${module_file_base_name}\r
257BASE_NAME = $(MODULE_NAME)\r
258MODULE_RELATIVE_DIR = ${module_relative_directory}\r
259PACKAGE_RELATIVE_DIR = ${package_relative_directory}\r
260MODULE_DIR = ${module_dir}\r
261FFS_OUTPUT_DIR = ${ffs_output_directory}\r
262\r
263MODULE_ENTRY_POINT = ${module_entry_point}\r
264ARCH_ENTRY_POINT = ${arch_entry_point}\r
265IMAGE_ENTRY_POINT = ${image_entry_point}\r
266\r
267${BEGIN}${module_extra_defines}\r
268${END}\r
269#\r
270# Build Configuration Macro Definition\r
271#\r
272ARCH = ${architecture}\r
273TOOLCHAIN = ${toolchain_tag}\r
274TOOLCHAIN_TAG = ${toolchain_tag}\r
275TARGET = ${build_target}\r
276\r
277#\r
278# Build Directory Macro Definition\r
279#\r
280# PLATFORM_BUILD_DIR = ${platform_build_directory}\r
281BUILD_DIR = ${platform_build_directory}\r
282BIN_DIR = $(BUILD_DIR)${separator}${architecture}\r
283LIB_DIR = $(BIN_DIR)\r
284MODULE_BUILD_DIR = ${module_build_directory}\r
285OUTPUT_DIR = ${module_output_directory}\r
286DEBUG_DIR = ${module_debug_directory}\r
287DEST_DIR_OUTPUT = $(OUTPUT_DIR)\r
288DEST_DIR_DEBUG = $(DEBUG_DIR)\r
289\r
290#\r
291# Shell Command Macro\r
292#\r
293${BEGIN}${shell_command_code} = ${shell_command}\r
294${END}\r
295\r
296#\r
297# Tools definitions specific to this module\r
298#\r
299${BEGIN}${module_tool_definitions}\r
300${END}\r
301MAKE_FILE = ${makefile_path}\r
302\r
303#\r
304# Build Macro\r
305#\r
306${BEGIN}${file_macro}\r
307${END}\r
308\r
309COMMON_DEPS = ${BEGIN}${common_dependency_file} \\\r
310 ${END}\r
311\r
312#\r
313# Overridable Target Macro Definitions\r
314#\r
315FORCE_REBUILD = force_build\r
316INIT_TARGET = init\r
317PCH_TARGET =\r
318BC_TARGET = ${BEGIN}${backward_compatible_target} ${END}\r
319CODA_TARGET = ${BEGIN}${remaining_build_target} \\\r
320 ${END}\r
321\r
322#\r
323# Default target, which will build dependent libraries in addition to source files\r
324#\r
325\r
326all: mbuild\r
327\r
328\r
329#\r
330# Target used when called from platform makefile, which will bypass the build of dependent libraries\r
331#\r
332\r
333pbuild: $(INIT_TARGET) $(BC_TARGET) $(PCH_TARGET) $(CODA_TARGET)\r
334\r
335#\r
336# ModuleTarget\r
337#\r
338\r
339mbuild: $(INIT_TARGET) $(BC_TARGET) gen_libs $(PCH_TARGET) $(CODA_TARGET)\r
340\r
341#\r
342# Build Target used in multi-thread build mode, which will bypass the init and gen_libs targets\r
343#\r
344\r
345tbuild: $(BC_TARGET) $(PCH_TARGET) $(CODA_TARGET)\r
346\r
347#\r
348# Phony target which is used to force executing commands for a target\r
349#\r
350force_build:\r
351\t-@\r
352\r
353#\r
354# Target to update the FD\r
355#\r
356\r
357fds: mbuild gen_fds\r
358\r
359#\r
360# Initialization target: print build information and create necessary directories\r
361#\r
362init: info dirs\r
363\r
364info:\r
365\t-@echo Building ... $(MODULE_DIR)${separator}$(MODULE_FILE) [$(ARCH)]\r
366\r
367dirs:\r
368${BEGIN}\t-@${create_directory_command}\n${END}\r
369\r
370strdefs:\r
371\t-@$(CP) $(DEBUG_DIR)${separator}AutoGen.h $(DEBUG_DIR)${separator}$(MODULE_NAME)StrDefs.h\r
372\r
373#\r
374# GenLibsTarget\r
375#\r
376gen_libs:\r
377\t${BEGIN}@"$(MAKE)" $(MAKE_FLAGS) -f ${dependent_library_build_directory}${separator}${makefile_name}\r
378\t${END}@cd $(MODULE_BUILD_DIR)\r
379\r
380#\r
381# Build Flash Device Image\r
382#\r
383gen_fds:\r
384\t@"$(MAKE)" $(MAKE_FLAGS) -f $(BUILD_DIR)${separator}${makefile_name} fds\r
385\t@cd $(MODULE_BUILD_DIR)\r
386\r
387#\r
388# Individual Object Build Targets\r
389#\r
390${BEGIN}${file_build_target}\r
391${END}\r
392\r
393#\r
394# clean all intermediate files\r
395#\r
396clean:\r
397\t${BEGIN}${clean_command}\r
398\t${END}\t$(RM) AutoGenTimeStamp\r
399\r
400#\r
401# clean all generated files\r
402#\r
403cleanall:\r
404${BEGIN}\t${cleanall_command}\r
405${END}\t$(RM) *.pdb *.idb > NUL 2>&1\r
406\t$(RM) $(BIN_DIR)${separator}$(MODULE_NAME).efi\r
407\t$(RM) AutoGenTimeStamp\r
408\r
409#\r
410# clean all dependent libraries built\r
411#\r
412cleanlib:\r
413\t${BEGIN}-@${library_build_command} cleanall\r
414\t${END}@cd $(MODULE_BUILD_DIR)\n\n''')\r
415\r
416 _FILE_MACRO_TEMPLATE = TemplateString("${macro_name} = ${BEGIN} \\\n ${source_file}${END}\n")\r
417 _BUILD_TARGET_TEMPLATE = TemplateString("${BEGIN}${target} : ${deps}\n${END}\t${cmd}\n")\r
418\r
419 ## Constructor of ModuleMakefile\r
420 #\r
421 # @param ModuleAutoGen Object of ModuleAutoGen class\r
422 #\r
423 def __init__(self, ModuleAutoGen):\r
424 BuildFile.__init__(self, ModuleAutoGen)\r
425 self.PlatformInfo = self._AutoGenObject.PlatformInfo\r
426\r
427 self.ResultFileList = []\r
428 self.IntermediateDirectoryList = ["$(DEBUG_DIR)", "$(OUTPUT_DIR)"]\r
429\r
430 self.FileBuildTargetList = [] # [(src, target string)]\r
431 self.BuildTargetList = [] # [target string]\r
432 self.PendingBuildTargetList = [] # [FileBuildRule objects]\r
433 self.CommonFileDependency = []\r
434 self.FileListMacros = {}\r
435 self.ListFileMacros = {}\r
436\r
437 self.FileCache = {}\r
438 self.FileDependency = []\r
439 self.LibraryBuildCommandList = []\r
440 self.LibraryFileList = []\r
441 self.LibraryMakefileList = []\r
442 self.LibraryBuildDirectoryList = []\r
443 self.SystemLibraryList = []\r
444 self.Macros = OrderedDict()\r
445 self.Macros["OUTPUT_DIR" ] = self._AutoGenObject.Macros["OUTPUT_DIR"]\r
446 self.Macros["DEBUG_DIR" ] = self._AutoGenObject.Macros["DEBUG_DIR"]\r
447 self.Macros["MODULE_BUILD_DIR"] = self._AutoGenObject.Macros["MODULE_BUILD_DIR"]\r
448 self.Macros["BIN_DIR" ] = self._AutoGenObject.Macros["BIN_DIR"]\r
449 self.Macros["BUILD_DIR" ] = self._AutoGenObject.Macros["BUILD_DIR"]\r
450 self.Macros["WORKSPACE" ] = self._AutoGenObject.Macros["WORKSPACE"]\r
451 self.Macros["FFS_OUTPUT_DIR" ] = self._AutoGenObject.Macros["FFS_OUTPUT_DIR"]\r
452 self.GenFfsList = ModuleAutoGen.GenFfsList\r
453 self.MacroList = ['FFS_OUTPUT_DIR', 'MODULE_GUID', 'OUTPUT_DIR']\r
454 self.FfsOutputFileList = []\r
455\r
456 # Compose a dict object containing information used to do replacement in template\r
457 def _CreateTemplateDict(self):\r
458 if self._FileType not in self._SEP_:\r
459 EdkLogger.error("build", PARAMETER_INVALID, "Invalid Makefile type [%s]" % self._FileType,\r
460 ExtraData="[%s]" % str(self._AutoGenObject))\r
461 MyAgo = self._AutoGenObject\r
462 Separator = self._SEP_[self._FileType]\r
463\r
464 # break build if no source files and binary files are found\r
465 if len(MyAgo.SourceFileList) == 0 and len(MyAgo.BinaryFileList) == 0:\r
466 EdkLogger.error("build", AUTOGEN_ERROR, "No files to be built in module [%s, %s, %s]"\r
467 % (MyAgo.BuildTarget, MyAgo.ToolChain, MyAgo.Arch),\r
468 ExtraData="[%s]" % str(MyAgo))\r
469\r
470 # convert dependent libraries to build command\r
471 self.ProcessDependentLibrary()\r
472 if len(MyAgo.Module.ModuleEntryPointList) > 0:\r
473 ModuleEntryPoint = MyAgo.Module.ModuleEntryPointList[0]\r
474 else:\r
475 ModuleEntryPoint = "_ModuleEntryPoint"\r
476\r
477 # Intel EBC compiler enforces EfiMain\r
478 if MyAgo.AutoGenVersion < 0x00010005 and MyAgo.Arch == "EBC":\r
479 ArchEntryPoint = "EfiMain"\r
480 else:\r
481 ArchEntryPoint = ModuleEntryPoint\r
482\r
483 if MyAgo.Arch == "EBC":\r
484 # EBC compiler always use "EfiStart" as entry point. Only applies to EdkII modules\r
485 ImageEntryPoint = "EfiStart"\r
486 elif MyAgo.AutoGenVersion < 0x00010005:\r
487 # Edk modules use entry point specified in INF file\r
488 ImageEntryPoint = ModuleEntryPoint\r
489 else:\r
490 # EdkII modules always use "_ModuleEntryPoint" as entry point\r
491 ImageEntryPoint = "_ModuleEntryPoint"\r
492\r
493 for k, v in MyAgo.Module.Defines.iteritems():\r
494 if k not in MyAgo.Macros:\r
495 MyAgo.Macros[k] = v\r
496\r
497 if 'MODULE_ENTRY_POINT' not in MyAgo.Macros:\r
498 MyAgo.Macros['MODULE_ENTRY_POINT'] = ModuleEntryPoint\r
499 if 'ARCH_ENTRY_POINT' not in MyAgo.Macros:\r
500 MyAgo.Macros['ARCH_ENTRY_POINT'] = ArchEntryPoint\r
501 if 'IMAGE_ENTRY_POINT' not in MyAgo.Macros:\r
502 MyAgo.Macros['IMAGE_ENTRY_POINT'] = ImageEntryPoint\r
503\r
504 PCI_COMPRESS_Flag = False\r
505 for k, v in MyAgo.Module.Defines.iteritems():\r
506 if 'PCI_COMPRESS' == k and 'TRUE' == v:\r
507 PCI_COMPRESS_Flag = True\r
508\r
509 # tools definitions\r
510 ToolsDef = []\r
511 IncPrefix = self._INC_FLAG_[MyAgo.ToolChainFamily]\r
512 for Tool in MyAgo.BuildOption:\r
513 for Attr in MyAgo.BuildOption[Tool]:\r
514 Value = MyAgo.BuildOption[Tool][Attr]\r
515 if Attr == "FAMILY":\r
516 continue\r
517 elif Attr == "PATH":\r
518 ToolsDef.append("%s = %s" % (Tool, Value))\r
519 else:\r
520 # Don't generate MAKE_FLAGS in makefile. It's put in environment variable.\r
521 if Tool == "MAKE":\r
522 continue\r
523 # Remove duplicated include path, if any\r
524 if Attr == "FLAGS":\r
525 Value = RemoveDupOption(Value, IncPrefix, MyAgo.IncludePathList)\r
526 if Tool == "OPTROM" and PCI_COMPRESS_Flag:\r
527 ValueList = Value.split()\r
528 if ValueList:\r
529 for i, v in enumerate(ValueList):\r
530 if '-e' == v:\r
531 ValueList[i] = '-ec'\r
532 Value = ' '.join(ValueList)\r
533\r
534 ToolsDef.append("%s_%s = %s" % (Tool, Attr, Value))\r
535 ToolsDef.append("")\r
536\r
537 # generate the Response file and Response flag\r
538 RespDict = self.CommandExceedLimit()\r
539 RespFileList = os.path.join(MyAgo.OutputDir, 'respfilelist.txt')\r
540 if RespDict:\r
541 RespFileListContent = ''\r
542 for Resp in RespDict:\r
543 RespFile = os.path.join(MyAgo.OutputDir, str(Resp).lower() + '.txt')\r
544 StrList = RespDict[Resp].split(' ')\r
545 UnexpandMacro = []\r
546 NewStr = []\r
547 for Str in StrList:\r
548 if '$' in Str:\r
549 UnexpandMacro.append(Str)\r
550 else:\r
551 NewStr.append(Str)\r
552 UnexpandMacroStr = ' '.join(UnexpandMacro)\r
553 NewRespStr = ' '.join(NewStr)\r
554 SaveFileOnChange(RespFile, NewRespStr, False)\r
555 ToolsDef.append("%s = %s" % (Resp, UnexpandMacroStr + ' @' + RespFile))\r
556 RespFileListContent += '@' + RespFile + os.linesep\r
557 RespFileListContent += NewRespStr + os.linesep\r
558 SaveFileOnChange(RespFileList, RespFileListContent, False)\r
559 else:\r
560 if os.path.exists(RespFileList):\r
561 os.remove(RespFileList)\r
562\r
563 # convert source files and binary files to build targets\r
564 self.ResultFileList = [str(T.Target) for T in MyAgo.CodaTargetList]\r
565 if len(self.ResultFileList) == 0 and len(MyAgo.SourceFileList) != 0:\r
566 EdkLogger.error("build", AUTOGEN_ERROR, "Nothing to build",\r
567 ExtraData="[%s]" % str(MyAgo))\r
568\r
569 self.ProcessBuildTargetList()\r
570 self.ParserGenerateFfsCmd()\r
571\r
572 # Generate macros used to represent input files\r
573 FileMacroList = [] # macro name = file list\r
574 for FileListMacro in self.FileListMacros:\r
575 FileMacro = self._FILE_MACRO_TEMPLATE.Replace(\r
576 {\r
577 "macro_name" : FileListMacro,\r
578 "source_file" : self.FileListMacros[FileListMacro]\r
579 }\r
580 )\r
581 FileMacroList.append(FileMacro)\r
582\r
583 # INC_LIST is special\r
584 FileMacro = ""\r
585 IncludePathList = []\r
586 for P in MyAgo.IncludePathList:\r
587 IncludePathList.append(IncPrefix + self.PlaceMacro(P, self.Macros))\r
588 if FileBuildRule.INC_LIST_MACRO in self.ListFileMacros:\r
589 self.ListFileMacros[FileBuildRule.INC_LIST_MACRO].append(IncPrefix + P)\r
590 FileMacro += self._FILE_MACRO_TEMPLATE.Replace(\r
591 {\r
592 "macro_name" : "INC",\r
593 "source_file" : IncludePathList\r
594 }\r
595 )\r
596 FileMacroList.append(FileMacro)\r
597\r
598 # Generate macros used to represent files containing list of input files\r
599 for ListFileMacro in self.ListFileMacros:\r
600 ListFileName = os.path.join(MyAgo.OutputDir, "%s.lst" % ListFileMacro.lower()[:len(ListFileMacro) - 5])\r
601 FileMacroList.append("%s = %s" % (ListFileMacro, ListFileName))\r
602 SaveFileOnChange(\r
603 ListFileName,\r
604 "\n".join(self.ListFileMacros[ListFileMacro]),\r
605 False\r
606 )\r
607\r
608 # Edk modules need <BaseName>StrDefs.h for string ID\r
609 #if MyAgo.AutoGenVersion < 0x00010005 and len(MyAgo.UnicodeFileList) > 0:\r
610 # BcTargetList = ['strdefs']\r
611 #else:\r
612 # BcTargetList = []\r
613 BcTargetList = []\r
614\r
615 MakefileName = self._FILE_NAME_[self._FileType]\r
616 LibraryMakeCommandList = []\r
617 for D in self.LibraryBuildDirectoryList:\r
618 Command = self._MAKE_TEMPLATE_[self._FileType] % {"file":os.path.join(D, MakefileName)}\r
619 LibraryMakeCommandList.append(Command)\r
620\r
621 package_rel_dir = MyAgo.SourceDir\r
622 current_dir = self.Macros["WORKSPACE"]\r
623 found = False\r
624 while not found and os.sep in package_rel_dir:\r
625 index = package_rel_dir.index(os.sep)\r
626 current_dir = mws.join(current_dir, package_rel_dir[:index])\r
627 if os.path.exists(current_dir):\r
628 for fl in os.listdir(current_dir):\r
629 if fl.endswith('.dec'):\r
630 found = True\r
631 break\r
632 package_rel_dir = package_rel_dir[index + 1:]\r
633\r
634 MakefileTemplateDict = {\r
635 "makefile_header" : self._FILE_HEADER_[self._FileType],\r
636 "makefile_path" : os.path.join("$(MODULE_BUILD_DIR)", MakefileName),\r
637 "makefile_name" : MakefileName,\r
638 "platform_name" : self.PlatformInfo.Name,\r
639 "platform_guid" : self.PlatformInfo.Guid,\r
640 "platform_version" : self.PlatformInfo.Version,\r
641 "platform_relative_directory": self.PlatformInfo.SourceDir,\r
642 "platform_output_directory" : self.PlatformInfo.OutputDir,\r
643 "ffs_output_directory" : MyAgo.Macros["FFS_OUTPUT_DIR"],\r
644 "platform_dir" : MyAgo.Macros["PLATFORM_DIR"],\r
645\r
646 "module_name" : MyAgo.Name,\r
647 "module_guid" : MyAgo.Guid,\r
648 "module_name_guid" : MyAgo.UniqueBaseName,\r
649 "module_version" : MyAgo.Version,\r
650 "module_type" : MyAgo.ModuleType,\r
651 "module_file" : MyAgo.MetaFile.Name,\r
652 "module_file_base_name" : MyAgo.MetaFile.BaseName,\r
653 "module_relative_directory" : MyAgo.SourceDir,\r
654 "module_dir" : mws.join (self.Macros["WORKSPACE"], MyAgo.SourceDir),\r
655 "package_relative_directory": package_rel_dir,\r
656 "module_extra_defines" : ["%s = %s" % (k, v) for k, v in MyAgo.Module.Defines.iteritems()],\r
657\r
658 "architecture" : MyAgo.Arch,\r
659 "toolchain_tag" : MyAgo.ToolChain,\r
660 "build_target" : MyAgo.BuildTarget,\r
661\r
662 "platform_build_directory" : self.PlatformInfo.BuildDir,\r
663 "module_build_directory" : MyAgo.BuildDir,\r
664 "module_output_directory" : MyAgo.OutputDir,\r
665 "module_debug_directory" : MyAgo.DebugDir,\r
666\r
667 "separator" : Separator,\r
668 "module_tool_definitions" : ToolsDef,\r
669\r
670 "shell_command_code" : self._SHELL_CMD_[self._FileType].keys(),\r
671 "shell_command" : self._SHELL_CMD_[self._FileType].values(),\r
672\r
673 "module_entry_point" : ModuleEntryPoint,\r
674 "image_entry_point" : ImageEntryPoint,\r
675 "arch_entry_point" : ArchEntryPoint,\r
676 "remaining_build_target" : self.ResultFileList,\r
677 "common_dependency_file" : self.CommonFileDependency,\r
678 "create_directory_command" : self.GetCreateDirectoryCommand(self.IntermediateDirectoryList),\r
679 "clean_command" : self.GetRemoveDirectoryCommand(["$(OUTPUT_DIR)"]),\r
680 "cleanall_command" : self.GetRemoveDirectoryCommand(["$(DEBUG_DIR)", "$(OUTPUT_DIR)"]),\r
681 "dependent_library_build_directory" : self.LibraryBuildDirectoryList,\r
682 "library_build_command" : LibraryMakeCommandList,\r
683 "file_macro" : FileMacroList,\r
684 "file_build_target" : self.BuildTargetList,\r
685 "backward_compatible_target": BcTargetList,\r
686 }\r
687\r
688 return MakefileTemplateDict\r
689\r
690 def ParserGenerateFfsCmd(self):\r
691 #Add Ffs cmd to self.BuildTargetList\r
692 OutputFile = ''\r
693 DepsFileList = []\r
694\r
695 for Cmd in self.GenFfsList:\r
696 if Cmd[2]:\r
697 for CopyCmd in Cmd[2]:\r
698 Src, Dst = CopyCmd\r
699 Src = self.ReplaceMacro(Src)\r
700 Dst = self.ReplaceMacro(Dst)\r
701 if Dst not in self.ResultFileList:\r
702 self.ResultFileList.append(Dst)\r
703 if '%s :' %(Dst) not in self.BuildTargetList:\r
704 self.BuildTargetList.append("%s :" %(Dst))\r
705 self.BuildTargetList.append('\t' + self._CP_TEMPLATE_[self._FileType] %{'Src': Src, 'Dst': Dst})\r
706\r
707 FfsCmdList = Cmd[0]\r
708 for index, Str in enumerate(FfsCmdList):\r
709 if '-o' == Str:\r
710 OutputFile = FfsCmdList[index + 1]\r
711 if '-i' == Str:\r
712 if DepsFileList == []:\r
713 DepsFileList = [FfsCmdList[index + 1]]\r
714 else:\r
715 DepsFileList.append(FfsCmdList[index + 1])\r
716 DepsFileString = ' '.join(DepsFileList).strip()\r
717 if DepsFileString == '':\r
718 continue\r
719 OutputFile = self.ReplaceMacro(OutputFile)\r
720 self.ResultFileList.append(OutputFile)\r
721 DepsFileString = self.ReplaceMacro(DepsFileString)\r
722 self.BuildTargetList.append('%s : %s' % (OutputFile, DepsFileString))\r
723 CmdString = ' '.join(FfsCmdList).strip()\r
724 CmdString = self.ReplaceMacro(CmdString)\r
725 self.BuildTargetList.append('\t%s' % CmdString)\r
726\r
727 self.ParseSecCmd(DepsFileList, Cmd[1])\r
728 for SecOutputFile, SecDepsFile, SecCmd in self.FfsOutputFileList :\r
729 self.BuildTargetList.append('%s : %s' % (self.ReplaceMacro(SecOutputFile), self.ReplaceMacro(SecDepsFile)))\r
730 self.BuildTargetList.append('\t%s' % self.ReplaceMacro(SecCmd))\r
731 self.FfsOutputFileList = []\r
732\r
733 def ParseSecCmd(self, OutputFileList, CmdTuple):\r
734 for OutputFile in OutputFileList:\r
735 for SecCmdStr in CmdTuple:\r
736 SecDepsFileList = []\r
737 SecCmdList = SecCmdStr.split()\r
738 CmdName = SecCmdList[0]\r
739 for index, CmdItem in enumerate(SecCmdList):\r
740 if '-o' == CmdItem and OutputFile == SecCmdList[index + 1]:\r
741 index = index + 1\r
742 while index + 1 < len(SecCmdList):\r
743 if not SecCmdList[index+1].startswith('-'):\r
744 SecDepsFileList.append(SecCmdList[index + 1])\r
745 index = index + 1\r
746 if CmdName == 'Trim':\r
747 SecDepsFileList.append(os.path.join('$(DEBUG_DIR)', os.path.basename(OutputFile).replace('offset', 'efi')))\r
748 if OutputFile.endswith('.ui') or OutputFile.endswith('.ver'):\r
749 SecDepsFileList.append(os.path.join('$(MODULE_DIR)', '$(MODULE_FILE)'))\r
750 self.FfsOutputFileList.append((OutputFile, ' '.join(SecDepsFileList), SecCmdStr))\r
751 if len(SecDepsFileList) > 0:\r
752 self.ParseSecCmd(SecDepsFileList, CmdTuple)\r
753 break\r
754 else:\r
755 continue\r
756\r
757 def ReplaceMacro(self, str):\r
758 for Macro in self.MacroList:\r
759 if self._AutoGenObject.Macros[Macro] and self._AutoGenObject.Macros[Macro] in str:\r
760 str = str.replace(self._AutoGenObject.Macros[Macro], '$(' + Macro + ')')\r
761 return str\r
762\r
763 def CommandExceedLimit(self):\r
764 FlagDict = {\r
765 'CC' : { 'Macro' : '$(CC_FLAGS)', 'Value' : False},\r
766 'PP' : { 'Macro' : '$(PP_FLAGS)', 'Value' : False},\r
767 'APP' : { 'Macro' : '$(APP_FLAGS)', 'Value' : False},\r
768 'ASLPP' : { 'Macro' : '$(ASLPP_FLAGS)', 'Value' : False},\r
769 'VFRPP' : { 'Macro' : '$(VFRPP_FLAGS)', 'Value' : False},\r
770 'ASM' : { 'Macro' : '$(ASM_FLAGS)', 'Value' : False},\r
771 'ASLCC' : { 'Macro' : '$(ASLCC_FLAGS)', 'Value' : False},\r
772 }\r
773\r
774 RespDict = {}\r
775 FileTypeList = []\r
776 IncPrefix = self._INC_FLAG_[self._AutoGenObject.ToolChainFamily]\r
777\r
778 # base on the source files to decide the file type\r
779 for File in self._AutoGenObject.SourceFileList:\r
780 for type in self._AutoGenObject.FileTypes:\r
781 if File in self._AutoGenObject.FileTypes[type]:\r
782 if type not in FileTypeList:\r
783 FileTypeList.append(type)\r
784\r
785 # calculate the command-line length\r
786 if FileTypeList:\r
787 for type in FileTypeList:\r
788 BuildTargets = self._AutoGenObject.BuildRules[type].BuildTargets\r
789 for Target in BuildTargets:\r
790 CommandList = BuildTargets[Target].Commands\r
791 for SingleCommand in CommandList:\r
792 Tool = ''\r
793 SingleCommandLength = len(SingleCommand)\r
794 SingleCommandList = SingleCommand.split()\r
795 if len(SingleCommandList) > 0:\r
796 for Flag in FlagDict:\r
797 if '$('+ Flag +')' in SingleCommandList[0]:\r
798 Tool = Flag\r
799 break\r
800 if Tool:\r
801 if 'PATH' not in self._AutoGenObject._BuildOption[Tool]:\r
802 EdkLogger.error("build", AUTOGEN_ERROR, "%s_PATH doesn't exist in %s ToolChain and %s Arch." %(Tool, self._AutoGenObject.ToolChain, self._AutoGenObject.Arch), ExtraData="[%s]" % str(self._AutoGenObject))\r
803 SingleCommandLength += len(self._AutoGenObject._BuildOption[Tool]['PATH'])\r
804 for item in SingleCommandList[1:]:\r
805 if FlagDict[Tool]['Macro'] in item:\r
806 if 'FLAGS' not in self._AutoGenObject._BuildOption[Tool]:\r
807 EdkLogger.error("build", AUTOGEN_ERROR, "%s_FLAGS doesn't exist in %s ToolChain and %s Arch." %(Tool, self._AutoGenObject.ToolChain, self._AutoGenObject.Arch), ExtraData="[%s]" % str(self._AutoGenObject))\r
808 Str = self._AutoGenObject._BuildOption[Tool]['FLAGS']\r
809 for Option in self._AutoGenObject.BuildOption:\r
810 for Attr in self._AutoGenObject.BuildOption[Option]:\r
811 if Str.find(Option + '_' + Attr) != -1:\r
812 Str = Str.replace('$(' + Option + '_' + Attr + ')', self._AutoGenObject.BuildOption[Option][Attr])\r
813 while(Str.find('$(') != -1):\r
814 for macro in self._AutoGenObject.Macros:\r
815 MacroName = '$('+ macro + ')'\r
816 if (Str.find(MacroName) != -1):\r
817 Str = Str.replace(MacroName, self._AutoGenObject.Macros[macro])\r
818 break\r
819 else:\r
820 break\r
821 SingleCommandLength += len(Str)\r
822 elif '$(INC)' in item:\r
823 SingleCommandLength += self._AutoGenObject.IncludePathLength + len(IncPrefix) * len(self._AutoGenObject._IncludePathList)\r
824 elif item.find('$(') != -1:\r
825 Str = item\r
826 for Option in self._AutoGenObject.BuildOption:\r
827 for Attr in self._AutoGenObject.BuildOption[Option]:\r
828 if Str.find(Option + '_' + Attr) != -1:\r
829 Str = Str.replace('$(' + Option + '_' + Attr + ')', self._AutoGenObject.BuildOption[Option][Attr])\r
830 while(Str.find('$(') != -1):\r
831 for macro in self._AutoGenObject.Macros:\r
832 MacroName = '$('+ macro + ')'\r
833 if (Str.find(MacroName) != -1):\r
834 Str = Str.replace(MacroName, self._AutoGenObject.Macros[macro])\r
835 break\r
836 else:\r
837 break\r
838 SingleCommandLength += len(Str)\r
839\r
840 if SingleCommandLength > GlobalData.gCommandMaxLength:\r
841 FlagDict[Tool]['Value'] = True\r
842\r
843 # generate the response file content by combine the FLAGS and INC\r
844 for Flag in FlagDict:\r
845 if FlagDict[Flag]['Value']:\r
846 Key = Flag + '_RESP'\r
847 RespMacro = FlagDict[Flag]['Macro'].replace('FLAGS', 'RESP')\r
848 Value = self._AutoGenObject.BuildOption[Flag]['FLAGS']\r
849 for inc in self._AutoGenObject._IncludePathList:\r
850 Value += ' ' + IncPrefix + inc\r
851 for Option in self._AutoGenObject.BuildOption:\r
852 for Attr in self._AutoGenObject.BuildOption[Option]:\r
853 if Value.find(Option + '_' + Attr) != -1:\r
854 Value = Value.replace('$(' + Option + '_' + Attr + ')', self._AutoGenObject.BuildOption[Option][Attr])\r
855 while (Value.find('$(') != -1):\r
856 for macro in self._AutoGenObject.Macros:\r
857 MacroName = '$('+ macro + ')'\r
858 if (Value.find(MacroName) != -1):\r
859 Value = Value.replace(MacroName, self._AutoGenObject.Macros[macro])\r
860 break\r
861 else:\r
862 break\r
863\r
864 if self._AutoGenObject.ToolChainFamily == 'GCC':\r
865 RespDict[Key] = Value.replace('\\', '/')\r
866 else:\r
867 RespDict[Key] = Value\r
868 for Target in BuildTargets:\r
869 for i, SingleCommand in enumerate(BuildTargets[Target].Commands):\r
870 if FlagDict[Flag]['Macro'] in SingleCommand:\r
871 BuildTargets[Target].Commands[i] = SingleCommand.replace('$(INC)', '').replace(FlagDict[Flag]['Macro'], RespMacro)\r
872 return RespDict\r
873\r
874 def ProcessBuildTargetList(self):\r
875 #\r
876 # Search dependency file list for each source file\r
877 #\r
878 ForceIncludedFile = []\r
879 for File in self._AutoGenObject.AutoGenFileList:\r
880 if File.Ext == '.h':\r
881 ForceIncludedFile.append(File)\r
882 SourceFileList = []\r
883 OutPutFileList = []\r
884 for Target in self._AutoGenObject.IntroTargetList:\r
885 SourceFileList.extend(Target.Inputs)\r
886 OutPutFileList.extend(Target.Outputs)\r
887\r
888 if OutPutFileList:\r
889 for Item in OutPutFileList:\r
890 if Item in SourceFileList:\r
891 SourceFileList.remove(Item)\r
892\r
893 self.FileDependency = self.GetFileDependency(\r
894 SourceFileList,\r
895 ForceIncludedFile,\r
896 self._AutoGenObject.IncludePathList + self._AutoGenObject.BuildOptionIncPathList\r
897 )\r
898 DepSet = None\r
899 for File in self.FileDependency:\r
900 if not self.FileDependency[File]:\r
901 self.FileDependency[File] = ['$(FORCE_REBUILD)']\r
902 continue\r
903\r
904 self._AutoGenObject.AutoGenDepSet |= set(self.FileDependency[File])\r
905\r
906 # skip non-C files\r
907 if File.Ext not in [".c", ".C"] or File.Name == "AutoGen.c":\r
908 continue\r
909 elif DepSet is None:\r
910 DepSet = set(self.FileDependency[File])\r
911 else:\r
912 DepSet &= set(self.FileDependency[File])\r
913 # in case nothing in SourceFileList\r
914 if DepSet is None:\r
915 DepSet = set()\r
916 #\r
917 # Extract common files list in the dependency files\r
918 #\r
919 for File in DepSet:\r
920 self.CommonFileDependency.append(self.PlaceMacro(File.Path, self.Macros))\r
921\r
922 for File in self.FileDependency:\r
923 # skip non-C files\r
924 if File.Ext not in [".c", ".C"] or File.Name == "AutoGen.c":\r
925 continue\r
926 NewDepSet = set(self.FileDependency[File])\r
927 NewDepSet -= DepSet\r
928 self.FileDependency[File] = ["$(COMMON_DEPS)"] + list(NewDepSet)\r
929\r
930 # Convert target description object to target string in makefile\r
931 for Type in self._AutoGenObject.Targets:\r
932 for T in self._AutoGenObject.Targets[Type]:\r
933 # Generate related macros if needed\r
934 if T.GenFileListMacro and T.FileListMacro not in self.FileListMacros:\r
935 self.FileListMacros[T.FileListMacro] = []\r
936 if T.GenListFile and T.ListFileMacro not in self.ListFileMacros:\r
937 self.ListFileMacros[T.ListFileMacro] = []\r
938 if T.GenIncListFile and T.IncListFileMacro not in self.ListFileMacros:\r
939 self.ListFileMacros[T.IncListFileMacro] = []\r
940\r
941 Deps = []\r
942 # Add force-dependencies\r
943 for Dep in T.Dependencies:\r
944 Deps.append(self.PlaceMacro(str(Dep), self.Macros))\r
945 # Add inclusion-dependencies\r
946 if len(T.Inputs) == 1 and T.Inputs[0] in self.FileDependency:\r
947 for F in self.FileDependency[T.Inputs[0]]:\r
948 Deps.append(self.PlaceMacro(str(F), self.Macros))\r
949 # Add source-dependencies\r
950 for F in T.Inputs:\r
951 NewFile = self.PlaceMacro(str(F), self.Macros)\r
952 # In order to use file list macro as dependency\r
953 if T.GenListFile:\r
954 # gnu tools need forward slash path separater, even on Windows\r
955 self.ListFileMacros[T.ListFileMacro].append(str(F).replace ('\\', '/'))\r
956 self.FileListMacros[T.FileListMacro].append(NewFile)\r
957 elif T.GenFileListMacro:\r
958 self.FileListMacros[T.FileListMacro].append(NewFile)\r
959 else:\r
960 Deps.append(NewFile)\r
961\r
962 # Use file list macro as dependency\r
963 if T.GenFileListMacro:\r
964 Deps.append("$(%s)" % T.FileListMacro)\r
965 if Type in [TAB_OBJECT_FILE, TAB_STATIC_LIBRARY]:\r
966 Deps.append("$(%s)" % T.ListFileMacro)\r
967\r
968 TargetDict = {\r
969 "target" : self.PlaceMacro(T.Target.Path, self.Macros),\r
970 "cmd" : "\n\t".join(T.Commands),\r
971 "deps" : Deps\r
972 }\r
973 self.BuildTargetList.append(self._BUILD_TARGET_TEMPLATE.Replace(TargetDict))\r
974\r
975 ## For creating makefile targets for dependent libraries\r
976 def ProcessDependentLibrary(self):\r
977 for LibraryAutoGen in self._AutoGenObject.LibraryAutoGenList:\r
978 if not LibraryAutoGen.IsBinaryModule:\r
979 self.LibraryBuildDirectoryList.append(self.PlaceMacro(LibraryAutoGen.BuildDir, self.Macros))\r
980\r
981 ## Return a list containing source file's dependencies\r
982 #\r
983 # @param FileList The list of source files\r
984 # @param ForceInculeList The list of files which will be included forcely\r
985 # @param SearchPathList The list of search path\r
986 #\r
987 # @retval dict The mapping between source file path and its dependencies\r
988 #\r
989 def GetFileDependency(self, FileList, ForceInculeList, SearchPathList):\r
990 Dependency = {}\r
991 for F in FileList:\r
992 Dependency[F] = self.GetDependencyList(F, ForceInculeList, SearchPathList)\r
993 return Dependency\r
994\r
995 ## Find dependencies for one source file\r
996 #\r
997 # By searching recursively "#include" directive in file, find out all the\r
998 # files needed by given source file. The dependecies will be only searched\r
999 # in given search path list.\r
1000 #\r
1001 # @param File The source file\r
1002 # @param ForceInculeList The list of files which will be included forcely\r
1003 # @param SearchPathList The list of search path\r
1004 #\r
1005 # @retval list The list of files the given source file depends on\r
1006 #\r
1007 def GetDependencyList(self, File, ForceList, SearchPathList):\r
1008 EdkLogger.debug(EdkLogger.DEBUG_1, "Try to get dependency files for %s" % File)\r
1009 FileStack = [File] + ForceList\r
1010 DependencySet = set()\r
1011\r
1012 if self._AutoGenObject.Arch not in gDependencyDatabase:\r
1013 gDependencyDatabase[self._AutoGenObject.Arch] = {}\r
1014 DepDb = gDependencyDatabase[self._AutoGenObject.Arch]\r
1015\r
1016 while len(FileStack) > 0:\r
1017 F = FileStack.pop()\r
1018\r
1019 FullPathDependList = []\r
1020 if F in self.FileCache:\r
1021 for CacheFile in self.FileCache[F]:\r
1022 FullPathDependList.append(CacheFile)\r
1023 if CacheFile not in DependencySet:\r
1024 FileStack.append(CacheFile)\r
1025 DependencySet.update(FullPathDependList)\r
1026 continue\r
1027\r
1028 CurrentFileDependencyList = []\r
1029 if F in DepDb:\r
1030 CurrentFileDependencyList = DepDb[F]\r
1031 else:\r
1032 try:\r
1033 Fd = open(F.Path, 'r')\r
1034 except BaseException as X:\r
1035 EdkLogger.error("build", FILE_OPEN_FAILURE, ExtraData=F.Path + "\n\t" + str(X))\r
1036\r
1037 FileContent = Fd.read()\r
1038 Fd.close()\r
1039 if len(FileContent) == 0:\r
1040 continue\r
1041\r
1042 if FileContent[0] == 0xff or FileContent[0] == 0xfe:\r
1043 FileContent = unicode(FileContent, "utf-16")\r
1044 IncludedFileList = gIncludePattern.findall(FileContent)\r
1045\r
1046 for Inc in IncludedFileList:\r
1047 Inc = Inc.strip()\r
1048 # if there's macro used to reference header file, expand it\r
1049 HeaderList = gMacroPattern.findall(Inc)\r
1050 if len(HeaderList) == 1 and len(HeaderList[0]) == 2:\r
1051 HeaderType = HeaderList[0][0]\r
1052 HeaderKey = HeaderList[0][1]\r
1053 if HeaderType in gIncludeMacroConversion:\r
1054 Inc = gIncludeMacroConversion[HeaderType] % {"HeaderKey" : HeaderKey}\r
1055 else:\r
1056 # not known macro used in #include, always build the file by\r
1057 # returning a empty dependency\r
1058 self.FileCache[File] = []\r
1059 return []\r
1060 Inc = os.path.normpath(Inc)\r
1061 CurrentFileDependencyList.append(Inc)\r
1062 DepDb[F] = CurrentFileDependencyList\r
1063\r
1064 CurrentFilePath = F.Dir\r
1065 PathList = [CurrentFilePath] + SearchPathList\r
1066 for Inc in CurrentFileDependencyList:\r
1067 for SearchPath in PathList:\r
1068 FilePath = os.path.join(SearchPath, Inc)\r
1069 if FilePath in gIsFileMap:\r
1070 if not gIsFileMap[FilePath]:\r
1071 continue\r
1072 # If isfile is called too many times, the performance is slow down.\r
1073 elif not os.path.isfile(FilePath):\r
1074 gIsFileMap[FilePath] = False\r
1075 continue\r
1076 else:\r
1077 gIsFileMap[FilePath] = True\r
1078 FilePath = PathClass(FilePath)\r
1079 FullPathDependList.append(FilePath)\r
1080 if FilePath not in DependencySet:\r
1081 FileStack.append(FilePath)\r
1082 break\r
1083 else:\r
1084 EdkLogger.debug(EdkLogger.DEBUG_9, "%s included by %s was not found "\\r
1085 "in any given path:\n\t%s" % (Inc, F, "\n\t".join(SearchPathList)))\r
1086\r
1087 self.FileCache[F] = FullPathDependList\r
1088 DependencySet.update(FullPathDependList)\r
1089\r
1090 DependencySet.update(ForceList)\r
1091 if File in DependencySet:\r
1092 DependencySet.remove(File)\r
1093 DependencyList = list(DependencySet) # remove duplicate ones\r
1094\r
1095 return DependencyList\r
1096\r
1097 _TemplateDict = property(_CreateTemplateDict)\r
1098\r
1099## CustomMakefile class\r
1100#\r
1101# This class encapsules makefie and its generation for module. It uses template to generate\r
1102# the content of makefile. The content of makefile will be got from ModuleAutoGen object.\r
1103#\r
1104class CustomMakefile(BuildFile):\r
1105 ## template used to generate the makefile for module with custom makefile\r
1106 _TEMPLATE_ = TemplateString('''\\r
1107${makefile_header}\r
1108\r
1109#\r
1110# Platform Macro Definition\r
1111#\r
1112PLATFORM_NAME = ${platform_name}\r
1113PLATFORM_GUID = ${platform_guid}\r
1114PLATFORM_VERSION = ${platform_version}\r
1115PLATFORM_RELATIVE_DIR = ${platform_relative_directory}\r
1116PLATFORM_DIR = ${platform_dir}\r
1117PLATFORM_OUTPUT_DIR = ${platform_output_directory}\r
1118\r
1119#\r
1120# Module Macro Definition\r
1121#\r
1122MODULE_NAME = ${module_name}\r
1123MODULE_GUID = ${module_guid}\r
1124MODULE_NAME_GUID = ${module_name_guid}\r
1125MODULE_VERSION = ${module_version}\r
1126MODULE_TYPE = ${module_type}\r
1127MODULE_FILE = ${module_file}\r
1128MODULE_FILE_BASE_NAME = ${module_file_base_name}\r
1129BASE_NAME = $(MODULE_NAME)\r
1130MODULE_RELATIVE_DIR = ${module_relative_directory}\r
1131MODULE_DIR = ${module_dir}\r
1132\r
1133#\r
1134# Build Configuration Macro Definition\r
1135#\r
1136ARCH = ${architecture}\r
1137TOOLCHAIN = ${toolchain_tag}\r
1138TOOLCHAIN_TAG = ${toolchain_tag}\r
1139TARGET = ${build_target}\r
1140\r
1141#\r
1142# Build Directory Macro Definition\r
1143#\r
1144# PLATFORM_BUILD_DIR = ${platform_build_directory}\r
1145BUILD_DIR = ${platform_build_directory}\r
1146BIN_DIR = $(BUILD_DIR)${separator}${architecture}\r
1147LIB_DIR = $(BIN_DIR)\r
1148MODULE_BUILD_DIR = ${module_build_directory}\r
1149OUTPUT_DIR = ${module_output_directory}\r
1150DEBUG_DIR = ${module_debug_directory}\r
1151DEST_DIR_OUTPUT = $(OUTPUT_DIR)\r
1152DEST_DIR_DEBUG = $(DEBUG_DIR)\r
1153\r
1154#\r
1155# Tools definitions specific to this module\r
1156#\r
1157${BEGIN}${module_tool_definitions}\r
1158${END}\r
1159MAKE_FILE = ${makefile_path}\r
1160\r
1161#\r
1162# Shell Command Macro\r
1163#\r
1164${BEGIN}${shell_command_code} = ${shell_command}\r
1165${END}\r
1166\r
1167${custom_makefile_content}\r
1168\r
1169#\r
1170# Target used when called from platform makefile, which will bypass the build of dependent libraries\r
1171#\r
1172\r
1173pbuild: init all\r
1174\r
1175\r
1176#\r
1177# ModuleTarget\r
1178#\r
1179\r
1180mbuild: init all\r
1181\r
1182#\r
1183# Build Target used in multi-thread build mode, which no init target is needed\r
1184#\r
1185\r
1186tbuild: all\r
1187\r
1188#\r
1189# Initialization target: print build information and create necessary directories\r
1190#\r
1191init:\r
1192\t-@echo Building ... $(MODULE_DIR)${separator}$(MODULE_FILE) [$(ARCH)]\r
1193${BEGIN}\t-@${create_directory_command}\n${END}\\r
1194\r
1195''')\r
1196\r
1197 ## Constructor of CustomMakefile\r
1198 #\r
1199 # @param ModuleAutoGen Object of ModuleAutoGen class\r
1200 #\r
1201 def __init__(self, ModuleAutoGen):\r
1202 BuildFile.__init__(self, ModuleAutoGen)\r
1203 self.PlatformInfo = self._AutoGenObject.PlatformInfo\r
1204 self.IntermediateDirectoryList = ["$(DEBUG_DIR)", "$(OUTPUT_DIR)"]\r
1205\r
1206 # Compose a dict object containing information used to do replacement in template\r
1207 def _CreateTemplateDict(self):\r
1208 Separator = self._SEP_[self._FileType]\r
1209 MyAgo = self._AutoGenObject\r
1210 if self._FileType not in MyAgo.CustomMakefile:\r
1211 EdkLogger.error('build', OPTION_NOT_SUPPORTED, "No custom makefile for %s" % self._FileType,\r
1212 ExtraData="[%s]" % str(MyAgo))\r
1213 MakefilePath = mws.join(\r
1214 MyAgo.WorkspaceDir,\r
1215 MyAgo.CustomMakefile[self._FileType]\r
1216 )\r
1217 try:\r
1218 CustomMakefile = open(MakefilePath, 'r').read()\r
1219 except:\r
1220 EdkLogger.error('build', FILE_OPEN_FAILURE, File=str(MyAgo),\r
1221 ExtraData=MyAgo.CustomMakefile[self._FileType])\r
1222\r
1223 # tools definitions\r
1224 ToolsDef = []\r
1225 for Tool in MyAgo.BuildOption:\r
1226 # Don't generate MAKE_FLAGS in makefile. It's put in environment variable.\r
1227 if Tool == "MAKE":\r
1228 continue\r
1229 for Attr in MyAgo.BuildOption[Tool]:\r
1230 if Attr == "FAMILY":\r
1231 continue\r
1232 elif Attr == "PATH":\r
1233 ToolsDef.append("%s = %s" % (Tool, MyAgo.BuildOption[Tool][Attr]))\r
1234 else:\r
1235 ToolsDef.append("%s_%s = %s" % (Tool, Attr, MyAgo.BuildOption[Tool][Attr]))\r
1236 ToolsDef.append("")\r
1237\r
1238 MakefileName = self._FILE_NAME_[self._FileType]\r
1239 MakefileTemplateDict = {\r
1240 "makefile_header" : self._FILE_HEADER_[self._FileType],\r
1241 "makefile_path" : os.path.join("$(MODULE_BUILD_DIR)", MakefileName),\r
1242 "platform_name" : self.PlatformInfo.Name,\r
1243 "platform_guid" : self.PlatformInfo.Guid,\r
1244 "platform_version" : self.PlatformInfo.Version,\r
1245 "platform_relative_directory": self.PlatformInfo.SourceDir,\r
1246 "platform_output_directory" : self.PlatformInfo.OutputDir,\r
1247 "platform_dir" : MyAgo.Macros["PLATFORM_DIR"],\r
1248\r
1249 "module_name" : MyAgo.Name,\r
1250 "module_guid" : MyAgo.Guid,\r
1251 "module_name_guid" : MyAgo.UniqueBaseName,\r
1252 "module_version" : MyAgo.Version,\r
1253 "module_type" : MyAgo.ModuleType,\r
1254 "module_file" : MyAgo.MetaFile,\r
1255 "module_file_base_name" : MyAgo.MetaFile.BaseName,\r
1256 "module_relative_directory" : MyAgo.SourceDir,\r
1257 "module_dir" : mws.join (MyAgo.WorkspaceDir, MyAgo.SourceDir),\r
1258\r
1259 "architecture" : MyAgo.Arch,\r
1260 "toolchain_tag" : MyAgo.ToolChain,\r
1261 "build_target" : MyAgo.BuildTarget,\r
1262\r
1263 "platform_build_directory" : self.PlatformInfo.BuildDir,\r
1264 "module_build_directory" : MyAgo.BuildDir,\r
1265 "module_output_directory" : MyAgo.OutputDir,\r
1266 "module_debug_directory" : MyAgo.DebugDir,\r
1267\r
1268 "separator" : Separator,\r
1269 "module_tool_definitions" : ToolsDef,\r
1270\r
1271 "shell_command_code" : self._SHELL_CMD_[self._FileType].keys(),\r
1272 "shell_command" : self._SHELL_CMD_[self._FileType].values(),\r
1273\r
1274 "create_directory_command" : self.GetCreateDirectoryCommand(self.IntermediateDirectoryList),\r
1275 "custom_makefile_content" : CustomMakefile\r
1276 }\r
1277\r
1278 return MakefileTemplateDict\r
1279\r
1280 _TemplateDict = property(_CreateTemplateDict)\r
1281\r
1282## PlatformMakefile class\r
1283#\r
1284# This class encapsules makefie and its generation for platform. It uses\r
1285# template to generate the content of makefile. The content of makefile will be\r
1286# got from PlatformAutoGen object.\r
1287#\r
1288class PlatformMakefile(BuildFile):\r
1289 ## template used to generate the makefile for platform\r
1290 _TEMPLATE_ = TemplateString('''\\r
1291${makefile_header}\r
1292\r
1293#\r
1294# Platform Macro Definition\r
1295#\r
1296PLATFORM_NAME = ${platform_name}\r
1297PLATFORM_GUID = ${platform_guid}\r
1298PLATFORM_VERSION = ${platform_version}\r
1299PLATFORM_FILE = ${platform_file}\r
1300PLATFORM_DIR = ${platform_dir}\r
1301PLATFORM_OUTPUT_DIR = ${platform_output_directory}\r
1302\r
1303#\r
1304# Build Configuration Macro Definition\r
1305#\r
1306TOOLCHAIN = ${toolchain_tag}\r
1307TOOLCHAIN_TAG = ${toolchain_tag}\r
1308TARGET = ${build_target}\r
1309\r
1310#\r
1311# Build Directory Macro Definition\r
1312#\r
1313BUILD_DIR = ${platform_build_directory}\r
1314FV_DIR = ${platform_build_directory}${separator}FV\r
1315\r
1316#\r
1317# Shell Command Macro\r
1318#\r
1319${BEGIN}${shell_command_code} = ${shell_command}\r
1320${END}\r
1321\r
1322MAKE = ${make_path}\r
1323MAKE_FILE = ${makefile_path}\r
1324\r
1325#\r
1326# Default target\r
1327#\r
1328all: init build_libraries build_modules\r
1329\r
1330#\r
1331# Initialization target: print build information and create necessary directories\r
1332#\r
1333init:\r
1334\t-@echo Building ... $(PLATFORM_FILE) [${build_architecture_list}]\r
1335\t${BEGIN}-@${create_directory_command}\r
1336\t${END}\r
1337#\r
1338# library build target\r
1339#\r
1340libraries: init build_libraries\r
1341\r
1342#\r
1343# module build target\r
1344#\r
1345modules: init build_libraries build_modules\r
1346\r
1347#\r
1348# Build all libraries:\r
1349#\r
1350build_libraries:\r
1351${BEGIN}\t@"$(MAKE)" $(MAKE_FLAGS) -f ${library_makefile_list} pbuild\r
1352${END}\t@cd $(BUILD_DIR)\r
1353\r
1354#\r
1355# Build all modules:\r
1356#\r
1357build_modules:\r
1358${BEGIN}\t@"$(MAKE)" $(MAKE_FLAGS) -f ${module_makefile_list} pbuild\r
1359${END}\t@cd $(BUILD_DIR)\r
1360\r
1361#\r
1362# Clean intermediate files\r
1363#\r
1364clean:\r
1365\t${BEGIN}-@${library_build_command} clean\r
1366\t${END}${BEGIN}-@${module_build_command} clean\r
1367\t${END}@cd $(BUILD_DIR)\r
1368\r
1369#\r
1370# Clean all generated files except to makefile\r
1371#\r
1372cleanall:\r
1373${BEGIN}\t${cleanall_command}\r
1374${END}\r
1375\r
1376#\r
1377# Clean all library files\r
1378#\r
1379cleanlib:\r
1380\t${BEGIN}-@${library_build_command} cleanall\r
1381\t${END}@cd $(BUILD_DIR)\n\r
1382''')\r
1383\r
1384 ## Constructor of PlatformMakefile\r
1385 #\r
1386 # @param ModuleAutoGen Object of PlatformAutoGen class\r
1387 #\r
1388 def __init__(self, PlatformAutoGen):\r
1389 BuildFile.__init__(self, PlatformAutoGen)\r
1390 self.ModuleBuildCommandList = []\r
1391 self.ModuleMakefileList = []\r
1392 self.IntermediateDirectoryList = []\r
1393 self.ModuleBuildDirectoryList = []\r
1394 self.LibraryBuildDirectoryList = []\r
1395 self.LibraryMakeCommandList = []\r
1396\r
1397 # Compose a dict object containing information used to do replacement in template\r
1398 def _CreateTemplateDict(self):\r
1399 Separator = self._SEP_[self._FileType]\r
1400\r
1401 MyAgo = self._AutoGenObject\r
1402 if "MAKE" not in MyAgo.ToolDefinition or "PATH" not in MyAgo.ToolDefinition["MAKE"]:\r
1403 EdkLogger.error("build", OPTION_MISSING, "No MAKE command defined. Please check your tools_def.txt!",\r
1404 ExtraData="[%s]" % str(MyAgo))\r
1405\r
1406 self.IntermediateDirectoryList = ["$(BUILD_DIR)"]\r
1407 self.ModuleBuildDirectoryList = self.GetModuleBuildDirectoryList()\r
1408 self.LibraryBuildDirectoryList = self.GetLibraryBuildDirectoryList()\r
1409\r
1410 MakefileName = self._FILE_NAME_[self._FileType]\r
1411 LibraryMakefileList = []\r
1412 LibraryMakeCommandList = []\r
1413 for D in self.LibraryBuildDirectoryList:\r
1414 D = self.PlaceMacro(D, {"BUILD_DIR":MyAgo.BuildDir})\r
1415 Makefile = os.path.join(D, MakefileName)\r
1416 Command = self._MAKE_TEMPLATE_[self._FileType] % {"file":Makefile}\r
1417 LibraryMakefileList.append(Makefile)\r
1418 LibraryMakeCommandList.append(Command)\r
1419 self.LibraryMakeCommandList = LibraryMakeCommandList\r
1420\r
1421 ModuleMakefileList = []\r
1422 ModuleMakeCommandList = []\r
1423 for D in self.ModuleBuildDirectoryList:\r
1424 D = self.PlaceMacro(D, {"BUILD_DIR":MyAgo.BuildDir})\r
1425 Makefile = os.path.join(D, MakefileName)\r
1426 Command = self._MAKE_TEMPLATE_[self._FileType] % {"file":Makefile}\r
1427 ModuleMakefileList.append(Makefile)\r
1428 ModuleMakeCommandList.append(Command)\r
1429\r
1430 MakefileTemplateDict = {\r
1431 "makefile_header" : self._FILE_HEADER_[self._FileType],\r
1432 "makefile_path" : os.path.join("$(BUILD_DIR)", MakefileName),\r
1433 "make_path" : MyAgo.ToolDefinition["MAKE"]["PATH"],\r
1434 "makefile_name" : MakefileName,\r
1435 "platform_name" : MyAgo.Name,\r
1436 "platform_guid" : MyAgo.Guid,\r
1437 "platform_version" : MyAgo.Version,\r
1438 "platform_file" : MyAgo.MetaFile,\r
1439 "platform_relative_directory": MyAgo.SourceDir,\r
1440 "platform_output_directory" : MyAgo.OutputDir,\r
1441 "platform_build_directory" : MyAgo.BuildDir,\r
1442 "platform_dir" : MyAgo.Macros["PLATFORM_DIR"],\r
1443\r
1444 "toolchain_tag" : MyAgo.ToolChain,\r
1445 "build_target" : MyAgo.BuildTarget,\r
1446 "shell_command_code" : self._SHELL_CMD_[self._FileType].keys(),\r
1447 "shell_command" : self._SHELL_CMD_[self._FileType].values(),\r
1448 "build_architecture_list" : MyAgo.Arch,\r
1449 "architecture" : MyAgo.Arch,\r
1450 "separator" : Separator,\r
1451 "create_directory_command" : self.GetCreateDirectoryCommand(self.IntermediateDirectoryList),\r
1452 "cleanall_command" : self.GetRemoveDirectoryCommand(self.IntermediateDirectoryList),\r
1453 "library_makefile_list" : LibraryMakefileList,\r
1454 "module_makefile_list" : ModuleMakefileList,\r
1455 "library_build_command" : LibraryMakeCommandList,\r
1456 "module_build_command" : ModuleMakeCommandList,\r
1457 }\r
1458\r
1459 return MakefileTemplateDict\r
1460\r
1461 ## Get the root directory list for intermediate files of all modules build\r
1462 #\r
1463 # @retval list The list of directory\r
1464 #\r
1465 def GetModuleBuildDirectoryList(self):\r
1466 DirList = []\r
1467 for ModuleAutoGen in self._AutoGenObject.ModuleAutoGenList:\r
1468 if not ModuleAutoGen.IsBinaryModule:\r
1469 DirList.append(os.path.join(self._AutoGenObject.BuildDir, ModuleAutoGen.BuildDir))\r
1470 return DirList\r
1471\r
1472 ## Get the root directory list for intermediate files of all libraries build\r
1473 #\r
1474 # @retval list The list of directory\r
1475 #\r
1476 def GetLibraryBuildDirectoryList(self):\r
1477 DirList = []\r
1478 for LibraryAutoGen in self._AutoGenObject.LibraryAutoGenList:\r
1479 if not LibraryAutoGen.IsBinaryModule:\r
1480 DirList.append(os.path.join(self._AutoGenObject.BuildDir, LibraryAutoGen.BuildDir))\r
1481 return DirList\r
1482\r
1483 _TemplateDict = property(_CreateTemplateDict)\r
1484\r
1485## TopLevelMakefile class\r
1486#\r
1487# This class encapsules makefie and its generation for entrance makefile. It\r
1488# uses template to generate the content of makefile. The content of makefile\r
1489# will be got from WorkspaceAutoGen object.\r
1490#\r
1491class TopLevelMakefile(BuildFile):\r
1492 ## template used to generate toplevel makefile\r
1493 _TEMPLATE_ = TemplateString('''${BEGIN}\tGenFds -f ${fdf_file} --conf=${conf_directory} -o ${platform_build_directory} -t ${toolchain_tag} -b ${build_target} -p ${active_platform} -a ${build_architecture_list} ${extra_options}${END}${BEGIN} -r ${fd} ${END}${BEGIN} -i ${fv} ${END}${BEGIN} -C ${cap} ${END}${BEGIN} -D ${macro} ${END}''')\r
1494\r
1495 ## Constructor of TopLevelMakefile\r
1496 #\r
1497 # @param Workspace Object of WorkspaceAutoGen class\r
1498 #\r
1499 def __init__(self, Workspace):\r
1500 BuildFile.__init__(self, Workspace)\r
1501 self.IntermediateDirectoryList = []\r
1502\r
1503 # Compose a dict object containing information used to do replacement in template\r
1504 def _CreateTemplateDict(self):\r
1505 Separator = self._SEP_[self._FileType]\r
1506\r
1507 # any platform autogen object is ok because we just need common information\r
1508 MyAgo = self._AutoGenObject\r
1509\r
1510 if "MAKE" not in MyAgo.ToolDefinition or "PATH" not in MyAgo.ToolDefinition["MAKE"]:\r
1511 EdkLogger.error("build", OPTION_MISSING, "No MAKE command defined. Please check your tools_def.txt!",\r
1512 ExtraData="[%s]" % str(MyAgo))\r
1513\r
1514 for Arch in MyAgo.ArchList:\r
1515 self.IntermediateDirectoryList.append(Separator.join(["$(BUILD_DIR)", Arch]))\r
1516 self.IntermediateDirectoryList.append("$(FV_DIR)")\r
1517\r
1518 # TRICK: for not generating GenFds call in makefile if no FDF file\r
1519 MacroList = []\r
1520 if MyAgo.FdfFile is not None and MyAgo.FdfFile != "":\r
1521 FdfFileList = [MyAgo.FdfFile]\r
1522 # macros passed to GenFds\r
1523 MacroList.append('"%s=%s"' % ("EFI_SOURCE", GlobalData.gEfiSource.replace('\\', '\\\\')))\r
1524 MacroList.append('"%s=%s"' % ("EDK_SOURCE", GlobalData.gEdkSource.replace('\\', '\\\\')))\r
1525 MacroDict = {}\r
1526 MacroDict.update(GlobalData.gGlobalDefines)\r
1527 MacroDict.update(GlobalData.gCommandLineDefines)\r
1528 MacroDict.pop("EFI_SOURCE", "dummy")\r
1529 MacroDict.pop("EDK_SOURCE", "dummy")\r
1530 for MacroName in MacroDict:\r
1531 if MacroDict[MacroName] != "":\r
1532 MacroList.append('"%s=%s"' % (MacroName, MacroDict[MacroName].replace('\\', '\\\\')))\r
1533 else:\r
1534 MacroList.append('"%s"' % MacroName)\r
1535 else:\r
1536 FdfFileList = []\r
1537\r
1538 # pass extra common options to external program called in makefile, currently GenFds.exe\r
1539 ExtraOption = ''\r
1540 LogLevel = EdkLogger.GetLevel()\r
1541 if LogLevel == EdkLogger.VERBOSE:\r
1542 ExtraOption += " -v"\r
1543 elif LogLevel <= EdkLogger.DEBUG_9:\r
1544 ExtraOption += " -d %d" % (LogLevel - 1)\r
1545 elif LogLevel == EdkLogger.QUIET:\r
1546 ExtraOption += " -q"\r
1547\r
1548 if GlobalData.gCaseInsensitive:\r
1549 ExtraOption += " -c"\r
1550 if GlobalData.gEnableGenfdsMultiThread:\r
1551 ExtraOption += " --genfds-multi-thread"\r
1552 if GlobalData.gIgnoreSource:\r
1553 ExtraOption += " --ignore-sources"\r
1554\r
1555 for pcd in GlobalData.BuildOptionPcd:\r
1556 if pcd[2]:\r
1557 pcdname = '.'.join(pcd[0:3])\r
1558 else:\r
1559 pcdname = '.'.join(pcd[0:2])\r
1560 if pcd[3].startswith('{'):\r
1561 ExtraOption += " --pcd " + pcdname + '=' + 'H' + '"' + pcd[3] + '"'\r
1562 else:\r
1563 ExtraOption += " --pcd " + pcdname + '=' + pcd[3]\r
1564\r
1565 MakefileName = self._FILE_NAME_[self._FileType]\r
1566 SubBuildCommandList = []\r
1567 for A in MyAgo.ArchList:\r
1568 Command = self._MAKE_TEMPLATE_[self._FileType] % {"file":os.path.join("$(BUILD_DIR)", A, MakefileName)}\r
1569 SubBuildCommandList.append(Command)\r
1570\r
1571 MakefileTemplateDict = {\r
1572 "makefile_header" : self._FILE_HEADER_[self._FileType],\r
1573 "makefile_path" : os.path.join("$(BUILD_DIR)", MakefileName),\r
1574 "make_path" : MyAgo.ToolDefinition["MAKE"]["PATH"],\r
1575 "platform_name" : MyAgo.Name,\r
1576 "platform_guid" : MyAgo.Guid,\r
1577 "platform_version" : MyAgo.Version,\r
1578 "platform_build_directory" : MyAgo.BuildDir,\r
1579 "conf_directory" : GlobalData.gConfDirectory,\r
1580\r
1581 "toolchain_tag" : MyAgo.ToolChain,\r
1582 "build_target" : MyAgo.BuildTarget,\r
1583 "shell_command_code" : self._SHELL_CMD_[self._FileType].keys(),\r
1584 "shell_command" : self._SHELL_CMD_[self._FileType].values(),\r
1585 'arch' : list(MyAgo.ArchList),\r
1586 "build_architecture_list" : ','.join(MyAgo.ArchList),\r
1587 "separator" : Separator,\r
1588 "create_directory_command" : self.GetCreateDirectoryCommand(self.IntermediateDirectoryList),\r
1589 "cleanall_command" : self.GetRemoveDirectoryCommand(self.IntermediateDirectoryList),\r
1590 "sub_build_command" : SubBuildCommandList,\r
1591 "fdf_file" : FdfFileList,\r
1592 "active_platform" : str(MyAgo),\r
1593 "fd" : MyAgo.FdTargetList,\r
1594 "fv" : MyAgo.FvTargetList,\r
1595 "cap" : MyAgo.CapTargetList,\r
1596 "extra_options" : ExtraOption,\r
1597 "macro" : MacroList,\r
1598 }\r
1599\r
1600 return MakefileTemplateDict\r
1601\r
1602 ## Get the root directory list for intermediate files of all modules build\r
1603 #\r
1604 # @retval list The list of directory\r
1605 #\r
1606 def GetModuleBuildDirectoryList(self):\r
1607 DirList = []\r
1608 for ModuleAutoGen in self._AutoGenObject.ModuleAutoGenList:\r
1609 if not ModuleAutoGen.IsBinaryModule:\r
1610 DirList.append(os.path.join(self._AutoGenObject.BuildDir, ModuleAutoGen.BuildDir))\r
1611 return DirList\r
1612\r
1613 ## Get the root directory list for intermediate files of all libraries build\r
1614 #\r
1615 # @retval list The list of directory\r
1616 #\r
1617 def GetLibraryBuildDirectoryList(self):\r
1618 DirList = []\r
1619 for LibraryAutoGen in self._AutoGenObject.LibraryAutoGenList:\r
1620 if not LibraryAutoGen.IsBinaryModule:\r
1621 DirList.append(os.path.join(self._AutoGenObject.BuildDir, LibraryAutoGen.BuildDir))\r
1622 return DirList\r
1623\r
1624 _TemplateDict = property(_CreateTemplateDict)\r
1625\r
1626# This acts like the main() function for the script, unless it is 'import'ed into another script.\r
1627if __name__ == '__main__':\r
1628 pass\r
1629\r