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