2 # Create makefile for MS nmake and GNU make
4 # Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
5 # This program and the accompanying materials
6 # are licensed and made available under the terms and conditions of the BSD License
7 # which accompanies this distribution. The full text of the license may be found at
8 # http://opensource.org/licenses/bsd-license.php
10 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
20 import os
.path
as path
22 from Common
.BuildToolError
import *
23 from Common
.Misc
import *
24 from Common
.String
import *
25 from BuildEngine
import *
26 import Common
.GlobalData
as GlobalData
28 ## Regular expression for finding header file inclusions
29 gIncludePattern
= re
.compile(r
"^[ \t]*#?[ \t]*include(?:[ \t]*(?:\\(?:\r\n|\r|\n))*[ \t]*)*(?:\(?[\"<]?
[ \t]*)([-\w
.\\/() \t]+)(?
:[ \t]*[\">]?\
)?
)", re.MULTILINE|re.UNICODE|re.IGNORECASE)
31 ## Regular expression for matching macro used in header file inclusion
32 gMacroPattern = re.compile("([_A
-Z
][_A
-Z0
-9]*)[ \t]*\
((.+)\
)", re.UNICODE)
36 ## pattern for include style in Edk.x code
37 gProtocolDefinition = "Protocol
/%(HeaderKey)s/%(HeaderKey)s.h
"
38 gGuidDefinition = "Guid
/%(HeaderKey)s/%(HeaderKey)s.h
"
39 gArchProtocolDefinition = "ArchProtocol
/%(HeaderKey)s/%(HeaderKey)s.h
"
40 gPpiDefinition = "Ppi
/%(HeaderKey)s/%(HeaderKey)s.h
"
41 gIncludeMacroConversion = {
42 "EFI_PROTOCOL_DEFINITION
" : gProtocolDefinition,
43 "EFI_GUID_DEFINITION
" : gGuidDefinition,
44 "EFI_ARCH_PROTOCOL_DEFINITION
" : gArchProtocolDefinition,
45 "EFI_PROTOCOL_PRODUCER
" : gProtocolDefinition,
46 "EFI_PROTOCOL_CONSUMER
" : gProtocolDefinition,
47 "EFI_PROTOCOL_DEPENDENCY
" : gProtocolDefinition,
48 "EFI_ARCH_PROTOCOL_PRODUCER
" : gArchProtocolDefinition,
49 "EFI_ARCH_PROTOCOL_CONSUMER
" : gArchProtocolDefinition,
50 "EFI_ARCH_PROTOCOL_DEPENDENCY
" : gArchProtocolDefinition,
51 "EFI_PPI_DEFINITION
" : gPpiDefinition,
52 "EFI_PPI_PRODUCER
" : gPpiDefinition,
53 "EFI_PPI_CONSUMER
" : gPpiDefinition,
54 "EFI_PPI_DEPENDENCY
" : gPpiDefinition,
57 ## default makefile type
59 if sys.platform == "win32
":
67 # This base class encapsules build file and its generation. It uses template to generate
68 # the content of build file. The content of build file will be got from AutoGen objects.
70 class BuildFile(object):
71 ## template used to generate the build file (i.e. makefile if using make)
72 _TEMPLATE_ = TemplateString('')
74 _DEFAULT_FILE_NAME_ = "Makefile
"
76 ## default file name for each type of build file
79 "gmake
" : "GNUmakefile
"
82 ## Fixed header string for makefile
83 _MAKEFILE_HEADER = '''#
85 # This file is auto-generated by build utility
93 # Auto-generated makefile for building modules, libraries or platform
97 ## Header string for each type of build file
99 "nmake
" : _MAKEFILE_HEADER % _FILE_NAME_["nmake
"],
100 "gmake
" : _MAKEFILE_HEADER % _FILE_NAME_["gmake
"]
103 ## shell commands which can be used in build file in the form of macro
104 # $(CP) copy file command
105 # $(MV) move file command
106 # $(RM) remove file command
107 # $(MD) create dir command
108 # $(RD) remove dir command
116 "RD
" : "rmdir
/s
/q
",
128 ## directory separator
134 ## directory creation template
136 "nmake
" : 'if not exist %(dir)s $(MD) %(dir)s',
137 "gmake
" : "$
(MD
) %(dir)s"
140 ## directory removal template
142 "nmake
" : 'if exist %(dir)s $(RD) %(dir)s',
143 "gmake
" : "$
(RD
) %(dir)s"
147 "nmake
" : 'if exist %(dir)s cd %(dir)s',
148 "gmake
" : "test
-e
%(dir)s && cd
%(dir)s"
152 "nmake
" : 'if exist %(file)s "$
(MAKE
)" $(MAKE_FLAGS) -f %(file)s',
153 "gmake
" : 'test -e %(file)s && "$
(MAKE
)" $(MAKE_FLAGS) -f %(file)s'
157 "nmake
" : '!INCLUDE',
161 _INC_FLAG_ = {"MSFT
" : "/I
", "GCC
" : "-I
", "INTEL
" : "-I
", "RVCT
" : "-I
"}
163 ## Constructor of BuildFile
165 # @param AutoGenObject Object of AutoGen class
167 def __init__(self, AutoGenObject):
168 self._AutoGenObject = AutoGenObject
169 self._FileType = gMakeType
173 # @param FileType Type of build file. Only nmake and gmake are supported now.
175 # @retval TRUE The build file is created or re-created successfully
176 # @retval FALSE The build file exists and is the same as the one to be generated
178 def Generate(self, FileType=gMakeType):
179 if FileType not in self._FILE_NAME_:
180 EdkLogger.error("build
", PARAMETER_INVALID, "Invalid build
type [%s]" % FileType,
181 ExtraData="[%s]" % str(self._AutoGenObject))
182 self._FileType = FileType
183 FileContent = self._TEMPLATE_.Replace(self._TemplateDict)
184 FileName = self._FILE_NAME_[FileType]
185 return SaveFileOnChange(os.path.join(self._AutoGenObject.MakeFileDir, FileName), FileContent, False)
187 ## Return a list of directory creation command string
189 # @param DirList The list of directory to be created
191 # @retval list The directory creation command list
193 def GetCreateDirectoryCommand(self, DirList):
194 return [self._MD_TEMPLATE_[self._FileType] % {'dir':Dir} for Dir in DirList]
196 ## Return a list of directory removal command string
198 # @param DirList The list of directory to be removed
200 # @retval list The directory removal command list
202 def GetRemoveDirectoryCommand(self, DirList):
203 return [self._RD_TEMPLATE_[self._FileType] % {'dir':Dir} for Dir in DirList]
205 def PlaceMacro(self, Path, MacroDefinitions={}):
206 if Path.startswith("$
("):
209 PathLength = len(Path)
210 for MacroName in MacroDefinitions:
211 MacroValue = MacroDefinitions[MacroName]
212 MacroValueLength = len(MacroValue)
213 if MacroValueLength <= PathLength and Path.startswith(MacroValue):
214 Path = "$
(%s)%s" % (MacroName, Path[MacroValueLength:])
218 ## ModuleMakefile class
220 # This class encapsules makefie and its generation for module. It uses template to generate
221 # the content of makefile. The content of makefile will be got from ModuleAutoGen object.
223 class ModuleMakefile(BuildFile):
224 ## template used to generate the makefile for module
225 _TEMPLATE_ = TemplateString('''\
229 # Platform Macro Definition
231 PLATFORM_NAME = ${platform_name}
232 PLATFORM_GUID = ${platform_guid}
233 PLATFORM_VERSION = ${platform_version}
234 PLATFORM_RELATIVE_DIR = ${platform_relative_directory}
235 PLATFORM_DIR = $(WORKSPACE)${separator}${platform_relative_directory}
236 PLATFORM_OUTPUT_DIR = ${platform_output_directory}
239 # Module Macro Definition
241 MODULE_NAME = ${module_name}
242 MODULE_GUID = ${module_guid}
243 MODULE_VERSION = ${module_version}
244 MODULE_TYPE = ${module_type}
245 MODULE_FILE = ${module_file}
246 MODULE_FILE_BASE_NAME = ${module_file_base_name}
247 BASE_NAME = $(MODULE_NAME)
248 MODULE_RELATIVE_DIR = ${module_relative_directory}
249 MODULE_DIR = $(WORKSPACE)${separator}${module_relative_directory}
251 MODULE_ENTRY_POINT = ${module_entry_point}
252 ARCH_ENTRY_POINT = ${arch_entry_point}
253 IMAGE_ENTRY_POINT = ${image_entry_point}
255 ${BEGIN}${module_extra_defines}
258 # Build Configuration Macro Definition
260 ARCH = ${architecture}
261 TOOLCHAIN = ${toolchain_tag}
262 TOOLCHAIN_TAG = ${toolchain_tag}
263 TARGET = ${build_target}
266 # Build Directory Macro Definition
268 # PLATFORM_BUILD_DIR = ${platform_build_directory}
269 BUILD_DIR = ${platform_build_directory}
270 BIN_DIR = $(BUILD_DIR)${separator}${architecture}
272 MODULE_BUILD_DIR = ${module_build_directory}
273 OUTPUT_DIR = ${module_output_directory}
274 DEBUG_DIR = ${module_debug_directory}
275 DEST_DIR_OUTPUT = $(OUTPUT_DIR)
276 DEST_DIR_DEBUG = $(DEBUG_DIR)
279 # Shell Command Macro
281 ${BEGIN}${shell_command_code} = ${shell_command}
285 # Tools definitions specific to this module
287 ${BEGIN}${module_tool_definitions}
289 MAKE_FILE = ${makefile_path}
294 ${BEGIN}${file_macro}
297 COMMON_DEPS = ${BEGIN}${common_dependency_file} \\
301 # Overridable Target Macro Definitions
303 FORCE_REBUILD = force_build
306 BC_TARGET = ${BEGIN}${backward_compatible_target} ${END}
307 CODA_TARGET = ${BEGIN}${remaining_build_target} \\
311 # Default target, which will build dependent libraries in addition to source files
318 # Target used when called from platform makefile, which will bypass the build of dependent libraries
321 pbuild: $(INIT_TARGET) $(BC_TARGET) $(PCH_TARGET) $(CODA_TARGET)
327 mbuild: $(INIT_TARGET) $(BC_TARGET) gen_libs $(PCH_TARGET) $(CODA_TARGET)
330 # Build Target used in multi-thread build mode, which will bypass the init and gen_libs targets
333 tbuild: $(BC_TARGET) $(PCH_TARGET) $(CODA_TARGET)
336 # Phony target which is used to force executing commands for a target
342 # Target to update the FD
348 # Initialization target: print build information and create necessary directories
353 \t-@echo Building ... $(MODULE_DIR)${separator}$(MODULE_FILE) [$(ARCH)]
356 ${BEGIN}\t-@${create_directory_command}\n${END}
359 \t-@$(CP) $(DEBUG_DIR)${separator}AutoGen.h $(DEBUG_DIR)${separator}$(MODULE_NAME)StrDefs.h
365 \t${BEGIN}@"$
(MAKE
)" $(MAKE_FLAGS) -f ${dependent_library_build_directory}${separator}${makefile_name}
366 \t${END}@cd $(MODULE_BUILD_DIR)
369 # Build Flash Device Image
372 \t@"$
(MAKE
)" $(MAKE_FLAGS) -f $(BUILD_DIR)${separator}${makefile_name} fds
373 \t@cd $(MODULE_BUILD_DIR)
376 # Individual Object Build Targets
378 ${BEGIN}${file_build_target}
382 # clean all intermediate files
385 \t${BEGIN}${clean_command}
389 # clean all generated files
392 ${BEGIN}\t${cleanall_command}
393 ${END}\t$(RM) *.pdb *.idb > NUL 2>&1
394 \t$(RM) $(BIN_DIR)${separator}$(MODULE_NAME).efi
397 # clean all dependent libraries built
400 \t${BEGIN}-@${library_build_command} cleanall
401 \t${END}@cd $(MODULE_BUILD_DIR)\n\n''')
403 _FILE_MACRO_TEMPLATE = TemplateString("${macro_name}
= ${BEGIN}
\\\n ${source_file}${END}
\n")
404 _BUILD_TARGET_TEMPLATE = TemplateString("${BEGIN}${target}
: ${deps}
\n${END}
\t${cmd}
\n")
406 ## Constructor of ModuleMakefile
408 # @param ModuleAutoGen Object of ModuleAutoGen class
410 def __init__(self, ModuleAutoGen):
411 BuildFile.__init__(self, ModuleAutoGen)
412 self.PlatformInfo = self._AutoGenObject.PlatformInfo
414 self.ResultFileList = []
415 self.IntermediateDirectoryList = ["$
(DEBUG_DIR
)", "$
(OUTPUT_DIR
)"]
417 self.SourceFileDatabase = {} # {file type : file path}
418 self.DestFileDatabase = {} # {file type : file path}
419 self.FileBuildTargetList = [] # [(src, target string)]
420 self.BuildTargetList = [] # [target string]
421 self.PendingBuildTargetList = [] # [FileBuildRule objects]
422 self.CommonFileDependency = []
423 self.FileListMacros = {}
424 self.ListFileMacros = {}
427 self.FileDependency = []
428 self.LibraryBuildCommandList = []
429 self.LibraryFileList = []
430 self.LibraryMakefileList = []
431 self.LibraryBuildDirectoryList = []
432 self.SystemLibraryList = []
433 self.Macros = sdict()
434 self.Macros["OUTPUT_DIR
" ] = self._AutoGenObject.Macros["OUTPUT_DIR
"]
435 self.Macros["DEBUG_DIR
" ] = self._AutoGenObject.Macros["DEBUG_DIR
"]
436 self.Macros["MODULE_BUILD_DIR
"] = self._AutoGenObject.Macros["MODULE_BUILD_DIR
"]
437 self.Macros["BIN_DIR
" ] = self._AutoGenObject.Macros["BIN_DIR
"]
438 self.Macros["BUILD_DIR
" ] = self._AutoGenObject.Macros["BUILD_DIR
"]
439 self.Macros["WORKSPACE
" ] = self._AutoGenObject.Macros["WORKSPACE
"]
441 # Compose a dict object containing information used to do replacement in template
442 def _CreateTemplateDict(self):
443 if self._FileType not in self._SEP_:
444 EdkLogger.error("build
", PARAMETER_INVALID, "Invalid Makefile
type [%s]" % self._FileType,
445 ExtraData="[%s]" % str(self._AutoGenObject))
446 Separator = self._SEP_[self._FileType]
448 # break build if no source files and binary files are found
449 if len(self._AutoGenObject.SourceFileList) == 0 and len(self._AutoGenObject.BinaryFileList) == 0:
450 EdkLogger.error("build
", AUTOGEN_ERROR, "No files to be built
in module
[%s, %s, %s]"
451 % (self._AutoGenObject.BuildTarget, self._AutoGenObject.ToolChain, self._AutoGenObject.Arch),
452 ExtraData="[%s]" % str(self._AutoGenObject))
454 # convert dependent libraries to build command
455 self.ProcessDependentLibrary()
456 if len(self._AutoGenObject.Module.ModuleEntryPointList) > 0:
457 ModuleEntryPoint = self._AutoGenObject.Module.ModuleEntryPointList[0]
459 ModuleEntryPoint = "_ModuleEntryPoint
"
461 # Intel EBC compiler enforces EfiMain
462 if self._AutoGenObject.AutoGenVersion < 0x00010005 and self._AutoGenObject.Arch == "EBC
":
463 ArchEntryPoint = "EfiMain
"
465 ArchEntryPoint = ModuleEntryPoint
467 if self._AutoGenObject.Arch == "EBC
":
468 # EBC compiler always use "EfiStart
" as entry point. Only applies to EdkII modules
469 ImageEntryPoint = "EfiStart
"
470 elif self._AutoGenObject.AutoGenVersion < 0x00010005:
471 # Edk modules use entry point specified in INF file
472 ImageEntryPoint = ModuleEntryPoint
474 # EdkII modules always use "_ModuleEntryPoint
" as entry point
475 ImageEntryPoint = "_ModuleEntryPoint
"
479 IncPrefix = self._INC_FLAG_[self._AutoGenObject.ToolChainFamily]
480 for Tool in self._AutoGenObject.BuildOption:
481 for Attr in self._AutoGenObject.BuildOption[Tool]:
482 Value = self._AutoGenObject.BuildOption[Tool][Attr]
486 ToolsDef.append("%s = %s" % (Tool, Value))
488 # Don't generate MAKE_FLAGS in makefile. It's put in environment variable.
491 # Remove duplicated include path, if any
493 Value = RemoveDupOption(Value, IncPrefix, self._AutoGenObject.IncludePathList)
494 ToolsDef.append("%s_%s = %s" % (Tool, Attr, Value))
497 # convert source files and binary files to build targets
498 self.ResultFileList = [str(T.Target) for T in self._AutoGenObject.CodaTargetList]
499 if len(self.ResultFileList) == 0 and len(self._AutoGenObject.SourceFileList) <> 0:
500 EdkLogger.error("build
", AUTOGEN_ERROR, "Nothing to build
",
501 ExtraData="[%s]" % str(self._AutoGenObject))
503 self.ProcessBuildTargetList()
505 # Generate macros used to represent input files
506 FileMacroList = [] # macro name = file list
507 for FileListMacro in self.FileListMacros:
508 FileMacro = self._FILE_MACRO_TEMPLATE.Replace(
510 "macro_name
" : FileListMacro,
511 "source_file
" : self.FileListMacros[FileListMacro]
514 FileMacroList.append(FileMacro)
516 # INC_LIST is special
519 for P in self._AutoGenObject.IncludePathList:
520 IncludePathList.append(IncPrefix+self.PlaceMacro(P, self.Macros))
521 if FileBuildRule.INC_LIST_MACRO in self.ListFileMacros:
522 self.ListFileMacros[FileBuildRule.INC_LIST_MACRO].append(IncPrefix+P)
523 FileMacro += self._FILE_MACRO_TEMPLATE.Replace(
525 "macro_name
" : "INC
",
526 "source_file
" : IncludePathList
529 FileMacroList.append(FileMacro)
531 # Generate macros used to represent files containing list of input files
532 for ListFileMacro in self.ListFileMacros:
533 ListFileName = os.path.join(self._AutoGenObject.OutputDir, "%s.lst
" % ListFileMacro.lower()[:len(ListFileMacro)-5])
534 FileMacroList.append("%s = %s" % (ListFileMacro, ListFileName))
537 "\n".join(self.ListFileMacros[ListFileMacro]),
541 # Edk modules need <BaseName>StrDefs.h for string ID
542 #if self._AutoGenObject.AutoGenVersion < 0x00010005 and len(self._AutoGenObject.UnicodeFileList) > 0:
543 # BcTargetList = ['strdefs']
548 MakefileName = self._FILE_NAME_[self._FileType]
549 LibraryMakeCommandList = []
550 for D in self.LibraryBuildDirectoryList:
551 Command = self._MAKE_TEMPLATE_[self._FileType] % {"file":os.path.join(D, MakefileName)}
552 LibraryMakeCommandList.append(Command)
554 MakefileTemplateDict = {
555 "makefile_header
" : self._FILE_HEADER_[self._FileType],
556 "makefile_path
" : os.path.join("$
(MODULE_BUILD_DIR
)", MakefileName),
557 "makefile_name
" : MakefileName,
558 "platform_name
" : self.PlatformInfo.Name,
559 "platform_guid
" : self.PlatformInfo.Guid,
560 "platform_version
" : self.PlatformInfo.Version,
561 "platform_relative_directory
": self.PlatformInfo.SourceDir,
562 "platform_output_directory
" : self.PlatformInfo.OutputDir,
564 "module_name
" : self._AutoGenObject.Name,
565 "module_guid
" : self._AutoGenObject.Guid,
566 "module_version
" : self._AutoGenObject.Version,
567 "module_type
" : self._AutoGenObject.ModuleType,
568 "module_file
" : self._AutoGenObject.MetaFile.Name,
569 "module_file_base_name
" : self._AutoGenObject.MetaFile.BaseName,
570 "module_relative_directory
" : self._AutoGenObject.SourceDir,
571 "module_extra_defines
" : ["%s = %s" % (k, v) for k,v in self._AutoGenObject.Module.Defines.iteritems()],
573 "architecture
" : self._AutoGenObject.Arch,
574 "toolchain_tag
" : self._AutoGenObject.ToolChain,
575 "build_target
" : self._AutoGenObject.BuildTarget,
577 "platform_build_directory
" : self.PlatformInfo.BuildDir,
578 "module_build_directory
" : self._AutoGenObject.BuildDir,
579 "module_output_directory
" : self._AutoGenObject.OutputDir,
580 "module_debug_directory
" : self._AutoGenObject.DebugDir,
582 "separator
" : Separator,
583 "module_tool_definitions
" : ToolsDef,
585 "shell_command_code
" : self._SHELL_CMD_[self._FileType].keys(),
586 "shell_command
" : self._SHELL_CMD_[self._FileType].values(),
588 "module_entry_point
" : ModuleEntryPoint,
589 "image_entry_point
" : ImageEntryPoint,
590 "arch_entry_point
" : ArchEntryPoint,
591 "remaining_build_target
" : self.ResultFileList,
592 "common_dependency_file
" : self.CommonFileDependency,
593 "create_directory_command
" : self.GetCreateDirectoryCommand(self.IntermediateDirectoryList),
594 "clean_command
" : self.GetRemoveDirectoryCommand(["$
(OUTPUT_DIR
)"]),
595 "cleanall_command
" : self.GetRemoveDirectoryCommand(["$
(DEBUG_DIR
)", "$
(OUTPUT_DIR
)"]),
596 "dependent_library_build_directory
" : self.LibraryBuildDirectoryList,
597 "library_build_command
" : LibraryMakeCommandList,
598 "file_macro
" : FileMacroList,
599 "file_build_target
" : self.BuildTargetList,
600 "backward_compatible_target
": BcTargetList,
603 return MakefileTemplateDict
605 def ProcessBuildTargetList(self):
607 # Search dependency file list for each source file
609 ForceIncludedFile = []
610 for File in self._AutoGenObject.AutoGenFileList:
612 ForceIncludedFile.append(File)
614 for Target in self._AutoGenObject.IntroTargetList:
615 SourceFileList.extend(Target.Inputs)
617 self.FileDependency = self.GetFileDependency(
620 self._AutoGenObject.IncludePathList + self._AutoGenObject.BuildOptionIncPathList
623 for File in self.FileDependency:
624 if not self.FileDependency[File]:
625 self.FileDependency[File] = ['$(FORCE_REBUILD)']
628 if File.Ext not in [".c
", ".C
"] or File.Name == "AutoGen
.c
":
631 DepSet = set(self.FileDependency[File])
633 DepSet &= set(self.FileDependency[File])
634 # in case nothing in SourceFileList
638 # Extract common files list in the dependency files
641 self.CommonFileDependency.append(self.PlaceMacro(File.Path, self.Macros))
643 for File in self.FileDependency:
645 if File.Ext not in [".c
", ".C
"] or File.Name == "AutoGen
.c
":
647 NewDepSet = set(self.FileDependency[File])
649 self.FileDependency[File] = ["$
(COMMON_DEPS
)"] + list(NewDepSet)
651 # Convert target description object to target string in makefile
652 for Type in self._AutoGenObject.Targets:
653 for T in self._AutoGenObject.Targets[Type]:
654 # Generate related macros if needed
655 if T.GenFileListMacro and T.FileListMacro not in self.FileListMacros:
656 self.FileListMacros[T.FileListMacro] = []
657 if T.GenListFile and T.ListFileMacro not in self.ListFileMacros:
658 self.ListFileMacros[T.ListFileMacro] = []
659 if T.GenIncListFile and T.IncListFileMacro not in self.ListFileMacros:
660 self.ListFileMacros[T.IncListFileMacro] = []
663 # Add force-dependencies
664 for Dep in T.Dependencies:
665 Deps.append(self.PlaceMacro(str(Dep), self.Macros))
666 # Add inclusion-dependencies
667 if len(T.Inputs) == 1 and T.Inputs[0] in self.FileDependency:
668 for F in self.FileDependency[T.Inputs[0]]:
669 Deps.append(self.PlaceMacro(str(F), self.Macros))
670 # Add source-dependencies
672 NewFile = self.PlaceMacro(str(F), self.Macros)
673 # In order to use file list macro as dependency
675 self.ListFileMacros[T.ListFileMacro].append(str(F))
676 self.FileListMacros[T.FileListMacro].append(NewFile)
677 elif T.GenFileListMacro:
678 self.FileListMacros[T.FileListMacro].append(NewFile)
682 # Use file list macro as dependency
683 if T.GenFileListMacro:
684 Deps.append("$
(%s)" % T.FileListMacro)
687 "target
" : self.PlaceMacro(T.Target.Path, self.Macros),
688 "cmd
" : "\n\t".join(T.Commands),
691 self.BuildTargetList.append(self._BUILD_TARGET_TEMPLATE.Replace(TargetDict))
693 ## For creating makefile targets for dependent libraries
694 def ProcessDependentLibrary(self):
695 for LibraryAutoGen in self._AutoGenObject.LibraryAutoGenList:
696 self.LibraryBuildDirectoryList.append(self.PlaceMacro(LibraryAutoGen.BuildDir, self.Macros))
698 ## Return a list containing source file's dependencies
700 # @param FileList The list of source files
701 # @param ForceInculeList The list of files which will be included forcely
702 # @param SearchPathList The list of search path
704 # @retval dict The mapping between source file path and its dependencies
706 def GetFileDependency(self, FileList, ForceInculeList, SearchPathList):
709 Dependency[F] = self.GetDependencyList(F, ForceInculeList, SearchPathList)
712 ## Find dependencies for one source file
714 # By searching recursively "#include" directive in file, find out all the
715 # files needed by given source file. The dependecies will be only searched
716 # in given search path list.
718 # @param File The source file
719 # @param ForceInculeList The list of files which will be included forcely
720 # @param SearchPathList The list of search path
722 # @retval list The list of files the given source file depends on
724 def GetDependencyList(self
, File
, ForceList
, SearchPathList
):
725 EdkLogger
.debug(EdkLogger
.DEBUG_1
, "Try to get dependency files for %s" % File
)
726 FileStack
= [File
] + ForceList
727 DependencySet
= set()
729 if self
._AutoGenObject
.Arch
not in gDependencyDatabase
:
730 gDependencyDatabase
[self
._AutoGenObject
.Arch
] = {}
731 DepDb
= gDependencyDatabase
[self
._AutoGenObject
.Arch
]
733 while len(FileStack
) > 0:
736 FullPathDependList
= []
737 if F
in self
.FileCache
:
738 for CacheFile
in self
.FileCache
[F
]:
739 FullPathDependList
.append(CacheFile
)
740 if CacheFile
not in DependencySet
:
741 FileStack
.append(CacheFile
)
742 DependencySet
.update(FullPathDependList
)
745 CurrentFileDependencyList
= []
747 CurrentFileDependencyList
= DepDb
[F
]
750 Fd
= open(F
.Path
, 'r')
751 except BaseException
, X
:
752 EdkLogger
.error("build", FILE_OPEN_FAILURE
, ExtraData
=F
.Path
+"\n\t"+str(X
))
754 FileContent
= Fd
.read()
756 if len(FileContent
) == 0:
759 if FileContent
[0] == 0xff or FileContent
[0] == 0xfe:
760 FileContent
= unicode(FileContent
, "utf-16")
761 IncludedFileList
= gIncludePattern
.findall(FileContent
)
763 for Inc
in IncludedFileList
:
765 # if there's macro used to reference header file, expand it
766 HeaderList
= gMacroPattern
.findall(Inc
)
767 if len(HeaderList
) == 1 and len(HeaderList
[0]) == 2:
768 HeaderType
= HeaderList
[0][0]
769 HeaderKey
= HeaderList
[0][1]
770 if HeaderType
in gIncludeMacroConversion
:
771 Inc
= gIncludeMacroConversion
[HeaderType
] % {"HeaderKey" : HeaderKey
}
773 # not known macro used in #include, always build the file by
774 # returning a empty dependency
775 self
.FileCache
[File
] = []
777 Inc
= os
.path
.normpath(Inc
)
778 CurrentFileDependencyList
.append(Inc
)
779 DepDb
[F
] = CurrentFileDependencyList
781 CurrentFilePath
= F
.Dir
782 PathList
= [CurrentFilePath
] + SearchPathList
783 for Inc
in CurrentFileDependencyList
:
784 for SearchPath
in PathList
:
785 FilePath
= os
.path
.join(SearchPath
, Inc
)
786 if FilePath
in gIsFileMap
:
787 if not gIsFileMap
[FilePath
]:
789 # If isfile is called too many times, the performance is slow down.
790 elif not os
.path
.isfile(FilePath
):
791 gIsFileMap
[FilePath
] = False
794 gIsFileMap
[FilePath
] = True
795 FilePath
= PathClass(FilePath
)
796 FullPathDependList
.append(FilePath
)
797 if FilePath
not in DependencySet
:
798 FileStack
.append(FilePath
)
801 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "%s included by %s was not found "\
802 "in any given path:\n\t%s" % (Inc
, F
, "\n\t".join(SearchPathList
)))
804 self
.FileCache
[F
] = FullPathDependList
805 DependencySet
.update(FullPathDependList
)
807 DependencySet
.update(ForceList
)
808 if File
in DependencySet
:
809 DependencySet
.remove(File
)
810 DependencyList
= list(DependencySet
) # remove duplicate ones
812 return DependencyList
814 _TemplateDict
= property(_CreateTemplateDict
)
816 ## CustomMakefile class
818 # This class encapsules makefie and its generation for module. It uses template to generate
819 # the content of makefile. The content of makefile will be got from ModuleAutoGen object.
821 class CustomMakefile(BuildFile
):
822 ## template used to generate the makefile for module with custom makefile
823 _TEMPLATE_
= TemplateString('''\
827 # Platform Macro Definition
829 PLATFORM_NAME = ${platform_name}
830 PLATFORM_GUID = ${platform_guid}
831 PLATFORM_VERSION = ${platform_version}
832 PLATFORM_RELATIVE_DIR = ${platform_relative_directory}
833 PLATFORM_DIR = $(WORKSPACE)${separator}${platform_relative_directory}
834 PLATFORM_OUTPUT_DIR = ${platform_output_directory}
837 # Module Macro Definition
839 MODULE_NAME = ${module_name}
840 MODULE_GUID = ${module_guid}
841 MODULE_VERSION = ${module_version}
842 MODULE_TYPE = ${module_type}
843 MODULE_FILE = ${module_file}
844 MODULE_FILE_BASE_NAME = ${module_file_base_name}
845 BASE_NAME = $(MODULE_NAME)
846 MODULE_RELATIVE_DIR = ${module_relative_directory}
847 MODULE_DIR = $(WORKSPACE)${separator}${module_relative_directory}
850 # Build Configuration Macro Definition
852 ARCH = ${architecture}
853 TOOLCHAIN = ${toolchain_tag}
854 TOOLCHAIN_TAG = ${toolchain_tag}
855 TARGET = ${build_target}
858 # Build Directory Macro Definition
860 # PLATFORM_BUILD_DIR = ${platform_build_directory}
861 BUILD_DIR = ${platform_build_directory}
862 BIN_DIR = $(BUILD_DIR)${separator}${architecture}
864 MODULE_BUILD_DIR = ${module_build_directory}
865 OUTPUT_DIR = ${module_output_directory}
866 DEBUG_DIR = ${module_debug_directory}
867 DEST_DIR_OUTPUT = $(OUTPUT_DIR)
868 DEST_DIR_DEBUG = $(DEBUG_DIR)
871 # Tools definitions specific to this module
873 ${BEGIN}${module_tool_definitions}
875 MAKE_FILE = ${makefile_path}
878 # Shell Command Macro
880 ${BEGIN}${shell_command_code} = ${shell_command}
883 ${custom_makefile_content}
886 # Target used when called from platform makefile, which will bypass the build of dependent libraries
899 # Build Target used in multi-thread build mode, which no init target is needed
905 # Initialization target: print build information and create necessary directories
908 \t-@echo Building ... $(MODULE_DIR)${separator}$(MODULE_FILE) [$(ARCH)]
909 ${BEGIN}\t-@${create_directory_command}\n${END}\
913 ## Constructor of CustomMakefile
915 # @param ModuleAutoGen Object of ModuleAutoGen class
917 def __init__(self
, ModuleAutoGen
):
918 BuildFile
.__init
__(self
, ModuleAutoGen
)
919 self
.PlatformInfo
= self
._AutoGenObject
.PlatformInfo
920 self
.IntermediateDirectoryList
= ["$(DEBUG_DIR)", "$(OUTPUT_DIR)"]
922 # Compose a dict object containing information used to do replacement in template
923 def _CreateTemplateDict(self
):
924 Separator
= self
._SEP
_[self
._FileType
]
925 if self
._FileType
not in self
._AutoGenObject
.CustomMakefile
:
926 EdkLogger
.error('build', OPTION_NOT_SUPPORTED
, "No custom makefile for %s" % self
._FileType
,
927 ExtraData
="[%s]" % str(self
._AutoGenObject
))
928 MakefilePath
= os
.path
.join(
929 self
._AutoGenObject
.WorkspaceDir
,
930 self
._AutoGenObject
.CustomMakefile
[self
._FileType
]
933 CustomMakefile
= open(MakefilePath
, 'r').read()
935 EdkLogger
.error('build', FILE_OPEN_FAILURE
, File
=str(self
._AutoGenObject
),
936 ExtraData
=self
._AutoGenObject
.CustomMakefile
[self
._FileType
])
940 for Tool
in self
._AutoGenObject
.BuildOption
:
941 # Don't generate MAKE_FLAGS in makefile. It's put in environment variable.
944 for Attr
in self
._AutoGenObject
.BuildOption
[Tool
]:
948 ToolsDef
.append("%s = %s" % (Tool
, self
._AutoGenObject
.BuildOption
[Tool
][Attr
]))
950 ToolsDef
.append("%s_%s = %s" % (Tool
, Attr
, self
._AutoGenObject
.BuildOption
[Tool
][Attr
]))
953 MakefileName
= self
._FILE
_NAME
_[self
._FileType
]
954 MakefileTemplateDict
= {
955 "makefile_header" : self
._FILE
_HEADER
_[self
._FileType
],
956 "makefile_path" : os
.path
.join("$(MODULE_BUILD_DIR)", MakefileName
),
957 "platform_name" : self
.PlatformInfo
.Name
,
958 "platform_guid" : self
.PlatformInfo
.Guid
,
959 "platform_version" : self
.PlatformInfo
.Version
,
960 "platform_relative_directory": self
.PlatformInfo
.SourceDir
,
961 "platform_output_directory" : self
.PlatformInfo
.OutputDir
,
963 "module_name" : self
._AutoGenObject
.Name
,
964 "module_guid" : self
._AutoGenObject
.Guid
,
965 "module_version" : self
._AutoGenObject
.Version
,
966 "module_type" : self
._AutoGenObject
.ModuleType
,
967 "module_file" : self
._AutoGenObject
.MetaFile
,
968 "module_file_base_name" : self
._AutoGenObject
.MetaFile
.BaseName
,
969 "module_relative_directory" : self
._AutoGenObject
.SourceDir
,
971 "architecture" : self
._AutoGenObject
.Arch
,
972 "toolchain_tag" : self
._AutoGenObject
.ToolChain
,
973 "build_target" : self
._AutoGenObject
.BuildTarget
,
975 "platform_build_directory" : self
.PlatformInfo
.BuildDir
,
976 "module_build_directory" : self
._AutoGenObject
.BuildDir
,
977 "module_output_directory" : self
._AutoGenObject
.OutputDir
,
978 "module_debug_directory" : self
._AutoGenObject
.DebugDir
,
980 "separator" : Separator
,
981 "module_tool_definitions" : ToolsDef
,
983 "shell_command_code" : self
._SHELL
_CMD
_[self
._FileType
].keys(),
984 "shell_command" : self
._SHELL
_CMD
_[self
._FileType
].values(),
986 "create_directory_command" : self
.GetCreateDirectoryCommand(self
.IntermediateDirectoryList
),
987 "custom_makefile_content" : CustomMakefile
990 return MakefileTemplateDict
992 _TemplateDict
= property(_CreateTemplateDict
)
994 ## PlatformMakefile class
996 # This class encapsules makefie and its generation for platform. It uses
997 # template to generate the content of makefile. The content of makefile will be
998 # got from PlatformAutoGen object.
1000 class PlatformMakefile(BuildFile
):
1001 ## template used to generate the makefile for platform
1002 _TEMPLATE_
= TemplateString('''\
1006 # Platform Macro Definition
1008 PLATFORM_NAME = ${platform_name}
1009 PLATFORM_GUID = ${platform_guid}
1010 PLATFORM_VERSION = ${platform_version}
1011 PLATFORM_FILE = ${platform_file}
1012 PLATFORM_DIR = $(WORKSPACE)${separator}${platform_relative_directory}
1013 PLATFORM_OUTPUT_DIR = ${platform_output_directory}
1016 # Build Configuration Macro Definition
1018 TOOLCHAIN = ${toolchain_tag}
1019 TOOLCHAIN_TAG = ${toolchain_tag}
1020 TARGET = ${build_target}
1023 # Build Directory Macro Definition
1025 BUILD_DIR = ${platform_build_directory}
1026 FV_DIR = ${platform_build_directory}${separator}FV
1029 # Shell Command Macro
1031 ${BEGIN}${shell_command_code} = ${shell_command}
1035 MAKE_FILE = ${makefile_path}
1040 all: init build_libraries build_modules
1043 # Initialization target: print build information and create necessary directories
1046 \t-@echo Building ... $(PLATFORM_FILE) [${build_architecture_list}]
1047 \t${BEGIN}-@${create_directory_command}
1050 # library build target
1052 libraries: init build_libraries
1055 # module build target
1057 modules: init build_libraries build_modules
1060 # Build all libraries:
1063 ${BEGIN}\t@"$(MAKE)" $(MAKE_FLAGS) -f ${library_makefile_list} pbuild
1064 ${END}\t@cd $(BUILD_DIR)
1067 # Build all modules:
1070 ${BEGIN}\t@"$(MAKE)" $(MAKE_FLAGS) -f ${module_makefile_list} pbuild
1071 ${END}\t@cd $(BUILD_DIR)
1074 # Clean intermediate files
1077 \t${BEGIN}-@${library_build_command} clean
1078 \t${END}${BEGIN}-@${module_build_command} clean
1079 \t${END}@cd $(BUILD_DIR)
1082 # Clean all generated files except to makefile
1085 ${BEGIN}\t${cleanall_command}
1089 # Clean all library files
1092 \t${BEGIN}-@${library_build_command} cleanall
1093 \t${END}@cd $(BUILD_DIR)\n
1096 ## Constructor of PlatformMakefile
1098 # @param ModuleAutoGen Object of PlatformAutoGen class
1100 def __init__(self
, PlatformAutoGen
):
1101 BuildFile
.__init
__(self
, PlatformAutoGen
)
1102 self
.ModuleBuildCommandList
= []
1103 self
.ModuleMakefileList
= []
1104 self
.IntermediateDirectoryList
= []
1105 self
.ModuleBuildDirectoryList
= []
1106 self
.LibraryBuildDirectoryList
= []
1108 # Compose a dict object containing information used to do replacement in template
1109 def _CreateTemplateDict(self
):
1110 Separator
= self
._SEP
_[self
._FileType
]
1112 PlatformInfo
= self
._AutoGenObject
1113 if "MAKE" not in PlatformInfo
.ToolDefinition
or "PATH" not in PlatformInfo
.ToolDefinition
["MAKE"]:
1114 EdkLogger
.error("build", OPTION_MISSING
, "No MAKE command defined. Please check your tools_def.txt!",
1115 ExtraData
="[%s]" % str(self
._AutoGenObject
))
1117 self
.IntermediateDirectoryList
= ["$(BUILD_DIR)"]
1118 self
.ModuleBuildDirectoryList
= self
.GetModuleBuildDirectoryList()
1119 self
.LibraryBuildDirectoryList
= self
.GetLibraryBuildDirectoryList()
1121 MakefileName
= self
._FILE
_NAME
_[self
._FileType
]
1122 LibraryMakefileList
= []
1123 LibraryMakeCommandList
= []
1124 for D
in self
.LibraryBuildDirectoryList
:
1125 D
= self
.PlaceMacro(D
, {"BUILD_DIR":PlatformInfo
.BuildDir
})
1126 Makefile
= os
.path
.join(D
, MakefileName
)
1127 Command
= self
._MAKE
_TEMPLATE
_[self
._FileType
] % {"file":Makefile
}
1128 LibraryMakefileList
.append(Makefile
)
1129 LibraryMakeCommandList
.append(Command
)
1131 ModuleMakefileList
= []
1132 ModuleMakeCommandList
= []
1133 for D
in self
.ModuleBuildDirectoryList
:
1134 D
= self
.PlaceMacro(D
, {"BUILD_DIR":PlatformInfo
.BuildDir
})
1135 Makefile
= os
.path
.join(D
, MakefileName
)
1136 Command
= self
._MAKE
_TEMPLATE
_[self
._FileType
] % {"file":Makefile
}
1137 ModuleMakefileList
.append(Makefile
)
1138 ModuleMakeCommandList
.append(Command
)
1140 MakefileTemplateDict
= {
1141 "makefile_header" : self
._FILE
_HEADER
_[self
._FileType
],
1142 "makefile_path" : os
.path
.join("$(BUILD_DIR)", MakefileName
),
1143 "make_path" : PlatformInfo
.ToolDefinition
["MAKE"]["PATH"],
1144 "makefile_name" : MakefileName
,
1145 "platform_name" : PlatformInfo
.Name
,
1146 "platform_guid" : PlatformInfo
.Guid
,
1147 "platform_version" : PlatformInfo
.Version
,
1148 "platform_file" : self
._AutoGenObject
.MetaFile
,
1149 "platform_relative_directory": PlatformInfo
.SourceDir
,
1150 "platform_output_directory" : PlatformInfo
.OutputDir
,
1151 "platform_build_directory" : PlatformInfo
.BuildDir
,
1153 "toolchain_tag" : PlatformInfo
.ToolChain
,
1154 "build_target" : PlatformInfo
.BuildTarget
,
1155 "shell_command_code" : self
._SHELL
_CMD
_[self
._FileType
].keys(),
1156 "shell_command" : self
._SHELL
_CMD
_[self
._FileType
].values(),
1157 "build_architecture_list" : self
._AutoGenObject
.Arch
,
1158 "architecture" : self
._AutoGenObject
.Arch
,
1159 "separator" : Separator
,
1160 "create_directory_command" : self
.GetCreateDirectoryCommand(self
.IntermediateDirectoryList
),
1161 "cleanall_command" : self
.GetRemoveDirectoryCommand(self
.IntermediateDirectoryList
),
1162 "library_makefile_list" : LibraryMakefileList
,
1163 "module_makefile_list" : ModuleMakefileList
,
1164 "library_build_command" : LibraryMakeCommandList
,
1165 "module_build_command" : ModuleMakeCommandList
,
1168 return MakefileTemplateDict
1170 ## Get the root directory list for intermediate files of all modules build
1172 # @retval list The list of directory
1174 def GetModuleBuildDirectoryList(self
):
1176 for ModuleAutoGen
in self
._AutoGenObject
.ModuleAutoGenList
:
1177 DirList
.append(os
.path
.join(self
._AutoGenObject
.BuildDir
, ModuleAutoGen
.BuildDir
))
1180 ## Get the root directory list for intermediate files of all libraries build
1182 # @retval list The list of directory
1184 def GetLibraryBuildDirectoryList(self
):
1186 for LibraryAutoGen
in self
._AutoGenObject
.LibraryAutoGenList
:
1187 DirList
.append(os
.path
.join(self
._AutoGenObject
.BuildDir
, LibraryAutoGen
.BuildDir
))
1190 _TemplateDict
= property(_CreateTemplateDict
)
1192 ## TopLevelMakefile class
1194 # This class encapsules makefie and its generation for entrance makefile. It
1195 # uses template to generate the content of makefile. The content of makefile
1196 # will be got from WorkspaceAutoGen object.
1198 class TopLevelMakefile(BuildFile
):
1199 ## template used to generate toplevel makefile
1200 _TEMPLATE_
= TemplateString('''\
1204 # Platform Macro Definition
1206 PLATFORM_NAME = ${platform_name}
1207 PLATFORM_GUID = ${platform_guid}
1208 PLATFORM_VERSION = ${platform_version}
1211 # Build Configuration Macro Definition
1213 TOOLCHAIN = ${toolchain_tag}
1214 TOOLCHAIN_TAG = ${toolchain_tag}
1215 TARGET = ${build_target}
1218 # Build Directory Macro Definition
1220 BUILD_DIR = ${platform_build_directory}
1221 FV_DIR = ${platform_build_directory}${separator}FV
1224 # Shell Command Macro
1226 ${BEGIN}${shell_command_code} = ${shell_command}
1230 MAKE_FILE = ${makefile_path}
1238 # Initialization target: print build information and create necessary directories
1242 \t${BEGIN}-@${create_directory_command}
1245 # library build target
1248 ${BEGIN}\t@cd $(BUILD_DIR)${separator}${arch} && "$(MAKE)" $(MAKE_FLAGS) libraries
1249 ${END}\t@cd $(BUILD_DIR)
1252 # module build target
1255 ${BEGIN}\t@cd $(BUILD_DIR)${separator}${arch} && "$(MAKE)" $(MAKE_FLAGS) modules
1256 ${END}\t@cd $(BUILD_DIR)
1259 # Flash Device Image Target
1263 ${BEGIN}\tGenFds -f ${fdf_file} -o $(BUILD_DIR) -t $(TOOLCHAIN) -b $(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}
1266 # run command for emulator platform only
1269 \tcd $(BUILD_DIR)${separator}IA32 && ".${separator}SecMain"
1273 # Clean intermediate files
1276 ${BEGIN}\t-@${sub_build_command} clean
1277 ${END}\t@cd $(BUILD_DIR)
1280 # Clean all generated files except to makefile
1283 ${BEGIN}\t${cleanall_command}
1287 # Clean all library files
1290 ${BEGIN}\t-@${sub_build_command} cleanlib
1291 ${END}\t@cd $(BUILD_DIR)\n
1294 ## Constructor of TopLevelMakefile
1296 # @param Workspace Object of WorkspaceAutoGen class
1298 def __init__(self
, Workspace
):
1299 BuildFile
.__init
__(self
, Workspace
)
1300 self
.IntermediateDirectoryList
= []
1302 # Compose a dict object containing information used to do replacement in template
1303 def _CreateTemplateDict(self
):
1304 Separator
= self
._SEP
_[self
._FileType
]
1306 # any platform autogen object is ok because we just need common information
1307 PlatformInfo
= self
._AutoGenObject
1309 if "MAKE" not in PlatformInfo
.ToolDefinition
or "PATH" not in PlatformInfo
.ToolDefinition
["MAKE"]:
1310 EdkLogger
.error("build", OPTION_MISSING
, "No MAKE command defined. Please check your tools_def.txt!",
1311 ExtraData
="[%s]" % str(self
._AutoGenObject
))
1313 for Arch
in PlatformInfo
.ArchList
:
1314 self
.IntermediateDirectoryList
.append(Separator
.join(["$(BUILD_DIR)", Arch
]))
1315 self
.IntermediateDirectoryList
.append("$(FV_DIR)")
1317 # TRICK: for not generating GenFds call in makefile if no FDF file
1319 if PlatformInfo
.FdfFile
!= None and PlatformInfo
.FdfFile
!= "":
1320 FdfFileList
= [PlatformInfo
.FdfFile
]
1321 # macros passed to GenFds
1322 MacroList
.append('"%s=%s"' % ("EFI_SOURCE", GlobalData
.gEfiSource
.replace('\\', '\\\\')))
1323 MacroList
.append('"%s=%s"' % ("EDK_SOURCE", GlobalData
.gEdkSource
.replace('\\', '\\\\')))
1325 MacroDict
.update(GlobalData
.gGlobalDefines
)
1326 MacroDict
.update(GlobalData
.gCommandLineDefines
)
1327 MacroDict
.pop("EFI_SOURCE", "dummy")
1328 MacroDict
.pop("EDK_SOURCE", "dummy")
1329 for MacroName
in MacroDict
:
1330 if MacroDict
[MacroName
] != "":
1331 MacroList
.append('"%s=%s"' % (MacroName
, MacroDict
[MacroName
].replace('\\', '\\\\')))
1333 MacroList
.append('"%s"' % MacroName
)
1337 # pass extra common options to external program called in makefile, currently GenFds.exe
1339 LogLevel
= EdkLogger
.GetLevel()
1340 if LogLevel
== EdkLogger
.VERBOSE
:
1341 ExtraOption
+= " -v"
1342 elif LogLevel
<= EdkLogger
.DEBUG_9
:
1343 ExtraOption
+= " -d %d" % (LogLevel
- 1)
1344 elif LogLevel
== EdkLogger
.QUIET
:
1345 ExtraOption
+= " -q"
1347 if GlobalData
.gCaseInsensitive
:
1348 ExtraOption
+= " -c"
1350 MakefileName
= self
._FILE
_NAME
_[self
._FileType
]
1351 SubBuildCommandList
= []
1352 for A
in PlatformInfo
.ArchList
:
1353 Command
= self
._MAKE
_TEMPLATE
_[self
._FileType
] % {"file":os
.path
.join("$(BUILD_DIR)", A
, MakefileName
)}
1354 SubBuildCommandList
.append(Command
)
1356 MakefileTemplateDict
= {
1357 "makefile_header" : self
._FILE
_HEADER
_[self
._FileType
],
1358 "makefile_path" : os
.path
.join("$(BUILD_DIR)", MakefileName
),
1359 "make_path" : PlatformInfo
.ToolDefinition
["MAKE"]["PATH"],
1360 "platform_name" : PlatformInfo
.Name
,
1361 "platform_guid" : PlatformInfo
.Guid
,
1362 "platform_version" : PlatformInfo
.Version
,
1363 "platform_build_directory" : PlatformInfo
.BuildDir
,
1365 "toolchain_tag" : PlatformInfo
.ToolChain
,
1366 "build_target" : PlatformInfo
.BuildTarget
,
1367 "shell_command_code" : self
._SHELL
_CMD
_[self
._FileType
].keys(),
1368 "shell_command" : self
._SHELL
_CMD
_[self
._FileType
].values(),
1369 'arch' : list(PlatformInfo
.ArchList
),
1370 "build_architecture_list" : ','.join(PlatformInfo
.ArchList
),
1371 "separator" : Separator
,
1372 "create_directory_command" : self
.GetCreateDirectoryCommand(self
.IntermediateDirectoryList
),
1373 "cleanall_command" : self
.GetRemoveDirectoryCommand(self
.IntermediateDirectoryList
),
1374 "sub_build_command" : SubBuildCommandList
,
1375 "fdf_file" : FdfFileList
,
1376 "active_platform" : str(PlatformInfo
),
1377 "fd" : PlatformInfo
.FdTargetList
,
1378 "fv" : PlatformInfo
.FvTargetList
,
1379 "cap" : PlatformInfo
.CapTargetList
,
1380 "extra_options" : ExtraOption
,
1381 "macro" : MacroList
,
1384 return MakefileTemplateDict
1386 ## Get the root directory list for intermediate files of all modules build
1388 # @retval list The list of directory
1390 def GetModuleBuildDirectoryList(self
):
1392 for ModuleAutoGen
in self
._AutoGenObject
.ModuleAutoGenList
:
1393 DirList
.append(os
.path
.join(self
._AutoGenObject
.BuildDir
, ModuleAutoGen
.BuildDir
))
1396 ## Get the root directory list for intermediate files of all libraries build
1398 # @retval list The list of directory
1400 def GetLibraryBuildDirectoryList(self
):
1402 for LibraryAutoGen
in self
._AutoGenObject
.LibraryAutoGenList
:
1403 DirList
.append(os
.path
.join(self
._AutoGenObject
.BuildDir
, LibraryAutoGen
.BuildDir
))
1406 _TemplateDict
= property(_CreateTemplateDict
)
1408 # This acts like the main() function for the script, unless it is 'import'ed into another script.
1409 if __name__
== '__main__':