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