## @file
# The engine for building files
#
# Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
# 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
#
# 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
#
import os
import re
import copy
import string
from Common.GlobalData import *
from Common.BuildToolError import *
## Convert file type to file list macro name
#
# @param FileType The name of file type
#
# @retval string The name of macro
#
## Convert file type to list file macro name
#
# @param FileType The name of file type
#
# @retval string The name of macro
#
# Factory method
else:
#Class._Cache_[Outputs[0]] = Tdb
return Tdb
else:
else:
def Renew():
TargetDescBlock._Cache_ = {}
## Class for one build rule
#
# This represents a build rule which can give out corresponding command list for
# building the given source file(s). The result can be used for generating the
# target for makefile.
#
class FileBuildRule:
## constructor
#
# @param Input The dictionary represeting input file(s) for a rule
# @param Output The list represeting output file(s) for a rule
# @param Command The list containing commands to generate the output from input
#
# The Input should not be empty
if not Input:
Input = []
if not Output:
Output = []
if not Command:
Command = []
# source files listed not in "*" or "?" pattern format
if not ExtraDependency:
self.ExtraSourceFileList = []
else:
#
# Search macros used in command lines for <FILE_TYPE>_LIST and INC_LIST.
# If found, generate a file to keep the input files used to get over the
# limitation of command line length
#
self.CommandList = []
# replace path separator with native one
# Indicate what should be generated
else:
else:
else:
# Check input files
self.SourceFileExtList = []
# There's "*" in the file name
# There's no "*" and "?" in file name
continue
# Check output files
self.DestFileList = []
# All build targets generated by this rule for a module
self.BuildTargets = {}
## str() function support
#
# @retval string
#
SourceString = ""
SourceString += " %s %s %s" % (self.SourceFileType, " ".join(self.SourceFileExtList), self.ExtraSourceFileList)
## Check if given file extension is supported by this rule
#
# @param FileExt The extension of a file
#
# @retval True If the extension is supported
# @retval False If the extension is not supported
#
return NewRuleObject
## Apply the rule to given source file(s)
#
# @param SourceFile One file or a list of files to be built
# @param RelativeToDir The relative path of the source file
# @param PathSeparator Path separator
#
# @retval tuple (Source file in full path, List of individual sourcefiles, Destionation file, List of build commands)
#
return None
# source file
if self.IsMultipleInput:
SrcFileName = ""
SrcFileBase = ""
SrcFileExt = ""
SrcFileDir = ""
SrcPath = ""
# SourceFile must be a list
else:
if SourceFile.Root:
if SrcFileDir == "":
SrcFileDir = "."
else:
SrcFileDir = "."
# destination file (the first one)
if self.DestFileList:
else:
DestFile = ""
DestPath = ""
DestFileName = ""
DestFileBase = ""
DestFileExt = ""
# source file
"src" : SrcFile,
"s_path" : SrcPath,
"s_dir" : SrcFileDir,
"s_name" : SrcFileName,
"s_base" : SrcFileBase,
"s_ext" : SrcFileExt,
# destination file
"dst" : DestFile,
"d_path" : DestPath,
"d_name" : DestFileName,
"d_base" : DestFileBase,
"d_ext" : DestFileExt,
}
DstFile = []
else:
CommandList = []
return TargetDesc
## Class for build rules
#
# BuildRule class parses rules defined in a file or passed by caller, and converts
# the rule into FileBuildRule object.
#
class BuildRule:
_BinaryFileRule = FileBuildRule(TAB_DEFAULT_BINARY_FILE, [], [os.path.join("$(OUTPUT_DIR)", "${s_name}")],
["$(CP) ${src} ${dst}"], [])
## Constructor
#
# @param File The file containing build rules in a well defined format
# @param Content The string list of build rules in a well defined format
# @param LineIndex The line number from which the parsing will begin
# @param SupportedFamily The list of supported tool chain families
#
def __init__(self, File=None, Content=None, LineIndex=0, SupportedFamily=["MSFT", "INTEL", "GCC", "RVCT"]):
# Read build rules from file if it's not none
if File != None:
try:
except:
elif Content != None:
else:
self._RuleInfo = tdict(True, 2) # {toolchain family : {"InputFile": {}, "OutputFile" : [], "Command" : []}}
self._BuildTypeList = []
self._FamilyList = []
# some intrinsic rules
## Parse the build rule strings
# Clean up the line and replace path separator with native one
# find the build_rule_version
if Line.find("=") <> -1 and Line.find("=") < (len(Line)-1) and (Line[(Line.find("=") + 1):]).split():
# skip empty or comment line
continue
# find out section header, enclosed by []
# merge last section information into rule database
# find out sub-section header, enclosed by <>
# call section handler to parse each (sub)section
# merge last section information into rule database
## Parse definitions under a section
#
# @param LineIndex The line index of build rule text
#
pass
## Parse definitions under a subsection
#
# @param LineIndex The line index of build rule text
#
# currenly nothing here
pass
## Placeholder for not supported sections
#
# @param LineIndex The line index of build rule text
#
pass
## Merge section information just got into rule database
# if there's specific toochain family, 'COMMON' doesn't make sense any more
## Parse section header
#
# @param LineIndex The line index of build rule text
#
self._BuildTypeList = []
self._FamilyList = []
FileType = ''
for RuleName in RuleNameList:
Arch = 'COMMON'
BuildType = 'COMMON'
# old format: Build.File-Type
if FileType == '':
ExtraData="Only character, number (non-first character), '_' and '-' are allowed in file type")
# new format: File-Type.Build-Type.Arch
else:
if FileType == '':
"Different file types are not allowed in the same rule section",
"Specific build types must not be mixed with common one",
"Specific ARCH must not be mixed with common one",
## Parse sub-section header
#
# @param LineIndex The line index of build rule text
#
SectionType = ""
FamilyList = []
if SectionType == "":
elif SectionType != Type:
"Two different section types are not allowed in the same sub-section",
else:
Family = "COMMON"
if Family not in FamilyList:
"Specific tool chain family should not be mixed with general one",
## Parse <InputFile> sub-section
#
# @param LineIndex The line index of build rule text
#
if InputFiles == None:
InputFiles = []
## Parse <ExtraDependency> sub-section
#
# @param LineIndex The line index of build rule text
#
if Items == None:
Items = []
## Get a build rule via [] operator
#
# @param FileExt The extension of a file
# @param ToolChainFamily The tool chain family name
# @param BuildVersion The build version number. "*" means any rule
# is applicalbe.
#
# @retval FileType The file type string
# @retval FileBuildRule The object of FileBuildRule
#
# Key = (FileExt, ModuleType, Arch, ToolChainFamily)
if not Key:
return None
else:
return None
else:
_StateHandler = {
}
# This acts like the main() function for the script, unless it is 'import'ed into another
# script.
if __name__ == '__main__':
import sys
print
print
print
print
print
print
print