1 #!/usr/bin/env python
\r
3 """Create makefile for MS nmake and GNU make"""
\r
5 import os, sys, string, re
\r
6 import os.path as path
\r
8 from SequentialDict import *
\r
9 from EdkIIWorkspaceBuild import *
\r
10 from EdkIIWorkspace import *
\r
11 from BuildInfo import *
\r
12 from BuildToolError import *
\r
14 gDependencyDatabase = {} # file path : [dependent files list]
\r
15 gIncludePattern = re.compile("^[ \t#]*include[ \t]+[\"<]*([^\"<>]+)[>\" \t\n\r]*", re.MULTILINE | re.UNICODE)
\r
17 class AutoGenString(object):
\r
24 def Append(self, AppendString, Dictionary=None):
\r
25 if Dictionary == None:
\r
26 self.String += AppendString
\r
28 while AppendString.find('${BEGIN}') >= 0:
\r
29 Start = AppendString.find('${BEGIN}')
\r
30 End = AppendString.find('${END}')
\r
31 SubString = AppendString[AppendString.find('${BEGIN}'):AppendString.find('${END}')+6]
\r
34 NewDict = {"BEGIN":"", "END":""}
\r
35 for Key in Dictionary:
\r
36 if SubString.find('$' + Key) >= 0 or SubString.find('${' + Key + '}') >= 0:
\r
37 Value = Dictionary[Key]
\r
38 if type(Value) != type([]):
\r
39 NewDict[Key] = Value
\r
42 RepeatTime = len(Value)
\r
43 elif RepeatTime != len(Value):
\r
44 raise AutoGenError(msg=Key + " has different repeat time from others!")
\r
48 for Index in range(0, RepeatTime):
\r
50 if Key == "BEGIN" or Key == "END" or type(Dictionary[Key]) != type([]):
\r
53 NewDict[Key] = Dictionary[Key][Index]
\r
54 NewString += string.Template(SubString).safe_substitute(NewDict)
\r
55 AppendString = AppendString[0:Start] + NewString + AppendString[End + 6:]
\r
58 for Key in Dictionary:
\r
59 if type(Dictionary[Key]) == type([]):
\r
61 NewDict[Key] = Dictionary[Key]
\r
62 self.String += string.Template(AppendString).safe_substitute(NewDict)
\r
65 MakefileHeader = '''#
\r
67 # This file is auto-generated by build utility
\r
75 # Auto-generated makefile for building module and libraries
\r
79 LibraryMakeCommand = '''cd %(makedir)s
\r
80 \t$(MAKE) $(MAKE_FLAGS) -f %(makefile)s %(target)s
\r
81 \tcd $(MODULE_BUILD_DIR)'''
\r
84 if sys.platform == "win32":
\r
89 gMakefileName = {"nmake" : "Makefile", "gmake" : "GNUmakefile"}
\r
91 gDirectorySeparator = {"nmake" : "\\", "gmake" : "/"}
\r
93 gCreateDirectoryCommand = {"nmake" : "mkdir", "gmake" : "mkdir -p"}
\r
94 gRemoveDirectoryCommand = {"nmake" : "rmdir /s /q", "gmake" : "rm -r -f"}
\r
95 gRemoveFileCommand = {"nmake" : "del /f /q", "gmake" : "rm -f"}
\r
98 ("MSFT", "CC", "OUTPUT") : "/Fo",
\r
99 ("MSFT", "SLINK", "OUTPUT") : "/OUT:",
\r
100 ("MSFT", "DLINK", "OUTPUT") : "/OUT:",
\r
101 ("MSFT", "ASMLINK", "OUTPUT") : "/OUT:",
\r
102 ("MSFT", "PCH", "OUTPUT") : "/Fp",
\r
103 ("MSFT", "ASM", "OUTPUT") : "/Fo",
\r
105 ("INTEL", "CC", "OUTPUT") : "/Fo",
\r
106 ("INTEL", "SLINK", "OUTPUT") : "/OUT:",
\r
107 ("INTEL", "DLINK", "OUTPUT") : "/OUT:",
\r
108 ("INTEL", "ASMLINK", "OUTPUT") : "/OUT:",
\r
109 ("INTEL", "PCH", "OUTPUT") : "/Fp",
\r
110 ("INTEL", "ASM", "OUTPUT") : "/Fo",
\r
111 ("INTEL", "IPF", "ASM", "OUTPUT") : "-o ",
\r
113 ("GCC", "CC", "OUTPUT") : "-o ",
\r
114 ("GCC", "SLINK", "OUTPUT") : "-cr ",
\r
115 ("GCC", "DLINK", "OUTPUT") : "-o ",
\r
116 ("GCC", "ASMLINK", "OUTPUT") : "-o ",
\r
117 ("GCC", "PCH", "OUTPUT") : "-o ",
\r
118 ("GCC", "ASM", "OUTPUT") : "-o ",
\r
123 IncludeFlag = {"MSFT" : "/I", "GCC" : "-I"}
\r
125 gCustomMakefileTemplate = '''
\r
129 # Platform Macro Definition
\r
131 PLATFORM_NAME = ${platform_name}
\r
132 PLATFORM_GUID = ${platform_guid}
\r
133 PLATFORM_VERSION = ${platform_version}
\r
134 PLATFORM_RELATIVE_DIR = ${platform_relative_directory}
\r
135 PLATFORM_DIR = $(WORKSPACE)${separator}${platform_relative_directory}
\r
136 PLATFORM_OUTPUT_DIR = ${platform_output_directory}
\r
139 # Package Macro Definition
\r
141 PACKAGE_NAME = ${package_name}
\r
142 PACKAGE_GUID = ${package_guid}
\r
143 PACKAGE_VERSION = ${package_version}
\r
144 PACKAGE_RELATIVE_DIR = ${package_relative_directory}
\r
145 PACKAGE_DIR = $(WORKSPACE)${separator}${package_relative_directory}
\r
148 # Module Macro Definition
\r
150 MODULE_NAME = ${module_name}
\r
151 MODULE_GUID = ${module_guid}
\r
152 MODULE_VERSION = ${module_version}
\r
153 MODULE_TYPE = ${module_type}
\r
154 MODULE_FILE_BASE_NAME = ${module_file_base_name}
\r
155 BASE_NAME = $(MODULE_NAME)
\r
156 MODULE_RELATIVE_DIR = ${module_relative_directory}
\r
157 MODULE_DIR = $(WORKSPACE)${separator}${module_relative_directory}
\r
160 # Build Configuration Macro Definition
\r
162 ARCH = ${architecture}
\r
163 TOOLCHAIN_TAG = ${toolchain_tag}
\r
164 TARGET = ${build_target}
\r
167 # Build Directory Macro Definition
\r
169 PLATFORM_BUILD_DIR = ${platform_build_directory}
\r
170 BUILD_DIR = ${platform_build_directory}${separator}${build_target}_${toolchain_tag}
\r
171 BIN_DIR = $(BUILD_DIR)${separator}${architecture}
\r
172 LIB_DIR = $(BIN_DIR)
\r
173 MODULE_BUILD_DIR = $(BUILD_DIR)${separator}${architecture}${separator}${module_relative_directory}${separator}${module_file_base_name}
\r
174 OUTPUT_DIR = $(MODULE_BUILD_DIR)${separator}OUTPUT
\r
175 DEBUG_DIR = $(MODULE_BUILD_DIR)${separator}DEBUG
\r
176 DEST_DIR_OUTPUT = $(OUTPUT_DIR)
\r
177 DEST_DIR_DEBUG = $(DEBUG_DIR)
\r
180 # Default Tools Flags Macro Definition (from tools_def.txt by default)
\r
182 ${BEGIN}DEFAULT_${tool_code}_FLAGS = ${default_tool_flags}
\r
186 # Platform Tools Flags Macro Definition (from platform description file)
\r
188 ${BEGIN}PLATFORM_${tool_code}_FLAGS = ${platform_tool_flags}
\r
192 # Platform Tools Flags Macro Definition (from platform description file)
\r
194 ${BEGIN}MODULE_${tool_code}_FLAGS = ${module_tool_flags}
\r
200 ${BEGIN}${tool_code}_FLAGS = $(DEFAULT_${tool_code}_FLAGS) $(PLATFORM_${tool_code}_FLAGS) $(MODULE_${tool_code}_FLAGS)
\r
202 MAKE_FLAGS = /nologo
\r
207 ${BEGIN}${tool_code} = ${tool_path}
\r
210 ${custom_makefile_content}
\r
213 # Target used when called from platform makefile, which will bypass the build of dependent libraries
\r
220 # Target used for library build, which will bypass the build of dependent libraries
\r
234 # Initialization target: print build information and create necessary directories
\r
237 \t-@echo Building ... $(MODULE_NAME)-$(MODULE_VERSION) [$(ARCH)] in package $(PACKAGE_NAME)-$(PACKAGE_VERSION)
\r
238 \t-${create_directory_command} $(DEBUG_DIR) > NUL 2>&1
\r
239 \t-${create_directory_command} $(OUTPUT_DIR) > NUL 2>&1
\r
240 \t${BEGIN}-${create_directory_command} $(OUTPUT_DIR)${separator}${directory_to_be_created} > NUL 2>&1
\r
245 gModuleMakefileTemplate = '''
\r
249 # Platform Macro Definition
\r
251 PLATFORM_NAME = ${platform_name}
\r
252 PLATFORM_GUID = ${platform_guid}
\r
253 PLATFORM_VERSION = ${platform_version}
\r
254 PLATFORM_RELATIVE_DIR = ${platform_relative_directory}
\r
255 PLATFORM_DIR = $(WORKSPACE)${separator}${platform_relative_directory}
\r
256 PLATFORM_OUTPUT_DIR = ${platform_output_directory}
\r
259 # Package Macro Definition
\r
261 PACKAGE_NAME = ${package_name}
\r
262 PACKAGE_GUID = ${package_guid}
\r
263 PACKAGE_VERSION = ${package_version}
\r
264 PACKAGE_RELATIVE_DIR = ${package_relative_directory}
\r
265 PACKAGE_DIR = $(WORKSPACE)${separator}${package_relative_directory}
\r
268 # Module Macro Definition
\r
270 MODULE_NAME = ${module_name}
\r
271 MODULE_GUID = ${module_guid}
\r
272 MODULE_VERSION = ${module_version}
\r
273 MODULE_TYPE = ${module_type}
\r
274 MODULE_FILE_BASE_NAME = ${module_file_base_name}
\r
275 BASE_NAME = $(MODULE_NAME)
\r
276 MODULE_RELATIVE_DIR = ${module_relative_directory}
\r
277 MODULE_DIR = $(WORKSPACE)${separator}${module_relative_directory}
\r
280 # Build Configuration Macro Definition
\r
282 ARCH = ${architecture}
\r
283 TOOLCHAIN_TAG = ${toolchain_tag}
\r
284 TARGET = ${build_target}
\r
287 # Build Directory Macro Definition
\r
289 PLATFORM_BUILD_DIR = ${platform_build_directory}
\r
290 BUILD_DIR = ${platform_build_directory}${separator}${build_target}_${toolchain_tag}
\r
291 BIN_DIR = $(BUILD_DIR)${separator}${architecture}
\r
292 LIB_DIR = $(BIN_DIR)
\r
293 MODULE_BUILD_DIR = $(BUILD_DIR)${separator}${architecture}${separator}${module_relative_directory}${separator}${module_file_base_name}
\r
294 OUTPUT_DIR = $(MODULE_BUILD_DIR)${separator}OUTPUT
\r
295 DEBUG_DIR = $(MODULE_BUILD_DIR)${separator}DEBUG
\r
296 DEST_DIR_OUTPUT = $(OUTPUT_DIR)
\r
297 DEST_DIR_DEBUG = $(DEBUG_DIR)
\r
300 # Default Tools Flags Macro Definition (from tools_def.txt by default)
\r
302 ${BEGIN}DEFAULT_${tool_code}_FLAGS = ${default_tool_flags}
\r
306 # Platform Tools Flags Macro Definition (from platform description file)
\r
308 ${BEGIN}PLATFORM_${tool_code}_FLAGS = ${platform_tool_flags}
\r
312 # Module Tools Flags Macro Definition (from platform/module description file)
\r
314 ${BEGIN}MODULE_${tool_code}_FLAGS = ${module_tool_flags}
\r
320 ${BEGIN}${tool_code}_FLAGS = $(DEFAULT_${tool_code}_FLAGS) $(PLATFORM_${tool_code}_FLAGS) $(MODULE_${tool_code}_FLAGS)
\r
322 MAKE_FLAGS = /nologo
\r
327 ${BEGIN}${tool_code} = ${tool_path}
\r
333 SOURCE_FILES = ${BEGIN}$(MODULE_DIR)${separator}${source_file} \\
\r
334 ${END}${BEGIN}$(DEBUG_DIR)${separator}${auto_generated_file}
\r
337 INC = ${BEGIN}${include_path_prefix}$(WORKSPACE)${separator}${include_path} \\
\r
340 OBJECTS = ${BEGIN}$(OUTPUT_DIR)${separator}${object_file} \\
\r
343 LIBS = ${BEGIN}$(LIB_DIR)${separator}${library_file} \\
\r
346 COMMON_DEPS = ${BEGIN}$(WORKSPACE)${separator}${common_dependency_file} \\
\r
349 ENTRYPOINT = ${module_entry_point}
\r
352 # Target File Macro Definitions
\r
354 PCH_FILE = $(OUTPUT_DIR)\$(MODULE_NAME).pch
\r
355 LIB_FILE = $(LIB_DIR)\$(MODULE_NAME).lib
\r
356 LLIB_FILE = $(OUTPUT_DIR)\$(MODULE_NAME)Local.lib
\r
357 DLL_FILE = $(DEBUG_DIR)\$(MODULE_NAME).dll
\r
358 EFI_FILE = $(OUTPUT_DIR)\$(MODULE_NAME).efi
\r
361 # Overridable Target Macro Definitions
\r
365 LLIB_TARGET = $(LLIB_FILE)
\r
368 # Default target, which will build dependent libraries in addition to source files
\r
375 # Target used when called from platform makefile, which will bypass the build of dependent libraries
\r
378 pbuild: $(INIT_TARGET) $(PCH_TARGET) gen_obj $(LLIB_TARGET) $(EFI_FILE) $(DLL_FILE)
\r
382 # Target used for library build, which will bypass the build of dependent libraries
\r
385 lbuild: $(INIT_TARGET) $(PCH_TARGET) gen_obj $(LIB_FILE)
\r
392 mbuild: $(INIT_TARGET) gen_libs $(PCH_TARGET) gen_obj $(LLIB_TARGET) $(EFI_FILE) $(DLL_FILE)
\r
396 # Initialization target: print build information and create necessary directories
\r
399 \t-@echo Building ... $(MODULE_NAME)-$(MODULE_VERSION) [$(ARCH)] in package $(PACKAGE_NAME)-$(PACKAGE_VERSION)
\r
400 \t-${create_directory_command} $(DEBUG_DIR) > NUL 2>&1
\r
401 \t-${create_directory_command} $(OUTPUT_DIR) > NUL 2>&1
\r
402 \t${BEGIN}-${create_directory_command} $(OUTPUT_DIR)${separator}${directory_to_be_created} > NUL 2>&1
\r
426 obj: $(PCH_TARGET) gen_obj
\r
432 locallib: $(PCH_TARGET) gen_obj $(LLIB_FILE)
\r
438 dll: gen_libs $(PCH_TARGET) gen_obj $(LLIB_TARGET) $(DLL_FILE)
\r
444 efi: gen_libs $(PCH_TARGET) gen_obj $(LLIB_TARGET) $(DLL_FILE) $(EFI_FILE)
\r
451 \t${BEGIN}cd $(BUILD_DIR)${separator}$(ARCH)${separator}${dependent_library_build_directory}
\r
452 \t$(MAKE) $(MAKE_FLAGS)
\r
453 \t${END}cd $(MODULE_BUILD_DIR)
\r
460 \t@echo placeholder: processing vfr files
\r
463 # Phony targets for objects
\r
466 gen_obj: $(PCH_TARGET) $(OBJECTS)
\r
470 # PCH file build target
\r
473 $(PCH_FILE): $(DEP_FILES)
\r
474 \t$(PCH) $(CC_FLAGS) $(PCH_FLAGS) $(DEP_FILES)
\r
477 # Local Lib file build target
\r
480 $(LLIB_FILE): $(OBJECTS)
\r
481 \t"$(SLINK)" $(SLINK_FLAGS) /OUT:$(LLIB_FILE) $(OBJECTS)
\r
484 # Library file build target
\r
487 $(LIB_FILE): $(OBJECTS)
\r
488 \t"$(SLINK)" $(SLINK_FLAGS) /OUT:$(LIB_FILE) $(OBJECTS)
\r
491 # DLL file build target
\r
494 $(DLL_FILE): $(LIBS) $(LLIB_FILE)
\r
495 \t"$(DLINK)" $(DLINK_FLAGS) /OUT:$(DLL_FILE) $(DLINK_SPATH) $(LIBS) $(LLIB_FILE)
\r
498 # EFI file build target
\r
501 $(EFI_FILE): $(LIBS) $(LLIB_FILE)
\r
502 \t"$(DLINK)" $(DLINK_FLAGS) /OUT:$(EFI_FILE) $(DLINK_SPATH) $(LIBS) $(LLIB_FILE)
\r
503 \tGenFw -e ${module_type} -o $(EFI_FILE) $(EFI_FILE)
\r
504 \tcopy /y $(EFI_FILE) $(BIN_DIR)
\r
507 # Individual Object Build Targets
\r
509 ${BEGIN}${object_build_target}
\r
514 # clean all intermediate files
\r
518 \t${remove_directory_command} $(OUTPUT_DIR) > NUL 2>&1
\r
521 # clean all generated files
\r
525 \t${remove_directory_command} $(OUTPUT_DIR) $(DEBUG_DIR) > NUL 2>&1
\r
526 \t${remove_file_command} *.pdb *.idb > NUL 2>&1
\r
529 # clean pre-compiled header files
\r
533 \t${remove_file_command} /f /q $(OUTPUT_DIR)\*.pch > NUL 2>&1
\r
536 # clean all dependent libraries built
\r
540 \t${BEGIN}cd $(BUILD_DIR)${separator}$(ARCH)${separator}${dependent_library_build_directory}
\r
541 \t$(MAKE) $(MAKE_FLAGS) cleanall
\r
542 \t${END}cd $(MODULE_BUILD_DIR)
\r
546 gPlatformMakefileTemplate = '''
\r
550 # Platform Macro Definition
\r
552 PLATFORM_NAME = ${platform_name}
\r
553 PLATFORM_GUID = ${platform_guid}
\r
554 PLATFORM_VERSION = ${platform_version}
\r
555 PLATFORM_DIR = $(WORKSPACE)${separator}${platform_relative_directory}
\r
556 PLATFORM_OUTPUT_DIR = ${platform_output_directory}
\r
559 # Build Configuration Macro Definition
\r
561 TOOLCHAIN_TAG = ${toolchain_tag}
\r
562 TARGET = ${build_target}
\r
563 MAKE_FLAGS = /nologo
\r
566 # Build Directory Macro Definition
\r
568 BUILD_DIR = ${platform_build_directory}${separator}${build_target}_${toolchain_tag}
\r
569 FV_DIR = ${platform_build_directory}${separator}${build_target}_${toolchain_tag}${separator}FV
\r
574 all: init build_libraries build_modules build_fds
\r
577 # Initialization target: print build information and create necessary directories
\r
580 \t-@echo Building ... $(PLATFORM_NAME)-$(PLATFORM_VERSION) [${build_architecture_list}]
\r
581 \t-${create_directory_command} $(FV_DIR) > NUL 2>&1
\r
582 \t${BEGIN}-${create_directory_command} $(BUILD_DIR)${separator}${architecture} > NUL 2>&1
\r
584 \t${BEGIN}-${create_directory_command} $(BUILD_DIR)${separator}${directory_to_be_created} > NUL 2>&1
\r
587 # library build target
\r
589 libraries: init build_libraries
\r
592 # module build target
\r
594 modules: init build_libraries build_modules
\r
597 # Flash Device Image Target
\r
599 fds: init build_libraries build_modules build_fds
\r
602 # Build all libraries:
\r
605 \t${BEGIN}cd $(WORKSPACE)${separator}${library_build_directory}
\r
606 \t$(MAKE) $(MAKE_FLAGS) lbuild
\r
607 \t${END}cd $(BUILD_DIR)
\r
610 # Build all modules:
\r
613 \t${BEGIN}cd $(WORKSPACE)${separator}${module_build_directory}
\r
614 \t$(MAKE) $(MAKE_FLAGS) pbuild
\r
615 \t${END}cd $(BUILD_DIR)
\r
618 # Build Flash Device Image
\r
621 \t-@echo Generating flash image, if any ...
\r
622 ${BEGIN}\tGenFds -f ${fdf_file} -o $(BUILD_DIR) -p ${active_platform}${END}
\r
625 # run command for emulator platform only
\r
628 \tcd $(BUILD_DIR)${separator}IA32
\r
633 # Clean intermediate files
\r
636 \t${BEGIN}cd $(WORKSPACE)${separator}${library_build_directory}
\r
637 \t$(MAKE) $(MAKE_FLAGS) clean
\r
638 \t${END}${BEGIN}cd $(WORKSPACE)${separator}${module_build_directory}
\r
639 \t$(MAKE) $(MAKE_FLAGS) clean
\r
640 \t${END}cd $(BUILD_DIR)
\r
643 # Clean all generated files except to makefile
\r
646 \t${remove_directory_command} $(FV_DIR) > NUL 2>&1
\r
647 \t${BEGIN}${remove_directory_command} $(BUILD_DIR)${separator}${architecture} > NUL 2>&1
\r
651 # Clean all library files
\r
654 \t${BEGIN}cd $(WORKSPACE)${separator}${library_build_directory}
\r
655 \t$(MAKE) $(MAKE_FLAGS) cleanall
\r
656 \t${END}cd $(BUILD_DIR)
\r
660 class Makefile(object):
\r
661 def __init__(self, info, opt):
\r
662 if isinstance(info, ModuleBuildInfo):
\r
663 self.ModuleInfo = info
\r
664 self.PlatformInfo = info.PlatformInfo
\r
665 self.PackageInfo = info.PackageInfo
\r
666 self.ModuleBuild = True
\r
668 self.BuildType = "mbuild"
\r
669 if self.ModuleInfo.IsLibrary:
\r
670 self.BuildType = "lbuild"
\r
672 self.BuildFileList = []
\r
673 self.ObjectFileList = []
\r
674 self.ObjectBuildTargetList = []
\r
676 self.FileDependency = []
\r
677 self.LibraryBuildCommandList = []
\r
678 self.LibraryFileList = []
\r
679 self.LibraryMakefileList = []
\r
680 self.LibraryBuildDirectoryList = []
\r
682 elif type(info) == type({}): # and isinstance(info, PlatformBuildInfo):
\r
683 self.PlatformInfo = info
\r
684 self.ModuleBuild = False
\r
685 self.ModuleBuildCommandList = []
\r
686 self.ModuleMakefileList = []
\r
687 self.ModuleBuildDirectoryList = self.GetModuleBuildDirectoryList()
\r
688 self.LibraryBuildDirectoryList = self.GetLibraryBuildDirectoryList()
\r
690 raise AutoGenError(msg="Non-buildable item:%s" % str(info))
\r
693 self.BuildWithPch = opt["ENABLE_PCH"]
\r
694 self.BuildWithLocalLib = opt["ENABLE_LOCAL_LIB"]
\r
695 self.IntermediateDirectoryList = []
\r
697 def PrepareDirectory(self):
\r
698 if self.ModuleBuild:
\r
699 CreateDirectory(path.join(self.ModuleInfo.WorkspaceDir, self.PlatformInfo.BuildDir))
\r
700 CreateDirectory(path.join(self.ModuleInfo.WorkspaceDir, self.ModuleInfo.BuildDir))
\r
701 CreateDirectory(path.join(self.ModuleInfo.WorkspaceDir, self.ModuleInfo.DebugDir))
\r
703 def Generate(self, file=None, makeType=gMakeType):
\r
704 if self.ModuleBuild:
\r
705 return self.GenerateModuleMakefile(file, makeType)
\r
707 return self.GeneratePlatformMakefile(file, makeType)
\r
709 def GeneratePlatformMakefile(self, file=None, makeType=gMakeType):
\r
710 separator = gDirectorySeparator[makeType]
\r
712 activePlatform = self.PlatformInfo.values()[0].Platform
\r
713 platformInfo = self.PlatformInfo.values()[0]
\r
715 outputDir = platformInfo.OutputDir
\r
716 if os.path.isabs(outputDir):
\r
717 self.PlatformBuildDirectory = outputDir
\r
719 self.PlatformBuildDirectory = "$(WORKSPACE)" + separator + outputDir
\r
721 makefileName = gMakefileName[makeType]
\r
722 makefileTemplateDict = {
\r
723 "makefile_header" : MakefileHeader % makefileName,
\r
724 "platform_name" : platformInfo.Name,
\r
725 "platform_guid" : platformInfo.Guid,
\r
726 "platform_version" : platformInfo.Version,
\r
727 "platform_relative_directory": platformInfo.SourceDir,
\r
728 "platform_output_directory" : platformInfo.OutputDir,
\r
729 "platform_build_directory" : self.PlatformBuildDirectory,
\r
731 "toolchain_tag" : platformInfo.ToolChain,
\r
732 "build_target" : platformInfo.BuildTarget,
\r
733 "build_architecture_list" : " ".join(self.PlatformInfo.keys()),
\r
734 "architecture" : self.PlatformInfo.keys(),
\r
735 "separator" : separator,
\r
736 "create_directory_command" : gCreateDirectoryCommand[makeType],
\r
737 "remove_directory_command" : gRemoveDirectoryCommand[makeType],
\r
738 "remove_file_command" : gRemoveFileCommand[makeType],
\r
739 "directory_to_be_created" : self.IntermediateDirectoryList,
\r
740 "library_build_directory" : self.LibraryBuildDirectoryList,
\r
741 "module_build_directory" : self.ModuleBuildDirectoryList,
\r
742 "fdf_file" : platformInfo.FdfFileList,
\r
743 "active_platform" : activePlatform.DescFilePath
\r
746 self.PrepareDirectory()
\r
748 autoGenMakefile = AutoGenString()
\r
749 autoGenMakefile.Append(gPlatformMakefileTemplate, makefileTemplateDict)
\r
750 #print autoGenMakefile.String
\r
754 filePath = path.join(platformInfo.WorkspaceDir, platformInfo.MakefileDir, makefileName)
\r
758 self.SaveFile(filePath, str(autoGenMakefile))
\r
761 def GenerateModuleMakefile(self, file=None, makeType=gMakeType):
\r
762 if makeType in self.ModuleInfo.CustomMakefile and self.ModuleInfo.CustomMakefile[makeType] != "":
\r
763 return self.GenerateCustomBuildMakefile(file, makeType)
\r
765 separator = gDirectorySeparator[makeType]
\r
767 if os.path.isabs(self.PlatformInfo.OutputDir):
\r
768 self.PlatformBuildDirectory = self.PlatformInfo.OutputDir
\r
770 self.PlatformBuildDirectory = "$(WORKSPACE)" + separator + self.PlatformInfo.OutputDir
\r
772 self.ProcessSourceFileList(makeType)
\r
773 self.ProcessDependentLibrary(makeType)
\r
775 entryPoint = "_ModuleEntryPoint"
\r
776 if self.ModuleInfo.Arch == "EBC":
\r
777 entryPoint = "EfiStart"
\r
779 defaultToolFlag = self.PlatformInfo.DefaultToolOption.values()
\r
780 if self.ModuleInfo.ModuleType == "USER_DEFINED":
\r
781 defaultToolFlag = ["" for p in defaultToolFlag]
\r
783 makefileName = gMakefileName[makeType]
\r
784 makefileTemplateDict = {
\r
785 "makefile_header" : MakefileHeader % makefileName,
\r
786 "platform_name" : self.PlatformInfo.Name,
\r
787 "platform_guid" : self.PlatformInfo.Guid,
\r
788 "platform_version" : self.PlatformInfo.Version,
\r
789 "platform_relative_directory": self.PlatformInfo.SourceDir,
\r
790 "platform_output_directory" : self.PlatformInfo.OutputDir,
\r
792 "package_name" : self.PackageInfo.Name,
\r
793 "package_guid" : self.PackageInfo.Guid,
\r
794 "package_version" : self.PackageInfo.Version,
\r
795 "package_relative_directory": self.PackageInfo.SourceDir,
\r
797 "module_name" : self.ModuleInfo.Name,
\r
798 "module_guid" : self.ModuleInfo.Guid,
\r
799 "module_version" : self.ModuleInfo.Version,
\r
800 "module_type" : self.ModuleInfo.ModuleType,
\r
801 "module_file_base_name" : self.ModuleInfo.FileBase,
\r
802 "module_relative_directory" : self.ModuleInfo.SourceDir,
\r
804 "architecture" : self.ModuleInfo.Arch,
\r
805 "toolchain_tag" : self.ModuleInfo.ToolChain,
\r
806 "build_target" : self.ModuleInfo.BuildTarget,
\r
808 "platform_build_directory" : self.PlatformBuildDirectory,
\r
810 "separator" : separator,
\r
811 "default_tool_flags" : defaultToolFlag,
\r
812 "platform_tool_flags" : [self.PlatformInfo.BuildOption[tool] for tool in self.PlatformInfo.ToolPath],
\r
813 "module_tool_flags" : [self.ModuleInfo.BuildOption[tool] for tool in self.PlatformInfo.ToolPath],
\r
815 "tool_code" : self.PlatformInfo.ToolPath.keys(),
\r
816 "tool_path" : self.PlatformInfo.ToolPath.values(),
\r
818 "module_entry_point" : entryPoint,
\r
819 "source_file" : self.BuildFileList,
\r
820 #"auto_generated_file" : self.AutoGenBuildFileList,
\r
821 "include_path_prefix" : "-I",
\r
822 "include_path" : self.ModuleInfo.IncludePathList,
\r
823 "object_file" : self.ObjectFileList,
\r
824 "library_file" : self.LibraryFileList,
\r
825 "common_dependency_file" : self.CommonFileDependency,
\r
826 "create_directory_command" : gCreateDirectoryCommand[makeType],
\r
827 "remove_directory_command" : gRemoveDirectoryCommand[makeType],
\r
828 "remove_file_command" : gRemoveFileCommand[makeType],
\r
829 "directory_to_be_created" : self.IntermediateDirectoryList,
\r
830 "dependent_library_build_directory" : self.LibraryBuildDirectoryList,
\r
831 #"dependent_library_makefile" : [path.join(bdir, makefileName) for bdir in self.LibraryBuildDirectoryList],
\r
832 "object_build_target" : self.ObjectBuildTargetList,
\r
833 "build_type" : self.BuildType,
\r
836 self.PrepareDirectory()
\r
838 autoGenMakefile = AutoGenString()
\r
839 autoGenMakefile.Append(gModuleMakefileTemplate, makefileTemplateDict)
\r
840 #print autoGenMakefile.String
\r
844 filePath = path.join(self.ModuleInfo.WorkspaceDir, self.ModuleInfo.MakefileDir, makefileName)
\r
848 self.SaveFile(filePath, str(autoGenMakefile))
\r
851 def GenerateCustomBuildMakefile(self, file=None, makeType=gMakeType):
\r
852 separator = gDirectorySeparator[makeType]
\r
854 if os.path.isabs(self.PlatformInfo.OutputDir):
\r
855 self.PlatformBuildDirectory = self.PlatformInfo.OutputDir
\r
857 self.PlatformBuildDirectory = "$(WORKSPACE)" + separator + self.PlatformInfo.OutputDir
\r
859 customMakefile = open(os.path.join(self.ModuleInfo.WorkspaceDir, self .ModuleInfo.CustomMakefile[makeType]), 'r').read()
\r
861 makefileName = gMakefileName[makeType]
\r
862 makefileTemplateDict = {
\r
863 "makefile_header" : MakefileHeader % makefileName,
\r
864 "platform_name" : self.PlatformInfo.Name,
\r
865 "platform_guid" : self.PlatformInfo.Guid,
\r
866 "platform_version" : self.PlatformInfo.Version,
\r
867 "platform_relative_directory": self.PlatformInfo.SourceDir,
\r
868 "platform_output_directory" : self.PlatformInfo.OutputDir,
\r
870 "package_name" : self.PackageInfo.Name,
\r
871 "package_guid" : self.PackageInfo.Guid,
\r
872 "package_version" : self.PackageInfo.Version,
\r
873 "package_relative_directory": self.PackageInfo.SourceDir,
\r
875 "module_name" : self.ModuleInfo.Name,
\r
876 "module_guid" : self.ModuleInfo.Guid,
\r
877 "module_version" : self.ModuleInfo.Version,
\r
878 "module_type" : self.ModuleInfo.ModuleType,
\r
879 "module_file_base_name" : self.ModuleInfo.FileBase,
\r
880 "module_relative_directory" : self.ModuleInfo.SourceDir,
\r
882 "architecture" : self.ModuleInfo.Arch,
\r
883 "toolchain_tag" : self.ModuleInfo.ToolChain,
\r
884 "build_target" : self.ModuleInfo.BuildTarget,
\r
886 "platform_build_directory" : self.PlatformBuildDirectory,
\r
888 "separator" : separator,
\r
889 "default_tool_flags" : self.PlatformInfo.DefaultToolOption.values(),
\r
890 "platform_tool_flags" : self.PlatformInfo.BuildOption.values(),
\r
891 "module_tool_flags" : self.ModuleInfo.BuildOption.values(),
\r
893 "tool_code" : self.PlatformInfo.ToolPath.keys(),
\r
894 "tool_path" : self.PlatformInfo.ToolPath.values(),
\r
896 "create_directory_command" : "-@mkdir",
\r
897 "directory_to_be_created" : self.IntermediateDirectoryList,
\r
898 "dependent_library_build_directory" : self.LibraryBuildDirectoryList,
\r
899 "custom_makefile_content" : customMakefile
\r
902 self.PrepareDirectory()
\r
904 autoGenMakefile = AutoGenString()
\r
905 autoGenMakefile.Append(gCustomMakefileTemplate, makefileTemplateDict)
\r
906 #print autoGenMakefile.String
\r
910 filePath = path.join(self.ModuleInfo.WorkspaceDir, self.ModuleInfo.MakefileDir, makefileName)
\r
914 self.SaveFile(filePath, str(autoGenMakefile))
\r
917 def SaveFile(self, file, content):
\r
918 # print "######",file,"######"
\r
920 if os.path.exists(file):
\r
921 f = open(file, 'r')
\r
922 if content == f.read():
\r
926 f = open(file, "w")
\r
930 def ProcessSourceFileList(self, makeType=gMakeType):
\r
931 rule = self.PlatformInfo.BuildRule
\r
932 separator = gDirectorySeparator[makeType]
\r
934 self.BuildFileList = []
\r
935 self.ObjectFileList = []
\r
936 self.ObjectBuildTargetList = []
\r
937 self.AutoGenBuildFileList = []
\r
938 self.IntermediateDirectoryList = []
\r
940 fileBuildTemplatetList = []
\r
941 forceIncludedFile = []
\r
943 for f in self.ModuleInfo.AutoGenFileList:
\r
944 fpath = path.join(self.ModuleInfo.DebugDir, f)
\r
945 fdir = path.dirname(f)
\r
948 fname = path.basename(f)
\r
949 fbase, fext = path.splitext(fname)
\r
951 ftype = rule.FileTypeMapping[fext]
\r
952 if ftype == "C-Header":
\r
953 forceIncludedFile.append(fpath)
\r
954 if ftype not in rule.Makefile[makeType]:
\r
957 self.BuildFileList.append(fpath)
\r
958 self.ObjectFileList.append(fdir + separator + fbase + ".obj")
\r
960 fileBuildTemplatetList.append({
\r
961 "string" : rule.Makefile[makeType][ftype],
\r
972 fileList = self.ModuleInfo.SourceFileList
\r
974 fpath = os.path.join(self.ModuleInfo.SourceDir, f)
\r
975 fname = path.basename(f)
\r
976 fbase, fext = path.splitext(fname)
\r
977 fdir = path.dirname(f)
\r
981 elif fdir not in self.IntermediateDirectoryList:
\r
982 self.IntermediateDirectoryList.append(fdir)
\r
984 ftype = rule.FileTypeMapping[fext]
\r
985 if ftype not in rule.Makefile[makeType]:
\r
988 self.BuildFileList.append(fpath)
\r
989 self.ObjectFileList.append(fdir + separator + fbase + ".obj")
\r
991 fileBuildTemplatetList.append({
\r
992 "string" : rule.Makefile[makeType][ftype],
\r
1000 "sep" : separator,
\r
1004 # Search dependency file list for each source file
\r
1006 self.FileDependency = self.GetFileDependency(forceIncludedFile)
\r
1007 depSet = set(self.FileDependency.values()[0])
\r
1008 for dep in self.FileDependency.values():
\r
1009 depSet &= set(dep)
\r
1011 # Extract comman files list in the dependency files
\r
1013 self.CommonFileDependency = forceIncludedFile + list(depSet)
\r
1014 for f in self.FileDependency:
\r
1015 newDepSet = set(self.FileDependency[f])
\r
1016 newDepSet -= depSet
\r
1017 self.FileDependency[f] = list(newDepSet)
\r
1022 for template in fileBuildTemplatetList:
\r
1023 makefileString = AutoGenString()
\r
1024 template["fdep"] = self.FileDependency[template["fpath"]]
\r
1025 makefileString.Append(template["string"], template)
\r
1026 self.ObjectBuildTargetList.append(makefileString)
\r
1028 def ProcessDependentLibrary(self, makeType=gMakeType):
\r
1029 for libm in self.ModuleInfo.DependentLibraryList:
\r
1031 libp = path.dirname(libf)
\r
1032 base = path.basename(libf).split(".")[0]
\r
1033 self.LibraryBuildDirectoryList.append(libp + gDirectorySeparator[makeType] + base)
\r
1034 self.LibraryFileList.append(libm.BaseName + ".lib")
\r
1036 def GetPlatformBuildDirectory(self):
\r
1037 if os.path.isabs(self.PlatformInfo.OutputDir):
\r
1038 return self.PlatformInfo.OutputDir
\r
1040 return os.path.join("$(WORKSPACE)", self.PlatformInfo.OutputDir)
\r
1042 def GetFileDependency(self, forceList):
\r
1044 os.chdir(self.ModuleInfo.WorkspaceDir)
\r
1046 for f in self.BuildFileList:
\r
1047 dependency[f] = self.GetDependencyList(f, forceList, self.ModuleInfo.IncludePathList)
\r
1051 def GetDependencyList(self, file, forceList, searchPathList):
\r
1053 os.chdir(self.ModuleInfo.WorkspaceDir)
\r
1055 EdkLogger.debug(EdkLogger.DEBUG_3, "Get dependency files for %s" % file)
\r
1056 EdkLogger.debug(EdkLogger.DEBUG_2, "Including %s" % " ".join(forceList))
\r
1057 fileStack = [file] + forceList
\r
1058 dependencyList = []
\r
1059 while len(fileStack) > 0:
\r
1060 EdkLogger.debug(EdkLogger.DEBUG_2, "Stack %s" % "\n\t".join(fileStack))
\r
1061 f = fileStack.pop()
\r
1063 currentFileDependencyList = []
\r
1064 if f in gDependencyDatabase:
\r
1065 currentFileDependencyList = gDependencyDatabase[f]
\r
1066 for dep in currentFileDependencyList:
\r
1067 if dep not in fileStack and dep not in dependencyList:
\r
1068 fileStack.append(dep)
\r
1071 fileContent = fd.read()
\r
1073 if len(fileContent) == 0:
\r
1076 if fileContent[0] == 0xff or fileContent[0] == 0xfe:
\r
1077 fileContent = unicode(fileContent, "utf-16")
\r
1078 includedFileList = gIncludePattern.findall(fileContent)
\r
1080 currentFilePath = os.path.dirname(f)
\r
1081 for inc in includedFileList:
\r
1082 inc = os.path.normpath(inc)
\r
1083 for searchPath in [currentFilePath] + searchPathList:
\r
1084 filePath = os.path.join(searchPath, inc)
\r
1085 if not os.path.exists(filePath) or filePath in currentFileDependencyList:
\r
1087 currentFileDependencyList.append(filePath)
\r
1088 if filePath not in fileStack and filePath not in dependencyList:
\r
1089 fileStack.append(filePath)
\r
1092 #raise AutoGenError("%s included by %s was not found in any given path:\n\t%s" % (inc, f, "\n\t".join(searchPathList)))
\r
1093 EdkLogger.verbose("%s included by %s was not found in any given path:\n\t%s" % (inc, f, "\n\t".join(searchPathList)))
\r
1094 gDependencyDatabase[f] = currentFileDependencyList
\r
1095 dependencyList.extend(currentFileDependencyList)
\r
1096 dependencyList = list(set(dependencyList)) # remove duplicate ones
\r
1099 dependencyList.append(file)
\r
1100 return dependencyList
\r
1102 def GetModuleBuildDirectoryList(self):
\r
1104 for arch in self.PlatformInfo:
\r
1105 for ma in self.PlatformInfo[arch].ModuleAutoGenList:
\r
1106 dirList.append(ma.BuildInfo.BuildDir)
\r
1109 def GetLibraryBuildDirectoryList(self):
\r
1111 for arch in self.PlatformInfo:
\r
1112 for la in self.PlatformInfo[arch].LibraryAutoGenList:
\r
1113 dirList.append(la.BuildInfo.BuildDir)
\r
1116 # This acts like the main() function for the script, unless it is 'import'ed into another
\r
1118 if __name__ == '__main__':
\r
1119 print "Running Operating System =", sys.platform
\r
1120 ewb = WorkspaceBuild()
\r
1121 #print ewb.Build.keys()
\r
1123 myArch = ewb.Build["IA32"].Arch
\r
1126 myBuild = ewb.Build["IA32"]
\r
1129 apf = ewb.TargetTxt.TargetTxtDictionary["ACTIVE_PLATFORM"][0]
\r
1130 myPlatform = myBuild.PlatformDatabase[os.path.normpath(apf)]
\r
1132 for mf in myBuild.ModuleDatabase:
\r
1133 #mf = "MdePkg\\Library\\BaseLib\\BaseLib.inf"
\r
1134 #if mf in myPlatform.Modules and mf in myBuild.ModuleDatabase:
\r
1137 myModule = myBuild.ModuleDatabase[mf]
\r
1139 myPackage = FindModuleOwner(myModule.DescFilePath, myBuild.PackageDatabase)
\r
1141 myToolchain = ewb.TargetTxt.TargetTxtDictionary["TOOL_CHAIN_TAG"][0]
\r
1142 #print myToolchain
\r
1144 myBuildTarget = ewb.TargetTxt.TargetTxtDictionary["TARGET"][0]
\r
1145 #print myBuildTarget
\r
1148 "ENABLE_PCH" : False,
\r
1149 "ENABLE_LOCAL_LIB" : True,
\r
1152 myMakefile = Makefile(myModule, myPackage, myPlatform, myWorkspace, myToolchain, myBuildTarget,
\r
1153 myArch, myBuildOption, "nmake")
\r
1155 myMakefile.NewGenerate()
\r