]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - BaseTools/Source/Python/AutoGen/GenMake.py
BaseTools: Cleanup unneeded code
[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 Separator = self._SEP_[self._FileType]\r
462\r
463 # break build if no source files and binary files are found\r
464 if len(self._AutoGenObject.SourceFileList) == 0 and len(self._AutoGenObject.BinaryFileList) == 0:\r
465 EdkLogger.error("build", AUTOGEN_ERROR, "No files to be built in module [%s, %s, %s]"\r
466 % (self._AutoGenObject.BuildTarget, self._AutoGenObject.ToolChain, self._AutoGenObject.Arch),\r
467 ExtraData="[%s]" % str(self._AutoGenObject))\r
468\r
469 # convert dependent libraries to build command\r
470 self.ProcessDependentLibrary()\r
471 if len(self._AutoGenObject.Module.ModuleEntryPointList) > 0:\r
472 ModuleEntryPoint = self._AutoGenObject.Module.ModuleEntryPointList[0]\r
473 else:\r
474 ModuleEntryPoint = "_ModuleEntryPoint"\r
475\r
476 # Intel EBC compiler enforces EfiMain\r
477 if self._AutoGenObject.AutoGenVersion < 0x00010005 and self._AutoGenObject.Arch == "EBC":\r
478 ArchEntryPoint = "EfiMain"\r
479 else:\r
480 ArchEntryPoint = ModuleEntryPoint\r
481\r
482 if self._AutoGenObject.Arch == "EBC":\r
483 # EBC compiler always use "EfiStart" as entry point. Only applies to EdkII modules\r
484 ImageEntryPoint = "EfiStart"\r
485 elif self._AutoGenObject.AutoGenVersion < 0x00010005:\r
486 # Edk modules use entry point specified in INF file\r
487 ImageEntryPoint = ModuleEntryPoint\r
488 else:\r
489 # EdkII modules always use "_ModuleEntryPoint" as entry point\r
490 ImageEntryPoint = "_ModuleEntryPoint"\r
491\r
492 for k, v in self._AutoGenObject.Module.Defines.iteritems():\r
493 if k not in self._AutoGenObject.Macros:\r
494 self._AutoGenObject.Macros[k] = v\r
495\r
496 if 'MODULE_ENTRY_POINT' not in self._AutoGenObject.Macros:\r
497 self._AutoGenObject.Macros['MODULE_ENTRY_POINT'] = ModuleEntryPoint\r
498 if 'ARCH_ENTRY_POINT' not in self._AutoGenObject.Macros:\r
499 self._AutoGenObject.Macros['ARCH_ENTRY_POINT'] = ArchEntryPoint\r
500 if 'IMAGE_ENTRY_POINT' not in self._AutoGenObject.Macros:\r
501 self._AutoGenObject.Macros['IMAGE_ENTRY_POINT'] = ImageEntryPoint\r
502\r
503 PCI_COMPRESS_Flag = False\r
504 for k, v in self._AutoGenObject.Module.Defines.iteritems():\r
505 if 'PCI_COMPRESS' == k and 'TRUE' == v:\r
506 PCI_COMPRESS_Flag = True\r
507\r
508 # tools definitions\r
509 ToolsDef = []\r
510 IncPrefix = self._INC_FLAG_[self._AutoGenObject.ToolChainFamily]\r
511 for Tool in self._AutoGenObject.BuildOption:\r
512 for Attr in self._AutoGenObject.BuildOption[Tool]:\r
513 Value = self._AutoGenObject.BuildOption[Tool][Attr]\r
514 if Attr == "FAMILY":\r
515 continue\r
516 elif Attr == "PATH":\r
517 ToolsDef.append("%s = %s" % (Tool, Value))\r
518 else:\r
519 # Don't generate MAKE_FLAGS in makefile. It's put in environment variable.\r
520 if Tool == "MAKE":\r
521 continue\r
522 # Remove duplicated include path, if any\r
523 if Attr == "FLAGS":\r
524 Value = RemoveDupOption(Value, IncPrefix, self._AutoGenObject.IncludePathList)\r
525 if Tool == "OPTROM" and PCI_COMPRESS_Flag:\r
526 ValueList = Value.split()\r
527 if ValueList:\r
528 for i, v in enumerate(ValueList):\r
529 if '-e' == v:\r
530 ValueList[i] = '-ec'\r
531 Value = ' '.join(ValueList)\r
532\r
533 ToolsDef.append("%s_%s = %s" % (Tool, Attr, Value))\r
534 ToolsDef.append("")\r
535\r
536 # generate the Response file and Response flag\r
537 RespDict = self.CommandExceedLimit()\r
538 RespFileList = os.path.join(self._AutoGenObject.OutputDir, 'respfilelist.txt')\r
539 if RespDict:\r
540 RespFileListContent = ''\r
541 for Resp in RespDict:\r
542 RespFile = os.path.join(self._AutoGenObject.OutputDir, str(Resp).lower() + '.txt')\r
543 StrList = RespDict[Resp].split(' ')\r
544 UnexpandMacro = []\r
545 NewStr = []\r
546 for Str in StrList:\r
547 if '$' in Str:\r
548 UnexpandMacro.append(Str)\r
549 else:\r
550 NewStr.append(Str)\r
551 UnexpandMacroStr = ' '.join(UnexpandMacro)\r
552 NewRespStr = ' '.join(NewStr)\r
553 SaveFileOnChange(RespFile, NewRespStr, False)\r
554 ToolsDef.append("%s = %s" % (Resp, UnexpandMacroStr + ' @' + RespFile))\r
555 RespFileListContent += '@' + RespFile + os.linesep\r
556 RespFileListContent += NewRespStr + os.linesep\r
557 SaveFileOnChange(RespFileList, RespFileListContent, False)\r
558 else:\r
559 if os.path.exists(RespFileList):\r
560 os.remove(RespFileList)\r
561\r
562 # convert source files and binary files to build targets\r
563 self.ResultFileList = [str(T.Target) for T in self._AutoGenObject.CodaTargetList]\r
564 if len(self.ResultFileList) == 0 and len(self._AutoGenObject.SourceFileList) <> 0:\r
565 EdkLogger.error("build", AUTOGEN_ERROR, "Nothing to build",\r
566 ExtraData="[%s]" % str(self._AutoGenObject))\r
567\r
568 self.ProcessBuildTargetList()\r
569 self.ParserGenerateFfsCmd()\r
570\r
571 # Generate macros used to represent input files\r
572 FileMacroList = [] # macro name = file list\r
573 for FileListMacro in self.FileListMacros:\r
574 FileMacro = self._FILE_MACRO_TEMPLATE.Replace(\r
575 {\r
576 "macro_name" : FileListMacro,\r
577 "source_file" : self.FileListMacros[FileListMacro]\r
578 }\r
579 )\r
580 FileMacroList.append(FileMacro)\r
581\r
582 # INC_LIST is special\r
583 FileMacro = ""\r
584 IncludePathList = []\r
585 for P in self._AutoGenObject.IncludePathList:\r
586 IncludePathList.append(IncPrefix + self.PlaceMacro(P, self.Macros))\r
587 if FileBuildRule.INC_LIST_MACRO in self.ListFileMacros:\r
588 self.ListFileMacros[FileBuildRule.INC_LIST_MACRO].append(IncPrefix + P)\r
589 FileMacro += self._FILE_MACRO_TEMPLATE.Replace(\r
590 {\r
591 "macro_name" : "INC",\r
592 "source_file" : IncludePathList\r
593 }\r
594 )\r
595 FileMacroList.append(FileMacro)\r
596\r
597 # Generate macros used to represent files containing list of input files\r
598 for ListFileMacro in self.ListFileMacros:\r
599 ListFileName = os.path.join(self._AutoGenObject.OutputDir, "%s.lst" % ListFileMacro.lower()[:len(ListFileMacro) - 5])\r
600 FileMacroList.append("%s = %s" % (ListFileMacro, ListFileName))\r
601 SaveFileOnChange(\r
602 ListFileName,\r
603 "\n".join(self.ListFileMacros[ListFileMacro]),\r
604 False\r
605 )\r
606\r
607 # Edk modules need <BaseName>StrDefs.h for string ID\r
608 #if self._AutoGenObject.AutoGenVersion < 0x00010005 and len(self._AutoGenObject.UnicodeFileList) > 0:\r
609 # BcTargetList = ['strdefs']\r
610 #else:\r
611 # BcTargetList = []\r
612 BcTargetList = []\r
613\r
614 MakefileName = self._FILE_NAME_[self._FileType]\r
615 LibraryMakeCommandList = []\r
616 for D in self.LibraryBuildDirectoryList:\r
617 Command = self._MAKE_TEMPLATE_[self._FileType] % {"file":os.path.join(D, MakefileName)}\r
618 LibraryMakeCommandList.append(Command)\r
619\r
620 package_rel_dir = self._AutoGenObject.SourceDir\r
621 current_dir = self.Macros["WORKSPACE"]\r
622 found = False\r
623 while not found and os.sep in package_rel_dir:\r
624 index = package_rel_dir.index(os.sep)\r
625 current_dir = mws.join(current_dir, package_rel_dir[:index])\r
626 if os.path.exists(current_dir):\r
627 for fl in os.listdir(current_dir):\r
628 if fl.endswith('.dec'):\r
629 found = True\r
630 break\r
631 package_rel_dir = package_rel_dir[index + 1:]\r
632\r
633 MakefileTemplateDict = {\r
634 "makefile_header" : self._FILE_HEADER_[self._FileType],\r
635 "makefile_path" : os.path.join("$(MODULE_BUILD_DIR)", MakefileName),\r
636 "makefile_name" : MakefileName,\r
637 "platform_name" : self.PlatformInfo.Name,\r
638 "platform_guid" : self.PlatformInfo.Guid,\r
639 "platform_version" : self.PlatformInfo.Version,\r
640 "platform_relative_directory": self.PlatformInfo.SourceDir,\r
641 "platform_output_directory" : self.PlatformInfo.OutputDir,\r
642 "ffs_output_directory" : self._AutoGenObject.Macros["FFS_OUTPUT_DIR"],\r
643 "platform_dir" : self._AutoGenObject.Macros["PLATFORM_DIR"],\r
644\r
645 "module_name" : self._AutoGenObject.Name,\r
646 "module_guid" : self._AutoGenObject.Guid,\r
647 "module_name_guid" : self._AutoGenObject._GetUniqueBaseName(),\r
648 "module_version" : self._AutoGenObject.Version,\r
649 "module_type" : self._AutoGenObject.ModuleType,\r
650 "module_file" : self._AutoGenObject.MetaFile.Name,\r
651 "module_file_base_name" : self._AutoGenObject.MetaFile.BaseName,\r
652 "module_relative_directory" : self._AutoGenObject.SourceDir,\r
653 "module_dir" : mws.join (self.Macros["WORKSPACE"], self._AutoGenObject.SourceDir),\r
654 "package_relative_directory": package_rel_dir,\r
655 "module_extra_defines" : ["%s = %s" % (k, v) for k, v in self._AutoGenObject.Module.Defines.iteritems()],\r
656\r
657 "architecture" : self._AutoGenObject.Arch,\r
658 "toolchain_tag" : self._AutoGenObject.ToolChain,\r
659 "build_target" : self._AutoGenObject.BuildTarget,\r
660\r
661 "platform_build_directory" : self.PlatformInfo.BuildDir,\r
662 "module_build_directory" : self._AutoGenObject.BuildDir,\r
663 "module_output_directory" : self._AutoGenObject.OutputDir,\r
664 "module_debug_directory" : self._AutoGenObject.DebugDir,\r
665\r
666 "separator" : Separator,\r
667 "module_tool_definitions" : ToolsDef,\r
668\r
669 "shell_command_code" : self._SHELL_CMD_[self._FileType].keys(),\r
670 "shell_command" : self._SHELL_CMD_[self._FileType].values(),\r
671\r
672 "module_entry_point" : ModuleEntryPoint,\r
673 "image_entry_point" : ImageEntryPoint,\r
674 "arch_entry_point" : ArchEntryPoint,\r
675 "remaining_build_target" : self.ResultFileList,\r
676 "common_dependency_file" : self.CommonFileDependency,\r
677 "create_directory_command" : self.GetCreateDirectoryCommand(self.IntermediateDirectoryList),\r
678 "clean_command" : self.GetRemoveDirectoryCommand(["$(OUTPUT_DIR)"]),\r
679 "cleanall_command" : self.GetRemoveDirectoryCommand(["$(DEBUG_DIR)", "$(OUTPUT_DIR)"]),\r
680 "dependent_library_build_directory" : self.LibraryBuildDirectoryList,\r
681 "library_build_command" : LibraryMakeCommandList,\r
682 "file_macro" : FileMacroList,\r
683 "file_build_target" : self.BuildTargetList,\r
684 "backward_compatible_target": BcTargetList,\r
685 }\r
686\r
687 return MakefileTemplateDict\r
688\r
689 def ParserGenerateFfsCmd(self):\r
690 #Add Ffs cmd to self.BuildTargetList\r
691 OutputFile = ''\r
692 DepsFileList = []\r
693\r
694 for Cmd in self.GenFfsList:\r
695 if Cmd[2]:\r
696 for CopyCmd in Cmd[2]:\r
697 Src, Dst = CopyCmd\r
698 Src = self.ReplaceMacro(Src)\r
699 Dst = self.ReplaceMacro(Dst)\r
700 if Dst not in self.ResultFileList:\r
701 self.ResultFileList.append(Dst)\r
702 if '%s :' %(Dst) not in self.BuildTargetList:\r
703 self.BuildTargetList.append("%s :" %(Dst))\r
704 self.BuildTargetList.append('\t' + self._CP_TEMPLATE_[self._FileType] %{'Src': Src, 'Dst': Dst})\r
705\r
706 FfsCmdList = Cmd[0]\r
707 for index, Str in enumerate(FfsCmdList):\r
708 if '-o' == Str:\r
709 OutputFile = FfsCmdList[index + 1]\r
710 if '-i' == Str:\r
711 if DepsFileList == []:\r
712 DepsFileList = [FfsCmdList[index + 1]]\r
713 else:\r
714 DepsFileList.append(FfsCmdList[index + 1])\r
715 DepsFileString = ' '.join(DepsFileList).strip()\r
716 if DepsFileString == '':\r
717 continue\r
718 OutputFile = self.ReplaceMacro(OutputFile)\r
719 self.ResultFileList.append(OutputFile)\r
720 DepsFileString = self.ReplaceMacro(DepsFileString)\r
721 self.BuildTargetList.append('%s : %s' % (OutputFile, DepsFileString))\r
722 CmdString = ' '.join(FfsCmdList).strip()\r
723 CmdString = self.ReplaceMacro(CmdString)\r
724 self.BuildTargetList.append('\t%s' % CmdString)\r
725\r
726 self.ParseSecCmd(DepsFileList, Cmd[1])\r
727 for SecOutputFile, SecDepsFile, SecCmd in self.FfsOutputFileList :\r
728 self.BuildTargetList.append('%s : %s' % (self.ReplaceMacro(SecOutputFile), self.ReplaceMacro(SecDepsFile)))\r
729 self.BuildTargetList.append('\t%s' % self.ReplaceMacro(SecCmd))\r
730 self.FfsOutputFileList = []\r
731\r
732 def ParseSecCmd(self, OutputFileList, CmdTuple):\r
733 for OutputFile in OutputFileList:\r
734 for SecCmdStr in CmdTuple:\r
735 SecDepsFileList = []\r
736 SecCmdList = SecCmdStr.split()\r
737 CmdName = SecCmdList[0]\r
738 for index, CmdItem in enumerate(SecCmdList):\r
739 if '-o' == CmdItem and OutputFile == SecCmdList[index + 1]:\r
740 index = index + 1\r
741 while index + 1 < len(SecCmdList):\r
742 if not SecCmdList[index+1].startswith('-'):\r
743 SecDepsFileList.append(SecCmdList[index + 1])\r
744 index = index + 1\r
745 if CmdName == 'Trim':\r
746 SecDepsFileList.append(os.path.join('$(DEBUG_DIR)', os.path.basename(OutputFile).replace('offset', 'efi')))\r
747 if OutputFile.endswith('.ui') or OutputFile.endswith('.ver'):\r
748 SecDepsFileList.append(os.path.join('$(MODULE_DIR)','$(MODULE_FILE)'))\r
749 self.FfsOutputFileList.append((OutputFile, ' '.join(SecDepsFileList), SecCmdStr))\r
750 if len(SecDepsFileList) > 0:\r
751 self.ParseSecCmd(SecDepsFileList, CmdTuple)\r
752 break\r
753 else:\r
754 continue\r
755\r
756 def ReplaceMacro(self, str):\r
757 for Macro in self.MacroList:\r
758 if self._AutoGenObject.Macros[Macro] and self._AutoGenObject.Macros[Macro] in str:\r
759 str = str.replace(self._AutoGenObject.Macros[Macro], '$(' + Macro + ')')\r
760 return str\r
761\r
762 def CommandExceedLimit(self):\r
763 FlagDict = {\r
764 'CC' : { 'Macro' : '$(CC_FLAGS)', 'Value' : False},\r
765 'PP' : { 'Macro' : '$(PP_FLAGS)', 'Value' : False},\r
766 'APP' : { 'Macro' : '$(APP_FLAGS)', 'Value' : False},\r
767 'ASLPP' : { 'Macro' : '$(ASLPP_FLAGS)', 'Value' : False},\r
768 'VFRPP' : { 'Macro' : '$(VFRPP_FLAGS)', 'Value' : False},\r
769 'ASM' : { 'Macro' : '$(ASM_FLAGS)', 'Value' : False},\r
770 'ASLCC' : { 'Macro' : '$(ASLCC_FLAGS)', 'Value' : False},\r
771 }\r
772\r
773 RespDict = {}\r
774 FileTypeList = []\r
775 IncPrefix = self._INC_FLAG_[self._AutoGenObject.ToolChainFamily]\r
776\r
777 # base on the source files to decide the file type\r
778 for File in self._AutoGenObject.SourceFileList:\r
779 for type in self._AutoGenObject.FileTypes:\r
780 if File in self._AutoGenObject.FileTypes[type]:\r
781 if type not in FileTypeList:\r
782 FileTypeList.append(type)\r
783\r
784 # calculate the command-line length\r
785 if FileTypeList:\r
786 for type in FileTypeList:\r
787 BuildTargets = self._AutoGenObject.BuildRules[type].BuildTargets\r
788 for Target in BuildTargets:\r
789 CommandList = BuildTargets[Target].Commands\r
790 for SingleCommand in CommandList:\r
791 Tool = ''\r
792 SingleCommandLength = len(SingleCommand)\r
793 SingleCommandList = SingleCommand.split()\r
794 if len(SingleCommandList) > 0:\r
795 for Flag in FlagDict:\r
796 if '$('+ Flag +')' in SingleCommandList[0]:\r
797 Tool = Flag\r
798 break\r
799 if Tool:\r
800 if 'PATH' not in self._AutoGenObject._BuildOption[Tool]:\r
801 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
802 SingleCommandLength += len(self._AutoGenObject._BuildOption[Tool]['PATH'])\r
803 for item in SingleCommandList[1:]:\r
804 if FlagDict[Tool]['Macro'] in item:\r
805 if 'FLAGS' not in self._AutoGenObject._BuildOption[Tool]:\r
806 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
807 Str = self._AutoGenObject._BuildOption[Tool]['FLAGS']\r
808 for Option in self._AutoGenObject.BuildOption:\r
809 for Attr in self._AutoGenObject.BuildOption[Option]:\r
810 if Str.find(Option + '_' + Attr) != -1:\r
811 Str = Str.replace('$(' + Option + '_' + Attr + ')', self._AutoGenObject.BuildOption[Option][Attr])\r
812 while(Str.find('$(') != -1):\r
813 for macro in self._AutoGenObject.Macros:\r
814 MacroName = '$('+ macro + ')'\r
815 if (Str.find(MacroName) != -1):\r
816 Str = Str.replace(MacroName, self._AutoGenObject.Macros[macro])\r
817 break\r
818 else:\r
819 break\r
820 SingleCommandLength += len(Str)\r
821 elif '$(INC)' in item:\r
822 SingleCommandLength += self._AutoGenObject.IncludePathLength + len(IncPrefix) * len(self._AutoGenObject._IncludePathList)\r
823 elif item.find('$(') != -1:\r
824 Str = item\r
825 for Option in self._AutoGenObject.BuildOption:\r
826 for Attr in self._AutoGenObject.BuildOption[Option]:\r
827 if Str.find(Option + '_' + Attr) != -1:\r
828 Str = Str.replace('$(' + Option + '_' + Attr + ')', self._AutoGenObject.BuildOption[Option][Attr])\r
829 while(Str.find('$(') != -1):\r
830 for macro in self._AutoGenObject.Macros:\r
831 MacroName = '$('+ macro + ')'\r
832 if (Str.find(MacroName) != -1):\r
833 Str = Str.replace(MacroName, self._AutoGenObject.Macros[macro])\r
834 break\r
835 else:\r
836 break\r
837 SingleCommandLength += len(Str)\r
838\r
839 if SingleCommandLength > GlobalData.gCommandMaxLength:\r
840 FlagDict[Tool]['Value'] = True\r
841\r
842 # generate the response file content by combine the FLAGS and INC\r
843 for Flag in FlagDict:\r
844 if FlagDict[Flag]['Value']:\r
845 Key = Flag + '_RESP'\r
846 RespMacro = FlagDict[Flag]['Macro'].replace('FLAGS', 'RESP')\r
847 Value = self._AutoGenObject.BuildOption[Flag]['FLAGS']\r
848 for inc in self._AutoGenObject._IncludePathList:\r
849 Value += ' ' + IncPrefix + inc\r
850 for Option in self._AutoGenObject.BuildOption:\r
851 for Attr in self._AutoGenObject.BuildOption[Option]:\r
852 if Value.find(Option + '_' + Attr) != -1:\r
853 Value = Value.replace('$(' + Option + '_' + Attr + ')', self._AutoGenObject.BuildOption[Option][Attr])\r
854 while (Value.find('$(') != -1):\r
855 for macro in self._AutoGenObject.Macros:\r
856 MacroName = '$('+ macro + ')'\r
857 if (Value.find(MacroName) != -1):\r
858 Value = Value.replace(MacroName, self._AutoGenObject.Macros[macro])\r
859 break\r
860 else:\r
861 break\r
862\r
863 if self._AutoGenObject.ToolChainFamily == 'GCC':\r
864 RespDict[Key] = Value.replace('\\', '/')\r
865 else:\r
866 RespDict[Key] = Value\r
867 for Target in BuildTargets:\r
868 for i, SingleCommand in enumerate(BuildTargets[Target].Commands):\r
869 if FlagDict[Flag]['Macro'] in SingleCommand:\r
870 BuildTargets[Target].Commands[i] = SingleCommand.replace('$(INC)','').replace(FlagDict[Flag]['Macro'], RespMacro)\r
871 return RespDict\r
872\r
873 def ProcessBuildTargetList(self):\r
874 #\r
875 # Search dependency file list for each source file\r
876 #\r
877 ForceIncludedFile = []\r
878 for File in self._AutoGenObject.AutoGenFileList:\r
879 if File.Ext == '.h':\r
880 ForceIncludedFile.append(File)\r
881 SourceFileList = []\r
882 OutPutFileList = []\r
883 for Target in self._AutoGenObject.IntroTargetList:\r
884 SourceFileList.extend(Target.Inputs)\r
885 OutPutFileList.extend(Target.Outputs)\r
886\r
887 if OutPutFileList:\r
888 for Item in OutPutFileList:\r
889 if Item in SourceFileList:\r
890 SourceFileList.remove(Item)\r
891\r
892 self.FileDependency = self.GetFileDependency(\r
893 SourceFileList,\r
894 ForceIncludedFile,\r
895 self._AutoGenObject.IncludePathList + self._AutoGenObject.BuildOptionIncPathList\r
896 )\r
897 DepSet = None\r
898 for File in self.FileDependency:\r
899 if not self.FileDependency[File]:\r
900 self.FileDependency[File] = ['$(FORCE_REBUILD)']\r
901 continue\r
902\r
903 self._AutoGenObject.AutoGenDepSet |= set(self.FileDependency[File])\r
904\r
905 # skip non-C files\r
906 if File.Ext not in [".c", ".C"] or File.Name == "AutoGen.c":\r
907 continue\r
908 elif DepSet is None:\r
909 DepSet = set(self.FileDependency[File])\r
910 else:\r
911 DepSet &= set(self.FileDependency[File])\r
912 # in case nothing in SourceFileList\r
913 if DepSet is None:\r
914 DepSet = set()\r
915 #\r
916 # Extract common files list in the dependency files\r
917 #\r
918 for File in DepSet:\r
919 self.CommonFileDependency.append(self.PlaceMacro(File.Path, self.Macros))\r
920\r
921 for File in self.FileDependency:\r
922 # skip non-C files\r
923 if File.Ext not in [".c", ".C"] or File.Name == "AutoGen.c":\r
924 continue\r
925 NewDepSet = set(self.FileDependency[File])\r
926 NewDepSet -= DepSet\r
927 self.FileDependency[File] = ["$(COMMON_DEPS)"] + list(NewDepSet)\r
928\r
929 # Convert target description object to target string in makefile\r
930 for Type in self._AutoGenObject.Targets:\r
931 for T in self._AutoGenObject.Targets[Type]:\r
932 # Generate related macros if needed\r
933 if T.GenFileListMacro and T.FileListMacro not in self.FileListMacros:\r
934 self.FileListMacros[T.FileListMacro] = []\r
935 if T.GenListFile and T.ListFileMacro not in self.ListFileMacros:\r
936 self.ListFileMacros[T.ListFileMacro] = []\r
937 if T.GenIncListFile and T.IncListFileMacro not in self.ListFileMacros:\r
938 self.ListFileMacros[T.IncListFileMacro] = []\r
939\r
940 Deps = []\r
941 # Add force-dependencies\r
942 for Dep in T.Dependencies:\r
943 Deps.append(self.PlaceMacro(str(Dep), self.Macros))\r
944 # Add inclusion-dependencies\r
945 if len(T.Inputs) == 1 and T.Inputs[0] in self.FileDependency:\r
946 for F in self.FileDependency[T.Inputs[0]]:\r
947 Deps.append(self.PlaceMacro(str(F), self.Macros))\r
948 # Add source-dependencies\r
949 for F in T.Inputs:\r
950 NewFile = self.PlaceMacro(str(F), self.Macros)\r
951 # In order to use file list macro as dependency\r
952 if T.GenListFile:\r
953 # gnu tools need forward slash path separater, even on Windows\r
954 self.ListFileMacros[T.ListFileMacro].append(str(F).replace ('\\', '/'))\r
955 self.FileListMacros[T.FileListMacro].append(NewFile)\r
956 elif T.GenFileListMacro:\r
957 self.FileListMacros[T.FileListMacro].append(NewFile)\r
958 else:\r
959 Deps.append(NewFile)\r
960\r
961 # Use file list macro as dependency\r
962 if T.GenFileListMacro:\r
963 Deps.append("$(%s)" % T.FileListMacro)\r
964 if Type in [TAB_OBJECT_FILE, TAB_STATIC_LIBRARY]:\r
965 Deps.append("$(%s)" % T.ListFileMacro)\r
966\r
967 TargetDict = {\r
968 "target" : self.PlaceMacro(T.Target.Path, self.Macros),\r
969 "cmd" : "\n\t".join(T.Commands),\r
970 "deps" : Deps\r
971 }\r
972 self.BuildTargetList.append(self._BUILD_TARGET_TEMPLATE.Replace(TargetDict))\r
973\r
974 ## For creating makefile targets for dependent libraries\r
975 def ProcessDependentLibrary(self):\r
976 for LibraryAutoGen in self._AutoGenObject.LibraryAutoGenList:\r
977 if not LibraryAutoGen.IsBinaryModule:\r
978 self.LibraryBuildDirectoryList.append(self.PlaceMacro(LibraryAutoGen.BuildDir, self.Macros))\r
979\r
980 ## Return a list containing source file's dependencies\r
981 #\r
982 # @param FileList The list of source files\r
983 # @param ForceInculeList The list of files which will be included forcely\r
984 # @param SearchPathList The list of search path\r
985 #\r
986 # @retval dict The mapping between source file path and its dependencies\r
987 #\r
988 def GetFileDependency(self, FileList, ForceInculeList, SearchPathList):\r
989 Dependency = {}\r
990 for F in FileList:\r
991 Dependency[F] = self.GetDependencyList(F, ForceInculeList, SearchPathList)\r
992 return Dependency\r
993\r
994 ## Find dependencies for one source file\r
995 #\r
996 # By searching recursively "#include" directive in file, find out all the\r
997 # files needed by given source file. The dependecies will be only searched\r
998 # in given search path list.\r
999 #\r
1000 # @param File The source file\r
1001 # @param ForceInculeList The list of files which will be included forcely\r
1002 # @param SearchPathList The list of search path\r
1003 #\r
1004 # @retval list The list of files the given source file depends on\r
1005 #\r
1006 def GetDependencyList(self, File, ForceList, SearchPathList):\r
1007 EdkLogger.debug(EdkLogger.DEBUG_1, "Try to get dependency files for %s" % File)\r
1008 FileStack = [File] + ForceList\r
1009 DependencySet = set()\r
1010\r
1011 if self._AutoGenObject.Arch not in gDependencyDatabase:\r
1012 gDependencyDatabase[self._AutoGenObject.Arch] = {}\r
1013 DepDb = gDependencyDatabase[self._AutoGenObject.Arch]\r
1014\r
1015 while len(FileStack) > 0:\r
1016 F = FileStack.pop()\r
1017\r
1018 FullPathDependList = []\r
1019 if F in self.FileCache:\r
1020 for CacheFile in self.FileCache[F]:\r
1021 FullPathDependList.append(CacheFile)\r
1022 if CacheFile not in DependencySet:\r
1023 FileStack.append(CacheFile)\r
1024 DependencySet.update(FullPathDependList)\r
1025 continue\r
1026\r
1027 CurrentFileDependencyList = []\r
1028 if F in DepDb:\r
1029 CurrentFileDependencyList = DepDb[F]\r
1030 else:\r
1031 try:\r
1032 Fd = open(F.Path, 'r')\r
1033 except BaseException, X:\r
1034 EdkLogger.error("build", FILE_OPEN_FAILURE, ExtraData=F.Path + "\n\t" + str(X))\r
1035\r
1036 FileContent = Fd.read()\r
1037 Fd.close()\r
1038 if len(FileContent) == 0:\r
1039 continue\r
1040\r
1041 if FileContent[0] == 0xff or FileContent[0] == 0xfe:\r
1042 FileContent = unicode(FileContent, "utf-16")\r
1043 IncludedFileList = gIncludePattern.findall(FileContent)\r
1044\r
1045 for Inc in IncludedFileList:\r
1046 Inc = Inc.strip()\r
1047 # if there's macro used to reference header file, expand it\r
1048 HeaderList = gMacroPattern.findall(Inc)\r
1049 if len(HeaderList) == 1 and len(HeaderList[0]) == 2:\r
1050 HeaderType = HeaderList[0][0]\r
1051 HeaderKey = HeaderList[0][1]\r
1052 if HeaderType in gIncludeMacroConversion:\r
1053 Inc = gIncludeMacroConversion[HeaderType] % {"HeaderKey" : HeaderKey}\r
1054 else:\r
1055 # not known macro used in #include, always build the file by\r
1056 # returning a empty dependency\r
1057 self.FileCache[File] = []\r
1058 return []\r
1059 Inc = os.path.normpath(Inc)\r
1060 CurrentFileDependencyList.append(Inc)\r
1061 DepDb[F] = CurrentFileDependencyList\r
1062\r
1063 CurrentFilePath = F.Dir\r
1064 PathList = [CurrentFilePath] + SearchPathList\r
1065 for Inc in CurrentFileDependencyList:\r
1066 for SearchPath in PathList:\r
1067 FilePath = os.path.join(SearchPath, Inc)\r
1068 if FilePath in gIsFileMap:\r
1069 if not gIsFileMap[FilePath]:\r
1070 continue\r
1071 # If isfile is called too many times, the performance is slow down.\r
1072 elif not os.path.isfile(FilePath):\r
1073 gIsFileMap[FilePath] = False\r
1074 continue\r
1075 else:\r
1076 gIsFileMap[FilePath] = True\r
1077 FilePath = PathClass(FilePath)\r
1078 FullPathDependList.append(FilePath)\r
1079 if FilePath not in DependencySet:\r
1080 FileStack.append(FilePath)\r
1081 break\r
1082 else:\r
1083 EdkLogger.debug(EdkLogger.DEBUG_9, "%s included by %s was not found "\\r
1084 "in any given path:\n\t%s" % (Inc, F, "\n\t".join(SearchPathList)))\r
1085\r
1086 self.FileCache[F] = FullPathDependList\r
1087 DependencySet.update(FullPathDependList)\r
1088\r
1089 DependencySet.update(ForceList)\r
1090 if File in DependencySet:\r
1091 DependencySet.remove(File)\r
1092 DependencyList = list(DependencySet) # remove duplicate ones\r
1093\r
1094 return DependencyList\r
1095\r
1096 _TemplateDict = property(_CreateTemplateDict)\r
1097\r
1098## CustomMakefile class\r
1099#\r
1100# This class encapsules makefie and its generation for module. It uses template to generate\r
1101# the content of makefile. The content of makefile will be got from ModuleAutoGen object.\r
1102#\r
1103class CustomMakefile(BuildFile):\r
1104 ## template used to generate the makefile for module with custom makefile\r
1105 _TEMPLATE_ = TemplateString('''\\r
1106${makefile_header}\r
1107\r
1108#\r
1109# Platform Macro Definition\r
1110#\r
1111PLATFORM_NAME = ${platform_name}\r
1112PLATFORM_GUID = ${platform_guid}\r
1113PLATFORM_VERSION = ${platform_version}\r
1114PLATFORM_RELATIVE_DIR = ${platform_relative_directory}\r
1115PLATFORM_DIR = ${platform_dir}\r
1116PLATFORM_OUTPUT_DIR = ${platform_output_directory}\r
1117\r
1118#\r
1119# Module Macro Definition\r
1120#\r
1121MODULE_NAME = ${module_name}\r
1122MODULE_GUID = ${module_guid}\r
1123MODULE_NAME_GUID = ${module_name_guid}\r
1124MODULE_VERSION = ${module_version}\r
1125MODULE_TYPE = ${module_type}\r
1126MODULE_FILE = ${module_file}\r
1127MODULE_FILE_BASE_NAME = ${module_file_base_name}\r
1128BASE_NAME = $(MODULE_NAME)\r
1129MODULE_RELATIVE_DIR = ${module_relative_directory}\r
1130MODULE_DIR = ${module_dir}\r
1131\r
1132#\r
1133# Build Configuration Macro Definition\r
1134#\r
1135ARCH = ${architecture}\r
1136TOOLCHAIN = ${toolchain_tag}\r
1137TOOLCHAIN_TAG = ${toolchain_tag}\r
1138TARGET = ${build_target}\r
1139\r
1140#\r
1141# Build Directory Macro Definition\r
1142#\r
1143# PLATFORM_BUILD_DIR = ${platform_build_directory}\r
1144BUILD_DIR = ${platform_build_directory}\r
1145BIN_DIR = $(BUILD_DIR)${separator}${architecture}\r
1146LIB_DIR = $(BIN_DIR)\r
1147MODULE_BUILD_DIR = ${module_build_directory}\r
1148OUTPUT_DIR = ${module_output_directory}\r
1149DEBUG_DIR = ${module_debug_directory}\r
1150DEST_DIR_OUTPUT = $(OUTPUT_DIR)\r
1151DEST_DIR_DEBUG = $(DEBUG_DIR)\r
1152\r
1153#\r
1154# Tools definitions specific to this module\r
1155#\r
1156${BEGIN}${module_tool_definitions}\r
1157${END}\r
1158MAKE_FILE = ${makefile_path}\r
1159\r
1160#\r
1161# Shell Command Macro\r
1162#\r
1163${BEGIN}${shell_command_code} = ${shell_command}\r
1164${END}\r
1165\r
1166${custom_makefile_content}\r
1167\r
1168#\r
1169# Target used when called from platform makefile, which will bypass the build of dependent libraries\r
1170#\r
1171\r
1172pbuild: init all\r
1173\r
1174\r
1175#\r
1176# ModuleTarget\r
1177#\r
1178\r
1179mbuild: init all\r
1180\r
1181#\r
1182# Build Target used in multi-thread build mode, which no init target is needed\r
1183#\r
1184\r
1185tbuild: all\r
1186\r
1187#\r
1188# Initialization target: print build information and create necessary directories\r
1189#\r
1190init:\r
1191\t-@echo Building ... $(MODULE_DIR)${separator}$(MODULE_FILE) [$(ARCH)]\r
1192${BEGIN}\t-@${create_directory_command}\n${END}\\r
1193\r
1194''')\r
1195\r
1196 ## Constructor of CustomMakefile\r
1197 #\r
1198 # @param ModuleAutoGen Object of ModuleAutoGen class\r
1199 #\r
1200 def __init__(self, ModuleAutoGen):\r
1201 BuildFile.__init__(self, ModuleAutoGen)\r
1202 self.PlatformInfo = self._AutoGenObject.PlatformInfo\r
1203 self.IntermediateDirectoryList = ["$(DEBUG_DIR)", "$(OUTPUT_DIR)"]\r
1204\r
1205 # Compose a dict object containing information used to do replacement in template\r
1206 def _CreateTemplateDict(self):\r
1207 Separator = self._SEP_[self._FileType]\r
1208 if self._FileType not in self._AutoGenObject.CustomMakefile:\r
1209 EdkLogger.error('build', OPTION_NOT_SUPPORTED, "No custom makefile for %s" % self._FileType,\r
1210 ExtraData="[%s]" % str(self._AutoGenObject))\r
1211 MakefilePath = mws.join(\r
1212 self._AutoGenObject.WorkspaceDir,\r
1213 self._AutoGenObject.CustomMakefile[self._FileType]\r
1214 )\r
1215 try:\r
1216 CustomMakefile = open(MakefilePath, 'r').read()\r
1217 except:\r
1218 EdkLogger.error('build', FILE_OPEN_FAILURE, File=str(self._AutoGenObject),\r
1219 ExtraData=self._AutoGenObject.CustomMakefile[self._FileType])\r
1220\r
1221 # tools definitions\r
1222 ToolsDef = []\r
1223 for Tool in self._AutoGenObject.BuildOption:\r
1224 # Don't generate MAKE_FLAGS in makefile. It's put in environment variable.\r
1225 if Tool == "MAKE":\r
1226 continue\r
1227 for Attr in self._AutoGenObject.BuildOption[Tool]:\r
1228 if Attr == "FAMILY":\r
1229 continue\r
1230 elif Attr == "PATH":\r
1231 ToolsDef.append("%s = %s" % (Tool, self._AutoGenObject.BuildOption[Tool][Attr]))\r
1232 else:\r
1233 ToolsDef.append("%s_%s = %s" % (Tool, Attr, self._AutoGenObject.BuildOption[Tool][Attr]))\r
1234 ToolsDef.append("")\r
1235\r
1236 MakefileName = self._FILE_NAME_[self._FileType]\r
1237 MakefileTemplateDict = {\r
1238 "makefile_header" : self._FILE_HEADER_[self._FileType],\r
1239 "makefile_path" : os.path.join("$(MODULE_BUILD_DIR)", MakefileName),\r
1240 "platform_name" : self.PlatformInfo.Name,\r
1241 "platform_guid" : self.PlatformInfo.Guid,\r
1242 "platform_version" : self.PlatformInfo.Version,\r
1243 "platform_relative_directory": self.PlatformInfo.SourceDir,\r
1244 "platform_output_directory" : self.PlatformInfo.OutputDir,\r
1245 "platform_dir" : self._AutoGenObject.Macros["PLATFORM_DIR"],\r
1246\r
1247 "module_name" : self._AutoGenObject.Name,\r
1248 "module_guid" : self._AutoGenObject.Guid,\r
1249 "module_name_guid" : self._AutoGenObject._GetUniqueBaseName(),\r
1250 "module_version" : self._AutoGenObject.Version,\r
1251 "module_type" : self._AutoGenObject.ModuleType,\r
1252 "module_file" : self._AutoGenObject.MetaFile,\r
1253 "module_file_base_name" : self._AutoGenObject.MetaFile.BaseName,\r
1254 "module_relative_directory" : self._AutoGenObject.SourceDir,\r
1255 "module_dir" : mws.join (self._AutoGenObject.WorkspaceDir, self._AutoGenObject.SourceDir),\r
1256\r
1257 "architecture" : self._AutoGenObject.Arch,\r
1258 "toolchain_tag" : self._AutoGenObject.ToolChain,\r
1259 "build_target" : self._AutoGenObject.BuildTarget,\r
1260\r
1261 "platform_build_directory" : self.PlatformInfo.BuildDir,\r
1262 "module_build_directory" : self._AutoGenObject.BuildDir,\r
1263 "module_output_directory" : self._AutoGenObject.OutputDir,\r
1264 "module_debug_directory" : self._AutoGenObject.DebugDir,\r
1265\r
1266 "separator" : Separator,\r
1267 "module_tool_definitions" : ToolsDef,\r
1268\r
1269 "shell_command_code" : self._SHELL_CMD_[self._FileType].keys(),\r
1270 "shell_command" : self._SHELL_CMD_[self._FileType].values(),\r
1271\r
1272 "create_directory_command" : self.GetCreateDirectoryCommand(self.IntermediateDirectoryList),\r
1273 "custom_makefile_content" : CustomMakefile\r
1274 }\r
1275\r
1276 return MakefileTemplateDict\r
1277\r
1278 _TemplateDict = property(_CreateTemplateDict)\r
1279\r
1280## PlatformMakefile class\r
1281#\r
1282# This class encapsules makefie and its generation for platform. It uses\r
1283# template to generate the content of makefile. The content of makefile will be\r
1284# got from PlatformAutoGen object.\r
1285#\r
1286class PlatformMakefile(BuildFile):\r
1287 ## template used to generate the makefile for platform\r
1288 _TEMPLATE_ = TemplateString('''\\r
1289${makefile_header}\r
1290\r
1291#\r
1292# Platform Macro Definition\r
1293#\r
1294PLATFORM_NAME = ${platform_name}\r
1295PLATFORM_GUID = ${platform_guid}\r
1296PLATFORM_VERSION = ${platform_version}\r
1297PLATFORM_FILE = ${platform_file}\r
1298PLATFORM_DIR = ${platform_dir}\r
1299PLATFORM_OUTPUT_DIR = ${platform_output_directory}\r
1300\r
1301#\r
1302# Build Configuration Macro Definition\r
1303#\r
1304TOOLCHAIN = ${toolchain_tag}\r
1305TOOLCHAIN_TAG = ${toolchain_tag}\r
1306TARGET = ${build_target}\r
1307\r
1308#\r
1309# Build Directory Macro Definition\r
1310#\r
1311BUILD_DIR = ${platform_build_directory}\r
1312FV_DIR = ${platform_build_directory}${separator}FV\r
1313\r
1314#\r
1315# Shell Command Macro\r
1316#\r
1317${BEGIN}${shell_command_code} = ${shell_command}\r
1318${END}\r
1319\r
1320MAKE = ${make_path}\r
1321MAKE_FILE = ${makefile_path}\r
1322\r
1323#\r
1324# Default target\r
1325#\r
1326all: init build_libraries build_modules\r
1327\r
1328#\r
1329# Initialization target: print build information and create necessary directories\r
1330#\r
1331init:\r
1332\t-@echo Building ... $(PLATFORM_FILE) [${build_architecture_list}]\r
1333\t${BEGIN}-@${create_directory_command}\r
1334\t${END}\r
1335#\r
1336# library build target\r
1337#\r
1338libraries: init build_libraries\r
1339\r
1340#\r
1341# module build target\r
1342#\r
1343modules: init build_libraries build_modules\r
1344\r
1345#\r
1346# Build all libraries:\r
1347#\r
1348build_libraries:\r
1349${BEGIN}\t@"$(MAKE)" $(MAKE_FLAGS) -f ${library_makefile_list} pbuild\r
1350${END}\t@cd $(BUILD_DIR)\r
1351\r
1352#\r
1353# Build all modules:\r
1354#\r
1355build_modules:\r
1356${BEGIN}\t@"$(MAKE)" $(MAKE_FLAGS) -f ${module_makefile_list} pbuild\r
1357${END}\t@cd $(BUILD_DIR)\r
1358\r
1359#\r
1360# Clean intermediate files\r
1361#\r
1362clean:\r
1363\t${BEGIN}-@${library_build_command} clean\r
1364\t${END}${BEGIN}-@${module_build_command} clean\r
1365\t${END}@cd $(BUILD_DIR)\r
1366\r
1367#\r
1368# Clean all generated files except to makefile\r
1369#\r
1370cleanall:\r
1371${BEGIN}\t${cleanall_command}\r
1372${END}\r
1373\r
1374#\r
1375# Clean all library files\r
1376#\r
1377cleanlib:\r
1378\t${BEGIN}-@${library_build_command} cleanall\r
1379\t${END}@cd $(BUILD_DIR)\n\r
1380''')\r
1381\r
1382 ## Constructor of PlatformMakefile\r
1383 #\r
1384 # @param ModuleAutoGen Object of PlatformAutoGen class\r
1385 #\r
1386 def __init__(self, PlatformAutoGen):\r
1387 BuildFile.__init__(self, PlatformAutoGen)\r
1388 self.ModuleBuildCommandList = []\r
1389 self.ModuleMakefileList = []\r
1390 self.IntermediateDirectoryList = []\r
1391 self.ModuleBuildDirectoryList = []\r
1392 self.LibraryBuildDirectoryList = []\r
1393 self.LibraryMakeCommandList = []\r
1394\r
1395 # Compose a dict object containing information used to do replacement in template\r
1396 def _CreateTemplateDict(self):\r
1397 Separator = self._SEP_[self._FileType]\r
1398\r
1399 PlatformInfo = self._AutoGenObject\r
1400 if "MAKE" not in PlatformInfo.ToolDefinition or "PATH" not in PlatformInfo.ToolDefinition["MAKE"]:\r
1401 EdkLogger.error("build", OPTION_MISSING, "No MAKE command defined. Please check your tools_def.txt!",\r
1402 ExtraData="[%s]" % str(self._AutoGenObject))\r
1403\r
1404 self.IntermediateDirectoryList = ["$(BUILD_DIR)"]\r
1405 self.ModuleBuildDirectoryList = self.GetModuleBuildDirectoryList()\r
1406 self.LibraryBuildDirectoryList = self.GetLibraryBuildDirectoryList()\r
1407\r
1408 MakefileName = self._FILE_NAME_[self._FileType]\r
1409 LibraryMakefileList = []\r
1410 LibraryMakeCommandList = []\r
1411 for D in self.LibraryBuildDirectoryList:\r
1412 D = self.PlaceMacro(D, {"BUILD_DIR":PlatformInfo.BuildDir})\r
1413 Makefile = os.path.join(D, MakefileName)\r
1414 Command = self._MAKE_TEMPLATE_[self._FileType] % {"file":Makefile}\r
1415 LibraryMakefileList.append(Makefile)\r
1416 LibraryMakeCommandList.append(Command)\r
1417 self.LibraryMakeCommandList = LibraryMakeCommandList\r
1418\r
1419 ModuleMakefileList = []\r
1420 ModuleMakeCommandList = []\r
1421 for D in self.ModuleBuildDirectoryList:\r
1422 D = self.PlaceMacro(D, {"BUILD_DIR":PlatformInfo.BuildDir})\r
1423 Makefile = os.path.join(D, MakefileName)\r
1424 Command = self._MAKE_TEMPLATE_[self._FileType] % {"file":Makefile}\r
1425 ModuleMakefileList.append(Makefile)\r
1426 ModuleMakeCommandList.append(Command)\r
1427\r
1428 MakefileTemplateDict = {\r
1429 "makefile_header" : self._FILE_HEADER_[self._FileType],\r
1430 "makefile_path" : os.path.join("$(BUILD_DIR)", MakefileName),\r
1431 "make_path" : PlatformInfo.ToolDefinition["MAKE"]["PATH"],\r
1432 "makefile_name" : MakefileName,\r
1433 "platform_name" : PlatformInfo.Name,\r
1434 "platform_guid" : PlatformInfo.Guid,\r
1435 "platform_version" : PlatformInfo.Version,\r
1436 "platform_file" : self._AutoGenObject.MetaFile,\r
1437 "platform_relative_directory": PlatformInfo.SourceDir,\r
1438 "platform_output_directory" : PlatformInfo.OutputDir,\r
1439 "platform_build_directory" : PlatformInfo.BuildDir,\r
1440 "platform_dir" : self._AutoGenObject.Macros["PLATFORM_DIR"],\r
1441\r
1442 "toolchain_tag" : PlatformInfo.ToolChain,\r
1443 "build_target" : PlatformInfo.BuildTarget,\r
1444 "shell_command_code" : self._SHELL_CMD_[self._FileType].keys(),\r
1445 "shell_command" : self._SHELL_CMD_[self._FileType].values(),\r
1446 "build_architecture_list" : self._AutoGenObject.Arch,\r
1447 "architecture" : self._AutoGenObject.Arch,\r
1448 "separator" : Separator,\r
1449 "create_directory_command" : self.GetCreateDirectoryCommand(self.IntermediateDirectoryList),\r
1450 "cleanall_command" : self.GetRemoveDirectoryCommand(self.IntermediateDirectoryList),\r
1451 "library_makefile_list" : LibraryMakefileList,\r
1452 "module_makefile_list" : ModuleMakefileList,\r
1453 "library_build_command" : LibraryMakeCommandList,\r
1454 "module_build_command" : ModuleMakeCommandList,\r
1455 }\r
1456\r
1457 return MakefileTemplateDict\r
1458\r
1459 ## Get the root directory list for intermediate files of all modules build\r
1460 #\r
1461 # @retval list The list of directory\r
1462 #\r
1463 def GetModuleBuildDirectoryList(self):\r
1464 DirList = []\r
1465 for ModuleAutoGen in self._AutoGenObject.ModuleAutoGenList:\r
1466 if not ModuleAutoGen.IsBinaryModule:\r
1467 DirList.append(os.path.join(self._AutoGenObject.BuildDir, ModuleAutoGen.BuildDir))\r
1468 return DirList\r
1469\r
1470 ## Get the root directory list for intermediate files of all libraries build\r
1471 #\r
1472 # @retval list The list of directory\r
1473 #\r
1474 def GetLibraryBuildDirectoryList(self):\r
1475 DirList = []\r
1476 for LibraryAutoGen in self._AutoGenObject.LibraryAutoGenList:\r
1477 if not LibraryAutoGen.IsBinaryModule:\r
1478 DirList.append(os.path.join(self._AutoGenObject.BuildDir, LibraryAutoGen.BuildDir))\r
1479 return DirList\r
1480\r
1481 _TemplateDict = property(_CreateTemplateDict)\r
1482\r
1483## TopLevelMakefile class\r
1484#\r
1485# This class encapsules makefie and its generation for entrance makefile. It\r
1486# uses template to generate the content of makefile. The content of makefile\r
1487# will be got from WorkspaceAutoGen object.\r
1488#\r
1489class TopLevelMakefile(BuildFile):\r
1490 ## template used to generate toplevel makefile\r
1491 _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
1492\r
1493 ## Constructor of TopLevelMakefile\r
1494 #\r
1495 # @param Workspace Object of WorkspaceAutoGen class\r
1496 #\r
1497 def __init__(self, Workspace):\r
1498 BuildFile.__init__(self, Workspace)\r
1499 self.IntermediateDirectoryList = []\r
1500\r
1501 # Compose a dict object containing information used to do replacement in template\r
1502 def _CreateTemplateDict(self):\r
1503 Separator = self._SEP_[self._FileType]\r
1504\r
1505 # any platform autogen object is ok because we just need common information\r
1506 PlatformInfo = self._AutoGenObject\r
1507\r
1508 if "MAKE" not in PlatformInfo.ToolDefinition or "PATH" not in PlatformInfo.ToolDefinition["MAKE"]:\r
1509 EdkLogger.error("build", OPTION_MISSING, "No MAKE command defined. Please check your tools_def.txt!",\r
1510 ExtraData="[%s]" % str(self._AutoGenObject))\r
1511\r
1512 for Arch in PlatformInfo.ArchList:\r
1513 self.IntermediateDirectoryList.append(Separator.join(["$(BUILD_DIR)", Arch]))\r
1514 self.IntermediateDirectoryList.append("$(FV_DIR)")\r
1515\r
1516 # TRICK: for not generating GenFds call in makefile if no FDF file\r
1517 MacroList = []\r
1518 if PlatformInfo.FdfFile is not None and PlatformInfo.FdfFile != "":\r
1519 FdfFileList = [PlatformInfo.FdfFile]\r
1520 # macros passed to GenFds\r
1521 MacroList.append('"%s=%s"' % ("EFI_SOURCE", GlobalData.gEfiSource.replace('\\', '\\\\')))\r
1522 MacroList.append('"%s=%s"' % ("EDK_SOURCE", GlobalData.gEdkSource.replace('\\', '\\\\')))\r
1523 MacroDict = {}\r
1524 MacroDict.update(GlobalData.gGlobalDefines)\r
1525 MacroDict.update(GlobalData.gCommandLineDefines)\r
1526 MacroDict.pop("EFI_SOURCE", "dummy")\r
1527 MacroDict.pop("EDK_SOURCE", "dummy")\r
1528 for MacroName in MacroDict:\r
1529 if MacroDict[MacroName] != "":\r
1530 MacroList.append('"%s=%s"' % (MacroName, MacroDict[MacroName].replace('\\', '\\\\')))\r
1531 else:\r
1532 MacroList.append('"%s"' % MacroName)\r
1533 else:\r
1534 FdfFileList = []\r
1535\r
1536 # pass extra common options to external program called in makefile, currently GenFds.exe\r
1537 ExtraOption = ''\r
1538 LogLevel = EdkLogger.GetLevel()\r
1539 if LogLevel == EdkLogger.VERBOSE:\r
1540 ExtraOption += " -v"\r
1541 elif LogLevel <= EdkLogger.DEBUG_9:\r
1542 ExtraOption += " -d %d" % (LogLevel - 1)\r
1543 elif LogLevel == EdkLogger.QUIET:\r
1544 ExtraOption += " -q"\r
1545\r
1546 if GlobalData.gCaseInsensitive:\r
1547 ExtraOption += " -c"\r
1548 if GlobalData.gEnableGenfdsMultiThread:\r
1549 ExtraOption += " --genfds-multi-thread"\r
1550 if GlobalData.gIgnoreSource:\r
1551 ExtraOption += " --ignore-sources"\r
1552\r
1553 for pcd in GlobalData.BuildOptionPcd:\r
1554 if pcd[2]:\r
1555 pcdname = '.'.join(pcd[0:3])\r
1556 else:\r
1557 pcdname = '.'.join(pcd[0:2])\r
1558 if pcd[3].startswith('{'):\r
1559 ExtraOption += " --pcd " + pcdname + '=' + 'H' + '"' + pcd[3] + '"'\r
1560 else:\r
1561 ExtraOption += " --pcd " + pcdname + '=' + pcd[3]\r
1562\r
1563 MakefileName = self._FILE_NAME_[self._FileType]\r
1564 SubBuildCommandList = []\r
1565 for A in PlatformInfo.ArchList:\r
1566 Command = self._MAKE_TEMPLATE_[self._FileType] % {"file":os.path.join("$(BUILD_DIR)", A, MakefileName)}\r
1567 SubBuildCommandList.append(Command)\r
1568\r
1569 MakefileTemplateDict = {\r
1570 "makefile_header" : self._FILE_HEADER_[self._FileType],\r
1571 "makefile_path" : os.path.join("$(BUILD_DIR)", MakefileName),\r
1572 "make_path" : PlatformInfo.ToolDefinition["MAKE"]["PATH"],\r
1573 "platform_name" : PlatformInfo.Name,\r
1574 "platform_guid" : PlatformInfo.Guid,\r
1575 "platform_version" : PlatformInfo.Version,\r
1576 "platform_build_directory" : PlatformInfo.BuildDir,\r
1577 "conf_directory" : GlobalData.gConfDirectory,\r
1578\r
1579 "toolchain_tag" : PlatformInfo.ToolChain,\r
1580 "build_target" : PlatformInfo.BuildTarget,\r
1581 "shell_command_code" : self._SHELL_CMD_[self._FileType].keys(),\r
1582 "shell_command" : self._SHELL_CMD_[self._FileType].values(),\r
1583 'arch' : list(PlatformInfo.ArchList),\r
1584 "build_architecture_list" : ','.join(PlatformInfo.ArchList),\r
1585 "separator" : Separator,\r
1586 "create_directory_command" : self.GetCreateDirectoryCommand(self.IntermediateDirectoryList),\r
1587 "cleanall_command" : self.GetRemoveDirectoryCommand(self.IntermediateDirectoryList),\r
1588 "sub_build_command" : SubBuildCommandList,\r
1589 "fdf_file" : FdfFileList,\r
1590 "active_platform" : str(PlatformInfo),\r
1591 "fd" : PlatformInfo.FdTargetList,\r
1592 "fv" : PlatformInfo.FvTargetList,\r
1593 "cap" : PlatformInfo.CapTargetList,\r
1594 "extra_options" : ExtraOption,\r
1595 "macro" : MacroList,\r
1596 }\r
1597\r
1598 return MakefileTemplateDict\r
1599\r
1600 ## Get the root directory list for intermediate files of all modules build\r
1601 #\r
1602 # @retval list The list of directory\r
1603 #\r
1604 def GetModuleBuildDirectoryList(self):\r
1605 DirList = []\r
1606 for ModuleAutoGen in self._AutoGenObject.ModuleAutoGenList:\r
1607 if not ModuleAutoGen.IsBinaryModule:\r
1608 DirList.append(os.path.join(self._AutoGenObject.BuildDir, ModuleAutoGen.BuildDir))\r
1609 return DirList\r
1610\r
1611 ## Get the root directory list for intermediate files of all libraries build\r
1612 #\r
1613 # @retval list The list of directory\r
1614 #\r
1615 def GetLibraryBuildDirectoryList(self):\r
1616 DirList = []\r
1617 for LibraryAutoGen in self._AutoGenObject.LibraryAutoGenList:\r
1618 if not LibraryAutoGen.IsBinaryModule:\r
1619 DirList.append(os.path.join(self._AutoGenObject.BuildDir, LibraryAutoGen.BuildDir))\r
1620 return DirList\r
1621\r
1622 _TemplateDict = property(_CreateTemplateDict)\r
1623\r
1624# This acts like the main() function for the script, unless it is 'import'ed into another script.\r
1625if __name__ == '__main__':\r
1626 pass\r
1627\r