2014-01-27 06:23:15 +01:00
|
|
|
## @file
|
|
|
|
# Create makefile for MS nmake and GNU make
|
|
|
|
#
|
2017-05-12 06:12:23 +02:00
|
|
|
# Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.<BR>
|
2014-01-27 06:23:15 +01:00
|
|
|
# This program and the accompanying materials
|
|
|
|
# are licensed and made available under the terms and conditions of the BSD License
|
|
|
|
# which accompanies this distribution. The full text of the license may be found at
|
|
|
|
# http://opensource.org/licenses/bsd-license.php
|
|
|
|
#
|
|
|
|
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
|
|
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
|
|
#
|
|
|
|
|
|
|
|
## Import Modules
|
|
|
|
#
|
2014-08-15 05:06:48 +02:00
|
|
|
import Common.LongFilePathOs as os
|
2014-01-27 06:23:15 +01:00
|
|
|
import sys
|
|
|
|
import string
|
|
|
|
import re
|
|
|
|
import os.path as path
|
2014-08-15 05:06:48 +02:00
|
|
|
from Common.LongFilePathSupport import OpenLongFilePath as open
|
2015-10-08 11:27:14 +02:00
|
|
|
from Common.MultipleWorkspace import MultipleWorkspace as mws
|
2014-01-27 06:23:15 +01:00
|
|
|
from Common.BuildToolError import *
|
|
|
|
from Common.Misc import *
|
|
|
|
from Common.String import *
|
|
|
|
from BuildEngine import *
|
|
|
|
import Common.GlobalData as GlobalData
|
|
|
|
|
|
|
|
## Regular expression for finding header file inclusions
|
2015-12-01 05:22:16 +01:00
|
|
|
gIncludePattern = re.compile(r"^[ \t]*#?[ \t]*include(?:[ \t]*(?:\\(?:\r\n|\r|\n))*[ \t]*)*(?:\(?[\"<]?[ \t]*)([-\w.\\/() \t]+)(?:[ \t]*[\">]?\)?)", re.MULTILINE | re.UNICODE | re.IGNORECASE)
|
2014-01-27 06:23:15 +01:00
|
|
|
|
|
|
|
## Regular expression for matching macro used in header file inclusion
|
|
|
|
gMacroPattern = re.compile("([_A-Z][_A-Z0-9]*)[ \t]*\((.+)\)", re.UNICODE)
|
|
|
|
|
|
|
|
gIsFileMap = {}
|
|
|
|
|
|
|
|
## pattern for include style in Edk.x code
|
|
|
|
gProtocolDefinition = "Protocol/%(HeaderKey)s/%(HeaderKey)s.h"
|
|
|
|
gGuidDefinition = "Guid/%(HeaderKey)s/%(HeaderKey)s.h"
|
|
|
|
gArchProtocolDefinition = "ArchProtocol/%(HeaderKey)s/%(HeaderKey)s.h"
|
|
|
|
gPpiDefinition = "Ppi/%(HeaderKey)s/%(HeaderKey)s.h"
|
|
|
|
gIncludeMacroConversion = {
|
|
|
|
"EFI_PROTOCOL_DEFINITION" : gProtocolDefinition,
|
|
|
|
"EFI_GUID_DEFINITION" : gGuidDefinition,
|
|
|
|
"EFI_ARCH_PROTOCOL_DEFINITION" : gArchProtocolDefinition,
|
|
|
|
"EFI_PROTOCOL_PRODUCER" : gProtocolDefinition,
|
|
|
|
"EFI_PROTOCOL_CONSUMER" : gProtocolDefinition,
|
|
|
|
"EFI_PROTOCOL_DEPENDENCY" : gProtocolDefinition,
|
|
|
|
"EFI_ARCH_PROTOCOL_PRODUCER" : gArchProtocolDefinition,
|
|
|
|
"EFI_ARCH_PROTOCOL_CONSUMER" : gArchProtocolDefinition,
|
|
|
|
"EFI_ARCH_PROTOCOL_DEPENDENCY" : gArchProtocolDefinition,
|
|
|
|
"EFI_PPI_DEFINITION" : gPpiDefinition,
|
|
|
|
"EFI_PPI_PRODUCER" : gPpiDefinition,
|
|
|
|
"EFI_PPI_CONSUMER" : gPpiDefinition,
|
|
|
|
"EFI_PPI_DEPENDENCY" : gPpiDefinition,
|
|
|
|
}
|
|
|
|
|
|
|
|
## default makefile type
|
|
|
|
gMakeType = ""
|
|
|
|
if sys.platform == "win32":
|
|
|
|
gMakeType = "nmake"
|
|
|
|
else:
|
|
|
|
gMakeType = "gmake"
|
|
|
|
|
|
|
|
|
|
|
|
## BuildFile class
|
|
|
|
#
|
|
|
|
# This base class encapsules build file and its generation. It uses template to generate
|
|
|
|
# the content of build file. The content of build file will be got from AutoGen objects.
|
|
|
|
#
|
|
|
|
class BuildFile(object):
|
|
|
|
## template used to generate the build file (i.e. makefile if using make)
|
|
|
|
_TEMPLATE_ = TemplateString('')
|
|
|
|
|
|
|
|
_DEFAULT_FILE_NAME_ = "Makefile"
|
|
|
|
|
|
|
|
## default file name for each type of build file
|
|
|
|
_FILE_NAME_ = {
|
|
|
|
"nmake" : "Makefile",
|
|
|
|
"gmake" : "GNUmakefile"
|
|
|
|
}
|
|
|
|
|
|
|
|
## Fixed header string for makefile
|
|
|
|
_MAKEFILE_HEADER = '''#
|
|
|
|
# DO NOT EDIT
|
|
|
|
# This file is auto-generated by build utility
|
|
|
|
#
|
|
|
|
# Module Name:
|
|
|
|
#
|
|
|
|
# %s
|
|
|
|
#
|
|
|
|
# Abstract:
|
|
|
|
#
|
|
|
|
# Auto-generated makefile for building modules, libraries or platform
|
|
|
|
#
|
|
|
|
'''
|
|
|
|
|
|
|
|
## Header string for each type of build file
|
|
|
|
_FILE_HEADER_ = {
|
|
|
|
"nmake" : _MAKEFILE_HEADER % _FILE_NAME_["nmake"],
|
|
|
|
"gmake" : _MAKEFILE_HEADER % _FILE_NAME_["gmake"]
|
|
|
|
}
|
|
|
|
|
|
|
|
## shell commands which can be used in build file in the form of macro
|
|
|
|
# $(CP) copy file command
|
|
|
|
# $(MV) move file command
|
|
|
|
# $(RM) remove file command
|
|
|
|
# $(MD) create dir command
|
|
|
|
# $(RD) remove dir command
|
|
|
|
#
|
|
|
|
_SHELL_CMD_ = {
|
|
|
|
"nmake" : {
|
|
|
|
"CP" : "copy /y",
|
|
|
|
"MV" : "move /y",
|
|
|
|
"RM" : "del /f /q",
|
|
|
|
"MD" : "mkdir",
|
|
|
|
"RD" : "rmdir /s /q",
|
|
|
|
},
|
|
|
|
|
|
|
|
"gmake" : {
|
|
|
|
"CP" : "cp -f",
|
|
|
|
"MV" : "mv -f",
|
|
|
|
"RM" : "rm -f",
|
|
|
|
"MD" : "mkdir -p",
|
|
|
|
"RD" : "rm -r -f",
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
## directory separator
|
|
|
|
_SEP_ = {
|
|
|
|
"nmake" : "\\",
|
|
|
|
"gmake" : "/"
|
|
|
|
}
|
|
|
|
|
|
|
|
## directory creation template
|
|
|
|
_MD_TEMPLATE_ = {
|
|
|
|
"nmake" : 'if not exist %(dir)s $(MD) %(dir)s',
|
|
|
|
"gmake" : "$(MD) %(dir)s"
|
|
|
|
}
|
|
|
|
|
|
|
|
## directory removal template
|
|
|
|
_RD_TEMPLATE_ = {
|
|
|
|
"nmake" : 'if exist %(dir)s $(RD) %(dir)s',
|
|
|
|
"gmake" : "$(RD) %(dir)s"
|
|
|
|
}
|
2017-11-22 08:42:25 +01:00
|
|
|
## cp if exist
|
|
|
|
_CP_TEMPLATE_ = {
|
|
|
|
"nmake" : 'if exist %(Src)s $(CP) %(Src)s %(Dst)s',
|
|
|
|
"gmake" : "test -f %(Src)s && $(CP) %(Src)s %(Dst)s"
|
|
|
|
}
|
2014-01-27 06:23:15 +01:00
|
|
|
|
|
|
|
_CD_TEMPLATE_ = {
|
|
|
|
"nmake" : 'if exist %(dir)s cd %(dir)s',
|
|
|
|
"gmake" : "test -e %(dir)s && cd %(dir)s"
|
|
|
|
}
|
|
|
|
|
|
|
|
_MAKE_TEMPLATE_ = {
|
|
|
|
"nmake" : 'if exist %(file)s "$(MAKE)" $(MAKE_FLAGS) -f %(file)s',
|
|
|
|
"gmake" : 'test -e %(file)s && "$(MAKE)" $(MAKE_FLAGS) -f %(file)s'
|
|
|
|
}
|
|
|
|
|
|
|
|
_INCLUDE_CMD_ = {
|
|
|
|
"nmake" : '!INCLUDE',
|
|
|
|
"gmake" : "include"
|
|
|
|
}
|
|
|
|
|
|
|
|
_INC_FLAG_ = {"MSFT" : "/I", "GCC" : "-I", "INTEL" : "-I", "RVCT" : "-I"}
|
|
|
|
|
|
|
|
## Constructor of BuildFile
|
|
|
|
#
|
|
|
|
# @param AutoGenObject Object of AutoGen class
|
|
|
|
#
|
|
|
|
def __init__(self, AutoGenObject):
|
|
|
|
self._AutoGenObject = AutoGenObject
|
|
|
|
self._FileType = gMakeType
|
|
|
|
|
|
|
|
## Create build file
|
|
|
|
#
|
|
|
|
# @param FileType Type of build file. Only nmake and gmake are supported now.
|
|
|
|
#
|
|
|
|
# @retval TRUE The build file is created or re-created successfully
|
|
|
|
# @retval FALSE The build file exists and is the same as the one to be generated
|
|
|
|
#
|
|
|
|
def Generate(self, FileType=gMakeType):
|
|
|
|
if FileType not in self._FILE_NAME_:
|
|
|
|
EdkLogger.error("build", PARAMETER_INVALID, "Invalid build type [%s]" % FileType,
|
|
|
|
ExtraData="[%s]" % str(self._AutoGenObject))
|
|
|
|
self._FileType = FileType
|
|
|
|
FileContent = self._TEMPLATE_.Replace(self._TemplateDict)
|
|
|
|
FileName = self._FILE_NAME_[FileType]
|
|
|
|
return SaveFileOnChange(os.path.join(self._AutoGenObject.MakeFileDir, FileName), FileContent, False)
|
|
|
|
|
|
|
|
## Return a list of directory creation command string
|
|
|
|
#
|
|
|
|
# @param DirList The list of directory to be created
|
|
|
|
#
|
|
|
|
# @retval list The directory creation command list
|
|
|
|
#
|
|
|
|
def GetCreateDirectoryCommand(self, DirList):
|
|
|
|
return [self._MD_TEMPLATE_[self._FileType] % {'dir':Dir} for Dir in DirList]
|
|
|
|
|
|
|
|
## Return a list of directory removal command string
|
|
|
|
#
|
|
|
|
# @param DirList The list of directory to be removed
|
|
|
|
#
|
|
|
|
# @retval list The directory removal command list
|
|
|
|
#
|
|
|
|
def GetRemoveDirectoryCommand(self, DirList):
|
|
|
|
return [self._RD_TEMPLATE_[self._FileType] % {'dir':Dir} for Dir in DirList]
|
|
|
|
|
|
|
|
def PlaceMacro(self, Path, MacroDefinitions={}):
|
|
|
|
if Path.startswith("$("):
|
|
|
|
return Path
|
|
|
|
else:
|
|
|
|
PathLength = len(Path)
|
|
|
|
for MacroName in MacroDefinitions:
|
|
|
|
MacroValue = MacroDefinitions[MacroName]
|
|
|
|
MacroValueLength = len(MacroValue)
|
2017-11-22 08:42:25 +01:00
|
|
|
if MacroValueLength == 0:
|
|
|
|
continue
|
2014-01-27 06:23:15 +01:00
|
|
|
if MacroValueLength <= PathLength and Path.startswith(MacroValue):
|
|
|
|
Path = "$(%s)%s" % (MacroName, Path[MacroValueLength:])
|
|
|
|
break
|
|
|
|
return Path
|
|
|
|
|
|
|
|
## ModuleMakefile class
|
|
|
|
#
|
|
|
|
# This class encapsules makefie and its generation for module. It uses template to generate
|
|
|
|
# the content of makefile. The content of makefile will be got from ModuleAutoGen object.
|
|
|
|
#
|
|
|
|
class ModuleMakefile(BuildFile):
|
|
|
|
## template used to generate the makefile for module
|
|
|
|
_TEMPLATE_ = TemplateString('''\
|
|
|
|
${makefile_header}
|
|
|
|
|
|
|
|
#
|
|
|
|
# Platform Macro Definition
|
|
|
|
#
|
|
|
|
PLATFORM_NAME = ${platform_name}
|
|
|
|
PLATFORM_GUID = ${platform_guid}
|
|
|
|
PLATFORM_VERSION = ${platform_version}
|
|
|
|
PLATFORM_RELATIVE_DIR = ${platform_relative_directory}
|
2016-04-13 07:09:17 +02:00
|
|
|
PLATFORM_DIR = ${platform_dir}
|
2014-01-27 06:23:15 +01:00
|
|
|
PLATFORM_OUTPUT_DIR = ${platform_output_directory}
|
|
|
|
|
|
|
|
#
|
|
|
|
# Module Macro Definition
|
|
|
|
#
|
|
|
|
MODULE_NAME = ${module_name}
|
|
|
|
MODULE_GUID = ${module_guid}
|
2015-06-10 09:50:59 +02:00
|
|
|
MODULE_NAME_GUID = ${module_name_guid}
|
2014-01-27 06:23:15 +01:00
|
|
|
MODULE_VERSION = ${module_version}
|
|
|
|
MODULE_TYPE = ${module_type}
|
|
|
|
MODULE_FILE = ${module_file}
|
|
|
|
MODULE_FILE_BASE_NAME = ${module_file_base_name}
|
|
|
|
BASE_NAME = $(MODULE_NAME)
|
|
|
|
MODULE_RELATIVE_DIR = ${module_relative_directory}
|
2014-08-28 15:53:34 +02:00
|
|
|
PACKAGE_RELATIVE_DIR = ${package_relative_directory}
|
2016-02-21 01:46:58 +01:00
|
|
|
MODULE_DIR = ${module_dir}
|
2017-11-22 08:42:25 +01:00
|
|
|
FFS_OUTPUT_DIR = ${ffs_output_directory}
|
2014-01-27 06:23:15 +01:00
|
|
|
|
|
|
|
MODULE_ENTRY_POINT = ${module_entry_point}
|
|
|
|
ARCH_ENTRY_POINT = ${arch_entry_point}
|
|
|
|
IMAGE_ENTRY_POINT = ${image_entry_point}
|
|
|
|
|
|
|
|
${BEGIN}${module_extra_defines}
|
|
|
|
${END}
|
|
|
|
#
|
|
|
|
# Build Configuration Macro Definition
|
|
|
|
#
|
|
|
|
ARCH = ${architecture}
|
|
|
|
TOOLCHAIN = ${toolchain_tag}
|
|
|
|
TOOLCHAIN_TAG = ${toolchain_tag}
|
|
|
|
TARGET = ${build_target}
|
|
|
|
|
|
|
|
#
|
|
|
|
# Build Directory Macro Definition
|
|
|
|
#
|
|
|
|
# PLATFORM_BUILD_DIR = ${platform_build_directory}
|
|
|
|
BUILD_DIR = ${platform_build_directory}
|
|
|
|
BIN_DIR = $(BUILD_DIR)${separator}${architecture}
|
|
|
|
LIB_DIR = $(BIN_DIR)
|
|
|
|
MODULE_BUILD_DIR = ${module_build_directory}
|
|
|
|
OUTPUT_DIR = ${module_output_directory}
|
|
|
|
DEBUG_DIR = ${module_debug_directory}
|
|
|
|
DEST_DIR_OUTPUT = $(OUTPUT_DIR)
|
|
|
|
DEST_DIR_DEBUG = $(DEBUG_DIR)
|
|
|
|
|
|
|
|
#
|
|
|
|
# Shell Command Macro
|
|
|
|
#
|
|
|
|
${BEGIN}${shell_command_code} = ${shell_command}
|
|
|
|
${END}
|
|
|
|
|
|
|
|
#
|
|
|
|
# Tools definitions specific to this module
|
|
|
|
#
|
|
|
|
${BEGIN}${module_tool_definitions}
|
|
|
|
${END}
|
|
|
|
MAKE_FILE = ${makefile_path}
|
|
|
|
|
|
|
|
#
|
|
|
|
# Build Macro
|
|
|
|
#
|
|
|
|
${BEGIN}${file_macro}
|
|
|
|
${END}
|
|
|
|
|
|
|
|
COMMON_DEPS = ${BEGIN}${common_dependency_file} \\
|
|
|
|
${END}
|
|
|
|
|
|
|
|
#
|
|
|
|
# Overridable Target Macro Definitions
|
|
|
|
#
|
|
|
|
FORCE_REBUILD = force_build
|
|
|
|
INIT_TARGET = init
|
|
|
|
PCH_TARGET =
|
|
|
|
BC_TARGET = ${BEGIN}${backward_compatible_target} ${END}
|
|
|
|
CODA_TARGET = ${BEGIN}${remaining_build_target} \\
|
|
|
|
${END}
|
|
|
|
|
|
|
|
#
|
|
|
|
# Default target, which will build dependent libraries in addition to source files
|
|
|
|
#
|
|
|
|
|
|
|
|
all: mbuild
|
|
|
|
|
|
|
|
|
|
|
|
#
|
|
|
|
# Target used when called from platform makefile, which will bypass the build of dependent libraries
|
|
|
|
#
|
|
|
|
|
|
|
|
pbuild: $(INIT_TARGET) $(BC_TARGET) $(PCH_TARGET) $(CODA_TARGET)
|
|
|
|
|
|
|
|
#
|
|
|
|
# ModuleTarget
|
|
|
|
#
|
|
|
|
|
|
|
|
mbuild: $(INIT_TARGET) $(BC_TARGET) gen_libs $(PCH_TARGET) $(CODA_TARGET)
|
|
|
|
|
|
|
|
#
|
|
|
|
# Build Target used in multi-thread build mode, which will bypass the init and gen_libs targets
|
|
|
|
#
|
|
|
|
|
|
|
|
tbuild: $(BC_TARGET) $(PCH_TARGET) $(CODA_TARGET)
|
|
|
|
|
|
|
|
#
|
|
|
|
# Phony target which is used to force executing commands for a target
|
|
|
|
#
|
|
|
|
force_build:
|
|
|
|
\t-@
|
|
|
|
|
|
|
|
#
|
|
|
|
# Target to update the FD
|
|
|
|
#
|
|
|
|
|
|
|
|
fds: mbuild gen_fds
|
|
|
|
|
|
|
|
#
|
|
|
|
# Initialization target: print build information and create necessary directories
|
|
|
|
#
|
|
|
|
init: info dirs
|
|
|
|
|
|
|
|
info:
|
|
|
|
\t-@echo Building ... $(MODULE_DIR)${separator}$(MODULE_FILE) [$(ARCH)]
|
|
|
|
|
|
|
|
dirs:
|
|
|
|
${BEGIN}\t-@${create_directory_command}\n${END}
|
|
|
|
|
|
|
|
strdefs:
|
|
|
|
\t-@$(CP) $(DEBUG_DIR)${separator}AutoGen.h $(DEBUG_DIR)${separator}$(MODULE_NAME)StrDefs.h
|
|
|
|
|
|
|
|
#
|
|
|
|
# GenLibsTarget
|
|
|
|
#
|
|
|
|
gen_libs:
|
|
|
|
\t${BEGIN}@"$(MAKE)" $(MAKE_FLAGS) -f ${dependent_library_build_directory}${separator}${makefile_name}
|
|
|
|
\t${END}@cd $(MODULE_BUILD_DIR)
|
|
|
|
|
|
|
|
#
|
|
|
|
# Build Flash Device Image
|
|
|
|
#
|
|
|
|
gen_fds:
|
|
|
|
\t@"$(MAKE)" $(MAKE_FLAGS) -f $(BUILD_DIR)${separator}${makefile_name} fds
|
|
|
|
\t@cd $(MODULE_BUILD_DIR)
|
|
|
|
|
|
|
|
#
|
|
|
|
# Individual Object Build Targets
|
|
|
|
#
|
|
|
|
${BEGIN}${file_build_target}
|
|
|
|
${END}
|
|
|
|
|
|
|
|
#
|
|
|
|
# clean all intermediate files
|
|
|
|
#
|
|
|
|
clean:
|
|
|
|
\t${BEGIN}${clean_command}
|
2017-04-11 04:47:53 +02:00
|
|
|
\t${END}\t$(RM) AutoGenTimeStamp
|
2014-01-27 06:23:15 +01:00
|
|
|
|
|
|
|
#
|
|
|
|
# clean all generated files
|
|
|
|
#
|
|
|
|
cleanall:
|
|
|
|
${BEGIN}\t${cleanall_command}
|
|
|
|
${END}\t$(RM) *.pdb *.idb > NUL 2>&1
|
|
|
|
\t$(RM) $(BIN_DIR)${separator}$(MODULE_NAME).efi
|
2017-04-11 04:47:53 +02:00
|
|
|
\t$(RM) AutoGenTimeStamp
|
2014-01-27 06:23:15 +01:00
|
|
|
|
|
|
|
#
|
|
|
|
# clean all dependent libraries built
|
|
|
|
#
|
|
|
|
cleanlib:
|
|
|
|
\t${BEGIN}-@${library_build_command} cleanall
|
|
|
|
\t${END}@cd $(MODULE_BUILD_DIR)\n\n''')
|
|
|
|
|
|
|
|
_FILE_MACRO_TEMPLATE = TemplateString("${macro_name} = ${BEGIN} \\\n ${source_file}${END}\n")
|
|
|
|
_BUILD_TARGET_TEMPLATE = TemplateString("${BEGIN}${target} : ${deps}\n${END}\t${cmd}\n")
|
|
|
|
|
|
|
|
## Constructor of ModuleMakefile
|
|
|
|
#
|
|
|
|
# @param ModuleAutoGen Object of ModuleAutoGen class
|
|
|
|
#
|
|
|
|
def __init__(self, ModuleAutoGen):
|
|
|
|
BuildFile.__init__(self, ModuleAutoGen)
|
|
|
|
self.PlatformInfo = self._AutoGenObject.PlatformInfo
|
|
|
|
|
|
|
|
self.ResultFileList = []
|
|
|
|
self.IntermediateDirectoryList = ["$(DEBUG_DIR)", "$(OUTPUT_DIR)"]
|
|
|
|
|
|
|
|
self.SourceFileDatabase = {} # {file type : file path}
|
|
|
|
self.DestFileDatabase = {} # {file type : file path}
|
|
|
|
self.FileBuildTargetList = [] # [(src, target string)]
|
|
|
|
self.BuildTargetList = [] # [target string]
|
|
|
|
self.PendingBuildTargetList = [] # [FileBuildRule objects]
|
|
|
|
self.CommonFileDependency = []
|
|
|
|
self.FileListMacros = {}
|
|
|
|
self.ListFileMacros = {}
|
|
|
|
|
|
|
|
self.FileCache = {}
|
|
|
|
self.FileDependency = []
|
|
|
|
self.LibraryBuildCommandList = []
|
|
|
|
self.LibraryFileList = []
|
|
|
|
self.LibraryMakefileList = []
|
|
|
|
self.LibraryBuildDirectoryList = []
|
|
|
|
self.SystemLibraryList = []
|
|
|
|
self.Macros = sdict()
|
|
|
|
self.Macros["OUTPUT_DIR" ] = self._AutoGenObject.Macros["OUTPUT_DIR"]
|
|
|
|
self.Macros["DEBUG_DIR" ] = self._AutoGenObject.Macros["DEBUG_DIR"]
|
|
|
|
self.Macros["MODULE_BUILD_DIR"] = self._AutoGenObject.Macros["MODULE_BUILD_DIR"]
|
|
|
|
self.Macros["BIN_DIR" ] = self._AutoGenObject.Macros["BIN_DIR"]
|
|
|
|
self.Macros["BUILD_DIR" ] = self._AutoGenObject.Macros["BUILD_DIR"]
|
|
|
|
self.Macros["WORKSPACE" ] = self._AutoGenObject.Macros["WORKSPACE"]
|
2017-11-22 08:42:25 +01:00
|
|
|
self.Macros["FFS_OUTPUT_DIR" ] = self._AutoGenObject.Macros["FFS_OUTPUT_DIR"]
|
|
|
|
self.GenFfsList = ModuleAutoGen.GenFfsList
|
|
|
|
self.MacroList = ['FFS_OUTPUT_DIR', 'MODULE_GUID', 'OUTPUT_DIR']
|
|
|
|
self.FfsOutputFileList = []
|
2014-01-27 06:23:15 +01:00
|
|
|
|
|
|
|
# Compose a dict object containing information used to do replacement in template
|
|
|
|
def _CreateTemplateDict(self):
|
|
|
|
if self._FileType not in self._SEP_:
|
|
|
|
EdkLogger.error("build", PARAMETER_INVALID, "Invalid Makefile type [%s]" % self._FileType,
|
|
|
|
ExtraData="[%s]" % str(self._AutoGenObject))
|
|
|
|
Separator = self._SEP_[self._FileType]
|
|
|
|
|
|
|
|
# break build if no source files and binary files are found
|
|
|
|
if len(self._AutoGenObject.SourceFileList) == 0 and len(self._AutoGenObject.BinaryFileList) == 0:
|
|
|
|
EdkLogger.error("build", AUTOGEN_ERROR, "No files to be built in module [%s, %s, %s]"
|
|
|
|
% (self._AutoGenObject.BuildTarget, self._AutoGenObject.ToolChain, self._AutoGenObject.Arch),
|
|
|
|
ExtraData="[%s]" % str(self._AutoGenObject))
|
|
|
|
|
|
|
|
# convert dependent libraries to build command
|
|
|
|
self.ProcessDependentLibrary()
|
|
|
|
if len(self._AutoGenObject.Module.ModuleEntryPointList) > 0:
|
|
|
|
ModuleEntryPoint = self._AutoGenObject.Module.ModuleEntryPointList[0]
|
|
|
|
else:
|
|
|
|
ModuleEntryPoint = "_ModuleEntryPoint"
|
|
|
|
|
|
|
|
# Intel EBC compiler enforces EfiMain
|
|
|
|
if self._AutoGenObject.AutoGenVersion < 0x00010005 and self._AutoGenObject.Arch == "EBC":
|
|
|
|
ArchEntryPoint = "EfiMain"
|
|
|
|
else:
|
|
|
|
ArchEntryPoint = ModuleEntryPoint
|
|
|
|
|
|
|
|
if self._AutoGenObject.Arch == "EBC":
|
|
|
|
# EBC compiler always use "EfiStart" as entry point. Only applies to EdkII modules
|
|
|
|
ImageEntryPoint = "EfiStart"
|
|
|
|
elif self._AutoGenObject.AutoGenVersion < 0x00010005:
|
|
|
|
# Edk modules use entry point specified in INF file
|
|
|
|
ImageEntryPoint = ModuleEntryPoint
|
|
|
|
else:
|
|
|
|
# EdkII modules always use "_ModuleEntryPoint" as entry point
|
|
|
|
ImageEntryPoint = "_ModuleEntryPoint"
|
|
|
|
|
2016-03-23 07:54:36 +01:00
|
|
|
for k, v in self._AutoGenObject.Module.Defines.iteritems():
|
|
|
|
if k not in self._AutoGenObject.Macros.keys():
|
|
|
|
self._AutoGenObject.Macros[k] = v
|
|
|
|
|
|
|
|
if 'MODULE_ENTRY_POINT' not in self._AutoGenObject.Macros.keys():
|
|
|
|
self._AutoGenObject.Macros['MODULE_ENTRY_POINT'] = ModuleEntryPoint
|
|
|
|
if 'ARCH_ENTRY_POINT' not in self._AutoGenObject.Macros.keys():
|
|
|
|
self._AutoGenObject.Macros['ARCH_ENTRY_POINT'] = ArchEntryPoint
|
|
|
|
if 'IMAGE_ENTRY_POINT' not in self._AutoGenObject.Macros.keys():
|
|
|
|
self._AutoGenObject.Macros['IMAGE_ENTRY_POINT'] = ImageEntryPoint
|
|
|
|
|
2016-06-03 04:01:53 +02:00
|
|
|
PCI_COMPRESS_Flag = False
|
|
|
|
for k, v in self._AutoGenObject.Module.Defines.iteritems():
|
|
|
|
if 'PCI_COMPRESS' == k and 'TRUE' == v:
|
|
|
|
PCI_COMPRESS_Flag = True
|
|
|
|
|
2014-01-27 06:23:15 +01:00
|
|
|
# tools definitions
|
|
|
|
ToolsDef = []
|
|
|
|
IncPrefix = self._INC_FLAG_[self._AutoGenObject.ToolChainFamily]
|
|
|
|
for Tool in self._AutoGenObject.BuildOption:
|
|
|
|
for Attr in self._AutoGenObject.BuildOption[Tool]:
|
|
|
|
Value = self._AutoGenObject.BuildOption[Tool][Attr]
|
|
|
|
if Attr == "FAMILY":
|
|
|
|
continue
|
|
|
|
elif Attr == "PATH":
|
|
|
|
ToolsDef.append("%s = %s" % (Tool, Value))
|
|
|
|
else:
|
|
|
|
# Don't generate MAKE_FLAGS in makefile. It's put in environment variable.
|
|
|
|
if Tool == "MAKE":
|
|
|
|
continue
|
|
|
|
# Remove duplicated include path, if any
|
|
|
|
if Attr == "FLAGS":
|
|
|
|
Value = RemoveDupOption(Value, IncPrefix, self._AutoGenObject.IncludePathList)
|
2016-06-03 04:01:53 +02:00
|
|
|
if Tool == "OPTROM" and PCI_COMPRESS_Flag:
|
|
|
|
ValueList = Value.split()
|
|
|
|
if ValueList:
|
|
|
|
for i, v in enumerate(ValueList):
|
|
|
|
if '-e' == v:
|
|
|
|
ValueList[i] = '-ec'
|
|
|
|
Value = ' '.join(ValueList)
|
|
|
|
|
2014-01-27 06:23:15 +01:00
|
|
|
ToolsDef.append("%s_%s = %s" % (Tool, Attr, Value))
|
|
|
|
ToolsDef.append("")
|
|
|
|
|
2016-03-16 04:06:44 +01:00
|
|
|
# generate the Response file and Response flag
|
|
|
|
RespDict = self.CommandExceedLimit()
|
|
|
|
RespFileList = os.path.join(self._AutoGenObject.OutputDir, 'respfilelist.txt')
|
|
|
|
if RespDict:
|
|
|
|
RespFileListContent = ''
|
|
|
|
for Resp in RespDict.keys():
|
|
|
|
RespFile = os.path.join(self._AutoGenObject.OutputDir, str(Resp).lower() + '.txt')
|
2016-03-23 07:54:36 +01:00
|
|
|
StrList = RespDict[Resp].split(' ')
|
|
|
|
UnexpandMacro = []
|
|
|
|
NewStr = []
|
|
|
|
for Str in StrList:
|
|
|
|
if '$' in Str:
|
|
|
|
UnexpandMacro.append(Str)
|
|
|
|
else:
|
|
|
|
NewStr.append(Str)
|
|
|
|
UnexpandMacroStr = ' '.join(UnexpandMacro)
|
|
|
|
NewRespStr = ' '.join(NewStr)
|
|
|
|
SaveFileOnChange(RespFile, NewRespStr, False)
|
|
|
|
ToolsDef.append("%s = %s" % (Resp, UnexpandMacroStr + ' @' + RespFile))
|
2016-03-16 04:06:44 +01:00
|
|
|
RespFileListContent += '@' + RespFile + os.linesep
|
2016-03-23 07:54:36 +01:00
|
|
|
RespFileListContent += NewRespStr + os.linesep
|
2016-03-16 04:06:44 +01:00
|
|
|
SaveFileOnChange(RespFileList, RespFileListContent, False)
|
|
|
|
else:
|
|
|
|
if os.path.exists(RespFileList):
|
|
|
|
os.remove(RespFileList)
|
|
|
|
|
2014-01-27 06:23:15 +01:00
|
|
|
# convert source files and binary files to build targets
|
|
|
|
self.ResultFileList = [str(T.Target) for T in self._AutoGenObject.CodaTargetList]
|
2015-12-01 05:22:16 +01:00
|
|
|
if len(self.ResultFileList) == 0 and len(self._AutoGenObject.SourceFileList) <> 0:
|
2014-01-27 06:23:15 +01:00
|
|
|
EdkLogger.error("build", AUTOGEN_ERROR, "Nothing to build",
|
|
|
|
ExtraData="[%s]" % str(self._AutoGenObject))
|
|
|
|
|
|
|
|
self.ProcessBuildTargetList()
|
2017-11-22 08:42:25 +01:00
|
|
|
self.ParserGenerateFfsCmd()
|
2014-01-27 06:23:15 +01:00
|
|
|
|
|
|
|
# Generate macros used to represent input files
|
|
|
|
FileMacroList = [] # macro name = file list
|
|
|
|
for FileListMacro in self.FileListMacros:
|
|
|
|
FileMacro = self._FILE_MACRO_TEMPLATE.Replace(
|
|
|
|
{
|
|
|
|
"macro_name" : FileListMacro,
|
|
|
|
"source_file" : self.FileListMacros[FileListMacro]
|
|
|
|
}
|
|
|
|
)
|
|
|
|
FileMacroList.append(FileMacro)
|
|
|
|
|
|
|
|
# INC_LIST is special
|
|
|
|
FileMacro = ""
|
|
|
|
IncludePathList = []
|
|
|
|
for P in self._AutoGenObject.IncludePathList:
|
2015-12-01 05:22:16 +01:00
|
|
|
IncludePathList.append(IncPrefix + self.PlaceMacro(P, self.Macros))
|
2014-01-27 06:23:15 +01:00
|
|
|
if FileBuildRule.INC_LIST_MACRO in self.ListFileMacros:
|
2015-12-01 05:22:16 +01:00
|
|
|
self.ListFileMacros[FileBuildRule.INC_LIST_MACRO].append(IncPrefix + P)
|
2014-01-27 06:23:15 +01:00
|
|
|
FileMacro += self._FILE_MACRO_TEMPLATE.Replace(
|
|
|
|
{
|
|
|
|
"macro_name" : "INC",
|
|
|
|
"source_file" : IncludePathList
|
|
|
|
}
|
|
|
|
)
|
|
|
|
FileMacroList.append(FileMacro)
|
|
|
|
|
|
|
|
# Generate macros used to represent files containing list of input files
|
|
|
|
for ListFileMacro in self.ListFileMacros:
|
2015-12-01 05:22:16 +01:00
|
|
|
ListFileName = os.path.join(self._AutoGenObject.OutputDir, "%s.lst" % ListFileMacro.lower()[:len(ListFileMacro) - 5])
|
2014-01-27 06:23:15 +01:00
|
|
|
FileMacroList.append("%s = %s" % (ListFileMacro, ListFileName))
|
|
|
|
SaveFileOnChange(
|
|
|
|
ListFileName,
|
|
|
|
"\n".join(self.ListFileMacros[ListFileMacro]),
|
|
|
|
False
|
|
|
|
)
|
|
|
|
|
|
|
|
# Edk modules need <BaseName>StrDefs.h for string ID
|
|
|
|
#if self._AutoGenObject.AutoGenVersion < 0x00010005 and len(self._AutoGenObject.UnicodeFileList) > 0:
|
|
|
|
# BcTargetList = ['strdefs']
|
|
|
|
#else:
|
|
|
|
# BcTargetList = []
|
|
|
|
BcTargetList = []
|
|
|
|
|
|
|
|
MakefileName = self._FILE_NAME_[self._FileType]
|
|
|
|
LibraryMakeCommandList = []
|
|
|
|
for D in self.LibraryBuildDirectoryList:
|
|
|
|
Command = self._MAKE_TEMPLATE_[self._FileType] % {"file":os.path.join(D, MakefileName)}
|
|
|
|
LibraryMakeCommandList.append(Command)
|
|
|
|
|
2014-08-28 15:53:34 +02:00
|
|
|
package_rel_dir = self._AutoGenObject.SourceDir
|
2015-06-16 06:23:00 +02:00
|
|
|
current_dir = self.Macros["WORKSPACE"]
|
|
|
|
found = False
|
|
|
|
while not found and os.sep in package_rel_dir:
|
|
|
|
index = package_rel_dir.index(os.sep)
|
2015-10-08 11:27:14 +02:00
|
|
|
current_dir = mws.join(current_dir, package_rel_dir[:index])
|
2016-06-03 03:29:06 +02:00
|
|
|
if os.path.exists(current_dir):
|
|
|
|
for fl in os.listdir(current_dir):
|
|
|
|
if fl.endswith('.dec'):
|
|
|
|
found = True
|
|
|
|
break
|
2015-06-16 06:23:00 +02:00
|
|
|
package_rel_dir = package_rel_dir[index + 1:]
|
2014-08-28 15:53:34 +02:00
|
|
|
|
2014-01-27 06:23:15 +01:00
|
|
|
MakefileTemplateDict = {
|
|
|
|
"makefile_header" : self._FILE_HEADER_[self._FileType],
|
|
|
|
"makefile_path" : os.path.join("$(MODULE_BUILD_DIR)", MakefileName),
|
|
|
|
"makefile_name" : MakefileName,
|
|
|
|
"platform_name" : self.PlatformInfo.Name,
|
|
|
|
"platform_guid" : self.PlatformInfo.Guid,
|
|
|
|
"platform_version" : self.PlatformInfo.Version,
|
|
|
|
"platform_relative_directory": self.PlatformInfo.SourceDir,
|
|
|
|
"platform_output_directory" : self.PlatformInfo.OutputDir,
|
2017-11-22 08:42:25 +01:00
|
|
|
"ffs_output_directory" : self._AutoGenObject.Macros["FFS_OUTPUT_DIR"],
|
2016-04-13 07:09:17 +02:00
|
|
|
"platform_dir" : self._AutoGenObject.Macros["PLATFORM_DIR"],
|
2014-01-27 06:23:15 +01:00
|
|
|
|
|
|
|
"module_name" : self._AutoGenObject.Name,
|
|
|
|
"module_guid" : self._AutoGenObject.Guid,
|
2015-06-10 09:50:59 +02:00
|
|
|
"module_name_guid" : self._AutoGenObject._GetUniqueBaseName(),
|
2014-01-27 06:23:15 +01:00
|
|
|
"module_version" : self._AutoGenObject.Version,
|
|
|
|
"module_type" : self._AutoGenObject.ModuleType,
|
|
|
|
"module_file" : self._AutoGenObject.MetaFile.Name,
|
|
|
|
"module_file_base_name" : self._AutoGenObject.MetaFile.BaseName,
|
|
|
|
"module_relative_directory" : self._AutoGenObject.SourceDir,
|
2016-02-21 01:46:58 +01:00
|
|
|
"module_dir" : mws.join (self.Macros["WORKSPACE"], self._AutoGenObject.SourceDir),
|
2014-08-28 15:53:34 +02:00
|
|
|
"package_relative_directory": package_rel_dir,
|
|
|
|
"module_extra_defines" : ["%s = %s" % (k, v) for k, v in self._AutoGenObject.Module.Defines.iteritems()],
|
2014-01-27 06:23:15 +01:00
|
|
|
|
|
|
|
"architecture" : self._AutoGenObject.Arch,
|
|
|
|
"toolchain_tag" : self._AutoGenObject.ToolChain,
|
|
|
|
"build_target" : self._AutoGenObject.BuildTarget,
|
|
|
|
|
|
|
|
"platform_build_directory" : self.PlatformInfo.BuildDir,
|
|
|
|
"module_build_directory" : self._AutoGenObject.BuildDir,
|
|
|
|
"module_output_directory" : self._AutoGenObject.OutputDir,
|
|
|
|
"module_debug_directory" : self._AutoGenObject.DebugDir,
|
|
|
|
|
|
|
|
"separator" : Separator,
|
|
|
|
"module_tool_definitions" : ToolsDef,
|
|
|
|
|
|
|
|
"shell_command_code" : self._SHELL_CMD_[self._FileType].keys(),
|
|
|
|
"shell_command" : self._SHELL_CMD_[self._FileType].values(),
|
|
|
|
|
|
|
|
"module_entry_point" : ModuleEntryPoint,
|
|
|
|
"image_entry_point" : ImageEntryPoint,
|
|
|
|
"arch_entry_point" : ArchEntryPoint,
|
|
|
|
"remaining_build_target" : self.ResultFileList,
|
|
|
|
"common_dependency_file" : self.CommonFileDependency,
|
|
|
|
"create_directory_command" : self.GetCreateDirectoryCommand(self.IntermediateDirectoryList),
|
|
|
|
"clean_command" : self.GetRemoveDirectoryCommand(["$(OUTPUT_DIR)"]),
|
|
|
|
"cleanall_command" : self.GetRemoveDirectoryCommand(["$(DEBUG_DIR)", "$(OUTPUT_DIR)"]),
|
|
|
|
"dependent_library_build_directory" : self.LibraryBuildDirectoryList,
|
|
|
|
"library_build_command" : LibraryMakeCommandList,
|
|
|
|
"file_macro" : FileMacroList,
|
|
|
|
"file_build_target" : self.BuildTargetList,
|
|
|
|
"backward_compatible_target": BcTargetList,
|
|
|
|
}
|
|
|
|
|
|
|
|
return MakefileTemplateDict
|
|
|
|
|
2017-11-22 08:42:25 +01:00
|
|
|
def ParserGenerateFfsCmd(self):
|
|
|
|
#Add Ffs cmd to self.BuildTargetList
|
|
|
|
OutputFile = ''
|
|
|
|
DepsFileList = []
|
|
|
|
|
|
|
|
for Cmd in self.GenFfsList:
|
|
|
|
if Cmd[2]:
|
|
|
|
for CopyCmd in Cmd[2]:
|
|
|
|
Src, Dst = CopyCmd
|
|
|
|
Src = self.ReplaceMacro(Src)
|
|
|
|
Dst = self.ReplaceMacro(Dst)
|
|
|
|
if Dst not in self.ResultFileList:
|
|
|
|
self.ResultFileList.append('%s' % Dst)
|
|
|
|
if '%s :' %(Dst) not in self.BuildTargetList:
|
|
|
|
self.BuildTargetList.append("%s :" %(Dst))
|
|
|
|
self.BuildTargetList.append('\t' + self._CP_TEMPLATE_[self._FileType] %{'Src': Src, 'Dst': Dst})
|
|
|
|
|
|
|
|
FfsCmdList = Cmd[0]
|
|
|
|
for index, Str in enumerate(FfsCmdList):
|
|
|
|
if '-o' == Str:
|
|
|
|
OutputFile = FfsCmdList[index + 1]
|
|
|
|
if '-i' == Str:
|
|
|
|
if DepsFileList == []:
|
|
|
|
DepsFileList = [FfsCmdList[index + 1]]
|
|
|
|
else:
|
|
|
|
DepsFileList.append(FfsCmdList[index + 1])
|
|
|
|
DepsFileString = ' '.join(DepsFileList).strip()
|
|
|
|
if DepsFileString == '':
|
|
|
|
continue
|
|
|
|
OutputFile = self.ReplaceMacro(OutputFile)
|
|
|
|
self.ResultFileList.append('%s' % OutputFile)
|
|
|
|
DepsFileString = self.ReplaceMacro(DepsFileString)
|
|
|
|
self.BuildTargetList.append('%s : %s' % (OutputFile, DepsFileString))
|
|
|
|
CmdString = ' '.join(FfsCmdList).strip()
|
|
|
|
CmdString = self.ReplaceMacro(CmdString)
|
|
|
|
self.BuildTargetList.append('\t%s' % CmdString)
|
|
|
|
|
|
|
|
self.ParseSecCmd(DepsFileList, Cmd[1])
|
|
|
|
for SecOutputFile, SecDepsFile, SecCmd in self.FfsOutputFileList :
|
|
|
|
self.BuildTargetList.append('%s : %s' % (self.ReplaceMacro(SecOutputFile), self.ReplaceMacro(SecDepsFile)))
|
|
|
|
self.BuildTargetList.append('\t%s' % self.ReplaceMacro(SecCmd))
|
|
|
|
self.FfsOutputFileList = []
|
|
|
|
|
|
|
|
def ParseSecCmd(self, OutputFileList, CmdTuple):
|
|
|
|
for OutputFile in OutputFileList:
|
|
|
|
for SecCmdStr in CmdTuple:
|
|
|
|
SecDepsFileList = []
|
|
|
|
SecCmdList = SecCmdStr.split()
|
|
|
|
CmdName = SecCmdList[0]
|
|
|
|
for index, CmdItem in enumerate(SecCmdList):
|
|
|
|
if '-o' == CmdItem and OutputFile == SecCmdList[index + 1]:
|
|
|
|
index = index + 1
|
|
|
|
while index + 1 < len(SecCmdList):
|
|
|
|
if not SecCmdList[index+1].startswith('-'):
|
|
|
|
SecDepsFileList.append(SecCmdList[index + 1])
|
|
|
|
index = index + 1
|
|
|
|
if CmdName == 'Trim':
|
|
|
|
SecDepsFileList.append(os.path.join('$(DEBUG_DIR)', os.path.basename(OutputFile).replace('offset', 'efi')))
|
|
|
|
if OutputFile.endswith('.ui') or OutputFile.endswith('.ver'):
|
|
|
|
SecDepsFileList.append(os.path.join('$(MODULE_DIR)','$(MODULE_FILE)'))
|
|
|
|
self.FfsOutputFileList.append((OutputFile, ' '.join(SecDepsFileList), SecCmdStr))
|
|
|
|
if len(SecDepsFileList) > 0:
|
|
|
|
self.ParseSecCmd(SecDepsFileList, CmdTuple)
|
|
|
|
break
|
|
|
|
else:
|
|
|
|
continue
|
|
|
|
|
|
|
|
def ReplaceMacro(self, str):
|
|
|
|
for Macro in self.MacroList:
|
|
|
|
if self._AutoGenObject.Macros[Macro] and self._AutoGenObject.Macros[Macro] in str:
|
|
|
|
str = str.replace(self._AutoGenObject.Macros[Macro], '$(' + Macro + ')')
|
|
|
|
return str
|
|
|
|
|
2016-03-16 04:06:44 +01:00
|
|
|
def CommandExceedLimit(self):
|
|
|
|
FlagDict = {
|
|
|
|
'CC' : { 'Macro' : '$(CC_FLAGS)', 'Value' : False},
|
|
|
|
'PP' : { 'Macro' : '$(PP_FLAGS)', 'Value' : False},
|
|
|
|
'APP' : { 'Macro' : '$(APP_FLAGS)', 'Value' : False},
|
|
|
|
'ASLPP' : { 'Macro' : '$(ASLPP_FLAGS)', 'Value' : False},
|
|
|
|
'VFRPP' : { 'Macro' : '$(VFRPP_FLAGS)', 'Value' : False},
|
|
|
|
'ASM' : { 'Macro' : '$(ASM_FLAGS)', 'Value' : False},
|
|
|
|
'ASLCC' : { 'Macro' : '$(ASLCC_FLAGS)', 'Value' : False},
|
|
|
|
}
|
|
|
|
|
|
|
|
RespDict = {}
|
|
|
|
FileTypeList = []
|
|
|
|
IncPrefix = self._INC_FLAG_[self._AutoGenObject.ToolChainFamily]
|
|
|
|
|
|
|
|
# base on the source files to decide the file type
|
|
|
|
for File in self._AutoGenObject.SourceFileList:
|
|
|
|
for type in self._AutoGenObject.FileTypes:
|
|
|
|
if File in self._AutoGenObject.FileTypes[type]:
|
|
|
|
if type not in FileTypeList:
|
|
|
|
FileTypeList.append(type)
|
|
|
|
|
|
|
|
# calculate the command-line length
|
|
|
|
if FileTypeList:
|
|
|
|
for type in FileTypeList:
|
|
|
|
BuildTargets = self._AutoGenObject.BuildRules[type].BuildTargets
|
|
|
|
for Target in BuildTargets:
|
|
|
|
CommandList = BuildTargets[Target].Commands
|
|
|
|
for SingleCommand in CommandList:
|
|
|
|
Tool = ''
|
|
|
|
SingleCommandLength = len(SingleCommand)
|
|
|
|
SingleCommandList = SingleCommand.split()
|
|
|
|
if len(SingleCommandList) > 0:
|
|
|
|
for Flag in FlagDict.keys():
|
|
|
|
if '$('+ Flag +')' in SingleCommandList[0]:
|
|
|
|
Tool = Flag
|
|
|
|
break
|
|
|
|
if Tool:
|
|
|
|
SingleCommandLength += len(self._AutoGenObject._BuildOption[Tool]['PATH'])
|
|
|
|
for item in SingleCommandList[1:]:
|
|
|
|
if FlagDict[Tool]['Macro'] in item:
|
|
|
|
Str = self._AutoGenObject._BuildOption[Tool]['FLAGS']
|
2016-03-23 07:54:36 +01:00
|
|
|
for Option in self._AutoGenObject.BuildOption.keys():
|
|
|
|
for Attr in self._AutoGenObject.BuildOption[Option]:
|
|
|
|
if Str.find(Option + '_' + Attr) != -1:
|
|
|
|
Str = Str.replace('$(' + Option + '_' + Attr + ')', self._AutoGenObject.BuildOption[Option][Attr])
|
2016-03-16 04:06:44 +01:00
|
|
|
while(Str.find('$(') != -1):
|
|
|
|
for macro in self._AutoGenObject.Macros.keys():
|
|
|
|
MacroName = '$('+ macro + ')'
|
|
|
|
if (Str.find(MacroName) != -1):
|
|
|
|
Str = Str.replace(MacroName, self._AutoGenObject.Macros[macro])
|
|
|
|
break
|
|
|
|
else:
|
2016-03-23 07:54:36 +01:00
|
|
|
break
|
2016-03-16 04:06:44 +01:00
|
|
|
SingleCommandLength += len(Str)
|
|
|
|
elif '$(INC)' in item:
|
|
|
|
SingleCommandLength += self._AutoGenObject.IncludePathLength + len(IncPrefix) * len(self._AutoGenObject._IncludePathList)
|
|
|
|
elif item.find('$(') != -1:
|
|
|
|
Str = item
|
|
|
|
for Option in self._AutoGenObject.BuildOption.keys():
|
|
|
|
for Attr in self._AutoGenObject.BuildOption[Option]:
|
|
|
|
if Str.find(Option + '_' + Attr) != -1:
|
|
|
|
Str = Str.replace('$(' + Option + '_' + Attr + ')', self._AutoGenObject.BuildOption[Option][Attr])
|
|
|
|
while(Str.find('$(') != -1):
|
|
|
|
for macro in self._AutoGenObject.Macros.keys():
|
|
|
|
MacroName = '$('+ macro + ')'
|
|
|
|
if (Str.find(MacroName) != -1):
|
|
|
|
Str = Str.replace(MacroName, self._AutoGenObject.Macros[macro])
|
|
|
|
break
|
|
|
|
else:
|
2016-03-23 07:54:36 +01:00
|
|
|
break
|
2016-03-16 04:06:44 +01:00
|
|
|
SingleCommandLength += len(Str)
|
|
|
|
|
|
|
|
if SingleCommandLength > GlobalData.gCommandMaxLength:
|
|
|
|
FlagDict[Tool]['Value'] = True
|
|
|
|
|
|
|
|
# generate the response file content by combine the FLAGS and INC
|
|
|
|
for Flag in FlagDict.keys():
|
|
|
|
if FlagDict[Flag]['Value']:
|
|
|
|
Key = Flag + '_RESP'
|
|
|
|
RespMacro = FlagDict[Flag]['Macro'].replace('FLAGS', 'RESP')
|
|
|
|
Value = self._AutoGenObject.BuildOption[Flag]['FLAGS']
|
|
|
|
for inc in self._AutoGenObject._IncludePathList:
|
|
|
|
Value += ' ' + IncPrefix + inc
|
2016-03-23 07:54:36 +01:00
|
|
|
for Option in self._AutoGenObject.BuildOption.keys():
|
|
|
|
for Attr in self._AutoGenObject.BuildOption[Option]:
|
|
|
|
if Value.find(Option + '_' + Attr) != -1:
|
|
|
|
Value = Value.replace('$(' + Option + '_' + Attr + ')', self._AutoGenObject.BuildOption[Option][Attr])
|
2016-03-16 04:06:44 +01:00
|
|
|
while (Value.find('$(') != -1):
|
|
|
|
for macro in self._AutoGenObject.Macros.keys():
|
|
|
|
MacroName = '$('+ macro + ')'
|
|
|
|
if (Value.find(MacroName) != -1):
|
|
|
|
Value = Value.replace(MacroName, self._AutoGenObject.Macros[macro])
|
|
|
|
break
|
|
|
|
else:
|
2016-03-23 07:54:36 +01:00
|
|
|
break
|
2016-11-03 08:44:17 +01:00
|
|
|
|
|
|
|
if self._AutoGenObject.ToolChainFamily == 'GCC':
|
|
|
|
RespDict[Key] = Value.replace('\\', '/')
|
|
|
|
else:
|
|
|
|
RespDict[Key] = Value
|
2016-03-16 04:06:44 +01:00
|
|
|
for Target in BuildTargets:
|
|
|
|
for i, SingleCommand in enumerate(BuildTargets[Target].Commands):
|
|
|
|
if FlagDict[Flag]['Macro'] in SingleCommand:
|
|
|
|
BuildTargets[Target].Commands[i] = SingleCommand.replace('$(INC)','').replace(FlagDict[Flag]['Macro'], RespMacro)
|
|
|
|
return RespDict
|
|
|
|
|
2014-01-27 06:23:15 +01:00
|
|
|
def ProcessBuildTargetList(self):
|
|
|
|
#
|
|
|
|
# Search dependency file list for each source file
|
|
|
|
#
|
|
|
|
ForceIncludedFile = []
|
|
|
|
for File in self._AutoGenObject.AutoGenFileList:
|
|
|
|
if File.Ext == '.h':
|
|
|
|
ForceIncludedFile.append(File)
|
|
|
|
SourceFileList = []
|
2017-09-15 10:14:17 +02:00
|
|
|
OutPutFileList = []
|
2014-01-27 06:23:15 +01:00
|
|
|
for Target in self._AutoGenObject.IntroTargetList:
|
|
|
|
SourceFileList.extend(Target.Inputs)
|
2017-09-15 10:14:17 +02:00
|
|
|
OutPutFileList.extend(Target.Outputs)
|
|
|
|
|
|
|
|
if OutPutFileList:
|
|
|
|
for Item in OutPutFileList:
|
|
|
|
if Item in SourceFileList:
|
|
|
|
SourceFileList.remove(Item)
|
2014-01-27 06:23:15 +01:00
|
|
|
|
|
|
|
self.FileDependency = self.GetFileDependency(
|
|
|
|
SourceFileList,
|
|
|
|
ForceIncludedFile,
|
|
|
|
self._AutoGenObject.IncludePathList + self._AutoGenObject.BuildOptionIncPathList
|
|
|
|
)
|
|
|
|
DepSet = None
|
|
|
|
for File in self.FileDependency:
|
|
|
|
if not self.FileDependency[File]:
|
|
|
|
self.FileDependency[File] = ['$(FORCE_REBUILD)']
|
|
|
|
continue
|
BaseTools: Skip module AutoGen by comparing timestamp.
[Introduction]
The BaseTool Build.py AutoGen parse INF meta-file and generate
AutoGen.c/AutoGen.h/makefile. When we only change .c .h code, the
AutoGen might be not necessary, but Build.py spend a lot of time on it.
There's a -u flag to skip all module's AutoGen. In my environment, it save
35%~50% of time in rebuild a ROM.
However, if user change one .INF meta-file, then -u flag is not available.
[Idea]
AutoGen can compare meta-file's timestamp and decide if the module's
AutoGen can be skipped. With this, when a module's INF is changed, we
only run this module's AutoGen, we don't need to run other module's.
[Implementation]
In the end of a module's AutoGen, we create a AutoGenTimeStamp.
The file save a file list that related to this module's AutoGen.
In other word, the file list in AutoGenTimeStamp is INPUT files of
module AutoGen, AutoGenTimeStamp file is OUTPUT.
During rebuild, we compare time stamp between INPUT and OUTPUT, and
decide if we can skip it.
Below is the Input/Output of a module's AutoGen.
[Input]
1. All the DSC/DEC/FDF used by the platform.
2. Macro and PCD defined by Build Options such as "build -D AAA=TRUE
--pcd BbbPcd=0".
3. INF file of a module.
4. Source files of a module, list in [Sources] section of INF.
5. All the library link by the module.
6. All the .h files included by the module's sources.
[Output]
AutoGen.c/AutoGen.h/makefile/AutoGenTimeStamp
[Testing]
This patch save my build time. When I make a change without touching
DSC/DEC/FDF, it is absolutely much faster than original rebuild,
35%~50% time saving in my environment
(compare to original tool rebuild time).
If I change any DSC/DEC/FDF, there's no performance improve, because it
can't skip any module's AutoGen.
Please note that if your environment will generate DSC/FDF during prebuild,
it will not skip any AutoGen because of DSC timestamp is changed. This will
require prebuild script not to update metafile when content is not changed.
2017-02-24 08:26:19 +01:00
|
|
|
|
|
|
|
self._AutoGenObject.AutoGenDepSet |= set(self.FileDependency[File])
|
|
|
|
|
2014-01-27 06:23:15 +01:00
|
|
|
# skip non-C files
|
|
|
|
if File.Ext not in [".c", ".C"] or File.Name == "AutoGen.c":
|
|
|
|
continue
|
|
|
|
elif DepSet == None:
|
|
|
|
DepSet = set(self.FileDependency[File])
|
|
|
|
else:
|
|
|
|
DepSet &= set(self.FileDependency[File])
|
|
|
|
# in case nothing in SourceFileList
|
|
|
|
if DepSet == None:
|
|
|
|
DepSet = set()
|
|
|
|
#
|
|
|
|
# Extract common files list in the dependency files
|
|
|
|
#
|
|
|
|
for File in DepSet:
|
|
|
|
self.CommonFileDependency.append(self.PlaceMacro(File.Path, self.Macros))
|
|
|
|
|
|
|
|
for File in self.FileDependency:
|
|
|
|
# skip non-C files
|
|
|
|
if File.Ext not in [".c", ".C"] or File.Name == "AutoGen.c":
|
|
|
|
continue
|
|
|
|
NewDepSet = set(self.FileDependency[File])
|
|
|
|
NewDepSet -= DepSet
|
|
|
|
self.FileDependency[File] = ["$(COMMON_DEPS)"] + list(NewDepSet)
|
|
|
|
|
|
|
|
# Convert target description object to target string in makefile
|
|
|
|
for Type in self._AutoGenObject.Targets:
|
|
|
|
for T in self._AutoGenObject.Targets[Type]:
|
|
|
|
# Generate related macros if needed
|
|
|
|
if T.GenFileListMacro and T.FileListMacro not in self.FileListMacros:
|
|
|
|
self.FileListMacros[T.FileListMacro] = []
|
|
|
|
if T.GenListFile and T.ListFileMacro not in self.ListFileMacros:
|
|
|
|
self.ListFileMacros[T.ListFileMacro] = []
|
|
|
|
if T.GenIncListFile and T.IncListFileMacro not in self.ListFileMacros:
|
|
|
|
self.ListFileMacros[T.IncListFileMacro] = []
|
|
|
|
|
|
|
|
Deps = []
|
|
|
|
# Add force-dependencies
|
|
|
|
for Dep in T.Dependencies:
|
|
|
|
Deps.append(self.PlaceMacro(str(Dep), self.Macros))
|
|
|
|
# Add inclusion-dependencies
|
|
|
|
if len(T.Inputs) == 1 and T.Inputs[0] in self.FileDependency:
|
|
|
|
for F in self.FileDependency[T.Inputs[0]]:
|
|
|
|
Deps.append(self.PlaceMacro(str(F), self.Macros))
|
|
|
|
# Add source-dependencies
|
|
|
|
for F in T.Inputs:
|
|
|
|
NewFile = self.PlaceMacro(str(F), self.Macros)
|
|
|
|
# In order to use file list macro as dependency
|
|
|
|
if T.GenListFile:
|
2014-11-18 03:38:20 +01:00
|
|
|
# gnu tools need forward slash path separater, even on Windows
|
|
|
|
self.ListFileMacros[T.ListFileMacro].append(str(F).replace ('\\', '/'))
|
2014-01-27 06:23:15 +01:00
|
|
|
self.FileListMacros[T.FileListMacro].append(NewFile)
|
|
|
|
elif T.GenFileListMacro:
|
|
|
|
self.FileListMacros[T.FileListMacro].append(NewFile)
|
|
|
|
else:
|
|
|
|
Deps.append(NewFile)
|
|
|
|
|
|
|
|
# Use file list macro as dependency
|
|
|
|
if T.GenFileListMacro:
|
|
|
|
Deps.append("$(%s)" % T.FileListMacro)
|
2017-12-04 03:25:43 +01:00
|
|
|
if Type in [TAB_OBJECT_FILE, TAB_STATIC_LIBRARY]:
|
|
|
|
Deps.append("$(%s)" % T.ListFileMacro)
|
2014-01-27 06:23:15 +01:00
|
|
|
|
|
|
|
TargetDict = {
|
|
|
|
"target" : self.PlaceMacro(T.Target.Path, self.Macros),
|
|
|
|
"cmd" : "\n\t".join(T.Commands),
|
|
|
|
"deps" : Deps
|
|
|
|
}
|
|
|
|
self.BuildTargetList.append(self._BUILD_TARGET_TEMPLATE.Replace(TargetDict))
|
|
|
|
|
|
|
|
## For creating makefile targets for dependent libraries
|
|
|
|
def ProcessDependentLibrary(self):
|
|
|
|
for LibraryAutoGen in self._AutoGenObject.LibraryAutoGenList:
|
2016-06-13 12:00:52 +02:00
|
|
|
if not LibraryAutoGen.IsBinaryModule:
|
|
|
|
self.LibraryBuildDirectoryList.append(self.PlaceMacro(LibraryAutoGen.BuildDir, self.Macros))
|
2014-01-27 06:23:15 +01:00
|
|
|
|
|
|
|
## Return a list containing source file's dependencies
|
|
|
|
#
|
|
|
|
# @param FileList The list of source files
|
|
|
|
# @param ForceInculeList The list of files which will be included forcely
|
|
|
|
# @param SearchPathList The list of search path
|
|
|
|
#
|
|
|
|
# @retval dict The mapping between source file path and its dependencies
|
|
|
|
#
|
|
|
|
def GetFileDependency(self, FileList, ForceInculeList, SearchPathList):
|
|
|
|
Dependency = {}
|
|
|
|
for F in FileList:
|
|
|
|
Dependency[F] = self.GetDependencyList(F, ForceInculeList, SearchPathList)
|
|
|
|
return Dependency
|
|
|
|
|
|
|
|
## Find dependencies for one source file
|
|
|
|
#
|
|
|
|
# By searching recursively "#include" directive in file, find out all the
|
|
|
|
# files needed by given source file. The dependecies will be only searched
|
|
|
|
# in given search path list.
|
|
|
|
#
|
|
|
|
# @param File The source file
|
|
|
|
# @param ForceInculeList The list of files which will be included forcely
|
|
|
|
# @param SearchPathList The list of search path
|
|
|
|
#
|
|
|
|
# @retval list The list of files the given source file depends on
|
|
|
|
#
|
|
|
|
def GetDependencyList(self, File, ForceList, SearchPathList):
|
|
|
|
EdkLogger.debug(EdkLogger.DEBUG_1, "Try to get dependency files for %s" % File)
|
|
|
|
FileStack = [File] + ForceList
|
|
|
|
DependencySet = set()
|
|
|
|
|
|
|
|
if self._AutoGenObject.Arch not in gDependencyDatabase:
|
|
|
|
gDependencyDatabase[self._AutoGenObject.Arch] = {}
|
|
|
|
DepDb = gDependencyDatabase[self._AutoGenObject.Arch]
|
|
|
|
|
|
|
|
while len(FileStack) > 0:
|
|
|
|
F = FileStack.pop()
|
|
|
|
|
|
|
|
FullPathDependList = []
|
|
|
|
if F in self.FileCache:
|
|
|
|
for CacheFile in self.FileCache[F]:
|
|
|
|
FullPathDependList.append(CacheFile)
|
|
|
|
if CacheFile not in DependencySet:
|
|
|
|
FileStack.append(CacheFile)
|
|
|
|
DependencySet.update(FullPathDependList)
|
|
|
|
continue
|
|
|
|
|
|
|
|
CurrentFileDependencyList = []
|
|
|
|
if F in DepDb:
|
|
|
|
CurrentFileDependencyList = DepDb[F]
|
|
|
|
else:
|
|
|
|
try:
|
|
|
|
Fd = open(F.Path, 'r')
|
|
|
|
except BaseException, X:
|
2015-12-01 05:22:16 +01:00
|
|
|
EdkLogger.error("build", FILE_OPEN_FAILURE, ExtraData=F.Path + "\n\t" + str(X))
|
2014-01-27 06:23:15 +01:00
|
|
|
|
|
|
|
FileContent = Fd.read()
|
|
|
|
Fd.close()
|
|
|
|
if len(FileContent) == 0:
|
|
|
|
continue
|
|
|
|
|
|
|
|
if FileContent[0] == 0xff or FileContent[0] == 0xfe:
|
|
|
|
FileContent = unicode(FileContent, "utf-16")
|
|
|
|
IncludedFileList = gIncludePattern.findall(FileContent)
|
|
|
|
|
|
|
|
for Inc in IncludedFileList:
|
|
|
|
Inc = Inc.strip()
|
|
|
|
# if there's macro used to reference header file, expand it
|
|
|
|
HeaderList = gMacroPattern.findall(Inc)
|
|
|
|
if len(HeaderList) == 1 and len(HeaderList[0]) == 2:
|
|
|
|
HeaderType = HeaderList[0][0]
|
|
|
|
HeaderKey = HeaderList[0][1]
|
|
|
|
if HeaderType in gIncludeMacroConversion:
|
|
|
|
Inc = gIncludeMacroConversion[HeaderType] % {"HeaderKey" : HeaderKey}
|
|
|
|
else:
|
|
|
|
# not known macro used in #include, always build the file by
|
|
|
|
# returning a empty dependency
|
|
|
|
self.FileCache[File] = []
|
|
|
|
return []
|
|
|
|
Inc = os.path.normpath(Inc)
|
|
|
|
CurrentFileDependencyList.append(Inc)
|
|
|
|
DepDb[F] = CurrentFileDependencyList
|
|
|
|
|
|
|
|
CurrentFilePath = F.Dir
|
|
|
|
PathList = [CurrentFilePath] + SearchPathList
|
|
|
|
for Inc in CurrentFileDependencyList:
|
|
|
|
for SearchPath in PathList:
|
|
|
|
FilePath = os.path.join(SearchPath, Inc)
|
|
|
|
if FilePath in gIsFileMap:
|
|
|
|
if not gIsFileMap[FilePath]:
|
|
|
|
continue
|
|
|
|
# If isfile is called too many times, the performance is slow down.
|
|
|
|
elif not os.path.isfile(FilePath):
|
|
|
|
gIsFileMap[FilePath] = False
|
|
|
|
continue
|
|
|
|
else:
|
|
|
|
gIsFileMap[FilePath] = True
|
|
|
|
FilePath = PathClass(FilePath)
|
|
|
|
FullPathDependList.append(FilePath)
|
|
|
|
if FilePath not in DependencySet:
|
|
|
|
FileStack.append(FilePath)
|
|
|
|
break
|
|
|
|
else:
|
|
|
|
EdkLogger.debug(EdkLogger.DEBUG_9, "%s included by %s was not found "\
|
|
|
|
"in any given path:\n\t%s" % (Inc, F, "\n\t".join(SearchPathList)))
|
|
|
|
|
|
|
|
self.FileCache[F] = FullPathDependList
|
|
|
|
DependencySet.update(FullPathDependList)
|
|
|
|
|
|
|
|
DependencySet.update(ForceList)
|
|
|
|
if File in DependencySet:
|
|
|
|
DependencySet.remove(File)
|
|
|
|
DependencyList = list(DependencySet) # remove duplicate ones
|
|
|
|
|
|
|
|
return DependencyList
|
|
|
|
|
|
|
|
_TemplateDict = property(_CreateTemplateDict)
|
|
|
|
|
|
|
|
## CustomMakefile class
|
|
|
|
#
|
|
|
|
# This class encapsules makefie and its generation for module. It uses template to generate
|
|
|
|
# the content of makefile. The content of makefile will be got from ModuleAutoGen object.
|
|
|
|
#
|
|
|
|
class CustomMakefile(BuildFile):
|
|
|
|
## template used to generate the makefile for module with custom makefile
|
|
|
|
_TEMPLATE_ = TemplateString('''\
|
|
|
|
${makefile_header}
|
|
|
|
|
|
|
|
#
|
|
|
|
# Platform Macro Definition
|
|
|
|
#
|
|
|
|
PLATFORM_NAME = ${platform_name}
|
|
|
|
PLATFORM_GUID = ${platform_guid}
|
|
|
|
PLATFORM_VERSION = ${platform_version}
|
|
|
|
PLATFORM_RELATIVE_DIR = ${platform_relative_directory}
|
2016-04-14 18:28:19 +02:00
|
|
|
PLATFORM_DIR = ${platform_dir}
|
2014-01-27 06:23:15 +01:00
|
|
|
PLATFORM_OUTPUT_DIR = ${platform_output_directory}
|
|
|
|
|
|
|
|
#
|
|
|
|
# Module Macro Definition
|
|
|
|
#
|
|
|
|
MODULE_NAME = ${module_name}
|
|
|
|
MODULE_GUID = ${module_guid}
|
2015-06-10 09:50:59 +02:00
|
|
|
MODULE_NAME_GUID = ${module_name_guid}
|
2014-01-27 06:23:15 +01:00
|
|
|
MODULE_VERSION = ${module_version}
|
|
|
|
MODULE_TYPE = ${module_type}
|
|
|
|
MODULE_FILE = ${module_file}
|
|
|
|
MODULE_FILE_BASE_NAME = ${module_file_base_name}
|
|
|
|
BASE_NAME = $(MODULE_NAME)
|
|
|
|
MODULE_RELATIVE_DIR = ${module_relative_directory}
|
2016-02-21 01:46:58 +01:00
|
|
|
MODULE_DIR = ${module_dir}
|
2014-01-27 06:23:15 +01:00
|
|
|
|
|
|
|
#
|
|
|
|
# Build Configuration Macro Definition
|
|
|
|
#
|
|
|
|
ARCH = ${architecture}
|
|
|
|
TOOLCHAIN = ${toolchain_tag}
|
|
|
|
TOOLCHAIN_TAG = ${toolchain_tag}
|
|
|
|
TARGET = ${build_target}
|
|
|
|
|
|
|
|
#
|
|
|
|
# Build Directory Macro Definition
|
|
|
|
#
|
|
|
|
# PLATFORM_BUILD_DIR = ${platform_build_directory}
|
|
|
|
BUILD_DIR = ${platform_build_directory}
|
|
|
|
BIN_DIR = $(BUILD_DIR)${separator}${architecture}
|
|
|
|
LIB_DIR = $(BIN_DIR)
|
|
|
|
MODULE_BUILD_DIR = ${module_build_directory}
|
|
|
|
OUTPUT_DIR = ${module_output_directory}
|
|
|
|
DEBUG_DIR = ${module_debug_directory}
|
|
|
|
DEST_DIR_OUTPUT = $(OUTPUT_DIR)
|
|
|
|
DEST_DIR_DEBUG = $(DEBUG_DIR)
|
|
|
|
|
|
|
|
#
|
|
|
|
# Tools definitions specific to this module
|
|
|
|
#
|
|
|
|
${BEGIN}${module_tool_definitions}
|
|
|
|
${END}
|
|
|
|
MAKE_FILE = ${makefile_path}
|
|
|
|
|
|
|
|
#
|
|
|
|
# Shell Command Macro
|
|
|
|
#
|
|
|
|
${BEGIN}${shell_command_code} = ${shell_command}
|
|
|
|
${END}
|
|
|
|
|
|
|
|
${custom_makefile_content}
|
|
|
|
|
|
|
|
#
|
|
|
|
# Target used when called from platform makefile, which will bypass the build of dependent libraries
|
|
|
|
#
|
|
|
|
|
|
|
|
pbuild: init all
|
|
|
|
|
|
|
|
|
|
|
|
#
|
|
|
|
# ModuleTarget
|
|
|
|
#
|
|
|
|
|
|
|
|
mbuild: init all
|
|
|
|
|
|
|
|
#
|
|
|
|
# Build Target used in multi-thread build mode, which no init target is needed
|
|
|
|
#
|
|
|
|
|
|
|
|
tbuild: all
|
|
|
|
|
|
|
|
#
|
|
|
|
# Initialization target: print build information and create necessary directories
|
|
|
|
#
|
|
|
|
init:
|
|
|
|
\t-@echo Building ... $(MODULE_DIR)${separator}$(MODULE_FILE) [$(ARCH)]
|
|
|
|
${BEGIN}\t-@${create_directory_command}\n${END}\
|
|
|
|
|
|
|
|
''')
|
|
|
|
|
|
|
|
## Constructor of CustomMakefile
|
|
|
|
#
|
|
|
|
# @param ModuleAutoGen Object of ModuleAutoGen class
|
|
|
|
#
|
|
|
|
def __init__(self, ModuleAutoGen):
|
|
|
|
BuildFile.__init__(self, ModuleAutoGen)
|
|
|
|
self.PlatformInfo = self._AutoGenObject.PlatformInfo
|
|
|
|
self.IntermediateDirectoryList = ["$(DEBUG_DIR)", "$(OUTPUT_DIR)"]
|
|
|
|
|
|
|
|
# Compose a dict object containing information used to do replacement in template
|
|
|
|
def _CreateTemplateDict(self):
|
|
|
|
Separator = self._SEP_[self._FileType]
|
|
|
|
if self._FileType not in self._AutoGenObject.CustomMakefile:
|
|
|
|
EdkLogger.error('build', OPTION_NOT_SUPPORTED, "No custom makefile for %s" % self._FileType,
|
|
|
|
ExtraData="[%s]" % str(self._AutoGenObject))
|
2016-02-21 01:46:58 +01:00
|
|
|
MakefilePath = mws.join(
|
2014-01-27 06:23:15 +01:00
|
|
|
self._AutoGenObject.WorkspaceDir,
|
|
|
|
self._AutoGenObject.CustomMakefile[self._FileType]
|
|
|
|
)
|
|
|
|
try:
|
|
|
|
CustomMakefile = open(MakefilePath, 'r').read()
|
|
|
|
except:
|
|
|
|
EdkLogger.error('build', FILE_OPEN_FAILURE, File=str(self._AutoGenObject),
|
|
|
|
ExtraData=self._AutoGenObject.CustomMakefile[self._FileType])
|
|
|
|
|
|
|
|
# tools definitions
|
|
|
|
ToolsDef = []
|
|
|
|
for Tool in self._AutoGenObject.BuildOption:
|
|
|
|
# Don't generate MAKE_FLAGS in makefile. It's put in environment variable.
|
|
|
|
if Tool == "MAKE":
|
|
|
|
continue
|
|
|
|
for Attr in self._AutoGenObject.BuildOption[Tool]:
|
|
|
|
if Attr == "FAMILY":
|
|
|
|
continue
|
|
|
|
elif Attr == "PATH":
|
|
|
|
ToolsDef.append("%s = %s" % (Tool, self._AutoGenObject.BuildOption[Tool][Attr]))
|
|
|
|
else:
|
|
|
|
ToolsDef.append("%s_%s = %s" % (Tool, Attr, self._AutoGenObject.BuildOption[Tool][Attr]))
|
|
|
|
ToolsDef.append("")
|
|
|
|
|
|
|
|
MakefileName = self._FILE_NAME_[self._FileType]
|
|
|
|
MakefileTemplateDict = {
|
|
|
|
"makefile_header" : self._FILE_HEADER_[self._FileType],
|
|
|
|
"makefile_path" : os.path.join("$(MODULE_BUILD_DIR)", MakefileName),
|
|
|
|
"platform_name" : self.PlatformInfo.Name,
|
|
|
|
"platform_guid" : self.PlatformInfo.Guid,
|
|
|
|
"platform_version" : self.PlatformInfo.Version,
|
|
|
|
"platform_relative_directory": self.PlatformInfo.SourceDir,
|
|
|
|
"platform_output_directory" : self.PlatformInfo.OutputDir,
|
2016-04-13 07:09:17 +02:00
|
|
|
"platform_dir" : self._AutoGenObject.Macros["PLATFORM_DIR"],
|
2014-01-27 06:23:15 +01:00
|
|
|
|
|
|
|
"module_name" : self._AutoGenObject.Name,
|
|
|
|
"module_guid" : self._AutoGenObject.Guid,
|
2015-06-10 09:50:59 +02:00
|
|
|
"module_name_guid" : self._AutoGenObject._GetUniqueBaseName(),
|
2014-01-27 06:23:15 +01:00
|
|
|
"module_version" : self._AutoGenObject.Version,
|
|
|
|
"module_type" : self._AutoGenObject.ModuleType,
|
|
|
|
"module_file" : self._AutoGenObject.MetaFile,
|
|
|
|
"module_file_base_name" : self._AutoGenObject.MetaFile.BaseName,
|
|
|
|
"module_relative_directory" : self._AutoGenObject.SourceDir,
|
2016-02-21 01:46:58 +01:00
|
|
|
"module_dir" : mws.join (self._AutoGenObject.WorkspaceDir, self._AutoGenObject.SourceDir),
|
2014-01-27 06:23:15 +01:00
|
|
|
|
|
|
|
"architecture" : self._AutoGenObject.Arch,
|
|
|
|
"toolchain_tag" : self._AutoGenObject.ToolChain,
|
|
|
|
"build_target" : self._AutoGenObject.BuildTarget,
|
|
|
|
|
|
|
|
"platform_build_directory" : self.PlatformInfo.BuildDir,
|
|
|
|
"module_build_directory" : self._AutoGenObject.BuildDir,
|
|
|
|
"module_output_directory" : self._AutoGenObject.OutputDir,
|
|
|
|
"module_debug_directory" : self._AutoGenObject.DebugDir,
|
|
|
|
|
|
|
|
"separator" : Separator,
|
|
|
|
"module_tool_definitions" : ToolsDef,
|
|
|
|
|
|
|
|
"shell_command_code" : self._SHELL_CMD_[self._FileType].keys(),
|
|
|
|
"shell_command" : self._SHELL_CMD_[self._FileType].values(),
|
|
|
|
|
|
|
|
"create_directory_command" : self.GetCreateDirectoryCommand(self.IntermediateDirectoryList),
|
|
|
|
"custom_makefile_content" : CustomMakefile
|
|
|
|
}
|
|
|
|
|
|
|
|
return MakefileTemplateDict
|
|
|
|
|
|
|
|
_TemplateDict = property(_CreateTemplateDict)
|
|
|
|
|
|
|
|
## PlatformMakefile class
|
|
|
|
#
|
|
|
|
# This class encapsules makefie and its generation for platform. It uses
|
|
|
|
# template to generate the content of makefile. The content of makefile will be
|
|
|
|
# got from PlatformAutoGen object.
|
|
|
|
#
|
|
|
|
class PlatformMakefile(BuildFile):
|
|
|
|
## template used to generate the makefile for platform
|
|
|
|
_TEMPLATE_ = TemplateString('''\
|
|
|
|
${makefile_header}
|
|
|
|
|
|
|
|
#
|
|
|
|
# Platform Macro Definition
|
|
|
|
#
|
|
|
|
PLATFORM_NAME = ${platform_name}
|
|
|
|
PLATFORM_GUID = ${platform_guid}
|
|
|
|
PLATFORM_VERSION = ${platform_version}
|
|
|
|
PLATFORM_FILE = ${platform_file}
|
2016-04-14 18:28:19 +02:00
|
|
|
PLATFORM_DIR = ${platform_dir}
|
2014-01-27 06:23:15 +01:00
|
|
|
PLATFORM_OUTPUT_DIR = ${platform_output_directory}
|
|
|
|
|
|
|
|
#
|
|
|
|
# Build Configuration Macro Definition
|
|
|
|
#
|
|
|
|
TOOLCHAIN = ${toolchain_tag}
|
|
|
|
TOOLCHAIN_TAG = ${toolchain_tag}
|
|
|
|
TARGET = ${build_target}
|
|
|
|
|
|
|
|
#
|
|
|
|
# Build Directory Macro Definition
|
|
|
|
#
|
|
|
|
BUILD_DIR = ${platform_build_directory}
|
|
|
|
FV_DIR = ${platform_build_directory}${separator}FV
|
|
|
|
|
|
|
|
#
|
|
|
|
# Shell Command Macro
|
|
|
|
#
|
|
|
|
${BEGIN}${shell_command_code} = ${shell_command}
|
|
|
|
${END}
|
|
|
|
|
|
|
|
MAKE = ${make_path}
|
|
|
|
MAKE_FILE = ${makefile_path}
|
|
|
|
|
|
|
|
#
|
|
|
|
# Default target
|
|
|
|
#
|
|
|
|
all: init build_libraries build_modules
|
|
|
|
|
|
|
|
#
|
|
|
|
# Initialization target: print build information and create necessary directories
|
|
|
|
#
|
|
|
|
init:
|
|
|
|
\t-@echo Building ... $(PLATFORM_FILE) [${build_architecture_list}]
|
|
|
|
\t${BEGIN}-@${create_directory_command}
|
|
|
|
\t${END}
|
|
|
|
#
|
|
|
|
# library build target
|
|
|
|
#
|
|
|
|
libraries: init build_libraries
|
|
|
|
|
|
|
|
#
|
|
|
|
# module build target
|
|
|
|
#
|
|
|
|
modules: init build_libraries build_modules
|
|
|
|
|
|
|
|
#
|
|
|
|
# Build all libraries:
|
|
|
|
#
|
|
|
|
build_libraries:
|
|
|
|
${BEGIN}\t@"$(MAKE)" $(MAKE_FLAGS) -f ${library_makefile_list} pbuild
|
|
|
|
${END}\t@cd $(BUILD_DIR)
|
|
|
|
|
|
|
|
#
|
|
|
|
# Build all modules:
|
|
|
|
#
|
|
|
|
build_modules:
|
|
|
|
${BEGIN}\t@"$(MAKE)" $(MAKE_FLAGS) -f ${module_makefile_list} pbuild
|
|
|
|
${END}\t@cd $(BUILD_DIR)
|
|
|
|
|
|
|
|
#
|
|
|
|
# Clean intermediate files
|
|
|
|
#
|
|
|
|
clean:
|
|
|
|
\t${BEGIN}-@${library_build_command} clean
|
|
|
|
\t${END}${BEGIN}-@${module_build_command} clean
|
|
|
|
\t${END}@cd $(BUILD_DIR)
|
|
|
|
|
|
|
|
#
|
|
|
|
# Clean all generated files except to makefile
|
|
|
|
#
|
|
|
|
cleanall:
|
|
|
|
${BEGIN}\t${cleanall_command}
|
|
|
|
${END}
|
|
|
|
|
|
|
|
#
|
|
|
|
# Clean all library files
|
|
|
|
#
|
|
|
|
cleanlib:
|
|
|
|
\t${BEGIN}-@${library_build_command} cleanall
|
|
|
|
\t${END}@cd $(BUILD_DIR)\n
|
|
|
|
''')
|
|
|
|
|
|
|
|
## Constructor of PlatformMakefile
|
|
|
|
#
|
|
|
|
# @param ModuleAutoGen Object of PlatformAutoGen class
|
|
|
|
#
|
|
|
|
def __init__(self, PlatformAutoGen):
|
|
|
|
BuildFile.__init__(self, PlatformAutoGen)
|
|
|
|
self.ModuleBuildCommandList = []
|
|
|
|
self.ModuleMakefileList = []
|
|
|
|
self.IntermediateDirectoryList = []
|
|
|
|
self.ModuleBuildDirectoryList = []
|
|
|
|
self.LibraryBuildDirectoryList = []
|
2014-08-18 06:59:01 +02:00
|
|
|
self.LibraryMakeCommandList = []
|
2014-01-27 06:23:15 +01:00
|
|
|
|
|
|
|
# Compose a dict object containing information used to do replacement in template
|
|
|
|
def _CreateTemplateDict(self):
|
|
|
|
Separator = self._SEP_[self._FileType]
|
|
|
|
|
|
|
|
PlatformInfo = self._AutoGenObject
|
|
|
|
if "MAKE" not in PlatformInfo.ToolDefinition or "PATH" not in PlatformInfo.ToolDefinition["MAKE"]:
|
|
|
|
EdkLogger.error("build", OPTION_MISSING, "No MAKE command defined. Please check your tools_def.txt!",
|
|
|
|
ExtraData="[%s]" % str(self._AutoGenObject))
|
|
|
|
|
|
|
|
self.IntermediateDirectoryList = ["$(BUILD_DIR)"]
|
|
|
|
self.ModuleBuildDirectoryList = self.GetModuleBuildDirectoryList()
|
|
|
|
self.LibraryBuildDirectoryList = self.GetLibraryBuildDirectoryList()
|
|
|
|
|
|
|
|
MakefileName = self._FILE_NAME_[self._FileType]
|
|
|
|
LibraryMakefileList = []
|
|
|
|
LibraryMakeCommandList = []
|
|
|
|
for D in self.LibraryBuildDirectoryList:
|
|
|
|
D = self.PlaceMacro(D, {"BUILD_DIR":PlatformInfo.BuildDir})
|
|
|
|
Makefile = os.path.join(D, MakefileName)
|
|
|
|
Command = self._MAKE_TEMPLATE_[self._FileType] % {"file":Makefile}
|
|
|
|
LibraryMakefileList.append(Makefile)
|
|
|
|
LibraryMakeCommandList.append(Command)
|
2014-08-18 06:59:01 +02:00
|
|
|
self.LibraryMakeCommandList = LibraryMakeCommandList
|
2014-01-27 06:23:15 +01:00
|
|
|
|
|
|
|
ModuleMakefileList = []
|
|
|
|
ModuleMakeCommandList = []
|
|
|
|
for D in self.ModuleBuildDirectoryList:
|
|
|
|
D = self.PlaceMacro(D, {"BUILD_DIR":PlatformInfo.BuildDir})
|
|
|
|
Makefile = os.path.join(D, MakefileName)
|
|
|
|
Command = self._MAKE_TEMPLATE_[self._FileType] % {"file":Makefile}
|
|
|
|
ModuleMakefileList.append(Makefile)
|
|
|
|
ModuleMakeCommandList.append(Command)
|
|
|
|
|
|
|
|
MakefileTemplateDict = {
|
|
|
|
"makefile_header" : self._FILE_HEADER_[self._FileType],
|
|
|
|
"makefile_path" : os.path.join("$(BUILD_DIR)", MakefileName),
|
|
|
|
"make_path" : PlatformInfo.ToolDefinition["MAKE"]["PATH"],
|
|
|
|
"makefile_name" : MakefileName,
|
|
|
|
"platform_name" : PlatformInfo.Name,
|
|
|
|
"platform_guid" : PlatformInfo.Guid,
|
|
|
|
"platform_version" : PlatformInfo.Version,
|
|
|
|
"platform_file" : self._AutoGenObject.MetaFile,
|
|
|
|
"platform_relative_directory": PlatformInfo.SourceDir,
|
|
|
|
"platform_output_directory" : PlatformInfo.OutputDir,
|
|
|
|
"platform_build_directory" : PlatformInfo.BuildDir,
|
2016-04-13 07:09:17 +02:00
|
|
|
"platform_dir" : self._AutoGenObject.Macros["PLATFORM_DIR"],
|
2014-01-27 06:23:15 +01:00
|
|
|
|
|
|
|
"toolchain_tag" : PlatformInfo.ToolChain,
|
|
|
|
"build_target" : PlatformInfo.BuildTarget,
|
|
|
|
"shell_command_code" : self._SHELL_CMD_[self._FileType].keys(),
|
|
|
|
"shell_command" : self._SHELL_CMD_[self._FileType].values(),
|
|
|
|
"build_architecture_list" : self._AutoGenObject.Arch,
|
|
|
|
"architecture" : self._AutoGenObject.Arch,
|
|
|
|
"separator" : Separator,
|
|
|
|
"create_directory_command" : self.GetCreateDirectoryCommand(self.IntermediateDirectoryList),
|
|
|
|
"cleanall_command" : self.GetRemoveDirectoryCommand(self.IntermediateDirectoryList),
|
|
|
|
"library_makefile_list" : LibraryMakefileList,
|
|
|
|
"module_makefile_list" : ModuleMakefileList,
|
|
|
|
"library_build_command" : LibraryMakeCommandList,
|
|
|
|
"module_build_command" : ModuleMakeCommandList,
|
|
|
|
}
|
|
|
|
|
|
|
|
return MakefileTemplateDict
|
|
|
|
|
|
|
|
## Get the root directory list for intermediate files of all modules build
|
|
|
|
#
|
|
|
|
# @retval list The list of directory
|
|
|
|
#
|
|
|
|
def GetModuleBuildDirectoryList(self):
|
|
|
|
DirList = []
|
|
|
|
for ModuleAutoGen in self._AutoGenObject.ModuleAutoGenList:
|
2014-08-28 15:53:34 +02:00
|
|
|
if not ModuleAutoGen.IsBinaryModule:
|
|
|
|
DirList.append(os.path.join(self._AutoGenObject.BuildDir, ModuleAutoGen.BuildDir))
|
2014-01-27 06:23:15 +01:00
|
|
|
return DirList
|
|
|
|
|
|
|
|
## Get the root directory list for intermediate files of all libraries build
|
|
|
|
#
|
|
|
|
# @retval list The list of directory
|
|
|
|
#
|
|
|
|
def GetLibraryBuildDirectoryList(self):
|
|
|
|
DirList = []
|
|
|
|
for LibraryAutoGen in self._AutoGenObject.LibraryAutoGenList:
|
2014-08-28 15:53:34 +02:00
|
|
|
if not LibraryAutoGen.IsBinaryModule:
|
|
|
|
DirList.append(os.path.join(self._AutoGenObject.BuildDir, LibraryAutoGen.BuildDir))
|
2014-01-27 06:23:15 +01:00
|
|
|
return DirList
|
|
|
|
|
|
|
|
_TemplateDict = property(_CreateTemplateDict)
|
|
|
|
|
|
|
|
## TopLevelMakefile class
|
|
|
|
#
|
|
|
|
# This class encapsules makefie and its generation for entrance makefile. It
|
|
|
|
# uses template to generate the content of makefile. The content of makefile
|
|
|
|
# will be got from WorkspaceAutoGen object.
|
|
|
|
#
|
|
|
|
class TopLevelMakefile(BuildFile):
|
|
|
|
## template used to generate toplevel makefile
|
2014-08-28 15:53:34 +02:00
|
|
|
_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}''')
|
2014-01-27 06:23:15 +01:00
|
|
|
|
|
|
|
## Constructor of TopLevelMakefile
|
|
|
|
#
|
|
|
|
# @param Workspace Object of WorkspaceAutoGen class
|
|
|
|
#
|
|
|
|
def __init__(self, Workspace):
|
|
|
|
BuildFile.__init__(self, Workspace)
|
|
|
|
self.IntermediateDirectoryList = []
|
|
|
|
|
|
|
|
# Compose a dict object containing information used to do replacement in template
|
|
|
|
def _CreateTemplateDict(self):
|
|
|
|
Separator = self._SEP_[self._FileType]
|
|
|
|
|
|
|
|
# any platform autogen object is ok because we just need common information
|
|
|
|
PlatformInfo = self._AutoGenObject
|
|
|
|
|
|
|
|
if "MAKE" not in PlatformInfo.ToolDefinition or "PATH" not in PlatformInfo.ToolDefinition["MAKE"]:
|
|
|
|
EdkLogger.error("build", OPTION_MISSING, "No MAKE command defined. Please check your tools_def.txt!",
|
|
|
|
ExtraData="[%s]" % str(self._AutoGenObject))
|
|
|
|
|
|
|
|
for Arch in PlatformInfo.ArchList:
|
|
|
|
self.IntermediateDirectoryList.append(Separator.join(["$(BUILD_DIR)", Arch]))
|
|
|
|
self.IntermediateDirectoryList.append("$(FV_DIR)")
|
|
|
|
|
|
|
|
# TRICK: for not generating GenFds call in makefile if no FDF file
|
|
|
|
MacroList = []
|
|
|
|
if PlatformInfo.FdfFile != None and PlatformInfo.FdfFile != "":
|
|
|
|
FdfFileList = [PlatformInfo.FdfFile]
|
|
|
|
# macros passed to GenFds
|
|
|
|
MacroList.append('"%s=%s"' % ("EFI_SOURCE", GlobalData.gEfiSource.replace('\\', '\\\\')))
|
|
|
|
MacroList.append('"%s=%s"' % ("EDK_SOURCE", GlobalData.gEdkSource.replace('\\', '\\\\')))
|
|
|
|
MacroDict = {}
|
|
|
|
MacroDict.update(GlobalData.gGlobalDefines)
|
|
|
|
MacroDict.update(GlobalData.gCommandLineDefines)
|
|
|
|
MacroDict.pop("EFI_SOURCE", "dummy")
|
|
|
|
MacroDict.pop("EDK_SOURCE", "dummy")
|
|
|
|
for MacroName in MacroDict:
|
|
|
|
if MacroDict[MacroName] != "":
|
|
|
|
MacroList.append('"%s=%s"' % (MacroName, MacroDict[MacroName].replace('\\', '\\\\')))
|
|
|
|
else:
|
|
|
|
MacroList.append('"%s"' % MacroName)
|
|
|
|
else:
|
|
|
|
FdfFileList = []
|
|
|
|
|
|
|
|
# pass extra common options to external program called in makefile, currently GenFds.exe
|
|
|
|
ExtraOption = ''
|
|
|
|
LogLevel = EdkLogger.GetLevel()
|
|
|
|
if LogLevel == EdkLogger.VERBOSE:
|
|
|
|
ExtraOption += " -v"
|
|
|
|
elif LogLevel <= EdkLogger.DEBUG_9:
|
|
|
|
ExtraOption += " -d %d" % (LogLevel - 1)
|
|
|
|
elif LogLevel == EdkLogger.QUIET:
|
|
|
|
ExtraOption += " -q"
|
|
|
|
|
|
|
|
if GlobalData.gCaseInsensitive:
|
|
|
|
ExtraOption += " -c"
|
2017-11-22 08:42:25 +01:00
|
|
|
if GlobalData.gEnableGenfdsMultiThread:
|
|
|
|
ExtraOption += " --genfds-multi-thread"
|
2014-08-28 15:53:34 +02:00
|
|
|
if GlobalData.gIgnoreSource:
|
|
|
|
ExtraOption += " --ignore-sources"
|
|
|
|
|
2016-04-20 03:32:52 +02:00
|
|
|
if GlobalData.BuildOptionPcd:
|
|
|
|
for index, option in enumerate(GlobalData.gCommand):
|
|
|
|
if "--pcd" == option and GlobalData.gCommand[index+1]:
|
2017-05-12 06:12:23 +02:00
|
|
|
pcdName, pcdValue = GlobalData.gCommand[index+1].split('=')
|
|
|
|
if pcdValue.startswith('H'):
|
|
|
|
pcdValue = 'H' + '"' + pcdValue[1:] + '"'
|
|
|
|
ExtraOption += " --pcd " + pcdName + '=' + pcdValue
|
|
|
|
elif pcdValue.startswith('L'):
|
|
|
|
pcdValue = 'L' + '"' + pcdValue[1:] + '"'
|
|
|
|
ExtraOption += " --pcd " + pcdName + '=' + pcdValue
|
|
|
|
else:
|
|
|
|
ExtraOption += " --pcd " + GlobalData.gCommand[index+1]
|
2016-04-20 03:32:52 +02:00
|
|
|
|
2014-01-27 06:23:15 +01:00
|
|
|
MakefileName = self._FILE_NAME_[self._FileType]
|
|
|
|
SubBuildCommandList = []
|
|
|
|
for A in PlatformInfo.ArchList:
|
|
|
|
Command = self._MAKE_TEMPLATE_[self._FileType] % {"file":os.path.join("$(BUILD_DIR)", A, MakefileName)}
|
|
|
|
SubBuildCommandList.append(Command)
|
|
|
|
|
|
|
|
MakefileTemplateDict = {
|
|
|
|
"makefile_header" : self._FILE_HEADER_[self._FileType],
|
|
|
|
"makefile_path" : os.path.join("$(BUILD_DIR)", MakefileName),
|
|
|
|
"make_path" : PlatformInfo.ToolDefinition["MAKE"]["PATH"],
|
|
|
|
"platform_name" : PlatformInfo.Name,
|
|
|
|
"platform_guid" : PlatformInfo.Guid,
|
|
|
|
"platform_version" : PlatformInfo.Version,
|
|
|
|
"platform_build_directory" : PlatformInfo.BuildDir,
|
2014-08-28 15:53:34 +02:00
|
|
|
"conf_directory" : GlobalData.gConfDirectory,
|
2014-01-27 06:23:15 +01:00
|
|
|
|
|
|
|
"toolchain_tag" : PlatformInfo.ToolChain,
|
|
|
|
"build_target" : PlatformInfo.BuildTarget,
|
|
|
|
"shell_command_code" : self._SHELL_CMD_[self._FileType].keys(),
|
|
|
|
"shell_command" : self._SHELL_CMD_[self._FileType].values(),
|
|
|
|
'arch' : list(PlatformInfo.ArchList),
|
|
|
|
"build_architecture_list" : ','.join(PlatformInfo.ArchList),
|
|
|
|
"separator" : Separator,
|
|
|
|
"create_directory_command" : self.GetCreateDirectoryCommand(self.IntermediateDirectoryList),
|
|
|
|
"cleanall_command" : self.GetRemoveDirectoryCommand(self.IntermediateDirectoryList),
|
|
|
|
"sub_build_command" : SubBuildCommandList,
|
|
|
|
"fdf_file" : FdfFileList,
|
|
|
|
"active_platform" : str(PlatformInfo),
|
|
|
|
"fd" : PlatformInfo.FdTargetList,
|
|
|
|
"fv" : PlatformInfo.FvTargetList,
|
|
|
|
"cap" : PlatformInfo.CapTargetList,
|
|
|
|
"extra_options" : ExtraOption,
|
|
|
|
"macro" : MacroList,
|
|
|
|
}
|
|
|
|
|
|
|
|
return MakefileTemplateDict
|
|
|
|
|
|
|
|
## Get the root directory list for intermediate files of all modules build
|
|
|
|
#
|
|
|
|
# @retval list The list of directory
|
|
|
|
#
|
|
|
|
def GetModuleBuildDirectoryList(self):
|
|
|
|
DirList = []
|
|
|
|
for ModuleAutoGen in self._AutoGenObject.ModuleAutoGenList:
|
2014-08-28 15:53:34 +02:00
|
|
|
if not ModuleAutoGen.IsBinaryModule:
|
|
|
|
DirList.append(os.path.join(self._AutoGenObject.BuildDir, ModuleAutoGen.BuildDir))
|
2014-01-27 06:23:15 +01:00
|
|
|
return DirList
|
|
|
|
|
|
|
|
## Get the root directory list for intermediate files of all libraries build
|
|
|
|
#
|
|
|
|
# @retval list The list of directory
|
|
|
|
#
|
|
|
|
def GetLibraryBuildDirectoryList(self):
|
|
|
|
DirList = []
|
|
|
|
for LibraryAutoGen in self._AutoGenObject.LibraryAutoGenList:
|
2014-08-28 15:53:34 +02:00
|
|
|
if not LibraryAutoGen.IsBinaryModule:
|
|
|
|
DirList.append(os.path.join(self._AutoGenObject.BuildDir, LibraryAutoGen.BuildDir))
|
2014-01-27 06:23:15 +01:00
|
|
|
return DirList
|
|
|
|
|
|
|
|
_TemplateDict = property(_CreateTemplateDict)
|
|
|
|
|
|
|
|
# This acts like the main() function for the script, unless it is 'import'ed into another script.
|
|
|
|
if __name__ == '__main__':
|
|
|
|
pass
|
|
|
|
|