2 # Create makefile for MS nmake and GNU make
\r
4 # Copyright (c) 2007, Intel Corporation
\r
5 # All rights reserved. This program and the accompanying materials
\r
6 # are licensed and made available under the terms and conditions of the BSD License
\r
7 # which accompanies this distribution. The full text of the license may be found at
\r
8 # http://opensource.org/licenses/bsd-license.php
\r
10 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
\r
11 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
\r
20 import os.path as path
\r
22 from Common.EdkIIWorkspaceBuild import *
\r
23 from Common.EdkIIWorkspace import *
\r
24 from Common.BuildToolError import *
\r
25 from Common.Misc import *
\r
26 from BuildInfo import *
\r
27 from BuildEngine import *
\r
28 import Common.GlobalData as GlobalData
\r
30 ## Regular expression for finding header file inclusions
\r
31 gIncludePattern = re.compile("^[ #]*include[ ]+[\"<]*([^\"< >\s]+)[>\" ]*$", re.MULTILINE | re.UNICODE)
\r
33 ## Regular expression for matching macro used in header file inclusion
\r
34 gMacroPattern = re.compile("([_A-Z][_A-Z0-9]*)\((.+)\)", re.UNICODE)
\r
37 gProtocolDefinition = "Protocol/%(HeaderKey)s/%(HeaderKey)s.h"
\r
38 gGuidDefinition = "Guid/%(HeaderKey)s/%(HeaderKey)s.h"
\r
39 gArchProtocolDefinition = "ArchProtocol/%(HeaderKey)s/%(HeaderKey)s.h"
\r
40 gPpiDefinition = "Ppi/%(HeaderKey)s/%(HeaderKey)s.h"
\r
41 gIncludeMacroConversion = {
\r
42 "EFI_PROTOCOL_DEFINITION" : gProtocolDefinition,
\r
43 "EFI_GUID_DEFINITION" : gGuidDefinition,
\r
44 "EFI_ARCH_PROTOCOL_DEFINITION" : gArchProtocolDefinition,
\r
45 "EFI_PROTOCOL_PRODUCER" : gProtocolDefinition,
\r
46 "EFI_PROTOCOL_CONSUMER" : gProtocolDefinition,
\r
47 "EFI_PROTOCOL_DEPENDENCY" : gProtocolDefinition,
\r
48 "EFI_ARCH_PROTOCOL_PRODUCER" : gArchProtocolDefinition,
\r
49 "EFI_ARCH_PROTOCOL_CONSUMER" : gArchProtocolDefinition,
\r
50 "EFI_ARCH_PROTOCOL_DEPENDENCY" : gArchProtocolDefinition,
\r
51 "EFI_PPI_DEFINITION" : gPpiDefinition,
\r
52 "EFI_PPI_PRODUCER" : gPpiDefinition,
\r
53 "EFI_PPI_CONSUMER" : gPpiDefinition,
\r
54 "EFI_PPI_DEPENDENCY" : gPpiDefinition,
\r
57 gMakefileHeader = '''#
\r
59 # This file is auto-generated by build utility
\r
67 # Auto-generated makefile for building modules and libraries
\r
71 gLibraryMakeCommand = '''cd %(makedir)s && "$(MAKE)" $(MAKE_FLAGS) %(target)s
\r
72 \tcd $(MODULE_BUILD_DIR)'''
\r
75 if sys.platform == "win32":
\r
80 gMakefileName = {"nmake" : "Makefile", "gmake" : "GNUmakefile"}
\r
82 gDirectorySeparator = {"nmake" : "\\", "gmake" : "/"}
\r
84 gCreateDirectoryCommand = {"nmake" : "mkdir", "gmake" : "mkdir -p"}
\r
85 gRemoveDirectoryCommand = {"nmake" : "rmdir /s /q", "gmake" : "rm -r -f"}
\r
86 gRemoveFileCommand = {"nmake" : "del /f /q", "gmake" : "rm -f"}
\r
87 gCopyFileCommand = {"nmake" : "copy /y", "gmake" : "cp -f"}
\r
88 gCreateDirectoryCommandTemplate = {"nmake" : 'if not exist %(dir)s mkdir %(dir)s',
\r
89 "gmake" : "test ! -e %(dir)s && mkdir -p %(dir)s"}
\r
90 gRemoveDirectoryCommandTemplate = {"nmake" : 'if exist %(dir)s rmdir /s /q %(dir)s',
\r
91 "gmake" : "test -e %(dir)s && rm -r -f %(dir)s"}
\r
93 # $(CP) copy file command
\r
94 # $(MV) move file command
\r
95 # $(RM) remove file command
\r
96 # $(MD) create dir command
\r
97 # $(RD) remove dir command
\r
99 # $(TCP) copy file if destination file doesn't exist
\r
100 # $(TMV) move file if destination file doesn't exist
\r
101 # $(TRM) remove file if destination file exists
\r
102 # $(TMD) create dir if destination dir doesn't exist
\r
103 # $(TRD) remove dir if destination dir exists
\r
108 "RM" : "del /f /q",
\r
110 "RD" : "rmdir /s /q",
\r
121 gIncludeFlag = {"MSFT" : "/I", "GCC" : "-I", "INTEL" : "-I"}
\r
123 gStartGroupFlag = {"MSFT" : "", "GCC" : "-(", "INTEL" : ""}
\r
124 gEndGroupFlag = {"MSFT" : "", "GCC" : "-)", "INTEL" : ""}
\r
126 gCustomMakefileTemplate = '''\
\r
130 # Platform Macro Definition
\r
132 PLATFORM_NAME = ${platform_name}
\r
133 PLATFORM_GUID = ${platform_guid}
\r
134 PLATFORM_VERSION = ${platform_version}
\r
135 PLATFORM_RELATIVE_DIR = ${platform_relative_directory}
\r
136 PLATFORM_DIR = $(WORKSPACE)${separator}${platform_relative_directory}
\r
137 PLATFORM_OUTPUT_DIR = ${platform_output_directory}
\r
140 # Module Macro Definition
\r
142 MODULE_NAME = ${module_name}
\r
143 MODULE_GUID = ${module_guid}
\r
144 MODULE_VERSION = ${module_version}
\r
145 MODULE_TYPE = ${module_type}
\r
146 MODULE_FILE_BASE_NAME = ${module_file_base_name}
\r
147 BASE_NAME = $(MODULE_NAME)
\r
148 MODULE_RELATIVE_DIR = ${module_relative_directory}
\r
149 MODULE_DIR = $(WORKSPACE)${separator}${module_relative_directory}
\r
152 # Build Configuration Macro Definition
\r
154 ARCH = ${architecture}
\r
155 TOOLCHAIN_TAG = ${toolchain_tag}
\r
156 TARGET = ${build_target}
\r
159 # Build Directory Macro Definition
\r
161 # PLATFORM_BUILD_DIR = ${platform_build_directory}
\r
162 BUILD_DIR = ${platform_build_directory}
\r
163 BIN_DIR = $(BUILD_DIR)${separator}${architecture}
\r
164 LIB_DIR = $(BIN_DIR)
\r
165 MODULE_BUILD_DIR = $(BUILD_DIR)${separator}${architecture}${separator}${module_relative_directory}${separator}${module_file_base_name}
\r
166 OUTPUT_DIR = $(MODULE_BUILD_DIR)${separator}OUTPUT
\r
167 DEBUG_DIR = $(MODULE_BUILD_DIR)${separator}DEBUG
\r
168 DEST_DIR_OUTPUT = $(OUTPUT_DIR)
\r
169 DEST_DIR_DEBUG = $(DEBUG_DIR)
\r
172 # Default Tools Flags Macro Definition (from tools_def.txt by default)
\r
174 ${BEGIN}DEFAULT_${tool_code}_FLAGS = ${default_tool_flags}
\r
178 # Platform Tools Flags Macro Definition (from platform description file)
\r
180 ${BEGIN}PLATFORM_${tool_code}_FLAGS = ${platform_tool_flags}
\r
184 # Platform Tools Flags Macro Definition (from platform description file)
\r
186 ${BEGIN}MODULE_${tool_code}_FLAGS = ${module_tool_flags}
\r
192 ${BEGIN}${tool_code}_FLAGS = $(DEFAULT_${tool_code}_FLAGS) $(PLATFORM_${tool_code}_FLAGS) $(MODULE_${tool_code}_FLAGS)
\r
198 ${BEGIN}${tool_code} = ${tool_path}
\r
201 ${custom_makefile_content}
\r
204 # Target used when called from platform makefile, which will bypass the build of dependent libraries
\r
211 # Target used for library build, which will bypass the build of dependent libraries
\r
225 # Initialization target: print build information and create necessary directories
\r
228 \t-@echo Building ... $(MODULE_NAME) $(MODULE_VERSION) [$(ARCH)] in platform $(PLATFORM_NAME) $(PLATFORM_VERSION)
\r
229 \t${BEGIN}-@${create_directory_command}
\r
234 gModuleMakefileTemplate = '''\
\r
238 # Platform Macro Definition
\r
240 PLATFORM_NAME = ${platform_name}
\r
241 PLATFORM_GUID = ${platform_guid}
\r
242 PLATFORM_VERSION = ${platform_version}
\r
243 PLATFORM_RELATIVE_DIR = ${platform_relative_directory}
\r
244 PLATFORM_DIR = $(WORKSPACE)${separator}${platform_relative_directory}
\r
245 PLATFORM_OUTPUT_DIR = ${platform_output_directory}
\r
248 # Module Macro Definition
\r
250 MODULE_NAME = ${module_name}
\r
251 MODULE_GUID = ${module_guid}
\r
252 MODULE_VERSION = ${module_version}
\r
253 MODULE_TYPE = ${module_type}
\r
254 MODULE_FILE_BASE_NAME = ${module_file_base_name}
\r
255 BASE_NAME = $(MODULE_NAME)
\r
256 MODULE_RELATIVE_DIR = ${module_relative_directory}
\r
257 MODULE_DIR = $(WORKSPACE)${separator}${module_relative_directory}
\r
260 # Build Configuration Macro Definition
\r
262 ARCH = ${architecture}
\r
263 TOOLCHAIN_TAG = ${toolchain_tag}
\r
264 TARGET = ${build_target}
\r
267 # Build Directory Macro Definition
\r
269 # PLATFORM_BUILD_DIR = ${platform_build_directory}
\r
270 BUILD_DIR = ${platform_build_directory}
\r
271 BIN_DIR = $(BUILD_DIR)${separator}${architecture}
\r
272 LIB_DIR = $(BIN_DIR)
\r
273 MODULE_BUILD_DIR = $(BUILD_DIR)${separator}${architecture}${separator}${module_relative_directory}${separator}${module_file_base_name}
\r
274 OUTPUT_DIR = $(MODULE_BUILD_DIR)${separator}OUTPUT
\r
275 DEBUG_DIR = $(MODULE_BUILD_DIR)${separator}DEBUG
\r
276 DEST_DIR_OUTPUT = $(OUTPUT_DIR)
\r
277 DEST_DIR_DEBUG = $(DEBUG_DIR)
\r
280 # Default Tools Flags Macro Definition (from tools_def.txt by default)
\r
282 ${BEGIN}DEFAULT_${tool_code}_FLAGS = ${default_tool_flags}
\r
286 # Platform Tools Flags Macro Definition (from platform description file)
\r
288 ${BEGIN}PLATFORM_${tool_code}_FLAGS = ${platform_tool_flags}
\r
292 # Module Tools Flags Macro Definition (from platform/module description file)
\r
294 ${BEGIN}MODULE_${tool_code}_FLAGS = ${module_tool_flags}
\r
300 ${BEGIN}${tool_code}_FLAGS = $(DEFAULT_${tool_code}_FLAGS) $(PLATFORM_${tool_code}_FLAGS) $(MODULE_${tool_code}_FLAGS)
\r
306 ${BEGIN}${tool_code} = ${tool_path}
\r
309 MAKE_FILE = ${makefile_path}
\r
312 # Shell Command Macro
\r
314 ${BEGIN}${shell_command_code} = ${shell_command}
\r
320 ${BEGIN}${source_file_macro}
\r
323 ${BEGIN}${target_file_macro}
\r
326 SOURCE_FILES = ${BEGIN}${source_file_macro_name} ${END}
\r
328 TARGET_FILES = ${BEGIN}${target_file_macro_name} ${END}
\r
330 INC = ${BEGIN}${include_path_prefix}${include_path} \\
\r
333 #OBJECTS = ${BEGIN}$(OUTPUT_DIR)${separator}${object_file} \\
\r
336 LIBS = ${BEGIN}$(BUILD_DIR)${separator}$(ARCH)${separator}${library_file} \\
\r
337 ${END}${BEGIN}${system_library} \\
\r
341 COMMON_DEPS = ${BEGIN}${common_dependency_file} \\
\r
344 IMAGE_ENTRY_POINT = ${module_entry_point}
\r
345 ENTRYPOINT = ${module_entry_point}
\r
348 # Overridable Target Macro Definitions
\r
352 CODA_TARGET = ${BEGIN}${remaining_build_target} \\
\r
356 # Default target, which will build dependent libraries in addition to source files
\r
363 # Target used when called from platform makefile, which will bypass the build of dependent libraries
\r
366 pbuild: $(INIT_TARGET) $(PCH_TARGET) $(CODA_TARGET)
\r
372 mbuild: $(INIT_TARGET) gen_libs $(PCH_TARGET) $(CODA_TARGET)
\r
376 # Target to update the FD
\r
379 fds: mbuild gen_fds
\r
382 # Initialization target: print build information and create necessary directories
\r
385 \t-@echo Building ... $(MODULE_NAME) $(MODULE_VERSION) [$(ARCH)] in platform $(PLATFORM_NAME) $(PLATFORM_VERSION)
\r
386 ${BEGIN}\t-@${create_directory_command}\n${END}\
\r
387 ${BEGIN}\t-@${copy_autogen_h}\n${END}
\r
393 \t${BEGIN}cd $(BUILD_DIR)${separator}$(ARCH)${separator}${dependent_library_build_directory} && "$(MAKE)" $(MAKE_FLAGS)
\r
394 \t${END}cd $(MODULE_BUILD_DIR)
\r
397 # Build Flash Device Image
\r
400 \tcd $(BUILD_DIR) && "$(MAKE)" $(MAKE_FLAGS) fds
\r
401 \tcd $(MODULE_BUILD_DIR)
\r
404 # Individual Object Build Targets
\r
406 ${BEGIN}${file_build_target}
\r
411 # clean all intermediate files
\r
415 \t${BEGIN}${clean_command}
\r
419 # clean all generated files
\r
423 ${BEGIN}\t${cleanall_command}
\r
424 ${END}\t$(RM) *.pdb *.idb > NUL 2>&1
\r
425 \t$(RM) $(BIN_DIR)${separator}$(MODULE_NAME).efi
\r
428 # clean pre-compiled header files
\r
432 \t$(RM) $(OUTPUT_DIR)\*.pch > NUL 2>&1
\r
435 # clean all dependent libraries built
\r
439 \t${BEGIN}cd $(BUILD_DIR)${separator}$(ARCH)${separator}${dependent_library_build_directory} && "$(MAKE)" $(MAKE_FLAGS) cleanall
\r
440 \t${END}cd $(MODULE_BUILD_DIR)
\r
444 gPlatformMakefileTemplate = '''\
\r
448 # Platform Macro Definition
\r
450 PLATFORM_NAME = ${platform_name}
\r
451 PLATFORM_GUID = ${platform_guid}
\r
452 PLATFORM_VERSION = ${platform_version}
\r
453 PLATFORM_DIR = $(WORKSPACE)${separator}${platform_relative_directory}
\r
454 PLATFORM_OUTPUT_DIR = ${platform_output_directory}
\r
457 # Build Configuration Macro Definition
\r
459 TOOLCHAIN_TAG = ${toolchain_tag}
\r
460 TARGET = ${build_target}
\r
463 # Build Directory Macro Definition
\r
465 BUILD_DIR = ${platform_build_directory}
\r
466 FV_DIR = ${platform_build_directory}${separator}FV
\r
469 # Shell Command Macro
\r
471 ${BEGIN}${shell_command_code} = ${shell_command}
\r
474 MAKE = ${make_path}
\r
475 MAKE_FLAGS = ${make_flag}
\r
476 MAKE_FILE = ${makefile_path}
\r
481 all: init build_libraries build_modules build_fds
\r
484 # Initialization target: print build information and create necessary directories
\r
487 \t-@echo Building ... $(PLATFORM_NAME) $(PLATFORM_VERSION) [${build_architecture_list}]
\r
488 \t${BEGIN}-@${create_directory_command}
\r
491 # library build target
\r
493 libraries: init build_libraries
\r
496 # module build target
\r
498 modules: init build_libraries build_modules
\r
501 # Flash Device Image Target
\r
503 fds: init build_fds
\r
506 # Build all libraries:
\r
509 ${BEGIN}\tcd ${library_build_directory} && "$(MAKE)" $(MAKE_FLAGS) pbuild
\r
510 ${END}\tcd $(BUILD_DIR)
\r
513 # Build all modules:
\r
516 ${BEGIN}\tcd ${module_build_directory} && "$(MAKE)" $(MAKE_FLAGS) pbuild
\r
517 ${END}\tcd $(BUILD_DIR)
\r
520 # Build Flash Device Image
\r
524 ${BEGIN}\tGenFds -f ${fdf_file} -o $(BUILD_DIR) -t $(TOOLCHAIN_TAG) -b $(TARGET) -p ${active_platform} -a ${build_architecture_list} ${log_level}${END}${BEGIN} -r ${fd} ${END}${BEGIN} -i ${fv} ${END}${BEGIN} -y ${macro} ${END}
\r
527 # run command for emulator platform only
\r
530 \tcd $(BUILD_DIR)${separator}IA32
\r
535 # Clean intermediate files
\r
538 \t${BEGIN}cd ${library_build_directory} && "$(MAKE)" $(MAKE_FLAGS) clean
\r
539 \t${END}${BEGIN}cd ${module_build_directory} && "$(MAKE)" $(MAKE_FLAGS) clean
\r
540 \t${END}cd $(BUILD_DIR)
\r
543 # Clean all generated files except to makefile
\r
546 ${BEGIN}\t${cleanall_command}
\r
550 # Clean all library files
\r
553 \t${BEGIN}cd ${library_build_directory} && "$(MAKE)" $(MAKE_FLAGS) cleanall
\r
554 \t${END}cd $(BUILD_DIR)
\r
560 # This class encapsules makefie and its generation. It uses template to generate
\r
561 # the content of makefile. The content of makefile will be got from PlatformBuildInfo
\r
562 # or ModuleBuildInfo objects.
\r
564 class Makefile(object):
\r
567 # Intitialize the data member simply
\r
569 # @param Info PlatformBuildInfo or ModuleBuildInfo object
\r
570 # @param Option Option for the makefile generation (not used)
\r
572 def __init__(self, Info, Option=None):
\r
573 if isinstance(Info, ModuleBuildInfo):
\r
574 if Info == None or Info == "":
\r
575 EdkLogger.error("AutoGen", AUTOGEN_ERROR, "No valid module found! Please check your build configuration!\n")
\r
576 self.ModuleInfo = Info
\r
577 self.PlatformInfo = Info.PlatformInfo
\r
578 self.ModuleBuild = True
\r
580 self.BuildType = "mbuild"
\r
581 self.TargetFileList = []
\r
582 self.ObjectFileList = []
\r
584 self.ResultFileList = []
\r
585 self.IntermediateDirectoryList = ["$(DEBUG_DIR)", "$(OUTPUT_DIR)"]
\r
587 self.SourceFileDatabase = {} # {file type : file path}
\r
588 self.DestFileDatabase = {} # {file type : file path}
\r
589 self.FileBuildTargetList = [] # [(src, target string)]
\r
590 self.BuildTargetList = [] # [target string]
\r
591 self.PendingBuildTargetList = [] # [FileBuildRule objects]
\r
592 self.CommonFileDependency = []
\r
594 self.FileDependency = []
\r
595 self.LibraryBuildCommandList = []
\r
596 self.LibraryFileList = []
\r
597 self.LibraryMakefileList = []
\r
598 self.LibraryBuildDirectoryList = []
\r
599 self.SystemLibraryList = []
\r
600 elif type(Info) == type({}): # and isinstance(info, PlatformBuildInfo):
\r
602 EdkLogger.error("AutoGen", AUTOGEN_ERROR, "No buildable platform found! Please check your build configuration!\n")
\r
603 self.PlatformInfo = Info
\r
604 self.ModuleBuild = False
\r
605 self.ModuleBuildCommandList = []
\r
606 self.ModuleMakefileList = []
\r
607 self.ModuleBuildDirectoryList = self.GetModuleBuildDirectoryList()
\r
608 self.LibraryBuildDirectoryList = self.GetLibraryBuildDirectoryList()
\r
610 EdkLogger.error("AutoGen", AUTOGEN_ERROR, "Non-buildable item:%s" % str(Info))
\r
612 self.IntermediateDirectoryList = []
\r
614 ## Create necessary directory for makefile generation
\r
615 def PrepareDirectory(self):
\r
616 if self.ModuleBuild:
\r
617 CreateDirectory(self.PlatformInfo.BuildDir)
\r
618 CreateDirectory(self.ModuleInfo.BuildDir)
\r
619 CreateDirectory(self.ModuleInfo.DebugDir)
\r
621 ## Create the makefile
\r
623 # @param File The path of the makefile
\r
624 # @param MakeType GNU makefile or MS makefile
\r
626 # @retval True If the file is changed or doesn't exist
\r
627 # @retval False If the file exists and its content is not changed
\r
630 def Generate(self, File=None, MakeType=gMakeType):
\r
631 if self.ModuleBuild:
\r
632 return self.GenerateModuleMakefile(File, MakeType)
\r
634 return self.GeneratePlatformMakefile(File, MakeType)
\r
636 ## Create makefile of platform
\r
638 # @param File The path of the makefile
\r
639 # @param MakeType GNU makefile or MS makefile
\r
641 # @retval True If the file is changed or doesn't exist
\r
642 # @retval False If the file exists and its content is not changed
\r
645 def GeneratePlatformMakefile(self, File=None, MakeType=gMakeType):
\r
646 Separator = gDirectorySeparator[MakeType]
\r
648 ArchList = self.PlatformInfo.keys()
\r
649 PlatformInfo = self.PlatformInfo.values()[0]
\r
650 ActivePlatform = PlatformInfo.Platform
\r
652 if "MAKE" not in PlatformInfo.ToolPath:
\r
653 EdkLogger.error("GenMake", OPTION_MISSING, "No MAKE command defined. Please check your tools_def.txt!")
\r
655 self.IntermediateDirectoryList = ["$(BUILD_DIR)%s%s" % (Separator, Arch) for Arch in self.PlatformInfo]
\r
656 self.IntermediateDirectoryList.append("$(FV_DIR)")
\r
658 # TRICK: for not generating GenFds call in makefile if no FDF file
\r
660 if PlatformInfo.FdfFile != None and PlatformInfo.FdfFile != "":
\r
661 FdfFileList = [PlatformInfo.FdfFile]
\r
662 for MacroName in GlobalData.gGlobalDefines:
\r
663 MacroList.append('"%s=%s"' % (MacroName, GlobalData.gGlobalDefines[MacroName]))
\r
667 # pass log level to external program called in makefile, currently GenFds.exe
\r
668 LogLevel = EdkLogger.GetLevel()
\r
669 if LogLevel == EdkLogger.VERBOSE:
\r
671 elif LogLevel <= EdkLogger.DEBUG_9:
\r
672 LogOption = "-d %d" % (LogLevel - 1)
\r
673 elif LogLevel == EdkLogger.QUIET:
\r
678 MakefileName = gMakefileName[MakeType]
\r
679 MakefileTemplateDict = {
\r
680 "makefile_header" : gMakefileHeader % MakefileName,
\r
681 "makefile_path" : os.path.join("$(BUILD_DIR)", MakefileName),
\r
682 "platform_name" : PlatformInfo.Name,
\r
683 "platform_guid" : PlatformInfo.Guid,
\r
684 "platform_version" : PlatformInfo.Version,
\r
685 "platform_relative_directory": PlatformInfo.SourceDir,
\r
686 "platform_output_directory" : PlatformInfo.OutputDir,
\r
687 "platform_build_directory" : PlatformInfo.BuildDir,
\r
689 "toolchain_tag" : PlatformInfo.ToolChain,
\r
690 "build_target" : PlatformInfo.BuildTarget,
\r
691 "make_path" : PlatformInfo.ToolPath["MAKE"],
\r
692 "make_flag" : PlatformInfo.ToolOption["MAKE"],
\r
693 "shell_command_code" : gShellCommand[MakeType].keys(),
\r
694 "shell_command" : gShellCommand[MakeType].values(),
\r
695 "build_architecture_list" : ",".join(ArchList),
\r
696 "architecture" : self.PlatformInfo.keys(),
\r
697 "separator" : Separator,
\r
698 "create_directory_command" : self.GetCreateDirectoryCommand(self.IntermediateDirectoryList, MakeType),
\r
699 "remove_directory_command" : gRemoveDirectoryCommand[MakeType],
\r
700 "remove_file_command" : gRemoveFileCommand[MakeType],
\r
701 "cleanall_command" : self.GetRemoveDirectoryCommand(self.IntermediateDirectoryList, MakeType),
\r
702 "library_build_directory" : self.LibraryBuildDirectoryList,
\r
703 "module_build_directory" : self.ModuleBuildDirectoryList,
\r
704 "fdf_file" : FdfFileList,
\r
705 "active_platform" : PlatformInfo.WorkspaceDir + Separator + ActivePlatform.DescFilePath,
\r
706 "fd" : PlatformInfo.FdTargetList,
\r
707 "fv" : PlatformInfo.FvTargetList,
\r
708 "log_level" : LogOption,
\r
709 "macro" : MacroList,
\r
712 self.PrepareDirectory()
\r
714 AutoGenMakefile = TemplateString()
\r
715 AutoGenMakefile.Append(gPlatformMakefileTemplate, MakefileTemplateDict)
\r
719 os.chdir(PlatformInfo.MakeFileDir)
\r
720 FilePath = MakefileName
\r
724 Result = SaveFileOnChange(FilePath, str(AutoGenMakefile))
\r
725 os.chdir(PlatformInfo.WorkspaceDir)
\r
728 ## Create makefile of a module
\r
730 # @param File The path of the makefile
\r
731 # @param MakeType GNU makefile or MS makefile
\r
733 # @retval True If the file is changed or doesn't exist
\r
734 # @retval False If the file exists and its content is not changed
\r
737 def GenerateModuleMakefile(self, File=None, MakeType=gMakeType):
\r
738 if MakeType in self.ModuleInfo.CustomMakefile and self.ModuleInfo.CustomMakefile[MakeType] != "":
\r
739 return self.GenerateCustomBuildMakefile(File, MakeType)
\r
741 Separator = gDirectorySeparator[MakeType]
\r
742 PlatformInfo = self.PlatformInfo
\r
744 # break build if no source files and binary files are found
\r
745 if len(self.ModuleInfo.SourceFileList) == 0 and len(self.ModuleInfo.BinaryFileDict) == 0:
\r
746 EdkLogger.error("AutoGen", AUTOGEN_ERROR, "No files to be built in module [%s, %s, %s]"
\r
747 % (self.ModuleInfo.BuildTarget, self.ModuleInfo.ToolChain, self.ModuleInfo.Arch),
\r
748 ExtraData=str(self.ModuleInfo.Module))
\r
749 # convert source files and binary files to build target
\r
750 if len(self.ModuleInfo.SourceFileList) > 0:
\r
751 self.ProcessSourceFileList(MakeType)
\r
752 if len(self.ModuleInfo.BinaryFileDict) > 0:
\r
753 self.ProcessBinaryFileList(MakeType)
\r
754 # convert dependent libaries to build command
\r
755 self.ProcessDependentLibrary(MakeType)
\r
757 if "DLINK" in PlatformInfo.ToolStaticLib:
\r
758 EdkLogger.debug(EdkLogger.DEBUG_5, "Static library: " + PlatformInfo.ToolStaticLib["DLINK"])
\r
759 self.SystemLibraryList.append(PlatformInfo.ToolStaticLib["DLINK"])
\r
761 if self.ModuleInfo.Arch == "EBC":
\r
762 # EBC compiler always use "EfiStart" as entry point
\r
763 EntryPoint = "EfiStart"
\r
764 elif self.ModuleInfo.AutoGenVersion < 0x00010005 and len(self.ModuleInfo.Module.ModuleEntryPointList) > 0:
\r
765 # R8 modules use different entry point functions
\r
766 EntryPoint = self.ModuleInfo.Module.ModuleEntryPointList[0]
\r
768 # R9 modules always use "_ModuleEntryPoint" as entry point
\r
769 EntryPoint = "_ModuleEntryPoint"
\r
771 DefaultToolFlag = PlatformInfo.ToolOption.values()
\r
772 if self.ModuleInfo.ModuleType == "USER_DEFINED":
\r
773 DefaultToolFlag = ["" for p in DefaultToolFlag]
\r
775 if "CC" not in PlatformInfo.ToolChainFamily:
\r
776 EdkLogger.error("AutoGen", AUTOGEN_ERROR, "Tool [CC] is not supported [%s, %s, %s]" % (self.ModuleInfo.BuildTarget,
\r
777 self.ModuleInfo.ToolChain, self.ModuleInfo.Arch))
\r
778 if "DLINK" not in PlatformInfo.ToolChainFamily:
\r
779 EdkLogger.error("AutoGen", AUTOGEN_ERROR, "Tool [DLINK] is not supported [%s, %s, %s]" % (self.ModuleInfo.BuildTarget,
\r
780 self.ModuleInfo.ToolChain, self.ModuleInfo.Arch))
\r
782 if self.ModuleInfo.IsLibrary:
\r
783 if "Static-Library-File" in self.DestFileDatabase:
\r
784 self.ResultFileList = self.DestFileDatabase["Static-Library-File"]
\r
785 elif self.ModuleInfo.ModuleType == "USER_DEFINED":
\r
786 if "Dynamic-Library-File" in self.DestFileDatabase:
\r
787 self.ResultFileList = self.DestFileDatabase["Dynamic-Library-File"]
\r
788 if len(self.ResultFileList) == 0:
\r
789 EdkLogger.error("AutoGen", AUTOGEN_ERROR, "Don't know how to end the module build")
\r
791 SourceFileMacroNameList = []
\r
792 SourceFileMacroList = [] # macro name = file list
\r
793 for FileType in self.SourceFileDatabase:
\r
794 Macro = "%s_LIST" % FileType.replace("-", "_").upper()
\r
795 SourceFileMacroNameList.append("$(%s)" % Macro)
\r
796 Template = TemplateString()
\r
797 Template.Append("%s = ${BEGIN}${source_file} \\\n\t${END}" % Macro,
\r
798 {"source_file" : self.SourceFileDatabase[FileType]})
\r
799 SourceFileMacroList.append(str(Template))
\r
800 TargetFileMacroList = []
\r
801 TargetFileMacroNameList = []
\r
802 for FileType in self.DestFileDatabase:
\r
803 Macro = "%s_LIST" % FileType.replace("-", "_").upper()
\r
804 TargetFileMacroNameList.append("$(%s)" % Macro)
\r
805 Template = TemplateString()
\r
806 Template.Append("%s = ${BEGIN}${target_file} \\\n\t${END}" % Macro,
\r
807 {"target_file" : self.DestFileDatabase[FileType]})
\r
808 TargetFileMacroList.append(str(Template))
\r
810 # R8 modules need <BaseName>StrDefs.h for string ID
\r
811 if self.ModuleInfo.AutoGenVersion < 0x00010005 and len(self.ModuleInfo.UnicodeFileList) > 0:
\r
812 AutoGenHeaderFile = os.path.join("$(DEBUG_DIR)", "AutoGen.h")
\r
813 StringHeaderFile = os.path.join("$(DEBUG_DIR)", "%sStrDefs.h" % self.ModuleInfo.BaseName)
\r
814 CopyAutoGenHeaderFile = ["$(CP) %s %s" % (AutoGenHeaderFile, StringHeaderFile)]
\r
816 CopyAutoGenHeaderFile = []
\r
818 MakefileName = gMakefileName[MakeType]
\r
819 MakefileTemplateDict = {
\r
820 "makefile_header" : gMakefileHeader % MakefileName,
\r
821 "makefile_path" : os.path.join("$(MODULE_BUILD_DIR)", MakefileName),
\r
822 "platform_name" : PlatformInfo.Name,
\r
823 "platform_guid" : PlatformInfo.Guid,
\r
824 "platform_version" : PlatformInfo.Version,
\r
825 "platform_relative_directory": PlatformInfo.SourceDir,
\r
826 "platform_output_directory" : PlatformInfo.OutputDir,
\r
828 "module_name" : self.ModuleInfo.Name,
\r
829 "module_guid" : self.ModuleInfo.Guid,
\r
830 "module_version" : self.ModuleInfo.Version,
\r
831 "module_type" : self.ModuleInfo.ModuleType,
\r
832 "module_file_base_name" : self.ModuleInfo.FileBase,
\r
833 "module_relative_directory" : self.ModuleInfo.SourceDir,
\r
835 "architecture" : self.ModuleInfo.Arch,
\r
836 "toolchain_tag" : self.ModuleInfo.ToolChain,
\r
837 "build_target" : self.ModuleInfo.BuildTarget,
\r
839 "platform_build_directory" : PlatformInfo.BuildDir,
\r
841 "separator" : Separator,
\r
842 "default_tool_flags" : DefaultToolFlag,
\r
843 "platform_tool_flags" : [PlatformInfo.BuildOption[tool] for tool in PlatformInfo.ToolPath],
\r
844 "module_tool_flags" : [self.ModuleInfo.BuildOption[tool] for tool in PlatformInfo.ToolPath],
\r
846 "tool_code" : PlatformInfo.ToolPath.keys(),
\r
847 "tool_path" : PlatformInfo.ToolPath.values(),
\r
849 "shell_command_code" : gShellCommand[MakeType].keys(),
\r
850 "shell_command" : gShellCommand[MakeType].values(),
\r
852 "module_entry_point" : EntryPoint,
\r
853 "include_path_prefix" : gIncludeFlag[PlatformInfo.ToolChainFamily["CC"]],
\r
854 "dlink_output_flag" : PlatformInfo.OutputFlag["DLINK"],
\r
855 "slink_output_flag" : PlatformInfo.OutputFlag["SLINK"],
\r
856 "start_group_flag" : gStartGroupFlag[PlatformInfo.ToolChainFamily["DLINK"]],
\r
857 "end_group_flag" : gEndGroupFlag[PlatformInfo.ToolChainFamily["DLINK"]],
\r
858 "include_path" : self.ModuleInfo.IncludePathList,
\r
859 #"target_file" : self.TargetFileList,
\r
860 #"object_file" : self.ObjectFileList,
\r
861 "library_file" : self.LibraryFileList,
\r
862 "remaining_build_target" : self.ResultFileList,
\r
863 "system_library" : self.SystemLibraryList,
\r
864 "common_dependency_file" : self.CommonFileDependency,
\r
865 "create_directory_command" : self.GetCreateDirectoryCommand(self.IntermediateDirectoryList, MakeType),
\r
866 "remove_directory_command" : gRemoveDirectoryCommand[MakeType],
\r
867 "remove_file_command" : gRemoveFileCommand[MakeType],
\r
868 "copy_file_command" : gCopyFileCommand[MakeType],
\r
869 "clean_command" : self.GetRemoveDirectoryCommand(["$(OUTPUT_DIR)"], MakeType),
\r
870 "cleanall_command" : self.GetRemoveDirectoryCommand(["$(DEBUG_DIR)", "$(OUTPUT_DIR)"], MakeType),
\r
871 "dependent_library_build_directory" : self.LibraryBuildDirectoryList,
\r
872 "build_type" : self.BuildType,
\r
873 "source_file_macro" : SourceFileMacroList,
\r
874 "target_file_macro" : TargetFileMacroList,
\r
875 "source_file_macro_name" : SourceFileMacroNameList,
\r
876 "target_file_macro_name" : TargetFileMacroNameList,
\r
877 "file_build_target" : self.BuildTargetList,
\r
878 "copy_autogen_h" : CopyAutoGenHeaderFile,
\r
881 self.PrepareDirectory()
\r
883 AutoGenMakefile = TemplateString()
\r
884 AutoGenMakefile.Append(gModuleMakefileTemplate, MakefileTemplateDict)
\r
888 os.chdir(self.ModuleInfo.PlatformInfo.BuildDir)
\r
889 os.chdir(self.ModuleInfo.MakeFileDir)
\r
890 FilePath = MakefileName
\r
894 Result = SaveFileOnChange(FilePath, str(AutoGenMakefile))
\r
895 os.chdir(self.ModuleInfo.WorkspaceDir)
\r
898 ## Create customized makefile for a module
\r
900 # @param File The path of the makefile
\r
901 # @param MakeType GNU makefile or MS makefile
\r
903 # @retval True If the file is changed or doesn't exist
\r
904 # @retval False If the file exists and its content is not changed
\r
907 def GenerateCustomBuildMakefile(self, File=None, MakeType=gMakeType):
\r
908 Separator = gDirectorySeparator[MakeType]
\r
909 CustomMakefile = open(os.path.join(self.ModuleInfo.WorkspaceDir, self .ModuleInfo.CustomMakefile[MakeType]), 'r').read()
\r
911 MakefileName = gMakefileName[MakeType]
\r
912 MakefileTemplateDict = {
\r
913 "makefile_header" : gMakefileHeader % MakefileName,
\r
914 "platform_name" : self.PlatformInfo.Name,
\r
915 "platform_guid" : self.PlatformInfo.Guid,
\r
916 "platform_version" : self.PlatformInfo.Version,
\r
917 "platform_relative_directory": self.PlatformInfo.SourceDir,
\r
918 "platform_output_directory" : self.PlatformInfo.OutputDir,
\r
920 "module_name" : self.ModuleInfo.Name,
\r
921 "module_guid" : self.ModuleInfo.Guid,
\r
922 "module_version" : self.ModuleInfo.Version,
\r
923 "module_type" : self.ModuleInfo.ModuleType,
\r
924 "module_file_base_name" : self.ModuleInfo.FileBase,
\r
925 "module_relative_directory" : self.ModuleInfo.SourceDir,
\r
927 "architecture" : self.ModuleInfo.Arch,
\r
928 "toolchain_tag" : self.ModuleInfo.ToolChain,
\r
929 "build_target" : self.ModuleInfo.BuildTarget,
\r
931 "platform_build_directory" : self.PlatformInfo.BuildDir,
\r
933 "separator" : Separator,
\r
934 "default_tool_flags" : self.PlatformInfo.ToolOption.values(),
\r
935 "platform_tool_flags" : self.PlatformInfo.BuildOption.values(),
\r
936 "module_tool_flags" : self.ModuleInfo.BuildOption.values(),
\r
938 "tool_code" : self.PlatformInfo.ToolPath.keys(),
\r
939 "tool_path" : self.PlatformInfo.ToolPath.values(),
\r
941 "create_directory_command" : self.GetCreateDirectoryCommand(self.IntermediateDirectoryList, MakeType),
\r
942 "directory_to_be_created" : self.IntermediateDirectoryList,
\r
943 "dependent_library_build_directory" : self.LibraryBuildDirectoryList,
\r
944 "custom_makefile_content" : CustomMakefile
\r
947 self.PrepareDirectory()
\r
949 AutoGenMakefile = TemplateString()
\r
950 AutoGenMakefile.Append(gCustomMakefileTemplate, MakefileTemplateDict)
\r
954 FilePath = path.join(self.ModuleInfo.WorkspaceDir, self.ModuleInfo.MakeFileDir, MakefileName)
\r
958 return SaveFileOnChange(FilePath, str(AutoGenMakefile))
\r
960 ## Process source files to generate makefile targets and dependencies
\r
962 # The intermediate and final targets and dependencies are controlled by
\r
963 # build rules in $(WORKSPACE)/Conf/build_rule.txt. The dependencies of source
\r
964 # file are figured out by search included files in the source file.
\r
966 # @param MakeType GNU makefile or MS makefile
\r
968 def ProcessSourceFileList(self, MakeType=gMakeType):
\r
969 Separator = gDirectorySeparator[MakeType]
\r
971 ForceIncludedFile = []
\r
972 SourceFileList = []
\r
974 if "CC" not in self.PlatformInfo.ToolChainFamily:
\r
975 EdkLogger.error("AutoGen", AUTOGEN_ERROR, "No CC tool found",
\r
976 ExtraData=str(self.ModuleInfo.Module))
\r
977 Family = self.PlatformInfo.ToolChainFamily["CC"]
\r
978 BuildRule = self.PlatformInfo.BuildRule
\r
981 FileList = self.ModuleInfo.SourceFileList
\r
982 SourceDir = os.path.join(self.ModuleInfo.WorkspaceDir, self.ModuleInfo.SourceDir)
\r
983 for FileInfo in FileList:
\r
984 F, SrcFileType, SrcFileBuildRule = FileInfo
\r
985 if SrcFileType == "C-Code-File":
\r
987 SrcFileName = path.basename(F)
\r
988 SrcFileBase, SrcFileExt = path.splitext(SrcFileName)
\r
989 SrcFileDir = path.dirname(F)
\r
990 if SrcFileDir == "":
\r
993 P = "$(OUTPUT_DIR)" + Separator + SrcFileDir
\r
994 if P not in self.IntermediateDirectoryList:
\r
995 self.IntermediateDirectoryList.append(P)
\r
996 SrcFileRelativePath = os.path.join(SourceDir, F)
\r
998 SrcFile, ExtraSrcFileList, DstFile, CommandList = SrcFileBuildRule.Apply(F, SourceDir, Separator)
\r
999 if SrcFileType not in self.SourceFileDatabase:
\r
1000 self.SourceFileDatabase[SrcFileType] = []
\r
1001 self.SourceFileDatabase[SrcFileType].append(SrcFile)
\r
1002 SourceFileList.append(SrcFileRelativePath)
\r
1004 BuildTargetTemplate = "${BEGIN}%s : ${deps}\n"\
\r
1005 "${END}\t%s\n" % (DstFile, "\n\t".join(CommandList))
\r
1006 self.FileBuildTargetList.append((SrcFileRelativePath, BuildTargetTemplate))
\r
1010 DstFileType, DstFileBuildRule = BuildRule.Get(SrcFileBuildRule.DestFileExt, Family)
\r
1011 if DstFileType == None:
\r
1012 DstFileType = "Unknown-Type-File"
\r
1014 if DstFileType in self.SourceFileDatabase:
\r
1015 self.SourceFileDatabase[DstFileType].append(DstFile)
\r
1017 if DstFileType not in self.DestFileDatabase:
\r
1018 self.DestFileDatabase[DstFileType] = []
\r
1019 self.DestFileDatabase[DstFileType].append(DstFile)
\r
1021 if DstFileBuildRule != None and DstFileBuildRule.IsMultipleInput:
\r
1022 if DstFileBuildRule not in self.PendingBuildTargetList:
\r
1023 self.PendingBuildTargetList.append(DstFileBuildRule)
\r
1025 elif DstFileBuildRule == None or DstFileBuildRule.CommandList == []:
\r
1026 self.ResultFileList.append(DstFile)
\r
1029 SrcFile, ExtraSrcFileList, DstFile, CommandList = DstFileBuildRule.Apply(DstFile, None, Separator)
\r
1030 BuildTargetString = "%s : %s %s\n"\
\r
1031 "\t%s\n" % (DstFile, SrcFile, " ".join(ExtraSrcFileList), "\n\t".join(CommandList))
\r
1032 self.FileBuildTargetList.append((SrcFile, BuildTargetString))
\r
1033 SrcFileBuildRule = DstFileBuildRule
\r
1035 # handle pending targets
\r
1036 TempBuildTargetList = []
\r
1038 while len(self.PendingBuildTargetList) > 0:
\r
1039 SrcFileBuildRule = self.PendingBuildTargetList.pop()
\r
1041 for FileType in SrcFileBuildRule.SourceFileType:
\r
1042 if FileType not in self.SourceFileDatabase:
\r
1043 if FileType not in self.DestFileDatabase:
\r
1046 SrcFileList.extend(self.DestFileDatabase[FileType])
\r
1048 SrcFileList.extend(self.SourceFileDatabase[FileType])
\r
1049 SrcFile, ExtraSrcFileList, DstFile, CommandList = SrcFileBuildRule.Apply(SrcFileList, None, Separator)
\r
1050 BuildTargetString = "%s : %s %s\n"\
\r
1051 "\t%s\n" % (DstFile, SrcFile, " ".join(ExtraSrcFileList), "\n\t".join(CommandList))
\r
1052 self.FileBuildTargetList.append((SrcFile, BuildTargetString))
\r
1054 # try to find next target
\r
1056 DstFileType, DstFileBuildRule = BuildRule.Get(SrcFileBuildRule.DestFileExt, Family)
\r
1057 if DstFileType == None:
\r
1058 DstFileType = "Unknown-Type-File"
\r
1060 if DstFileType in self.SourceFileDatabase:
\r
1061 self.SourceFileDatabase[DstFileType].append(DstFile)
\r
1063 if DstFileType not in self.DestFileDatabase:
\r
1064 self.DestFileDatabase[DstFileType] = []
\r
1065 self.DestFileDatabase[DstFileType].append(DstFile)
\r
1067 if DstFileBuildRule != None and DstFileBuildRule.IsMultipleInput:
\r
1068 TempBuildTargetList.append(DstFileBuildRule)
\r
1070 elif DstFileBuildRule == None or DstFileBuildRule.CommandList == []:
\r
1071 self.ResultFileList.append(DstFile)
\r
1074 SrcFile, ExtraSrcFileList, DstFile, CommandList = DstFileBuildRule.Apply(DstFile, None, Separator)
\r
1075 BuildTargetString = "%s : %s %s\n"\
\r
1076 "\t%s\n" % (DstFile, SrcFile, " ".join(ExtraSrcFileList), "\n\t".join(CommandList))
\r
1077 self.FileBuildTargetList.append((SrcFile, BuildTargetString))
\r
1078 SrcFileBuildRule = DstFileBuildRule
\r
1079 if len(TempBuildTargetList) == 0:
\r
1081 self.PendingBuildTargetList = TempBuildTargetList
\r
1083 # Build AutoGen files only if we have C source files
\r
1084 if CCodeFlag == True:
\r
1085 for F in self.ModuleInfo.AutoGenFileList:
\r
1086 SrcFileName = path.basename(F)
\r
1087 SrcFileBase, SrcFileExt = path.splitext(SrcFileName)
\r
1088 SrcFileDir = path.dirname(F)
\r
1089 if SrcFileDir == "":
\r
1092 P = "$(DEBUG_DIR)" + Separator + SrcFileDir
\r
1093 if P not in self.IntermediateDirectoryList:
\r
1094 self.IntermediateDirectoryList.append(P)
\r
1096 SrcFileRelativePath = os.path.join(self.ModuleInfo.DebugDir, F)
\r
1098 SrcFileType, SrcFileBuildRule = BuildRule.Get(SrcFileExt, Family)
\r
1099 if SrcFileType != None and SrcFileType == "C-Header-File":
\r
1100 ForceIncludedFile.append(SrcFileRelativePath)
\r
1101 if SrcFileBuildRule == None or SrcFileBuildRule.CommandList == []:
\r
1104 SrcFile, ExtraSrcFileList, DstFile, CommandList = SrcFileBuildRule.Apply(F, self.ModuleInfo.DebugDir, Separator)
\r
1106 if SrcFileType not in self.SourceFileDatabase:
\r
1107 self.SourceFileDatabase[SrcFileType] = []
\r
1108 self.SourceFileDatabase[SrcFileType].append(SrcFile)
\r
1109 SourceFileList.append(SrcFileRelativePath)
\r
1111 BuildTargetTemplate = "${BEGIN}%s : ${deps}\n"\
\r
1112 "${END}\t%s\n" % (DstFile, "\n\t".join(CommandList))
\r
1113 self.FileBuildTargetList.append((SrcFileRelativePath, BuildTargetTemplate))
\r
1117 DstFileType, DstFileBuildRule = BuildRule.Get(SrcFileBuildRule.DestFileExt, Family)
\r
1118 if DstFileType == None:
\r
1119 DstFileType = "Unknown-Type-File"
\r
1121 if DstFileType in self.SourceFileDatabase:
\r
1122 self.SourceFileDatabase[DstFileType].append(DstFile)
\r
1124 if DstFileType not in self.DestFileDatabase:
\r
1125 self.DestFileDatabase[DstFileType] = []
\r
1126 self.DestFileDatabase[DstFileType].append(DstFile)
\r
1128 if DstFileBuildRule != None and DstFileBuildRule.IsMultipleInput:
\r
1129 if DstFileBuildRule not in self.PendingBuildTargetList:
\r
1130 self.PendingBuildTargetList.append(DstFileBuildRule)
\r
1132 elif DstFileBuildRule == None or DstFileBuildRule.CommandList == []:
\r
1133 self.ResultFileList.append(DstFile)
\r
1136 SrcFile, ExtraSrcFileList, DstFile, CommandList = DstFileBuildRule.Apply(DstFile, None, Separator)
\r
1137 BuildTargetString = "%s : %s %s\n"\
\r
1138 "\t%s\n" % (DstFile, SrcFile, " ".join(ExtraSrcFileList), "\n\t".join(CommandList))
\r
1139 self.FileBuildTargetList.append((SrcFile, BuildTargetString))
\r
1140 SrcFileBuildRule = DstFileBuildRule
\r
1143 # Search dependency file list for each source file
\r
1145 self.FileDependency = self.GetFileDependency(SourceFileList, ForceIncludedFile, self.ModuleInfo.IncludePathList)
\r
1147 for File in self.FileDependency:
\r
1148 # skip non-C files
\r
1149 if (not File.endswith(".c") and not File.endswith(".C")) or File.endswith("AutoGen.c"):
\r
1151 elif DepSet == None:
\r
1152 DepSet = set(self.FileDependency[File])
\r
1154 DepSet &= set(self.FileDependency[File])
\r
1155 # in case nothing in SourceFileList
\r
1156 if DepSet == None:
\r
1159 # Extract comman files list in the dependency files
\r
1161 self.CommonFileDependency = list(DepSet)
\r
1162 for F in self.FileDependency:
\r
1163 NewDepSet = set(self.FileDependency[F])
\r
1164 NewDepSet -= DepSet
\r
1165 if File.endswith(".c") or File.endswith(".C") or not File.endswith("AutoGen.c"):
\r
1166 self.FileDependency[F] = ["$(COMMON_DEPS)"] + list(NewDepSet)
\r
1168 for File, TargetTemplate in self.FileBuildTargetList:
\r
1169 if File not in self.FileDependency:
\r
1170 self.BuildTargetList.append(TargetTemplate)
\r
1172 Template = TemplateString()
\r
1173 Template.Append(TargetTemplate, {"deps" : self.FileDependency[File]})
\r
1174 self.BuildTargetList.append(str(Template))
\r
1177 ## Process binary files to generate makefile targets and dependencies
\r
1179 # All binary files are just copied to $(OUTPUT_DIR)
\r
1181 # @param MakeType GNU makefile or MS makefile
\r
1183 def ProcessBinaryFileList(self, MakeType=gMakeType):
\r
1184 BinaryFiles = self.ModuleInfo.BinaryFileDict
\r
1185 BuildTargetString = "%(dst)s : %(src)s\n"\
\r
1186 "\t$(CP) %(src)s %(dst)s\n"
\r
1187 for FileType in BinaryFiles:
\r
1188 if FileType not in self.DestFileDatabase:
\r
1189 self.DestFileDatabase[FileType] = []
\r
1190 for F in BinaryFiles[FileType]:
\r
1191 Src = os.path.join("$(MODULE_DIR)", F)
\r
1192 FileName = os.path.basename(F)
\r
1193 Dst = os.path.join("$(OUTPUT_DIR)", FileName)
\r
1194 self.DestFileDatabase[FileType].append(Dst)
\r
1195 self.ResultFileList.append(Dst)
\r
1196 self.BuildTargetList.append(BuildTargetString % {"dst":Dst, "src":Src})
\r
1198 ## For creating makefile targets for dependent libraries
\r
1200 # @param MakeType GNU makefile or MS makefile
\r
1202 def ProcessDependentLibrary(self, MakeType=gMakeType):
\r
1203 for LibraryModule in self.ModuleInfo.DependentLibraryList:
\r
1204 LibraryFile = str(LibraryModule)
\r
1205 FileBase = path.basename(LibraryFile).split(".")[0]
\r
1206 LibraryBuildPath = path.dirname(LibraryFile) + gDirectorySeparator[MakeType] + FileBase
\r
1207 self.LibraryBuildDirectoryList.append(LibraryBuildPath)
\r
1208 self.LibraryFileList.append(gDirectorySeparator[MakeType].join([LibraryBuildPath, "OUTPUT", LibraryModule.BaseName + ".lib"]))
\r
1210 ## Determine the root directory for a platform build
\r
1211 def GetPlatformBuildDirectory(self):
\r
1212 return self.PlatformInfo.BuildDir
\r
1214 ## Return a list containing source file's dependencies
\r
1216 # @param FileList The list of source files
\r
1217 # @param ForceInculeList The list of files which will be included forcely
\r
1218 # @param SearchPathList The list of search path
\r
1220 # @retval dict The mapping between source file path and its dependencies
\r
1222 def GetFileDependency(self, FileList, ForceInculeList, SearchPathList):
\r
1224 for F in FileList:
\r
1225 Dependency[F] = self.GetDependencyList(F, ForceInculeList, SearchPathList)
\r
1228 ## Find dependencies for one source file
\r
1230 # By searching recursively "#include" directive in file, find out all the
\r
1231 # files needed by given source file. The dependecies will be only searched
\r
1232 # in given search path list.
\r
1234 # @param File The source file
\r
1235 # @param ForceInculeList The list of files which will be included forcely
\r
1236 # @param SearchPathList The list of search path
\r
1238 # @retval list The list of files the given source file depends on
\r
1240 def GetDependencyList(self, File, ForceList, SearchPathList):
\r
1241 EdkLogger.debug(EdkLogger.DEBUG_1, "Try to get dependency files for %s" % File)
\r
1242 EdkLogger.debug(EdkLogger.DEBUG_0, "Including %s" % " ".join(ForceList))
\r
1243 FileStack = [File] + ForceList
\r
1244 DependencySet = set()
\r
1245 MacroUsedByIncludedFile = False
\r
1247 if self.ModuleInfo.Arch not in gDependencyDatabase:
\r
1248 gDependencyDatabase[self.ModuleInfo.Arch] = {}
\r
1249 DepDb = gDependencyDatabase[self.ModuleInfo.Arch]
\r
1250 while len(FileStack) > 0:
\r
1251 EdkLogger.debug(EdkLogger.DEBUG_0, "Stack %s" % "\n\t".join(FileStack))
\r
1252 F = FileStack.pop()
\r
1254 CurrentFileDependencyList = []
\r
1255 if F in DepDb and not IsChanged(F):
\r
1256 CurrentFileDependencyList = DepDb[F]
\r
1257 for Dep in CurrentFileDependencyList:
\r
1258 if Dep not in FileStack and Dep not in DependencySet:
\r
1259 FileStack.append(Dep)
\r
1264 EdkLogger.error("AutoGen", FILE_OPEN_FAILURE, ExtraData=F)
\r
1266 FileContent = Fd.read()
\r
1268 if len(FileContent) == 0:
\r
1271 if FileContent[0] == 0xff or FileContent[0] == 0xfe:
\r
1272 FileContent = unicode(FileContent, "utf-16")
\r
1273 IncludedFileList = gIncludePattern.findall(FileContent)
\r
1275 CurrentFilePath = os.path.dirname(F)
\r
1276 for Inc in IncludedFileList:
\r
1277 # if there's macro used to reference header file, expand it
\r
1278 HeaderList = gMacroPattern.findall(Inc)
\r
1279 if len(HeaderList) == 1 and len(HeaderList[0]) == 2:
\r
1280 HeaderType = HeaderList[0][0]
\r
1281 HeaderKey = HeaderList[0][1]
\r
1282 if HeaderType in gIncludeMacroConversion:
\r
1283 Inc = gIncludeMacroConversion[HeaderType] % {"HeaderKey" : HeaderKey}
\r
1285 # not known macro used in #include
\r
1286 MacroUsedByIncludedFile = True
\r
1288 Inc = os.path.normpath(Inc)
\r
1289 for SearchPath in [CurrentFilePath] + SearchPathList:
\r
1290 FilePath = os.path.join(SearchPath, Inc)
\r
1291 if not os.path.exists(FilePath) or FilePath in CurrentFileDependencyList:
\r
1293 CurrentFileDependencyList.append(FilePath)
\r
1294 if FilePath not in FileStack and FilePath not in DependencySet:
\r
1295 FileStack.append(FilePath)
\r
1298 EdkLogger.verbose("%s included by %s was not found in any given path:\n\t%s" % (Inc, F, "\n\t".join(SearchPathList)))
\r
1300 if not MacroUsedByIncludedFile:
\r
1302 CurrentFileDependencyList += ForceList
\r
1304 # Don't keep the file in cache if it uses macro in included file.
\r
1305 # So it will be scanned again if another file includes this file.
\r
1307 DepDb[F] = CurrentFileDependencyList
\r
1308 DependencySet.update(CurrentFileDependencyList)
\r
1311 # If there's macro used in included file, always build the file by
\r
1312 # returning a empty dependency
\r
1314 if MacroUsedByIncludedFile:
\r
1315 DependencyList = [""]
\r
1317 DependencyList = list(DependencySet) # remove duplicate ones
\r
1318 DependencyList.append(File)
\r
1320 return DependencyList
\r
1322 ## Get the root directory list for intermediate files of all modules build
\r
1324 # @retval list The list of directory
\r
1326 def GetModuleBuildDirectoryList(self):
\r
1328 for Arch in self.PlatformInfo:
\r
1329 for ModuleAutoGen in self.PlatformInfo[Arch].ModuleAutoGenList:
\r
1330 DirList.append(ModuleAutoGen.BuildInfo.BuildDir)
\r
1333 ## Get the root directory list for intermediate files of all libraries build
\r
1335 # @retval list The list of directory
\r
1337 def GetLibraryBuildDirectoryList(self):
\r
1339 for Arch in self.PlatformInfo:
\r
1340 for LibraryAutoGen in self.PlatformInfo[Arch].LibraryAutoGenList:
\r
1341 DirList.append(LibraryAutoGen.BuildInfo.BuildDir)
\r
1344 ## Return a list of directory creation command string
\r
1346 # @param DirList The list of directory to be created
\r
1347 # @param MakeType GNU makefile or MS makefile
\r
1349 # @retval list The directory creation command list
\r
1351 def GetCreateDirectoryCommand(self, DirList, MakeType=gMakeType):
\r
1352 return [gCreateDirectoryCommandTemplate[MakeType] % {'dir':Dir} for Dir in DirList]
\r
1354 ## Return a list of directory removal command string
\r
1356 # @param DirList The list of directory to be removed
\r
1357 # @param MakeType GNU makefile or MS makefile
\r
1359 # @retval list The directory removal command list
\r
1361 def GetRemoveDirectoryCommand(self, DirList, MakeType=gMakeType):
\r
1362 return [gRemoveDirectoryCommandTemplate[MakeType] % {'dir':Dir} for Dir in DirList]
\r
1364 # This acts like the main() function for the script, unless it is 'import'ed into another script.
\r
1365 if __name__ == '__main__':
\r